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()