On 18.11.2013 15:38, Dr Stephen Henson wrote: > Erk typo.. I of course meant "...after you call SSL_CTX_use_certificate_file > or > SSL_CTX_use_certificate_chain_file..."
Yeah this was obvious... makes me cringe as well but here we go: https://people.apache.org/~kbrand/mod_ssl_pkey_2013-11-18_wip.patch (interdiff attached to this message) For the SSL_CONF_cmd loop, I had to insert a call to ssl_stapling_init_cert as well - currently I'm testing for the "Certificate" parameter name being set, but if there's a better way to figure out if we need to call ssl_stapling_init_cert, I'm all ears. > Unfortunately due to a limitation in OpenSSL 1.0.1 and earlier you can only > have > one chain for the SSL_CTX shared by all certificate types and all SSL > structures > created from it. > > That means if you have more than one certificate configured and they have > different chains the second will replace the first in the SSL_CTX and it will > end up sending the wrong chain in some cases. Right, that's essentially what the last paragraph of the SSLCertificateChainFile is stating (http://httpd.apache.org/docs/2.4/mod/mod_ssl.html#sslcertificatechainfile), so I wouldn't worry too much about the behavior with releases up to 1.0.1. > For OpenSSL 1.0.2 this limitation is removed and you can have different chains > for each certificate type (and for SSL structures too) and it just uses the > right one. This uses the function SSL_CTX_add1_chain_cert which adds a > certificate to the chain for the current certificate. > > I *could* change SSL_CTX_use_certificate_chain_file to use > SSL_CTX_add1_chain_cert instead of SSL_CTX_add_extra_chain_cert or perhaps > have > a different function. I'm always cautious about changing the behaviour of > existing functions though as the most innocent change will usually break > *something*, though I can't see how it can in this case. I would be in favor this change for 1.0.2 - to me that would be more like a "fix" of SSL_CTX_use_certificate_chain_file than a change in behavior, actually. Kaspar
diff -u trunk/modules/ssl/ssl_engine_init.c trunk/modules/ssl/ssl_engine_init.c --- trunk/modules/ssl/ssl_engine_init.c (working copy) +++ trunk/modules/ssl/ssl_engine_init.c (working copy) @@ -836,6 +836,8 @@ DH *dhparams; ssl_asn1_t *asn1; EVP_PKEY *pkey; + SSL *ssl; + X509 *cert; SSLModConfigRec *mc = myModConfig(s); const char *certfile, *keyfile; @@ -889,31 +891,39 @@ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO() "Certificate and private key #%d for %s do not match", i + 1, vhost_id); - /* - * XXX we can't call ssl_check_public_cert() here, currently, - * as there's no way to get at the X509 * which was configured - * by SSL_CTX_use_certificate_[chain_]file... eventually, we - * would probably want to call: - * ssl_check_public_cert(s, ptemp, cert, i + 1); - */ break; } + /* + * workaround for those OpenSSL versions where SSL_CTX_get_certificate + * is not yet available: create an SSL * which we'll simply throw away + * a few lines further down + */ + if (!(ssl = SSL_new(mctx->ssl_ctx)) || + !(cert = SSL_get_certificate(ssl))) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO() + "Unable to retrieve certificate #%d for %s", + i + 1, vhost_id); + if (ssl) + SSL_free(ssl); + break; + } + + /* warn about potential cert issues */ + ssl_check_public_cert(s, ptemp, cert, i + 1); + #ifdef HAVE_OCSP_STAPLING if ((mctx->pkp == FALSE) && (mctx->stapling_enabled == TRUE)) { - /* - * XXX can't call ssl_stapling_init_cert currently, for the - * same reason as above with ssl_check_public_cert - * if (!ssl_stapling_init_cert(s, mctx, cert)) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02235) "Unable to configure certificate #%d for %s " "for stapling", i + 1, vhost_id); } - */ } #endif + SSL_free(ssl); + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO() "Certificate and key #%d for %s configured from %s and %s", i + 1, vhost_id, certfile, keyfile); @@ -1189,6 +1199,23 @@ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); ssl_die(s); } +#ifdef HAVE_OCSP_STAPLING + if (!strcasecmp(param->name, "Certificate") && + sc->server->stapling_enabled == TRUE) { + SSL *ssl; + X509 *cert; + if (!(ssl = SSL_new(sc->server->ssl_ctx)) || + !(cert = SSL_get_certificate(ssl)) || + !ssl_stapling_init_cert(s, sc->server, cert)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO() + "Unable to configure certificate loaded " + "from %s for %s for stapling", + param->value, sc->vhost_id); + } + if (ssl) + SSL_free(ssl); + } +#endif } if (SSL_CONF_CTX_finish(cctx) == 0) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO()