summaryrefslogtreecommitdiff
path: root/modules/ssl/ssl_engine_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/ssl/ssl_engine_init.c')
-rw-r--r--modules/ssl/ssl_engine_init.c143
1 files changed, 127 insertions, 16 deletions
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index 6baf2f51..8b26c353 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -142,12 +142,12 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
apr_status_t rv;
apr_array_header_t *pphrases;
- if (SSLeay() < SSL_LIBRARY_VERSION) {
+ if (SSLeay() < MODSSL_LIBRARY_VERSION) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(01882)
"Init: this version of mod_ssl was compiled against "
"a newer library (%s, version currently loaded is %s)"
" - may result in undefined or erroneous behavior",
- SSL_LIBRARY_TEXT, SSLeay_version(SSLEAY_VERSION));
+ MODSSL_LIBRARY_TEXT, SSLeay_version(SSLEAY_VERSION));
}
/* We initialize mc->pid per-process in the child init,
@@ -236,7 +236,7 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
#endif
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01883)
- "Init: Initialized %s library", SSL_LIBRARY_NAME);
+ "Init: Initialized %s library", MODSSL_LIBRARY_NAME);
/*
* Seed the Pseudo Random Number Generator (PRNG)
@@ -327,7 +327,7 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
*/
ssl_add_version_components(p, base_server);
- SSL_init_app_data2_idx(); /* for SSL_get_app_data2() at request time */
+ modssl_init_app_data2_idx(); /* for modssl_get_app_data2() at request time */
init_dh_params();
@@ -471,7 +471,9 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
}
cp = apr_pstrcat(p,
+#ifndef OPENSSL_NO_SSL3
(protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
+#endif
(protocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""),
#ifdef HAVE_TLSV1_X
(protocol & SSL_PROTOCOL_TLSV1_1 ? "TLSv1.1, " : ""),
@@ -483,12 +485,15 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
"Creating new SSL context (protocols: %s)", cp);
+#ifndef OPENSSL_NO_SSL3
if (protocol == SSL_PROTOCOL_SSLV3) {
method = mctx->pkp ?
SSLv3_client_method() : /* proxy */
SSLv3_server_method(); /* server */
}
- else if (protocol == SSL_PROTOCOL_TLSV1) {
+ else
+#endif
+ if (protocol == SSL_PROTOCOL_TLSV1) {
method = mctx->pkp ?
TLSv1_client_method() : /* proxy */
TLSv1_server_method(); /* server */
@@ -519,9 +524,11 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
/* always disable SSLv2, as per RFC 6176 */
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
+#ifndef OPENSSL_NO_SSL3
if (!(protocol & SSL_PROTOCOL_SSLV3)) {
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
}
+#endif
if (!(protocol & SSL_PROTOCOL_TLSV1)) {
SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
@@ -625,6 +632,10 @@ static void ssl_init_ctx_callbacks(server_rec *s,
SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH);
SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
+
+#ifdef HAVE_TLS_ALPN
+ SSL_CTX_set_alpn_select_cb(ctx, ssl_callback_alpn_select, NULL);
+#endif
}
static apr_status_t ssl_init_ctx_verify(server_rec *s,
@@ -726,11 +737,11 @@ static apr_status_t ssl_init_ctx_cipher_suite(server_rec *s,
* Configure SSL Cipher Suite. Always disable NULL and export ciphers,
* see also ssl_engine_config.c:ssl_cmd_SSLCipherSuite().
* OpenSSL's SSL_DEFAULT_CIPHER_LIST includes !aNULL:!eNULL from 0.9.8f,
- * and !EXP from 0.9.8zf/1.0.1m/1.0.2a, so prepend them while we support
+ * and !EXP from 0.9.8zf/1.0.1m/1.0.2a, so append them while we support
* earlier versions.
*/
suite = mctx->auth.cipher_suite ? mctx->auth.cipher_suite :
- apr_pstrcat(ptemp, "!aNULL:!eNULL:!EXP:", SSL_DEFAULT_CIPHER_LIST,
+ apr_pstrcat(ptemp, SSL_DEFAULT_CIPHER_LIST, ":!aNULL:!eNULL:!EXP",
NULL);
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
@@ -807,6 +818,65 @@ static apr_status_t ssl_init_ctx_crl(server_rec *s,
return APR_SUCCESS;
}
+/*
+ * Read a file that optionally contains the server certificate in PEM
+ * format, possibly followed by a sequence of CA certificates that
+ * should be sent to the peer in the SSL Certificate message.
+ */
+static int use_certificate_chain(
+ SSL_CTX *ctx, char *file, int skipfirst, pem_password_cb *cb)
+{
+ BIO *bio;
+ X509 *x509;
+ unsigned long err;
+ int n;
+
+ if ((bio = BIO_new(BIO_s_file_internal())) == NULL)
+ return -1;
+ if (BIO_read_filename(bio, file) <= 0) {
+ BIO_free(bio);
+ return -1;
+ }
+ /* optionally skip a leading server certificate */
+ if (skipfirst) {
+ if ((x509 = PEM_read_bio_X509(bio, NULL, cb, NULL)) == NULL) {
+ BIO_free(bio);
+ return -1;
+ }
+ X509_free(x509);
+ }
+ /* free a perhaps already configured extra chain */
+#ifdef OPENSSL_NO_SSL_INTERN
+ SSL_CTX_clear_extra_chain_certs(ctx);
+#else
+ if (ctx->extra_certs != NULL) {
+ sk_X509_pop_free((STACK_OF(X509) *)ctx->extra_certs, X509_free);
+ ctx->extra_certs = NULL;
+ }
+#endif
+ /* create new extra chain by loading the certs */
+ n = 0;
+ while ((x509 = PEM_read_bio_X509(bio, NULL, cb, NULL)) != NULL) {
+ if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) {
+ X509_free(x509);
+ BIO_free(bio);
+ return -1;
+ }
+ n++;
+ }
+ /* Make sure that only the error is just an EOF */
+ if ((err = ERR_peek_error()) > 0) {
+ if (!( ERR_GET_LIB(err) == ERR_LIB_PEM
+ && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
+ BIO_free(bio);
+ return -1;
+ }
+ while (ERR_get_error() > 0) ;
+ }
+ BIO_free(bio);
+ return n;
+}
+
static apr_status_t ssl_init_ctx_cert_chain(server_rec *s,
apr_pool_t *p,
apr_pool_t *ptemp,
@@ -842,9 +912,7 @@ static apr_status_t ssl_init_ctx_cert_chain(server_rec *s,
}
}
- n = SSL_CTX_use_certificate_chain(mctx->ssl_ctx,
- (char *)chain,
- skip_first, NULL);
+ n = use_certificate_chain(mctx->ssl_ctx, (char *)chain, skip_first, NULL);
if (n < 0) {
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01903)
"Failed to configure CA certificate chain!");
@@ -917,7 +985,7 @@ static void ssl_check_public_cert(server_rec *s,
* Some information about the certificate(s)
*/
- if (SSL_X509_getBC(cert, &is_ca, &pathlen)) {
+ if (modssl_X509_getBC(cert, &is_ca, &pathlen)) {
if (is_ca) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01906)
"%s server certificate is a CA certificate "
@@ -932,8 +1000,8 @@ static void ssl_check_public_cert(server_rec *s,
}
}
- if (SSL_X509_match_name(ptemp, cert, (const char *)s->server_hostname,
- TRUE, s) == FALSE) {
+ if (modssl_X509_match_name(ptemp, cert, (const char *)s->server_hostname,
+ TRUE, s) == FALSE) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01909)
"%s server certificate does NOT include an ID "
"which matches the server name", key_id);
@@ -1198,6 +1266,30 @@ static apr_status_t ssl_init_ticket_key(server_rec *s,
}
#endif
+static BOOL load_x509_info(apr_pool_t *ptemp,
+ STACK_OF(X509_INFO) *sk,
+ const char *filename)
+{
+ BIO *in;
+
+ if (!(in = BIO_new(BIO_s_file()))) {
+ return FALSE;
+ }
+
+ if (BIO_read_filename(in, filename) <= 0) {
+ BIO_free(in);
+ return FALSE;
+ }
+
+ ERR_clear_error();
+
+ PEM_X509_INFO_read_bio(in, sk, NULL, NULL);
+
+ BIO_free(in);
+
+ return TRUE;
+}
+
static apr_status_t ssl_init_proxy_certs(server_rec *s,
apr_pool_t *p,
apr_pool_t *ptemp,
@@ -1220,11 +1312,30 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
sk = sk_X509_INFO_new_null();
if (pkp->cert_file) {
- SSL_X509_INFO_load_file(ptemp, sk, pkp->cert_file);
+ load_x509_info(ptemp, sk, pkp->cert_file);
}
if (pkp->cert_path) {
- SSL_X509_INFO_load_path(ptemp, sk, pkp->cert_path);
+ apr_dir_t *dir;
+ apr_finfo_t dirent;
+ apr_int32_t finfo_flags = APR_FINFO_TYPE|APR_FINFO_NAME;
+
+ if (apr_dir_open(&dir, pkp->cert_path, ptemp) == APR_SUCCESS) {
+ while ((apr_dir_read(&dirent, finfo_flags, dir)) == APR_SUCCESS) {
+ const char *fullname;
+
+ if (dirent.filetype == APR_DIR) {
+ continue; /* don't try to load directories */
+ }
+
+ fullname = apr_pstrcat(ptemp,
+ pkp->cert_path, "/", dirent.name,
+ NULL);
+ load_x509_info(ptemp, sk, fullname);
+ }
+
+ apr_dir_close(dir);
+ }
}
if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
@@ -1612,7 +1723,7 @@ static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list,
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02209)
"CA certificate: %s",
- SSL_X509_NAME_to_string(ptemp, name, 0));
+ modssl_X509_NAME_to_string(ptemp, name, 0));
/*
* note that SSL_load_client_CA_file() checks for duplicates,