MEDIUM: ssl: does not use default_ctx for 'generate-certificate' option

The 'generate-certificates' option does not need its dedicated SSL_CTX
*, it only needs the default SSL_CTX.

Use the default SSL_CTX found in the sni_ctx to generate certificates.

It allows to remove all the specific default_ctx initialization, as
well as the default_ssl_conf and 'default_inst'.
This commit is contained in:
William Lallemand 2024-01-11 15:10:33 +01:00
parent 0bf9d122a9
commit b80635a7e0
2 changed files with 27 additions and 26 deletions

View File

@ -169,9 +169,6 @@ struct bind_conf {
unsigned long long ca_ignerr_bitfield[IGNERR_BF_SIZE]; /* ignored verify errors in handshake if depth > 0 */
unsigned long long crt_ignerr_bitfield[IGNERR_BF_SIZE]; /* ignored verify errors in handshake if depth == 0 */
void *initial_ctx; /* SSL context for initial negotiation */
void *default_ctx; /* SSL context of first/default certificate */
struct ckch_inst *default_inst;
struct ssl_bind_conf *default_ssl_conf; /* custom SSL conf of default_ctx */
int strict_sni; /* refuse negotiation if sni doesn't match a certificate */
int ssl_options; /* ssl options */
struct eb_root sni_ctx; /* sni_ctx tree of all known certs full-names sorted by name */

View File

@ -1931,6 +1931,9 @@ cleanup:
return failure;
}
static __maybe_unused struct sni_ctx *ssl_sock_chose_sni_ctx(struct bind_conf *s, const char *servername,
int have_rsa_sig, int have_ecdsa_sig);
/* Create a X509 certificate with the specified servername and serial. This
* function returns a SSL_CTX object or NULL if an error occurs. */
static SSL_CTX *
@ -1948,12 +1951,17 @@ ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL
X509V3_CTX ctx;
unsigned int i;
int key_type;
struct sni_ctx *sni_ctx;
sni_ctx = ssl_sock_chose_sni_ctx(bind_conf, "", 1, 1);
if (!sni_ctx)
goto mkcert_error;
/* Get the private key of the default certificate and use it */
#ifdef HAVE_SSL_CTX_get0_privatekey
pkey = SSL_CTX_get0_privatekey(bind_conf->default_ctx);
pkey = SSL_CTX_get0_privatekey(sni_ctx->ctx);
#else
tmp_ssl = SSL_new(bind_conf->default_ctx);
tmp_ssl = SSL_new(sni_ctx->ctx);
if (tmp_ssl)
pkey = SSL_get_privatekey(tmp_ssl);
#endif
@ -3855,14 +3863,6 @@ int ckch_inst_new_load_store(const char *path, struct ckch_store *ckchs, struct
* the tree, so it will be discovered and cleaned in time.
*/
#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
if (bind_conf->default_ctx) {
memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
err && *err ? *err : "");
errcode |= ERR_ALERT | ERR_FATAL;
goto error;
}
#endif
if (is_default) {
ckch_inst->is_default = 1;
@ -5554,16 +5554,12 @@ int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
to initial_ctx in ssl_initial_ctx. */
errcode |= ssl_sock_prep_ctx_and_inst(bind_conf, NULL, bind_conf->initial_ctx, NULL, &errmsg);
}
if (bind_conf->default_ctx) {
errcode |= ssl_sock_prep_ctx_and_inst(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx, bind_conf->default_inst, &errmsg);
}
node = ebmb_first(&bind_conf->sni_ctx);
while (node) {
sni = ebmb_entry(node, struct sni_ctx, name);
if (!sni->order && sni->ctx != bind_conf->default_ctx) {
/* only initialize the CTX on its first occurrence and
if it is not the default_ctx */
if (!sni->order) {
/* only initialize the CTX on its first occurrence */
errcode |= ssl_sock_prep_ctx_and_inst(bind_conf, sni->conf, sni->ctx, sni->ckch_inst, &errmsg);
}
node = ebmb_next(node);
@ -5572,9 +5568,8 @@ int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
node = ebmb_first(&bind_conf->sni_w_ctx);
while (node) {
sni = ebmb_entry(node, struct sni_ctx, name);
if (!sni->order && sni->ctx != bind_conf->default_ctx) {
/* only initialize the CTX on its first occurrence and
if it is not the default_ctx */
if (!sni->order) {
/* only initialize the CTX on its first occurrence */
errcode |= ssl_sock_prep_ctx_and_inst(bind_conf, sni->conf, sni->ctx, sni->ckch_inst, &errmsg);
}
node = ebmb_next(node);
@ -5622,6 +5617,19 @@ int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
return -1;
}
}
if ((bind_conf->options & BC_O_GENERATE_CERTS)) {
struct sni_ctx *sni_ctx;
/* if we use the generate-certificates option, look for the first default cert available */
sni_ctx = ssl_sock_chose_sni_ctx(bind_conf, "", 1, 1);
if (!sni_ctx) {
ha_alert("Proxy '%s': no SSL certificate specified for bind '%s' and 'generate-certificates' option at [%s:%d] (use 'crt').\n",
px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
return -1;
}
}
if (!ssl_shctx && global.tune.sslcachesize) {
alloc_ctx = shctx_init(&ssl_shctx, global.tune.sslcachesize,
sizeof(struct sh_ssl_sess_hdr) + SHSESS_BLOCK_MIN_SIZE, -1,
@ -5723,10 +5731,6 @@ void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
SSL_CTX_free(bind_conf->initial_ctx);
bind_conf->initial_ctx = NULL;
SSL_CTX_free(bind_conf->default_ctx);
bind_conf->default_ctx = NULL;
bind_conf->default_inst = NULL;
bind_conf->default_ssl_conf = NULL;
}