summaryrefslogtreecommitdiff
path: root/modules/ssl/ssl_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/ssl/ssl_util.c')
-rw-r--r--modules/ssl/ssl_util.c147
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);