From c1932e542863f0f646f005b3492452acc57c7e66 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Fri, 1 Apr 2022 15:41:44 +0200 Subject: [PATCH] libpq: Allow IP address SANs in server certificates The current implementation supports exactly one IP address in a server certificate's Common Name, which is brittle (the strings must match exactly). This patch adds support for IPv4 and IPv6 addresses in a server's Subject Alternative Names. Per discussion on-list: - If the client's expected host is an IP address, we allow fallback to the Subject Common Name if an iPAddress SAN is not present, even if a dNSName is present. This matches the behavior of NSS, in violation of the relevant RFCs. - We also, counter-intuitively, match IP addresses embedded in dNSName SANs. From inspection this appears to have been the behavior since the SAN matching feature was introduced in acd08d76. - Unlike NSS, we don't map IPv4 to IPv6 addresses, or vice-versa. Author: Jacob Champion Co-authored-by: Kyotaro Horiguchi Co-authored-by: Daniel Gustafsson Discussion: https://www.postgresql.org/message-id/flat/9f5f20974cd3a4091a788cf7f00ab663d5fcdffe.camel@vmware.com --- configure | 2 +- configure.ac | 1 + doc/src/sgml/libpq.sgml | 21 ++- src/include/pg_config.h.in | 3 + src/interfaces/libpq/fe-secure-common.c | 104 +++++++++++++ src/interfaces/libpq/fe-secure-common.h | 4 + src/interfaces/libpq/fe-secure-openssl.c | 145 ++++++++++++++++-- .../conf/server-cn-and-ip-alt-names.config | 24 +++ src/test/ssl/conf/server-ip-alt-names.config | 19 +++ .../conf/server-ip-cn-and-alt-names.config | 21 +++ .../server-ip-cn-and-dns-alt-names.config | 21 +++ .../ssl/ssl/server-cn-and-ip-alt-names.crt | 20 +++ .../ssl/ssl/server-cn-and-ip-alt-names.key | 27 ++++ src/test/ssl/ssl/server-ip-alt-names.crt | 19 +++ src/test/ssl/ssl/server-ip-alt-names.key | 27 ++++ .../ssl/ssl/server-ip-cn-and-alt-names.crt | 19 +++ .../ssl/ssl/server-ip-cn-and-alt-names.key | 27 ++++ .../ssl/server-ip-cn-and-dns-alt-names.crt | 20 +++ .../ssl/server-ip-cn-and-dns-alt-names.key | 27 ++++ src/test/ssl/sslfiles.mk | 4 + src/test/ssl/t/001_ssltests.pl | 98 ++++++++++++ src/tools/msvc/Solution.pm | 1 + 22 files changed, 636 insertions(+), 18 deletions(-) create mode 100644 src/test/ssl/conf/server-cn-and-ip-alt-names.config create mode 100644 src/test/ssl/conf/server-ip-alt-names.config create mode 100644 src/test/ssl/conf/server-ip-cn-and-alt-names.config create mode 100644 src/test/ssl/conf/server-ip-cn-and-dns-alt-names.config create mode 100644 src/test/ssl/ssl/server-cn-and-ip-alt-names.crt create mode 100644 src/test/ssl/ssl/server-cn-and-ip-alt-names.key create mode 100644 src/test/ssl/ssl/server-ip-alt-names.crt create mode 100644 src/test/ssl/ssl/server-ip-alt-names.key create mode 100644 src/test/ssl/ssl/server-ip-cn-and-alt-names.crt create mode 100644 src/test/ssl/ssl/server-ip-cn-and-alt-names.key create mode 100644 src/test/ssl/ssl/server-ip-cn-and-dns-alt-names.crt create mode 100644 src/test/ssl/ssl/server-ip-cn-and-dns-alt-names.key diff --git a/configure b/configure index 8b361e211b..c5e2769701 100755 --- a/configure +++ b/configure @@ -15982,7 +15982,7 @@ fi LIBS_including_readline="$LIBS" LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'` -for ac_func in backtrace_symbols clock_gettime copyfile fdatasync getifaddrs getpeerucred getrlimit kqueue mbstowcs_l memset_s poll posix_fallocate ppoll pstat pthread_is_threaded_np readlink readv setproctitle setproctitle_fast setsid shm_open strchrnul strsignal symlink syncfs sync_file_range uselocale wcstombs_l writev +for ac_func in backtrace_symbols clock_gettime copyfile fdatasync getifaddrs getpeerucred getrlimit inet_pton kqueue mbstowcs_l memset_s poll posix_fallocate ppoll pstat pthread_is_threaded_np readlink readv setproctitle setproctitle_fast setsid shm_open strchrnul strsignal symlink syncfs sync_file_range uselocale wcstombs_l writev do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/configure.ac b/configure.ac index 68ade8f7a6..6a48982c23 100644 --- a/configure.ac +++ b/configure.ac @@ -1787,6 +1787,7 @@ AC_CHECK_FUNCS(m4_normalize([ getifaddrs getpeerucred getrlimit + inet_pton kqueue mbstowcs_l memset_s diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 0b2a8720f0..1c20901c3c 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -8356,16 +8356,31 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) In verify-full mode, the host name is matched against the - certificate's Subject Alternative Name attribute(s), or against the - Common Name attribute if no Subject Alternative Name of type dNSName is + certificate's Subject Alternative Name attribute(s) (SAN), or against the + Common Name attribute if no SAN of type dNSName is present. If the certificate's name attribute starts with an asterisk (*), the asterisk will be treated as a wildcard, which will match all characters except a dot (.). This means the certificate will not match subdomains. If the connection is made using an IP address instead of a host name, the - IP address will be matched (without doing any DNS lookups). + IP address will be matched (without doing any DNS lookups) against SANs of + type iPAddress or dNSName. If no + iPAddress SAN is present and no + matching dNSName SAN is present, the host IP address is + matched against the Common Name attribute. + + + For backward compatibility with earlier versions of PostgreSQL, the host + IP address is verified in a manner different + from RFC 6125. + The host IP address is always matched against dNSName + SANs as well as iPAddress SANs, and can be matched + against the Common Name attribute if no relevant SANs exist. + + + To allow server certificate verification, one or more root certificates must be placed in the file ~/.postgresql/root.crt diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 9e2ca83993..13a2049df4 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -283,6 +283,9 @@ /* Define to 1 if you have the `inet_aton' function. */ #undef HAVE_INET_ATON +/* Define to 1 if you have the `inet_pton' function. */ +#undef HAVE_INET_PTON + /* Define to 1 if the system has the type `int64'. */ #undef HAVE_INT64 diff --git a/src/interfaces/libpq/fe-secure-common.c b/src/interfaces/libpq/fe-secure-common.c index bd46f08fae..165a6ed9b7 100644 --- a/src/interfaces/libpq/fe-secure-common.c +++ b/src/interfaces/libpq/fe-secure-common.c @@ -19,6 +19,8 @@ #include "postgres_fe.h" +#include + #include "fe-secure-common.h" #include "libpq-int.h" @@ -144,6 +146,108 @@ pq_verify_peer_name_matches_certificate_name(PGconn *conn, return result; } +/* + * Check if an IP address from a server's certificate matches the peer's + * hostname (which must itself be an IPv4/6 address). + * + * Returns 1 if the address matches, and 0 if it does not. On error, returns + * -1, and sets the libpq error message. + * + * A string representation of the certificate's IP address is returned in + * *store_name. The caller is responsible for freeing it. + */ +int +pq_verify_peer_name_matches_certificate_ip(PGconn *conn, + const unsigned char *ipdata, + size_t iplen, + char **store_name) +{ + char *addrstr; + int match = 0; + char *host = conn->connhost[conn->whichhost].host; + int family; + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; + char sebuf[PG_STRERROR_R_BUFLEN]; + + *store_name = NULL; + + if (!(host && host[0] != '\0')) + { + appendPQExpBufferStr(&conn->errorMessage, + libpq_gettext("host name must be specified\n")); + return -1; + } + + /* + * The data from the certificate is in network byte order. Convert our + * host string to network-ordered bytes as well, for comparison. (The host + * string isn't guaranteed to actually be an IP address, so if this + * conversion fails we need to consider it a mismatch rather than an + * error.) + */ + if (iplen == 4) + { + /* IPv4 */ + struct in_addr addr; + + family = AF_INET; + + /* + * The use of inet_aton() is deliberate; we accept alternative IPv4 + * address notations that are accepted by inet_aton() but not + * inet_pton() as server addresses. + */ + if (inet_aton(host, &addr)) + { + if (memcmp(ipdata, &addr.s_addr, iplen) == 0) + match = 1; + } + } + /* + * If they don't have inet_pton(), skip this. Then, an IPv6 address in a + * certificate will cause an error. + */ +#ifdef HAVE_INET_PTON + else if (iplen == 16) + { + /* IPv6 */ + struct in6_addr addr; + + family = AF_INET6; + + if (inet_pton(AF_INET6, host, &addr) == 1) + { + if (memcmp(ipdata, &addr.s6_addr, iplen) == 0) + match = 1; + } + } +#endif + else + { + /* + * Not IPv4 or IPv6. We could ignore the field, but leniency seems + * wrong given the subject matter. + */ + appendPQExpBuffer(&conn->errorMessage, + libpq_gettext("certificate contains IP address with invalid length %lu\n"), + (unsigned long) iplen); + return -1; + } + + /* Generate a human-readable representation of the certificate's IP. */ + addrstr = pg_inet_net_ntop(family, ipdata, 8 * iplen, tmp, sizeof(tmp)); + if (!addrstr) + { + appendPQExpBuffer(&conn->errorMessage, + libpq_gettext("could not convert certificate's IP address to string: %s\n"), + strerror_r(errno, sebuf, sizeof(sebuf))); + return -1; + } + + *store_name = strdup(addrstr); + return match; +} + /* * Verify that the server certificate matches the hostname we connected to. * diff --git a/src/interfaces/libpq/fe-secure-common.h b/src/interfaces/libpq/fe-secure-common.h index 1cca6d785a..d18db7138c 100644 --- a/src/interfaces/libpq/fe-secure-common.h +++ b/src/interfaces/libpq/fe-secure-common.h @@ -21,6 +21,10 @@ extern int pq_verify_peer_name_matches_certificate_name(PGconn *conn, const char *namedata, size_t namelen, char **store_name); +extern int pq_verify_peer_name_matches_certificate_ip(PGconn *conn, + const unsigned char *addrdata, + size_t addrlen, + char **store_name); extern bool pq_verify_peer_name_matches_certificate(PGconn *conn); #endif /* FE_SECURE_COMMON_H */ diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 0cba5c5cf2..24a598b6e4 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -72,6 +72,9 @@ static int verify_cb(int ok, X509_STORE_CTX *ctx); static int openssl_verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name, char **store_name); +static int openssl_verify_peer_name_matches_certificate_ip(PGconn *conn, + ASN1_OCTET_STRING *addr_entry, + char **store_name); static void destroy_ssl_system(void); static int initialize_SSL(PGconn *conn); static PostgresPollingStatusType open_client_SSL(PGconn *); @@ -509,6 +512,56 @@ openssl_verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *nam return pq_verify_peer_name_matches_certificate_name(conn, (const char *) namedata, len, store_name); } +/* + * OpenSSL-specific wrapper around + * pq_verify_peer_name_matches_certificate_ip(), converting the + * ASN1_OCTET_STRING into a plain C string. + */ +static int +openssl_verify_peer_name_matches_certificate_ip(PGconn *conn, + ASN1_OCTET_STRING *addr_entry, + char **store_name) +{ + int len; + const unsigned char *addrdata; + + /* Should not happen... */ + if (addr_entry == NULL) + { + appendPQExpBufferStr(&conn->errorMessage, + libpq_gettext("SSL certificate's address entry is missing\n")); + return -1; + } + + /* + * GEN_IPADD is an OCTET STRING containing an IP address in network byte + * order. + */ +#ifdef HAVE_ASN1_STRING_GET0_DATA + addrdata = ASN1_STRING_get0_data(addr_entry); +#else + addrdata = ASN1_STRING_data(addr_entry); +#endif + len = ASN1_STRING_length(addr_entry); + + return pq_verify_peer_name_matches_certificate_ip(conn, addrdata, len, store_name); +} + +static bool +is_ip_address(const char *host) +{ + struct in_addr dummy4; +#ifdef HAVE_INET_PTON + struct in6_addr dummy6; +#endif + + return inet_aton(host, &dummy4) +#ifdef HAVE_INET_PTON + || (inet_pton(AF_INET6, host, &dummy6) == 1) +#endif + ; +} + /* * Verify that the server certificate matches the hostname we connected to. * @@ -522,6 +575,36 @@ pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn, STACK_OF(GENERAL_NAME) * peer_san; int i; int rc = 0; + char *host = conn->connhost[conn->whichhost].host; + int host_type; + bool check_cn = true; + + Assert(host && host[0]); /* should be guaranteed by caller */ + + /* + * We try to match the NSS behavior here, which is a slight departure from + * the spec but seems to make more intuitive sense: + * + * If connhost contains a DNS name, and the certificate's SANs contain any + * dNSName entries, then we'll ignore the Subject Common Name entirely; + * otherwise, we fall back to checking the CN. (This behavior matches the + * RFC.) + * + * If connhost contains an IP address, and the SANs contain iPAddress + * entries, we again ignore the CN. Otherwise, we allow the CN to match, + * EVEN IF there is a dNSName in the SANs. (RFC 6125 prohibits this: "A + * client MUST NOT seek a match for a reference identifier of CN-ID if the + * presented identifiers include a DNS-ID, SRV-ID, URI-ID, or any + * application-specific identifier types supported by the client.") + * + * NOTE: Prior versions of libpq did not consider iPAddress entries at + * all, so this new behavior might break a certificate that has different + * IP addresses in the Subject CN and the SANs. + */ + if (is_ip_address(host)) + host_type = GEN_IPADD; + else + host_type = GEN_DNS; /* * First, get the Subject Alternative Names (SANs) from the certificate, @@ -537,38 +620,62 @@ pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn, for (i = 0; i < san_len; i++) { const GENERAL_NAME *name = sk_GENERAL_NAME_value(peer_san, i); + char *alt_name = NULL; + + if (name->type == host_type) + { + /* + * This SAN is of the same type (IP or DNS) as our host name, + * so don't allow a fallback check of the CN. + */ + check_cn = false; + } if (name->type == GEN_DNS) { - char *alt_name; - (*names_examined)++; rc = openssl_verify_peer_name_matches_certificate_name(conn, name->d.dNSName, &alt_name); - - if (alt_name) - { - if (!*first_name) - *first_name = alt_name; - else - free(alt_name); - } } + else if (name->type == GEN_IPADD) + { + (*names_examined)++; + rc = openssl_verify_peer_name_matches_certificate_ip(conn, + name->d.iPAddress, + &alt_name); + } + + if (alt_name) + { + if (!*first_name) + *first_name = alt_name; + else + free(alt_name); + } + if (rc != 0) + { + /* + * Either we hit an error or a match, and either way we should + * not fall back to the CN. + */ + check_cn = false; break; + } } sk_GENERAL_NAME_pop_free(peer_san, GENERAL_NAME_free); } /* - * If there is no subjectAltName extension of type dNSName, check the + * If there is no subjectAltName extension of the matching type, check the * Common Name. * * (Per RFC 2818 and RFC 6125, if the subjectAltName extension of type - * dNSName is present, the CN must be ignored.) + * dNSName is present, the CN must be ignored. We break this rule if host + * is an IP address; see the comment above.) */ - if (*names_examined == 0) + if (check_cn) { X509_NAME *subject_name; @@ -581,10 +688,20 @@ pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn, NID_commonName, -1); if (cn_index >= 0) { + char *common_name = NULL; + (*names_examined)++; rc = openssl_verify_peer_name_matches_certificate_name(conn, X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, cn_index)), - first_name); + &common_name); + + if (common_name) + { + if (!*first_name) + *first_name = common_name; + else + free(common_name); + } } } } diff --git a/src/test/ssl/conf/server-cn-and-ip-alt-names.config b/src/test/ssl/conf/server-cn-and-ip-alt-names.config new file mode 100644 index 0000000000..a6fa09bad3 --- /dev/null +++ b/src/test/ssl/conf/server-cn-and-ip-alt-names.config @@ -0,0 +1,24 @@ +# An OpenSSL format CSR config file for creating a server certificate. +# +# This certificate contains a CN and SANs for both IPv4 and IPv6. + + +[ req ] +distinguished_name = req_distinguished_name +req_extensions = v3_req +prompt = no + +[ req_distinguished_name ] +# Note: According to RFC 2818 and 6125, the CN is ignored, when DNS names are +# present in the SANs. But they are silent on whether the CN is checked when IP +# addresses are present. +CN = common-name.pg-ssltest.test +OU = PostgreSQL test suite + +# For Subject Alternative Names +[ v3_req ] +subjectAltName = @alt_names + +[ alt_names ] +IP.1 = 192.0.2.1 +IP.2 = 2001:DB8::1 diff --git a/src/test/ssl/conf/server-ip-alt-names.config b/src/test/ssl/conf/server-ip-alt-names.config new file mode 100644 index 0000000000..c22f22951a --- /dev/null +++ b/src/test/ssl/conf/server-ip-alt-names.config @@ -0,0 +1,19 @@ +# An OpenSSL format CSR config file for creating a server certificate. +# +# This certificate has a two IP-address SANs, and no CN. + +[ req ] +distinguished_name = req_distinguished_name +req_extensions = v3_req +prompt = no + +[ req_distinguished_name ] +OU = PostgreSQL test suite + +# For Subject Alternative Names +[ v3_req ] +subjectAltName = @alt_names + +[ alt_names ] +IP.1 = 192.0.2.1 +IP.2 = 2001:DB8::1 diff --git a/src/test/ssl/conf/server-ip-cn-and-alt-names.config b/src/test/ssl/conf/server-ip-cn-and-alt-names.config new file mode 100644 index 0000000000..a4087f0a18 --- /dev/null +++ b/src/test/ssl/conf/server-ip-cn-and-alt-names.config @@ -0,0 +1,21 @@ +# An OpenSSL format CSR config file for creating a server certificate. +# +# This certificate contains both a CN and SANs in IP address format. + + +[ req ] +distinguished_name = req_distinguished_name +req_extensions = v3_req +prompt = no + +[ req_distinguished_name ] +CN = 192.0.2.1 +OU = PostgreSQL test suite + +# For Subject Alternative Names +[ v3_req ] +subjectAltName = @alt_names + +[ alt_names ] +IP.1 = 192.0.2.2 +IP.2 = 2001:DB8::1 diff --git a/src/test/ssl/conf/server-ip-cn-and-dns-alt-names.config b/src/test/ssl/conf/server-ip-cn-and-dns-alt-names.config new file mode 100644 index 0000000000..7121803b49 --- /dev/null +++ b/src/test/ssl/conf/server-ip-cn-and-dns-alt-names.config @@ -0,0 +1,21 @@ +# An OpenSSL format CSR config file for creating a server certificate. +# +# This certificate contains both a CN and SANs in IP address format. + + +[ req ] +distinguished_name = req_distinguished_name +req_extensions = v3_req +prompt = no + +[ req_distinguished_name ] +CN = 192.0.2.1 +OU = PostgreSQL test suite + +# For Subject Alternative Names +[ v3_req ] +subjectAltName = @alt_names + +[ alt_names ] +DNS.1 = dns1.alt-name.pg-ssltest.test +DNS.2 = dns2.alt-name.pg-ssltest.test diff --git a/src/test/ssl/ssl/server-cn-and-ip-alt-names.crt b/src/test/ssl/ssl/server-cn-and-ip-alt-names.crt new file mode 100644 index 0000000000..4e58c85ccb --- /dev/null +++ b/src/test/ssl/ssl/server-cn-and-ip-alt-names.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDLzCCAhegAwIBAgIIICERKRE1UQAwDQYJKoZIhvcNAQELBQAwQjFAMD4GA1UE +Aww3VGVzdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHNl +cnZlciBjZXJ0czAeFw0yMTExMjkxOTM1NTFaFw00OTA0MTYxOTM1NTFaMEYxHjAc +BgNVBAsMFVBvc3RncmVTUUwgdGVzdCBzdWl0ZTEkMCIGA1UEAwwbY29tbW9uLW5h +bWUucGctc3NsdGVzdC50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA6+8IYKAFnZ7V+fDo1cyMpbGBLzCfJOQ/1o2jOGP4+GjpsZgv6S6UT2MheC8M +iiEFrYwdsSIZyYc3jEZrluy/UuR0bCGtqU92BCqa0iBLhvHOgjR588u253eLxQtQ +8iJn11QPrKMk35nMkmY8GfHt4sGFbvBL6+GpipHq7a6cde3Z+v4kCB5dKMYDUDtm +3mJmviuGNAu5wOqItk2Yi5dwJs1054007KNH0Il43urxiOfnkLS0cG5kehboPf86 +vxBt3iHByrU/9/DY5IvQCfSXVNa6rb5w5/pGja9aCei6Mv1jQY/V8SMQTga+MOsA +0WB9akxMi2NxwS2+BQ4k/McPlwIDAQABoyUwIzAhBgNVHREEGjAYhwTAAAIBhxAg +AQ24AAAAAAAAAAAAAAABMA0GCSqGSIb3DQEBCwUAA4IBAQAQLo2RzC07dG9p+J3A +W6C0p3Y+Os/YE2D9wfp4TIDTZxcRUQZ0S6ahF1N6sp8l9KHBJHPU1cUpRAU1oD+Y +SqmnP/VJRRDTTj9Ytdc/Vuo2jeLpSYhVKrCqtjqIrCwYJFoYRmMoxTtJGlwA0hSd +kwo3XYrALPUQWUErTYPvNfDNIuUwqUXNfS0CXuIOVN3LJ+shegg6Pwbh9B5T9NHx +kH+HswajhdpdnZIgh0FYTlTCPILDrB49aOWwqLa54AUA6WXa35hPsP8SoqL9Eucq +ifPhBYyadsjOb+70N8GbbAsDPN1jCX9L8RuNcEkxSCKCYx91cWXh7K5KMPuGlzB7 +j8xB +-----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/server-cn-and-ip-alt-names.key b/src/test/ssl/ssl/server-cn-and-ip-alt-names.key new file mode 100644 index 0000000000..837eef996d --- /dev/null +++ b/src/test/ssl/ssl/server-cn-and-ip-alt-names.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA6+8IYKAFnZ7V+fDo1cyMpbGBLzCfJOQ/1o2jOGP4+GjpsZgv +6S6UT2MheC8MiiEFrYwdsSIZyYc3jEZrluy/UuR0bCGtqU92BCqa0iBLhvHOgjR5 +88u253eLxQtQ8iJn11QPrKMk35nMkmY8GfHt4sGFbvBL6+GpipHq7a6cde3Z+v4k +CB5dKMYDUDtm3mJmviuGNAu5wOqItk2Yi5dwJs1054007KNH0Il43urxiOfnkLS0 +cG5kehboPf86vxBt3iHByrU/9/DY5IvQCfSXVNa6rb5w5/pGja9aCei6Mv1jQY/V +8SMQTga+MOsA0WB9akxMi2NxwS2+BQ4k/McPlwIDAQABAoIBAQCuNFKVNdKvrUYF +RLJGmsAG3+eo9lern7TbML2ht39vu9dBwEMwA6qSa3mdCfBSVUuh9uE9lxY/TU3g +j2aFi81A4VptNPjLGNblAKhMGnhp7UUzspeRQYuNoSFcnpxoDKtrvK/OIq/pQeBh +AIfECHRDh+yEG32Tb44FuPQkB1eTYl8xbMEImrhNUaSjJk7tTsmydHy0DjmqHVKX +HUj0TREfDBDOBiHtY0XV6Pu3bnqDH/TKLTfUf3UdfTuay3Yai9aEcRPWp9GrMO7G +axsKCifTz6177gyr6Fv8HLeMZMh9rMZRn3e0zfaF6vrH1QnZZOts5jpUa0KugSCd +//uC0iNxAoGBAPXVc3b+o3hY5gcwwpaW6JtsarDrmNRxrizqIDG7NgpqwdFXgTi6 +6q0t2pjv81ATqij69IcPkNSissyR4OEKnu/OFJWzreg8yLi75WHKi0E/6msHpwRk +d1yP0Zgd05ots/yOjDSp593RagaPVvHBxMECZ/Tm3B+Tq55Azudd/zvLAoGBAPWw +xf0oUEJl6NdUZD6K7eFc6jf8yrpD85dldeko6LeN8x0XlKKWvUDJ2+3oizXoQvCm +8by6KOYEIo4MrtXuy9MmtPWfNvRBr+hsUHchIj7IgFa9bKXyK2FnJqu/8CbEymli +eZu7hoOhelurhnFy1zSqwNO4GC+kw60Y/BO3Z1nlAoGAVOyYJtNwxXJwhKtjjYI0 +ePzLHrNE6J8c/Ick+AkkchTPP/JqwZ5Q0+KzUYITG+avMdkAAGhwMATEn8cFWLjC +jzUyB0U7Hq9g5/CBHXdLBA+Ae9j46ZuLYH6OeW5UWz7OnsDfzpGjeA2QAxQhhQLb +ZZHfN8tI39+zucfJskPWmGECgYEAg9guF1Fn6InJrqwR82IYj6SN6CeXHufSM392 +C/4xDDd3rDf4QlwECV2J0RzGf9I5Ae2EshNwWScE6Be0RweTh6cw2tJq6h7J6D8f +2x4Dw49TF7klMdRIJUf2f5pLpHJccLswqTqzz7V69PCSABVxmUi8m6EiEYconp5W +v7nfE2UCgYALrEqzncuSIX3q6TVAjnzT7gO4h8h2TUekIWdHQFldFx8R7Kncggnd +48gQqhewchNR83UCcd7pPsCcTqu6UR1QRdq/DV5P6J3xdZ2iS/2gCM6hvWIvKZEv +/ClnkyFCOW7zX6RKIXtRYZTV1kz3TajApi34RTIeIMTieaCarnBJbA== +-----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/server-ip-alt-names.crt b/src/test/ssl/ssl/server-ip-alt-names.crt new file mode 100644 index 0000000000..8a1bc620bb --- /dev/null +++ b/src/test/ssl/ssl/server-ip-alt-names.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCTCCAfGgAwIBAgIIICERKREEUAAwDQYJKoZIhvcNAQELBQAwQjFAMD4GA1UE +Aww3VGVzdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHNl +cnZlciBjZXJ0czAeFw0yMTExMjkxOTA0NTBaFw00OTA0MTYxOTA0NTBaMCAxHjAc +BgNVBAsMFVBvc3RncmVTUUwgdGVzdCBzdWl0ZTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAOM8yB6aVWb17ujr3ayU62mxHQoqn4CvG9yXlJvGOGv/ursW +Vs0UYJdc96LsNZN1szdm9ayNzCIw3eja+ULsjxCi6+3LM4pO76IORL/XFamlTPYb +BZ4pHdZVB0nnZAAnWCZPyXdnjOKQ5+8unVXkfibkjj8UELBJ2snehsOa+CTkOBez +zxYMqxAgbywLIYsW448brun7UXpWmqbGK+SsdGaIZ5Sb7Zezc5lt6CrLemTZTHHK +7l4WZFCCEi4t3sgO8o1vDELD/IE5G8lyXvIdgJg6t8ssper7iCw6S8x+okhjiSjT +vDLU2g4AanqZRZB49aPwTo0QUcJA2BCJxL9xLy8CAwEAAaMlMCMwIQYDVR0RBBow +GIcEwAACAYcQIAENuAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAQEAwZJ+ +8KpABTlMEgKnHIYb35ItGhtFiTLQta9RkXx7vaeDwpOdPP/IvuvpjpQZkobRgBsk +bNM0KuJpd2mSTphQAt6eKQIdcPrkzvc/Yh9OK3YNLUAbu/ZhBUnBvFnUL4wn2f1U +mfO+m8P/LxybwqKx7r1mbaB+tP3RTxxLcIMvm9ECPQEoBntfEL325Wdoj+WuQH5Y +IvcM6FaCTkQsNIPbaBD5l5MhMLHRULZujbDjXqGSvRMQfns6np/biMjNdQA8NZ5z +STeUFvkQbCxoA0YYLgoSHL5KhZjXrg2g+T+2TUyCTR/91xf9OoOjBZdixR0S0DzJ +B1+5vnUjZaCfnSEA7A== +-----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/server-ip-alt-names.key b/src/test/ssl/ssl/server-ip-alt-names.key new file mode 100644 index 0000000000..b210b3a991 --- /dev/null +++ b/src/test/ssl/ssl/server-ip-alt-names.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA4zzIHppVZvXu6OvdrJTrabEdCiqfgK8b3JeUm8Y4a/+6uxZW +zRRgl1z3ouw1k3WzN2b1rI3MIjDd6Nr5QuyPEKLr7cszik7vog5Ev9cVqaVM9hsF +nikd1lUHSedkACdYJk/Jd2eM4pDn7y6dVeR+JuSOPxQQsEnayd6Gw5r4JOQ4F7PP +FgyrECBvLAshixbjjxuu6ftRelaapsYr5Kx0ZohnlJvtl7NzmW3oKst6ZNlMccru +XhZkUIISLi3eyA7yjW8MQsP8gTkbyXJe8h2AmDq3yyyl6vuILDpLzH6iSGOJKNO8 +MtTaDgBqeplFkHj1o/BOjRBRwkDYEInEv3EvLwIDAQABAoIBACp3uY6+mSdc3wF4 +0zzlt/lQuHSl8plCIJrhWUyjhvfoGyXLzv0Uydh/72frbTfZz1yTSWauOXBKYa6a +/eqb+0DIsf8G8uLuTaqjsAWKVOoXkoKMGkistn7P9UTCkdXVhIvkbWp7V8EgA7iX +pZ/fzBPIsyzmuxe3NcR0ags0cxuxkNuu+YXDv1oTedmT2wS3CZq1d/T1Y/EOVIf8 +Iznd2aOverlsnt6iiQ3ZWdG/W5F8FhnrR/rrBdYsdCv6TH/KUYexnDOUYpayjDbu +oAKnifPp6UqiOM4SuBL83OAz19jptp5vpF370BEVRs3eK0q+zo/mETjv9HsXdolZ +lfoXA0ECgYEA/7nb2azbq/2muvXCh1ZxCEbn3mt8KXoJP/xkx/v9eEc/cc5Q9e0V +2oGfjC2hSE+bjOWMwiUMD6uU+iRjhz5A3IvUxnoSdoL7H9p0hTqLMyP7dTDkoVF5 +aEuLMaiI5YEnfAFu9L5h8ZKieoQTBoscT06wnGjh9pBV9bthfTKA7ksCgYEA43sb +55m9WL4kWCPwOAp3vdEAFyxzmZHlO26sEQOU/m5aN01pumYybBruziEXMI96yfTj +VmXKReeYb6XUiCcs3fLSipD/+8/8CsjO4uMORtxWumXe8AbKZfysGFzL7wJlByGT +38AGQwIG/XD8cKnaiEMX4E/3Owbcoxwixo3WZC0CgYEAovaqJ9mEU+Jc8h/TS7PG +bGPjN1Z/1V6zrlcFUnw/Vvrwb3HvHglsN8cLCaW6df5lPjC6tq4tNX8+fPnbg0Ak +zWc+vQzl3ygxKGdqgcyBEKIJiPETgcoN+GzL02V3d+oKY3f2YXlBqVSsvi6UgUL9 +U3zuB36/IQVyAhrbUZFxoGkCgYEAnaFAO+Nvrp/LhXwZyGuQf+rkmipGTIMpil5t +QzjtNMV5JFszSWPpyrl7A0Ew1YiG+I0GP2c3m+sY2TzbIiGrWH0b4cMKbw63Qy3V +FqlpyjaCrpVKv56k/7jv883RzuQk56Uf1+szK5mrCFITy2oXsVZ0pA4lbjSaDTjA +7D968V0CgYEA+qKqXKL98+c5CMPnpf+0B1x2zgyUym1ouPfon2x5fhK84T53zDMA +zfdUJ/SOZw6/c9vRF7RL8h+ZfFdIyoAXv4Tt6mIiZe7P+AUVg6XgJ0ce2MUSeWjI +W8D4WdSi0jyqr99TuVBWhbTZJviMB3pHqKaHQ07hnd/lPtvzsiH12qk= +-----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/server-ip-cn-and-alt-names.crt b/src/test/ssl/ssl/server-ip-cn-and-alt-names.crt new file mode 100644 index 0000000000..2be02feb03 --- /dev/null +++ b/src/test/ssl/ssl/server-ip-cn-and-alt-names.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDHTCCAgWgAwIBAgIIICIBBBQ2MQAwDQYJKoZIhvcNAQELBQAwQjFAMD4GA1UE +Aww3VGVzdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHNl +cnZlciBjZXJ0czAeFw0yMjAxMDQyMjM2MzFaFw00OTA1MjIyMjM2MzFaMDQxHjAc +BgNVBAsMFVBvc3RncmVTUUwgdGVzdCBzdWl0ZTESMBAGA1UEAwwJMTkyLjAuMi4x +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwmqTdQJfs2Ti9tPitYp2 +27I0HvL/kNSgA6egFr0foRo0BorwJNIzdbV0+EnsfiBNTWL5It26gqO7UP3ms8t2 +vHD5gkXfT+f6ts0lVJEcIOkUD/8ws4Ic9Y4uPqb4gN+pUKqcxtmLW1TYk84MBK59 +Xz4yPPS6N+G/DMMeFHTNkM9EQwn/+DC3fDsWdGYM2GRWDTJGg1A5tSUcF+seu7i1 +Vg7XajBfsvgAUAsrAxV+X/sLZh94HY+paD6wfaI99mY2OXVc/XW/z1r9WQznor65 +ZkonNCaPfavqPG5vqnab9AyQcqPqmX8hf/xrniASBAkqNCctbASrFCIYvCJfGfmX +EQIDAQABoyUwIzAhBgNVHREEGjAYhwTAAAIChxAgAQ24AAAAAAAAAAAAAAABMA0G +CSqGSIb3DQEBCwUAA4IBAQBf7kmYfRYfnWk1OUfY3N1kaNg9piBBlFr9g+OQn9KU +zirkN7s0ZQbCGxV1uJQBKS58NyE414Vorau77379emgYDcCBpDIYpkLiNujVrIOr +ggRFKsFRgxu4/mw0BSgCcV8RPe9SWHZ90Mos7TMCnW/PdxOCD1wD0YMkcs0rwB3l +0Kzc7jDnfOEvmgw/Ysm7v67ps+05Uq5VskQ6WrpSAw6kPD/QMuuBAX8ATPczIaox +zAMyncq1IiSIwG93f3EoQQThdQ70C6G9vLcu9TtL6JAsEMFEzR99gt1Wsqvmgl9W +kStzj1yjIWeo5gIsa4Jgcke1lZviWyrTxHDfyunYE5i5 +-----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/server-ip-cn-and-alt-names.key b/src/test/ssl/ssl/server-ip-cn-and-alt-names.key new file mode 100644 index 0000000000..54fe80fc68 --- /dev/null +++ b/src/test/ssl/ssl/server-ip-cn-and-alt-names.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAwmqTdQJfs2Ti9tPitYp227I0HvL/kNSgA6egFr0foRo0Borw +JNIzdbV0+EnsfiBNTWL5It26gqO7UP3ms8t2vHD5gkXfT+f6ts0lVJEcIOkUD/8w +s4Ic9Y4uPqb4gN+pUKqcxtmLW1TYk84MBK59Xz4yPPS6N+G/DMMeFHTNkM9EQwn/ ++DC3fDsWdGYM2GRWDTJGg1A5tSUcF+seu7i1Vg7XajBfsvgAUAsrAxV+X/sLZh94 +HY+paD6wfaI99mY2OXVc/XW/z1r9WQznor65ZkonNCaPfavqPG5vqnab9AyQcqPq +mX8hf/xrniASBAkqNCctbASrFCIYvCJfGfmXEQIDAQABAoIBAB6GgVST5NbT9lbu ++d+rN/JSzqA1Yy8oU19/iEFJvJec96I3WnFNl8rZjN4XLUy4YarO6XMyAUDV2Gll +FD4Sqjf4PRTZR7DSKaleGIhoqFP6hK3mUY091rIves9XhBkoBPunbipCqgDTF5ZN +edGaXBECQP0VJ8/yX/7u++AWXthnjDis9X0taZfFg/PYbV7SCJ1Hg1O/wEsgXlnC +7mbL6wkCW0f6700B0x1kKbZqJY95xRqp6Ipq2lIQbJDdGywoj0WzKqNltf9cer+r +cXl8WjeiMvvvpl4uGhckAbzUifUzxN6A3f1fu/XKtOmabMi9t7J4MRfgOgedgtQB +0jaZGSkCgYEA+lBLnNY6M48HX2mdtr86+n41gh69v8Z7oNikJFDZkodrvI8uqE0i +0XwnYPFddt8NbmuUhhuzI2M8RKhGLgdlbKpkSSVafnMfcxRmX2EAtWQgdvX1Iult +752LWdBgSuw2vlzvy3T/GYnjMrXSCGput4amqojMEbvUGvIdSUMdHGMCgYEAxtU1 +WixKPL6aEnYy1f4bybzcNgGtl8PBRz9xw+P46g+ijOPoaG9O73Tr7An11AO003Ot +DHhMW+b8yHLyxoKwS2sU2cN/lKB8xNQYZc1D61RNJlzgnHMXnA0lcH0I3M35fqKr +/71pD1ZP40SSJS+od/KEjW80XzuOdyiXg8q81vsCgYEAnUPLbbsuj+whzrFVlFZr +IKwgxCK6Rn3WeIUEA4kEWUpZxvsSbk0gPgtJ1l9uwFt9Xc2bX/KRRv93Aw/SH+Mn +tvEK1uXwCBgePzgm5W/VeSFyQCthm1CbcHtD7Oa9SPVFo65SPjrAd3QpWVfgoMb1 +zrp7hhMyW0XuCgvpmHjhFk8CgYEAxq/thXM2p+bLLWGhwQcRG5G299zLbBl4PUsf +0uEvLi17gJCKADoiRdSvoAn/9eHSQ26XYRuhKkDzHxcGlOmpY2PYzRa3mXyZ0VIk +Iy5wDWwLQCeVZ6D22cClRfgb8BF/nFTPzVmn72SPpgoyhChQj7PvUynpyrRH07jj +VxYziBsCgYAFr37Xbl0VnXVK+XU+vMwUZjcF4jpoCr7SFZqgRbW2GbYSUoMuPXns +RnJh+Fvi1NUei+E5s1H4P1pVq4p0jFxP4GvH/qvNjnIn/Er3bbqvpox6dWUJXprq +qTQSDIeoDC/V8cyRoIfqPvTVqY8Rgew6GEkv0bAImdxhoSng7vIseg== +-----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/server-ip-cn-and-dns-alt-names.crt b/src/test/ssl/ssl/server-ip-cn-and-dns-alt-names.crt new file mode 100644 index 0000000000..23c06da01c --- /dev/null +++ b/src/test/ssl/ssl/server-ip-cn-and-dns-alt-names.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQzCCAiugAwIBAgIIICIBBBQ2MQEwDQYJKoZIhvcNAQELBQAwQjFAMD4GA1UE +Aww3VGVzdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHNl +cnZlciBjZXJ0czAeFw0yMjAxMDQyMjM2MzFaFw00OTA1MjIyMjM2MzFaMDQxHjAc +BgNVBAsMFVBvc3RncmVTUUwgdGVzdCBzdWl0ZTESMBAGA1UEAwwJMTkyLjAuMi4x +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8xddbo/x2TOSIa/br8BN +o/URdTr9+l2R5YojiZKDuLxiQVkgC30PJ2/CNFKIh2nHhRrzknI6sETVtrxZ+9V2 +qRc1yShVu462u0DHPRMIZnZIOZg3hlNB0cRWbOglUKlttIARNEQUcTUyPOtyo4/v ++u0Ej5NTNcHFbFT01vdD9MjQiCO3jKdAwPIb14jTg4C71EpZ+LuelDo4DzF2/XgG +WqUTrgD/XnBU/60PU9Iy3G0nVpx21q6ppn9G7a9R+i8FjBcwW1T+cfsBDWhAv+bi +RmSAkENf8L8TwOlDQUwROkfz3Hz36vuJjdkreQJsiqL0HnrnH5T5G9UzJO86FvZQ +5wIDAQABo0swSTBHBgNVHREEQDA+gh1kbnMxLmFsdC1uYW1lLnBnLXNzbHRlc3Qu +dGVzdIIdZG5zMi5hbHQtbmFtZS5wZy1zc2x0ZXN0LnRlc3QwDQYJKoZIhvcNAQEL +BQADggEBAF+mfaw6iBPzpCgqq830pHRa3Yzm1aezt8SkeRohUYHNv/yCnDSRaqtj +xbENih3lJMSTBL3g0wtTOHfH8ViC/h+lvYELHzXKic7gkjV7H5XETKGr0ZsjBBT2 +4cZQKbD9e0x0HrENXMYgGpBf747qL6uTOVJdG0s15hwpLq47bY5WUjXathejbpxW +prmF8F+xaC52N9P/1VnqguQB909F4x1pyOK7D7tjFu+Y8Je7PHKbb6WY5K6xAv6t +R17CY0749/FotlphquElUR2bs5Zzv5YrjUHPTcbwKvcH5cdNi93/u6NJt2xNAoYf +aZERhX5TA9DYk4gC8OY0yGaYCIj3Dd4= +-----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/server-ip-cn-and-dns-alt-names.key b/src/test/ssl/ssl/server-ip-cn-and-dns-alt-names.key new file mode 100644 index 0000000000..0ace41e0a1 --- /dev/null +++ b/src/test/ssl/ssl/server-ip-cn-and-dns-alt-names.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA8xddbo/x2TOSIa/br8BNo/URdTr9+l2R5YojiZKDuLxiQVkg +C30PJ2/CNFKIh2nHhRrzknI6sETVtrxZ+9V2qRc1yShVu462u0DHPRMIZnZIOZg3 +hlNB0cRWbOglUKlttIARNEQUcTUyPOtyo4/v+u0Ej5NTNcHFbFT01vdD9MjQiCO3 +jKdAwPIb14jTg4C71EpZ+LuelDo4DzF2/XgGWqUTrgD/XnBU/60PU9Iy3G0nVpx2 +1q6ppn9G7a9R+i8FjBcwW1T+cfsBDWhAv+biRmSAkENf8L8TwOlDQUwROkfz3Hz3 +6vuJjdkreQJsiqL0HnrnH5T5G9UzJO86FvZQ5wIDAQABAoIBAGv0BFoFMrHyZQLw +xe7Wx6P4QTh+aiu1QgVdw0pk9nojrr62hbSUZRZuWyBBRsBcCW7i+Sgf8lA1QXNV +UeC0e228EPa0It6YEi42JkTJHwHhpVFud7n/X0t4lajnryqTE1UFSp6bXTipFxZW +uSJJ2ZjliRD5rApDcxkY4WJVjKg3aEt7P/DiM8iKGfyE6stq72VjEbJjdViMEcOP +BNf0TiREZz5Mp7jAVWhpen0ebbLOBVWV4/ONNcL+yqR4mCEDUSFGewrTVX4zHL0A +hYk198C5F8sFvEDnFkPco9sXMVanmLoI8sbhP4IIz9g4+GU6kFuj7fUKp11Azqv+ +3WQDKYECgYEA/XG4mmG/g8FG44y42mfZpUXWi1pwU4CQIrhkoU5j7EPQrvRboOOE +Rv95jSwyZu4vCqjyI5FN1jCGTdhmt++R1e//zH6Hqa9Smo+jw7DtAFrCYd1JnCf1 +ToOwsYPHv4P7A8q8kc5vCNIv+AQSlP/wqdVNo3grdf7cGXkMtEY4F9UCgYEA9Yrq +zWdnNGPATuSBqL6TSjQ37oR+dBD6WnGsiDenQkOzyDPFZ3CT1DjJghjEtxc8EfNf +Oo8dMMR2q+5FZQo7WuqONEgyzKePiNR8RK2gOYpgdjN9bih1sAhHR10D26cpwlDJ +bx7D5ZzENLbdZmfEiWwKswnaIhN4yMalgE0mP8sCgYAhzJy12ftUct4lUosEdX0N +EXc/NlxshmSyfKzO5kllJNYbvvLJTg5B+agYL6C5IWKcpVNFcwdSXT5L+2QXe5eT +VGJkvysQchUuD6HjYyD4PyJVMtGyRZHtWpqh0dU9sTg0lUD4oPMl1gIXrVNdE5Tg +0VV9S3VgUxC/ROlw0TyB0QKBgGsVE0NS9hJF8mc1hko2GnwA++d8Rr2NbfElo+2f +/8SJTA1ibpOm6AFkZpTjAl8qtdrKPVyHb16GP47Jkd/3r1z979hjKCxSYul0aWF2 +KusNKvZBjFEPOgv0AEniCb2wUCjbHI3mZ95qGLM4kKOJW4/m21+rS0MTJNjCsQic +HLMzAoGAeCsY09d3m8xGeU+DuTPC6GH7Sgy/NBYqS5VaVNjb2jnuZlW2SSW2oiID +4tXTi4ruKmHC898BfyFxhSMqub+tg3pVqIYADC71rnJLrVyc1SzoWzL7yMT3qFj7 +C7ZYZYmfG9agcZb5NkqKPTfCxkBhWbdgTTgBKVO/xQst8EUgko8= +-----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/sslfiles.mk b/src/test/ssl/sslfiles.mk index 7a28d82f95..cc023667af 100644 --- a/src/test/ssl/sslfiles.mk +++ b/src/test/ssl/sslfiles.mk @@ -22,8 +22,12 @@ # key/certificate pair will be generated for you, signed by the appropriate CA. # SERVERS := server-cn-and-alt-names \ + server-cn-and-ip-alt-names \ server-cn-only \ + server-ip-alt-names \ server-ip-cn-only \ + server-ip-cn-and-alt-names \ + server-ip-cn-and-dns-alt-names \ server-ip-in-dnsname \ server-single-alt-name \ server-multiple-alt-names \ diff --git a/src/test/ssl/t/001_ssltests.pl b/src/test/ssl/t/001_ssltests.pl index fabbe1570a..58d2bc336f 100644 --- a/src/test/ssl/t/001_ssltests.pl +++ b/src/test/ssl/t/001_ssltests.pl @@ -305,6 +305,64 @@ $node->connect_fails( qr/\Qserver certificate for "single.alt-name.pg-ssltest.test" does not match host name "deep.subdomain.wildcard.pg-ssltest.test"\E/ ); +SKIP: +{ + skip 'IPv6 addresses in certificates not support on this platform', 1 + unless check_pg_config('#define HAVE_INET_PTON 1'); + + # Test certificate with IP addresses in the SANs. + switch_server_cert($node, certfile => 'server-ip-alt-names'); + + $node->connect_ok("$common_connstr host=192.0.2.1", + "host matching an IPv4 address (Subject Alternative Name 1)"); + + $node->connect_ok( + "$common_connstr host=192.000.002.001", + "host matching an IPv4 address in alternate form (Subject Alternative Name 1)" + ); + + $node->connect_fails( + "$common_connstr host=192.0.2.2", + "host not matching an IPv4 address (Subject Alternative Name 1)", + expected_stderr => + qr/\Qserver certificate for "192.0.2.1" (and 1 other name) does not match host name "192.0.2.2"\E/ + ); + + $node->connect_fails( + "$common_connstr host=192.0.2.1/32", + "IPv4 host with CIDR mask does not match", + expected_stderr => + qr/\Qserver certificate for "192.0.2.1" (and 1 other name) does not match host name "192.0.2.1\/32"\E/ + ); + + $node->connect_ok("$common_connstr host=2001:DB8::1", + "host matching an IPv6 address (Subject Alternative Name 2)"); + + $node->connect_ok( + "$common_connstr host=2001:db8:0:0:0:0:0:1", + "host matching an IPv6 address in alternate form (Subject Alternative Name 2)" + ); + + $node->connect_ok( + "$common_connstr host=2001:db8::0.0.0.1", + "host matching an IPv6 address in mixed form (Subject Alternative Name 2)" + ); + + $node->connect_fails( + "$common_connstr host=::1", + "host not matching an IPv6 address (Subject Alternative Name 2)", + expected_stderr => + qr/\Qserver certificate for "192.0.2.1" (and 1 other name) does not match host name "::1"\E/ + ); + + $node->connect_fails( + "$common_connstr host=2001:DB8::1/128", + "IPv6 host with CIDR mask does not match", + expected_stderr => + qr/\Qserver certificate for "192.0.2.1" (and 1 other name) does not match host name "2001:DB8::1\/128"\E/ + ); +} + # Test server certificate with a CN and DNS SANs. Per RFCs 2818 and 6125, the CN # should be ignored when the certificate has both. switch_server_cert($node, certfile => 'server-cn-and-alt-names'); @@ -323,6 +381,46 @@ $node->connect_fails( qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 1 other name) does not match host name "common-name.pg-ssltest.test"\E/ ); +SKIP: +{ + skip 'IPv6 addresses in certificates not support on this platform', 1 + unless check_pg_config('#define HAVE_INET_PTON 1'); + + # But we will fall back to check the CN if the SANs contain only IP addresses. + switch_server_cert($node, certfile => 'server-cn-and-ip-alt-names'); + + $node->connect_ok( + "$common_connstr host=common-name.pg-ssltest.test", + "certificate with both a CN and IP SANs matches CN"); + $node->connect_ok("$common_connstr host=192.0.2.1", + "certificate with both a CN and IP SANs matches SAN 1"); + $node->connect_ok("$common_connstr host=2001:db8::1", + "certificate with both a CN and IP SANs matches SAN 2"); + + # And now the same tests, but with IP addresses and DNS names swapped. + switch_server_cert($node, certfile => 'server-ip-cn-and-alt-names'); + + $node->connect_ok("$common_connstr host=192.0.2.2", + "certificate with both an IP CN and IP SANs 1"); + $node->connect_ok("$common_connstr host=2001:db8::1", + "certificate with both an IP CN and IP SANs 2"); + $node->connect_fails( + "$common_connstr host=192.0.2.1", + "certificate with both an IP CN and IP SANs ignores CN", + expected_stderr => + qr/\Qserver certificate for "192.0.2.2" (and 1 other name) does not match host name "192.0.2.1"\E/ + ); +} + +switch_server_cert($node, certfile => 'server-ip-cn-and-dns-alt-names'); + +$node->connect_ok("$common_connstr host=192.0.2.1", + "certificate with both an IP CN and DNS SANs matches CN"); +$node->connect_ok("$common_connstr host=dns1.alt-name.pg-ssltest.test", + "certificate with both an IP CN and DNS SANs matches SAN 1"); +$node->connect_ok("$common_connstr host=dns2.alt-name.pg-ssltest.test", + "certificate with both an IP CN and DNS SANs matches SAN 2"); + # Finally, test a server certificate that has no CN or SANs. Of course, that's # not a very sensible certificate, but libpq should handle it gracefully. switch_server_cert($node, certfile => 'server-no-names'); diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index ef5476d034..cb2ad6cd29 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -288,6 +288,7 @@ sub GenerateFiles HAVE_HISTORY_TRUNCATE_FILE => undef, HAVE_IFADDRS_H => undef, HAVE_INET_ATON => undef, + HAVE_INET_PTON => 1, HAVE_INT_TIMEZONE => 1, HAVE_INT64 => undef, HAVE_INT8 => undef,