diff --git a/src/rdkafka_ssl.c b/src/rdkafka_ssl.c index 8338cf5c8..21fd9c845 100644 --- a/src/rdkafka_ssl.c +++ b/src/rdkafka_ssl.c @@ -536,19 +536,47 @@ static int rd_kafka_transport_ssl_set_endpoint_id(rd_kafka_transport_t *rktrans, name, name_for_verify); } + /* Check if connecting to an IP address */ + rd_bool_t is_ip = rd_false; + if (/*ipv6*/ (strchr(name_for_verify, ':') && + strspn(name_for_verify, "0123456789abcdefABCDEF:.[]%") == + strlen(name_for_verify)) || + /*ipv4*/ strspn(name_for_verify, "0123456789.") == strlen(name_for_verify)) { + is_ip = rd_true; + } + #if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(OPENSSL_IS_BORINGSSL) - if (!SSL_set1_host(rktrans->rktrans_ssl, name_for_verify)) - goto fail; + /* OpenSSL 1.1.0+ has SSL_set1_host for hostnames + * but IP addresses should use the IP-specific function */ + if (is_ip) { +#if OPENSSL_VERSION_NUMBER >= 0x10100000 + /* Use IP-specific function for proper IP matching */ + X509_VERIFY_PARAM *param = SSL_get0_param(rktrans->rktrans_ssl); + if (!X509_VERIFY_PARAM_set1_ip_asc(param, name_for_verify)) + goto fail; +#else + if (!SSL_set1_host(rktrans->rktrans_ssl, name_for_verify)) + goto fail; +#endif + } else { + if (!SSL_set1_host(rktrans->rktrans_ssl, name_for_verify)) + goto fail; + } #elif OPENSSL_VERSION_NUMBER >= 0x1000200fL /* 1.0.2 */ { X509_VERIFY_PARAM *param; param = SSL_get0_param(rktrans->rktrans_ssl); - if (!X509_VERIFY_PARAM_set1_host(param, name_for_verify, - strnlen(name_for_verify, - sizeof(name_for_verify)))) - goto fail; + /* Use IP-specific function for IP addresses */ + if (is_ip) { + if (!X509_VERIFY_PARAM_set1_ip_asc(param, name_for_verify)) + goto fail; + } else { + if (!X509_VERIFY_PARAM_set1_host(param, name_for_verify, + strnlen(name_for_verify, sizeof(name_for_verify)))) + goto fail; + } } #else rd_snprintf(errstr, errstr_size, @@ -662,10 +690,20 @@ static int rd_kafka_transport_ssl_verify(rd_kafka_transport_t *rktrans) { } if ((rl = SSL_get_verify_result(rktrans->rktrans_ssl)) != X509_V_OK) { + char subject[256] = ""; + char issuer[256] = ""; + if (cert) { + X509_NAME_oneline(X509_get_subject_name(cert), subject, + sizeof(subject)); + X509_NAME_oneline(X509_get_issuer_name(cert), issuer, + sizeof(issuer)); + } rd_kafka_broker_fail(rktrans->rktrans_rkb, LOG_ERR, RD_KAFKA_RESP_ERR__SSL, - "Failed to verify broker certificate: %s", - X509_verify_cert_error_string(rl)); + "Failed to verify broker certificate: %s " + "(subject=%s, issuer=%s, openssl=0x%lx)", + X509_verify_cert_error_string(rl), + subject, issuer, OPENSSL_VERSION_NUMBER); return -1; } @@ -1269,6 +1307,11 @@ static int rd_kafka_ssl_set_certs(rd_kafka_t *rk, return -1; } + rd_kafka_dbg(rk, SECURITY, "SSL", + "Loaded CA certificates from %s: %s", + is_dir ? "directory" : "file", + rk->rk_conf.ssl.ca_location); + ca_probe = rd_false; } @@ -1964,6 +2007,12 @@ int rd_kafka_ssl_ctx_init(rd_kafka_t *rk, char *errstr, size_t errstr_size) { } /* Set up broker certificate verification. */ + rd_kafka_dbg(rk, SECURITY, "SSL", + "Setting up verification: enable_verify=%d, " + "cert_verify_cb=%s, security_level=%d", + rk->rk_conf.ssl.enable_verify, + rk->rk_conf.ssl.cert_verify_cb ? "set" : "NULL", + SSL_CTX_get_security_level(ctx)); SSL_CTX_set_verify(ctx, rk->rk_conf.ssl.enable_verify ? SSL_VERIFY_PEER : SSL_VERIFY_NONE,