MINOR: ssl: generated certificate is missing in switchctx early callback
Openssl 1.1.1 supports switchctx early callback and generated certificate.
Generated certificate calls must be available in switchctx early callback.
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index e1cfc66..fceccc9 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -1771,7 +1771,7 @@
/* Generate a cert and immediately assign it to the SSL session so that the cert's
* refcount is maintained regardless of the cert's presence in the LRU cache.
*/
-static SSL_CTX *
+static int
ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
{
X509 *cacert = bind_conf->ca_sign_cert;
@@ -1789,14 +1789,35 @@
lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
}
SSL_set_SSL_CTX(ssl, ssl_ctx);
+ return 1;
}
else {
ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
SSL_set_SSL_CTX(ssl, ssl_ctx);
/* No LRU cache, this CTX will be released as soon as the session dies */
SSL_CTX_free(ssl_ctx);
+ return 1;
}
- return ssl_ctx;
+ return 0;
+}
+static int
+ssl_sock_generate_certificate_from_conn(struct bind_conf *bind_conf, SSL *ssl)
+{
+ unsigned int key;
+ SSL_CTX *ssl_ctx = NULL;
+ struct connection *conn = SSL_get_app_data(ssl);
+
+ conn_get_to_addr(conn);
+ if (conn->flags & CO_FL_ADDR_TO_SET) {
+ key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
+ ssl_ctx = ssl_sock_get_generated_cert(key, bind_conf);
+ if (ssl_ctx) {
+ /* switch ctx */
+ SSL_set_SSL_CTX(ssl, ssl_ctx);
+ return 1;
+ }
+ }
+ return 0;
}
#endif /* !defined SSL_NO_GENERATE_CERTIFICATES */
@@ -1955,12 +1976,12 @@
static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
{
+ struct bind_conf *s = priv;
(void)al; /* shut gcc stupid warning */
- (void)priv;
- if (!SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
- return SSL_TLSEXT_ERR_NOACK;
- return SSL_TLSEXT_ERR_OK;
+ if (SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name) || s->generate_certs)
+ return SSL_TLSEXT_ERR_OK;
+ return SSL_TLSEXT_ERR_NOACK;
}
#ifdef OPENSSL_IS_BORINGSSL
@@ -2022,6 +2043,11 @@
servername = extension_data;
servername_len = len;
} else {
+#if (!defined SSL_NO_GENERATE_CERTIFICATES)
+ if (s->generate_certs && ssl_sock_generate_certificate_from_conn(s, ssl)) {
+ return 1;
+ }
+#endif
/* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
if (!s->strict_sni) {
ssl_sock_switchctx_set(ssl, s->default_ctx);
@@ -2165,6 +2191,12 @@
methodVersions[conf->ssl_methods.max].ssl_set_version(ssl, SET_MAX);
return 1;
}
+#if (!defined SSL_NO_GENERATE_CERTIFICATES)
+ if (s->generate_certs && ssl_sock_generate_certificate(trash.str, s, ssl)) {
+ /* switch ctx done in ssl_sock_generate_certificate */
+ return 1;
+ }
+#endif
if (!s->strict_sni) {
/* no certificate match, is the default_ctx */
ssl_sock_switchctx_set(ssl, s->default_ctx);
@@ -2199,22 +2231,8 @@
servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
if (!servername) {
#if (!defined SSL_NO_GENERATE_CERTIFICATES)
- if (s->generate_certs) {
- struct connection *conn = SSL_get_app_data(ssl);
- unsigned int key;
- SSL_CTX *ctx;
-
- conn_get_to_addr(conn);
- if (conn->flags & CO_FL_ADDR_TO_SET) {
- key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
- ctx = ssl_sock_get_generated_cert(key, s);
- if (ctx) {
- /* switch ctx */
- SSL_set_SSL_CTX(ssl, ctx);
- return SSL_TLSEXT_ERR_OK;
- }
- }
- }
+ if (s->generate_certs && ssl_sock_generate_certificate_from_conn(s, ssl))
+ return SSL_TLSEXT_ERR_OK;
#endif
if (s->strict_sni)
return SSL_TLSEXT_ERR_ALERT_FATAL;
@@ -2247,10 +2265,8 @@
}
if (!node || container_of(node, struct sni_ctx, name)->neg) {
#if (!defined SSL_NO_GENERATE_CERTIFICATES)
- SSL_CTX *ctx;
- if (s->generate_certs &&
- (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
- /* switch ctx */
+ if (s->generate_certs && ssl_sock_generate_certificate(servername, s, ssl)) {
+ /* switch ctx done in ssl_sock_generate_certificate */
return SSL_TLSEXT_ERR_OK;
}
#endif
@@ -3678,8 +3694,8 @@
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
#else
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
- SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
#endif
+ SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
#endif
return cfgerr;
}