mirror of
https://github.com/znc/znc.git
synced 2026-03-28 17:42:41 +01:00
Support IP while verifying SSL certificates
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <znc/SSLVerifyHost.h>
|
||||
#include <znc/Translation.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
#if defined(OPENSSL_VERSION_NUMBER) && !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100007
|
||||
@@ -369,6 +370,14 @@ static HostnameValidationResult matches_subject_alternative_name(
|
||||
}
|
||||
san_names_nb = sk_GENERAL_NAME_num(san_names);
|
||||
|
||||
// Precompute binary representation of hostname in case if it's IP address.
|
||||
// Not the other way around, because there can be multiple text
|
||||
// representation of the same IP.
|
||||
char ip4[4] = {};
|
||||
char ip6[16] = {};
|
||||
const int ip4try = inet_pton(AF_INET, hostname, ip4);
|
||||
const int ip6try = inet_pton(AF_INET6, hostname, ip6);
|
||||
|
||||
// Check each name within the extension
|
||||
for (i = 0; i < san_names_nb; i++) {
|
||||
const GENERAL_NAME* current_name = sk_GENERAL_NAME_value(san_names, i);
|
||||
@@ -381,16 +390,40 @@ static HostnameValidationResult matches_subject_alternative_name(
|
||||
|
||||
// Make sure there isn't an embedded NUL character in the DNS name
|
||||
if (ASN1_STRING_length(current_name->d.dNSName) !=
|
||||
static_cast<int>(strlen(dns_name))) {
|
||||
static_cast<int>(strnlen(
|
||||
dns_name, ASN1_STRING_length(current_name->d.dNSName)))) {
|
||||
DEBUG("SSLVerifyHost: embedded null in DNS SAN");
|
||||
result = MalformedCertificate;
|
||||
break;
|
||||
} else { // Compare expected hostname with the DNS name
|
||||
DEBUG("SSLVerifyHost: Found SAN " << dns_name);
|
||||
DEBUG("SSLVerifyHost: Found DNS SAN " << dns_name);
|
||||
if (ZNC_Curl::Curl_cert_hostcheck(dns_name, hostname)) {
|
||||
result = MatchFound;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (current_name->type == GEN_IPADD) {
|
||||
CString ip(reinterpret_cast<const char*>(
|
||||
ASN1_STRING_get0_data(current_name->d.iPAddress)),
|
||||
ASN1_STRING_length(current_name->d.iPAddress));
|
||||
DEBUG("SSLVerifyHost: Found IP SAN "
|
||||
<< ip.Escape_n(CString::EHEXCOLON));
|
||||
if (ip4try && ASN1_STRING_length(current_name->d.iPAddress) == 4) {
|
||||
if (memcmp(ip4,
|
||||
ASN1_STRING_get0_data(current_name->d.iPAddress),
|
||||
4) == 0) {
|
||||
result = MatchFound;
|
||||
break;
|
||||
}
|
||||
} else if (ip6try &&
|
||||
ASN1_STRING_length(current_name->d.iPAddress) == 16) {
|
||||
if (memcmp(ip6,
|
||||
ASN1_STRING_get0_data(current_name->d.iPAddress),
|
||||
16) == 0) {
|
||||
result = MatchFound;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sk_GENERAL_NAME_pop_free(san_names, GENERAL_NAME_free);
|
||||
|
||||
Reference in New Issue
Block a user