diff --git a/modules/tls_mgm/tls_mgm.c b/modules/tls_mgm/tls_mgm.c index 29b1241bb62..4540263ae35 100644 --- a/modules/tls_mgm/tls_mgm.c +++ b/modules/tls_mgm/tls_mgm.c @@ -642,11 +642,21 @@ static int init_tls_dom(struct tls_domain *d) } if (!d->cert.s) { - init_flags |= TLS_DOM_CERT_FILE_FL; - LM_NOTICE("no certificate for tls domain '%.*s' defined, using default '%s'\n", - d->name.len, ZSW(d->name.s), tls_cert_file); - d->cert.s = tls_cert_file; - d->cert.len = len(tls_cert_file); + /* Client domains can operate without a certificate (RFC 8446 4.4.2.4, + * RFC 5246 7.4.6) - an empty certificate message will be sent if the + * server requests one. Server domains require a certificate. */ + if (d->flags & DOM_FLAG_SRV) { + init_flags |= TLS_DOM_CERT_FILE_FL; + LM_NOTICE("no certificate for tls server domain '%.*s' defined, " + "using default '%s'\n", + d->name.len, ZSW(d->name.s), tls_cert_file); + d->cert.s = tls_cert_file; + d->cert.len = len(tls_cert_file); + } else { + LM_INFO("no certificate for tls client domain '%.*s', " + "will not send client certificate\n", + d->name.len, ZSW(d->name.s)); + } } if (!d->ca.s) { @@ -722,6 +732,15 @@ static int init_tls_domains(struct tls_domain **dom) prev = NULL; while (d) { if (!d->pkey.s) { + /* Client domains without a certificate don't need a private key */ + if (!d->cert.s && (d->flags & DOM_FLAG_CLI)) { + LM_DBG("no private key needed for tls client domain '%.*s' " + "(no certificate configured)\n", + d->name.len, ZSW(d->name.s)); + prev = d; + d = d->next; + continue; + } LM_NOTICE("no private key for tls domain '%.*s' defined, using default '%s'\n", d->name.len, ZSW(d->name.s), tls_pkey_file); d->pkey.s = tls_pkey_file; diff --git a/modules/tls_openssl/openssl_config.c b/modules/tls_openssl/openssl_config.c index 45d3059bee2..2086574a132 100644 --- a/modules/tls_openssl/openssl_config.c +++ b/modules/tls_openssl/openssl_config.c @@ -831,14 +831,16 @@ int openssl_init_tls_dom(struct tls_domain *d, int init_flags) } /* - * load certificate + * load certificate (optional for client domains per RFC 8446 4.4.2.4) */ - if (!(d->flags & DOM_FLAG_DB) || init_flags & TLS_DOM_CERT_FILE_FL) { - if (load_certificate(((void**)d->ctx)[i], d->cert.s) < 0) - return -1; - } else - if (load_certificate_db(((void**)d->ctx)[i], &d->cert) < 0) - return -1; + if (d->cert.s) { + if (!(d->flags & DOM_FLAG_DB) || init_flags & TLS_DOM_CERT_FILE_FL) { + if (load_certificate(((void**)d->ctx)[i], d->cert.s) < 0) + return -1; + } else + if (load_certificate_db(((void**)d->ctx)[i], &d->cert) < 0) + return -1; + } /** * load crl from directory diff --git a/modules/tls_wolfssl/wolfssl_config.c b/modules/tls_wolfssl/wolfssl_config.c index f1394309e39..1ec28d3d416 100644 --- a/modules/tls_wolfssl/wolfssl_config.c +++ b/modules/tls_wolfssl/wolfssl_config.c @@ -532,12 +532,15 @@ int _wolfssl_init_tls_dom(struct tls_domain *d, int init_flags) goto end; } - if (!(d->flags & DOM_FLAG_DB) || init_flags & TLS_DOM_CERT_FILE_FL) { - if (load_certificate(d->ctx, d->cert.s) < 0) - goto end; - } else { - if (load_certificate_db(d->ctx, &d->cert) < 0) - goto end; + /* load certificate (optional for client domains per RFC 8446 4.4.2.4) */ + if (d->cert.s) { + if (!(d->flags & DOM_FLAG_DB) || init_flags & TLS_DOM_CERT_FILE_FL) { + if (load_certificate(d->ctx, d->cert.s) < 0) + goto end; + } else { + if (load_certificate_db(d->ctx, &d->cert) < 0) + goto end; + } } if (d->crl_directory && load_crl(d->ctx, d->crl_directory,