mirror of https://github.com/postgres/postgres
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 <pchampion@vmware.com>
Co-authored-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Co-authored-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://www.postgresql.org/message-id/flat/9f5f20974cd3a4091a788cf7f00ab663d5fcdffe.camel@vmware.com
This commit is contained in:
parent
fa25bebb82
commit
c1932e5428
|
@ -15982,7 +15982,7 @@ fi
|
||||||
LIBS_including_readline="$LIBS"
|
LIBS_including_readline="$LIBS"
|
||||||
LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'`
|
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 :
|
do :
|
||||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||||
|
|
|
@ -1787,6 +1787,7 @@ AC_CHECK_FUNCS(m4_normalize([
|
||||||
getifaddrs
|
getifaddrs
|
||||||
getpeerucred
|
getpeerucred
|
||||||
getrlimit
|
getrlimit
|
||||||
|
inet_pton
|
||||||
kqueue
|
kqueue
|
||||||
mbstowcs_l
|
mbstowcs_l
|
||||||
memset_s
|
memset_s
|
||||||
|
|
|
@ -8356,16 +8356,31 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
In <literal>verify-full</literal> mode, the host name is matched against the
|
In <literal>verify-full</literal> mode, the host name is matched against the
|
||||||
certificate's Subject Alternative Name attribute(s), or against the
|
certificate's Subject Alternative Name attribute(s) (SAN), or against the
|
||||||
Common Name attribute if no Subject Alternative Name of type <literal>dNSName</literal> is
|
Common Name attribute if no SAN of type <literal>dNSName</literal> is
|
||||||
present. If the certificate's name attribute starts with an asterisk
|
present. If the certificate's name attribute starts with an asterisk
|
||||||
(<literal>*</literal>), the asterisk will be treated as
|
(<literal>*</literal>), the asterisk will be treated as
|
||||||
a wildcard, which will match all characters <emphasis>except</emphasis> a dot
|
a wildcard, which will match all characters <emphasis>except</emphasis> a dot
|
||||||
(<literal>.</literal>). This means the certificate will not match subdomains.
|
(<literal>.</literal>). This means the certificate will not match subdomains.
|
||||||
If the connection is made using an IP address instead of a host name, the
|
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 <literal>iPAddress</literal> or <literal>dNSName</literal>. If no
|
||||||
|
<literal>iPAddress</literal> SAN is present and no
|
||||||
|
matching <literal>dNSName</literal> SAN is present, the host IP address is
|
||||||
|
matched against the Common Name attribute.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>
|
||||||
|
For backward compatibility with earlier versions of PostgreSQL, the host
|
||||||
|
IP address is verified in a manner different
|
||||||
|
from <ulink url="https://tools.ietf.org/html/rfc6125">RFC 6125</ulink>.
|
||||||
|
The host IP address is always matched against <literal>dNSName</literal>
|
||||||
|
SANs as well as <literal>iPAddress</literal> SANs, and can be matched
|
||||||
|
against the Common Name attribute if no relevant SANs exist.
|
||||||
|
</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To allow server certificate verification, one or more root certificates
|
To allow server certificate verification, one or more root certificates
|
||||||
must be placed in the file <filename>~/.postgresql/root.crt</filename>
|
must be placed in the file <filename>~/.postgresql/root.crt</filename>
|
||||||
|
|
|
@ -283,6 +283,9 @@
|
||||||
/* Define to 1 if you have the `inet_aton' function. */
|
/* Define to 1 if you have the `inet_aton' function. */
|
||||||
#undef HAVE_INET_ATON
|
#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'. */
|
/* Define to 1 if the system has the type `int64'. */
|
||||||
#undef HAVE_INT64
|
#undef HAVE_INT64
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include "postgres_fe.h"
|
#include "postgres_fe.h"
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include "fe-secure-common.h"
|
#include "fe-secure-common.h"
|
||||||
|
|
||||||
#include "libpq-int.h"
|
#include "libpq-int.h"
|
||||||
|
@ -144,6 +146,108 @@ pq_verify_peer_name_matches_certificate_name(PGconn *conn,
|
||||||
return result;
|
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.
|
* Verify that the server certificate matches the hostname we connected to.
|
||||||
*
|
*
|
||||||
|
|
|
@ -21,6 +21,10 @@
|
||||||
extern int pq_verify_peer_name_matches_certificate_name(PGconn *conn,
|
extern int pq_verify_peer_name_matches_certificate_name(PGconn *conn,
|
||||||
const char *namedata, size_t namelen,
|
const char *namedata, size_t namelen,
|
||||||
char **store_name);
|
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);
|
extern bool pq_verify_peer_name_matches_certificate(PGconn *conn);
|
||||||
|
|
||||||
#endif /* FE_SECURE_COMMON_H */
|
#endif /* FE_SECURE_COMMON_H */
|
||||||
|
|
|
@ -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,
|
static int openssl_verify_peer_name_matches_certificate_name(PGconn *conn,
|
||||||
ASN1_STRING *name,
|
ASN1_STRING *name,
|
||||||
char **store_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 void destroy_ssl_system(void);
|
||||||
static int initialize_SSL(PGconn *conn);
|
static int initialize_SSL(PGconn *conn);
|
||||||
static PostgresPollingStatusType open_client_SSL(PGconn *);
|
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);
|
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.
|
* 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;
|
STACK_OF(GENERAL_NAME) * peer_san;
|
||||||
int i;
|
int i;
|
||||||
int rc = 0;
|
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,
|
* 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++)
|
for (i = 0; i < san_len; i++)
|
||||||
{
|
{
|
||||||
const GENERAL_NAME *name = sk_GENERAL_NAME_value(peer_san, 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)
|
if (name->type == GEN_DNS)
|
||||||
{
|
{
|
||||||
char *alt_name;
|
|
||||||
|
|
||||||
(*names_examined)++;
|
(*names_examined)++;
|
||||||
rc = openssl_verify_peer_name_matches_certificate_name(conn,
|
rc = openssl_verify_peer_name_matches_certificate_name(conn,
|
||||||
name->d.dNSName,
|
name->d.dNSName,
|
||||||
&alt_name);
|
&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)
|
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;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sk_GENERAL_NAME_pop_free(peer_san, GENERAL_NAME_free);
|
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.
|
* Common Name.
|
||||||
*
|
*
|
||||||
* (Per RFC 2818 and RFC 6125, if the subjectAltName extension of type
|
* (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;
|
X509_NAME *subject_name;
|
||||||
|
|
||||||
|
@ -581,10 +688,20 @@ pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn,
|
||||||
NID_commonName, -1);
|
NID_commonName, -1);
|
||||||
if (cn_index >= 0)
|
if (cn_index >= 0)
|
||||||
{
|
{
|
||||||
|
char *common_name = NULL;
|
||||||
|
|
||||||
(*names_examined)++;
|
(*names_examined)++;
|
||||||
rc = openssl_verify_peer_name_matches_certificate_name(conn,
|
rc = openssl_verify_peer_name_matches_certificate_name(conn,
|
||||||
X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, cn_index)),
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -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-----
|
|
@ -22,8 +22,12 @@
|
||||||
# key/certificate pair will be generated for you, signed by the appropriate CA.
|
# key/certificate pair will be generated for you, signed by the appropriate CA.
|
||||||
#
|
#
|
||||||
SERVERS := server-cn-and-alt-names \
|
SERVERS := server-cn-and-alt-names \
|
||||||
|
server-cn-and-ip-alt-names \
|
||||||
server-cn-only \
|
server-cn-only \
|
||||||
|
server-ip-alt-names \
|
||||||
server-ip-cn-only \
|
server-ip-cn-only \
|
||||||
|
server-ip-cn-and-alt-names \
|
||||||
|
server-ip-cn-and-dns-alt-names \
|
||||||
server-ip-in-dnsname \
|
server-ip-in-dnsname \
|
||||||
server-single-alt-name \
|
server-single-alt-name \
|
||||||
server-multiple-alt-names \
|
server-multiple-alt-names \
|
||||||
|
|
|
@ -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/
|
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
|
# Test server certificate with a CN and DNS SANs. Per RFCs 2818 and 6125, the CN
|
||||||
# should be ignored when the certificate has both.
|
# should be ignored when the certificate has both.
|
||||||
switch_server_cert($node, certfile => 'server-cn-and-alt-names');
|
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/
|
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
|
# 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.
|
# not a very sensible certificate, but libpq should handle it gracefully.
|
||||||
switch_server_cert($node, certfile => 'server-no-names');
|
switch_server_cert($node, certfile => 'server-no-names');
|
||||||
|
|
|
@ -288,6 +288,7 @@ sub GenerateFiles
|
||||||
HAVE_HISTORY_TRUNCATE_FILE => undef,
|
HAVE_HISTORY_TRUNCATE_FILE => undef,
|
||||||
HAVE_IFADDRS_H => undef,
|
HAVE_IFADDRS_H => undef,
|
||||||
HAVE_INET_ATON => undef,
|
HAVE_INET_ATON => undef,
|
||||||
|
HAVE_INET_PTON => 1,
|
||||||
HAVE_INT_TIMEZONE => 1,
|
HAVE_INT_TIMEZONE => 1,
|
||||||
HAVE_INT64 => undef,
|
HAVE_INT64 => undef,
|
||||||
HAVE_INT8 => undef,
|
HAVE_INT8 => undef,
|
||||||
|
|
Loading…
Reference in New Issue