diff options
Diffstat (limited to 'modules/ssl/ssl_util.c')
| -rw-r--r-- | modules/ssl/ssl_util.c | 147 |
1 files changed, 96 insertions, 51 deletions
diff --git a/modules/ssl/ssl_util.c b/modules/ssl/ssl_util.c index e4387e61..6b5a7de6 100644 --- a/modules/ssl/ssl_util.c +++ b/modules/ssl/ssl_util.c @@ -125,6 +125,8 @@ BOOL ssl_util_path_check(ssl_pathcheck_t pcm, const char *path, apr_pool_t *p) if (pcm & SSL_PCM_EXISTS && apr_stat(&finfo, path, APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0) return FALSE; + AP_DEBUG_ASSERT((pcm & SSL_PCM_EXISTS) || + !(pcm & (SSL_PCM_ISREG|SSL_PCM_ISDIR|SSL_PCM_ISNONZERO))); if (pcm & SSL_PCM_ISREG && finfo.filetype != APR_REG) return FALSE; if (pcm & SSL_PCM_ISDIR && finfo.filetype != APR_DIR) @@ -143,22 +145,24 @@ ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey) if (pCert != NULL) pFreeKey = pKey = X509_get_pubkey(pCert); if (pKey != NULL) { - switch (EVP_PKEY_key_type(pKey)) { + switch (EVP_PKEY_type(pKey->type)) { case EVP_PKEY_RSA: t = SSL_ALGO_RSA; break; case EVP_PKEY_DSA: t = SSL_ALGO_DSA; break; +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + t = SSL_ALGO_ECC; + break; +#endif default: break; } } -#ifdef OPENSSL_VERSION_NUMBER - /* Only refcounted in OpenSSL */ if (pFreeKey != NULL) EVP_PKEY_free(pFreeKey); -#endif return t; } @@ -174,6 +178,11 @@ char *ssl_util_algotypestr(ssl_algo_t t) case SSL_ALGO_DSA: cp = "DSA"; break; +#ifndef OPENSSL_NO_EC + case SSL_ALGO_ECC: + cp = "ECC"; + break; +#endif default: break; } @@ -206,14 +215,14 @@ unsigned char *ssl_asn1_table_set(apr_hash_t *table, } } else { - asn1 = malloc(sizeof(*asn1)); + asn1 = ap_malloc(sizeof(*asn1)); asn1->source_mtime = 0; /* used as a note for encrypted private keys */ asn1->cpData = NULL; } asn1->nData = length; if (!asn1->cpData) { - asn1->cpData = malloc(length); + asn1->cpData = ap_malloc(length); } apr_hash_set(table, key, klen, asn1); @@ -245,7 +254,11 @@ void ssl_asn1_table_unset(apr_hash_t *table, apr_hash_set(table, key, klen, NULL); } +#ifndef OPENSSL_NO_EC +static const char *ssl_asn1_key_types[] = {"RSA", "DSA", "ECC"}; +#else static const char *ssl_asn1_key_types[] = {"RSA", "DSA"}; +#endif const char *ssl_asn1_keystr(int keytype) { @@ -265,6 +278,56 @@ const char *ssl_asn1_table_keyfmt(apr_pool_t *p, return apr_pstrcat(p, id, ":", keystr, NULL); } +STACK_OF(X509) *ssl_read_pkcs7(server_rec *s, const char *pkcs7) +{ + PKCS7 *p7; + STACK_OF(X509) *certs = NULL; + FILE *f; + + f = fopen(pkcs7, "r"); + if (!f) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02212) "Can't open %s", pkcs7); + ssl_die(); + } + + p7 = PEM_read_PKCS7(f, NULL, NULL, NULL); + if (!p7) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02274) + "Can't read PKCS7 object %s", pkcs7); + ssl_log_ssl_error(SSLLOG_MARK, APLOG_CRIT, s); + exit(1); + } + + switch (OBJ_obj2nid(p7->type)) { + case NID_pkcs7_signed: + certs = p7->d.sign->cert; + p7->d.sign->cert = NULL; + PKCS7_free(p7); + break; + + case NID_pkcs7_signedAndEnveloped: + certs = p7->d.signed_and_enveloped->cert; + p7->d.signed_and_enveloped->cert = NULL; + PKCS7_free(p7); + break; + + default: + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02213) + "Don't understand PKCS7 file %s", pkcs7); + ssl_die(); + } + + if (!certs) { + ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02214) + "No certificates in %s", pkcs7); + ssl_die(); + } + + fclose(f); + + return certs; +} + #if APR_HAS_THREADS /* @@ -274,18 +337,8 @@ const char *ssl_asn1_table_keyfmt(apr_pool_t *p, static apr_thread_mutex_t **lock_cs; static int lock_num_locks; -#ifdef HAVE_SSLC -#if SSLC_VERSION_NUMBER >= 0x2000 -static int ssl_util_thr_lock(int mode, int type, - char *file, int line) -#else -static void ssl_util_thr_lock(int mode, int type, - char *file, int line) -#endif -#else static void ssl_util_thr_lock(int mode, int type, const char *file, int line) -#endif { if (type < lock_num_locks) { if (mode & CRYPTO_LOCK) { @@ -294,21 +347,13 @@ static void ssl_util_thr_lock(int mode, int type, else { apr_thread_mutex_unlock(lock_cs[type]); } -#ifdef HAVE_SSLC -#if SSLC_VERSION_NUMBER >= 0x2000 - return 1; - } - else { - return -1; -#endif -#endif } } /* Dynamic lock structure */ struct CRYPTO_dynlock_value { apr_pool_t *pool; - const char* file; + const char* file; int line; apr_thread_mutex_t *mutex; }; @@ -319,45 +364,45 @@ apr_pool_t *dynlockpool = NULL; /* * Dynamic lock creation callback */ -static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file, +static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file, int line) { struct CRYPTO_dynlock_value *value; apr_pool_t *p; apr_status_t rv; - /* + /* * We need a pool to allocate our mutex. Since we can't clear * allocated memory from a pool, create a subpool that we can blow - * away in the destruction callback. + * away in the destruction callback. */ rv = apr_pool_create(&p, dynlockpool); if (rv != APR_SUCCESS) { - ap_log_perror(file, line, APLOG_ERR, rv, dynlockpool, - "Failed to create subpool for dynamic lock"); + ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, dynlockpool, + APLOGNO(02183) "Failed to create subpool for dynamic lock"); return NULL; } - ap_log_perror(file, line, APLOG_DEBUG, 0, p, + ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, p, "Creating dynamic lock"); - - value = (struct CRYPTO_dynlock_value *)apr_palloc(p, + + value = (struct CRYPTO_dynlock_value *)apr_palloc(p, sizeof(struct CRYPTO_dynlock_value)); if (!value) { - ap_log_perror(file, line, APLOG_ERR, 0, p, - "Failed to allocate dynamic lock structure"); + ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, 0, p, + APLOGNO(02185) "Failed to allocate dynamic lock structure"); return NULL; } - + value->pool = p; /* Keep our own copy of the place from which we were created, using our own pool. */ value->file = apr_pstrdup(p, file); value->line = line; - rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT, + rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT, p); if (rv != APR_SUCCESS) { - ap_log_perror(file, line, APLOG_ERR, rv, p, + ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, p, APLOGNO(02186) "Failed to create thread mutex for dynamic lock"); apr_pool_destroy(p); return NULL; @@ -375,17 +420,17 @@ static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, apr_status_t rv; if (mode & CRYPTO_LOCK) { - ap_log_perror(file, line, APLOG_DEBUG, 0, l->pool, + ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool, "Acquiring mutex %s:%d", l->file, l->line); rv = apr_thread_mutex_lock(l->mutex); - ap_log_perror(file, line, APLOG_DEBUG, rv, l->pool, + ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool, "Mutex %s:%d acquired!", l->file, l->line); } else { - ap_log_perror(file, line, APLOG_DEBUG, 0, l->pool, + ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool, "Releasing mutex %s:%d", l->file, l->line); rv = apr_thread_mutex_unlock(l->mutex); - ap_log_perror(file, line, APLOG_DEBUG, rv, l->pool, + ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool, "Mutex %s:%d released!", l->file, l->line); } } @@ -393,18 +438,18 @@ static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, /* * Dynamic lock destruction callback */ -static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l, +static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line) { apr_status_t rv; - ap_log_perror(file, line, APLOG_DEBUG, 0, l->pool, + ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, l->pool, "Destroying dynamic lock %s:%d", l->file, l->line); rv = apr_thread_mutex_destroy(l->mutex); if (rv != APR_SUCCESS) { - ap_log_perror(file, line, APLOG_ERR, rv, l->pool, - "Failed to destroy mutex for dynamic lock %s:%d", - l->file, l->line); + ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, l->pool, + APLOGNO(02192) "Failed to destroy mutex for dynamic " + "lock %s:%d", l->file, l->line); } /* Trust that whomever owned the CRYPTO_dynlock_value we were @@ -435,11 +480,11 @@ static apr_status_t ssl_util_thread_cleanup(void *data) { CRYPTO_set_locking_callback(NULL); CRYPTO_set_id_callback(NULL); - + CRYPTO_set_dynlock_create_callback(NULL); CRYPTO_set_dynlock_lock_callback(NULL); CRYPTO_set_dynlock_destroy_callback(NULL); - + dynlockpool = NULL; /* Let the registered mutex cleanups do their own thing @@ -461,9 +506,9 @@ void ssl_util_thread_setup(apr_pool_t *p) CRYPTO_set_id_callback(ssl_util_thr_id); CRYPTO_set_locking_callback(ssl_util_thr_lock); - + /* Set up dynamic locking scaffolding for OpenSSL to use at its - * convenience. + * convenience. */ dynlockpool = p; CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function); |
