ssl_util.c revision 8e09f1830f114c016598a3b76fd6d31e1589c012
842ae4bd224140319ae7feec1872b93dfd491143fielding/* Licensed to the Apache Software Foundation (ASF) under one or more
842ae4bd224140319ae7feec1872b93dfd491143fielding * contributor license agreements. See the NOTICE file distributed with
842ae4bd224140319ae7feec1872b93dfd491143fielding * this work for additional information regarding copyright ownership.
842ae4bd224140319ae7feec1872b93dfd491143fielding * The ASF licenses this file to You under the Apache License, Version 2.0
842ae4bd224140319ae7feec1872b93dfd491143fielding * (the "License"); you may not use this file except in compliance with
842ae4bd224140319ae7feec1872b93dfd491143fielding * the License. You may obtain a copy of the License at
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Unless required by applicable law or agreed to in writing, software
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * distributed under the License is distributed on an "AS IS" BASIS,
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * See the License for the specific language governing permissions and
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * limitations under the License.
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * _ __ ___ ___ __| | ___ ___| | mod_ssl
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * | | | | | | (_) | (_| | \__ \__ \ |
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * |_| |_| |_|\___/ \__,_|___|___/___/_|
ce9621257ef9e54c1bbe5ad8a5f445a1f211c2dcnd * Utility Functions
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse /* ``Every day of my life
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse I am forced to add another
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse name to the list of people
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse who piss me off!''
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse -- Calvin */
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse/* _________________________________________________________________
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse** Utility Functions
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse** _________________________________________________________________
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse if (s->port != 0)
05413593151a238718198cc04ca849b2426be106rse id = apr_psprintf(p, "%s:%lu", host, (unsigned long)port);
87a1c79b7b37702a254920ca5214fb282a4fb085dougmapr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, const char *cmd,
87a1c79b7b37702a254920ca5214fb282a4fb085dougm const char * const *argv)
e8f95a682820a599fe41b22977010636be5c2717jim if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK,
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS)
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse if ((proc = (apr_proc_t *)apr_pcalloc(p, sizeof(apr_proc_t))) == NULL)
87a1c79b7b37702a254920ca5214fb282a4fb085dougm if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS)
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rsevoid ssl_util_ppclose(server_rec *s, apr_pool_t *p, apr_file_t *fp)
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse * Run a filter program and read the first line of its stdout output
87a1c79b7b37702a254920ca5214fb282a4fb085dougmchar *ssl_util_readfilter(server_rec *s, apr_pool_t *p, const char *cmd,
87a1c79b7b37702a254920ca5214fb282a4fb085dougm const char * const *argv)
87a1c79b7b37702a254920ca5214fb282a4fb085dougm /* XXX: we are reading 1 byte at a time here */
bb0b94431dc9a1591a0a38a6c48925c6d9213c83rse for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS
03181bdde77be8e10ed297a02db5d8f98ecb703ewroweBOOL ssl_util_path_check(ssl_pathcheck_t pcm, const char *path, apr_pool_t *p)
e8f95a682820a599fe41b22977010636be5c2717jimssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey)
14099c5540ce39114b5501a71ff96e40f48efc4bmartin /* Only refcounted in OpenSSL */
cc003103e52ff9d5fe9bed567ef9438613ab4fbfrse switch (t) {
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * certain key and cert data needs to survive restarts,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * which are stored in the user data table of s->process->pool.
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * to prevent "leaking" of this data, we use malloc/free
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * rather than apr_palloc and these wrappers to help make sure
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * we do not leak the malloc-ed data.
a0e0d20b666cfc453ac76506079eb50e03997eefdougm const char *key,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * if a value for this key already exists,
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * reuse as much of the already malloc-ed data
a0e0d20b666cfc453ac76506079eb50e03997eefdougm * as possible.
a0e0d20b666cfc453ac76506079eb50e03997eefdougm asn1->source_mtime = 0; /* used as a note for encrypted private keys */
a0e0d20b666cfc453ac76506079eb50e03997eefdougm return asn1->cpData; /* caller will assign a value to this */
a0e0d20b666cfc453ac76506079eb50e03997eefdougm const char *key)
a0e0d20b666cfc453ac76506079eb50e03997eefdougm return (ssl_asn1_t *)apr_hash_get(table, key, APR_HASH_KEY_STRING);
a0e0d20b666cfc453ac76506079eb50e03997eefdougm const char *key)
22357f10585a847ebf7b084cbe1db07ba071aeb6dougmstatic const char *ssl_asn1_key_types[] = {"RSA", "DSA"};
dd7c683f683624b082d430935b594df7406782c2dougm const char *id,
f4311d5c9112156f84d47a1ca2ff6811de838031rpluemSTACK_OF(X509) *ssl_read_pkcs7(server_rec *s, const char *pkcs7)
176c2742db03fcb7b7d13e6408dd967d87e542e9ben ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Can't open %s", pkcs7);
e0c3fda9f782aee1140d83fbce32672ac299f2a4ben ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_NOERRNO, 0, s,
e0c3fda9f782aee1140d83fbce32672ac299f2a4ben ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_NOERRNO, 0, s,
d94fd18ee21dc9b8c1f422144a881e941687d41fdougm * To ensure thread-safetyness in OpenSSL - work in progress
8e09f1830f114c016598a3b76fd6d31e1589c012sctemme/* Dynamic lock structure */
8e09f1830f114c016598a3b76fd6d31e1589c012sctemme const char* file;
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme/* Global reference to the pool passed into ssl_util_thread_setup() */
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * Dynamic lock creation callback
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemmestatic struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * We need a pool to allocate our mutex. Since we can't clear
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * allocated memory from a pool, create a subpool that we can blow
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * away in the destruction callback.
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme ap_log_perror(file, line, APLOG_ERR, rv, dynlockpool,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme "Failed to create subpool for dynamic lock");
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme "Creating dynamic lock");
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme value = (struct CRYPTO_dynlock_value *)apr_palloc(p,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme sizeof(struct CRYPTO_dynlock_value));
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme "Failed to allocate dynamic lock structure");
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme /* Keep our own copy of the place from which we were created,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme using our own pool. */
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme "Failed to create thread mutex for dynamic lock");
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * Dynamic locking and unlocking function
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemmestatic void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * Dynamic lock destruction callback
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemmestatic void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l,
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme "Failed to destroy mutex for dynamic lock %s:%d",
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme /* Trust that whomever owned the CRYPTO_dynlock_value we were
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * passed has no future use for it...
dd9940ba9b4d9c09f034b910d1569db4a5111c75dougmstatic unsigned long ssl_util_thr_id(void)
e8f95a682820a599fe41b22977010636be5c2717jim /* OpenSSL needs this to return an unsigned long. On OS/390, the pthread
e8f95a682820a599fe41b22977010636be5c2717jim * id is a structure twice that big. Use the TCB pointer instead as a
98f81eac9530d487f05013cda9df99755bb59689trawick * unique unsigned long.
98f81eac9530d487f05013cda9df99755bb59689trawick unsigned long PSATOLD;
e62985c7a1b46a5036a247f35bddac1308985758dougm return (unsigned long) apr_os_thread_current();
8464a9c46b967001e38fe3c8afff51a649e9de51dougmstatic apr_status_t ssl_util_thread_cleanup(void *data)
e8f95a682820a599fe41b22977010636be5c2717jim /* Let the registered mutex cleanups do their own thing
3c65aa88903de7330a07e133dfda779842fadad4wrowe lock_cs = apr_palloc(p, lock_num_locks * sizeof(*lock_cs));
3c65aa88903de7330a07e133dfda779842fadad4wrowe for (i = 0; i < lock_num_locks; i++) {
e18e68b42830409bf48de0df9eed3fe363664aa7aaron apr_thread_mutex_create(&(lock_cs[i]), APR_THREAD_MUTEX_DEFAULT, p);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme /* Set up dynamic locking scaffolding for OpenSSL to use at its
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme * convenience.
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock_function);
1eddce0da057f6fa5c5e9dde32e9dc6596616b12sctemme CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy_function);