From 0268781a38f5518e7ab71d95203b7e98ccb4aefd Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Mon, 8 Feb 2021 23:52:48 +0100 Subject: [PATCH v50 08/10] nss: Support NSS in sslinfo Since sslinfo to a large extent uses the be_tls_* API this mostly disables functionality which currently is OpenSSL specific. --- contrib/sslinfo/sslinfo.c | 32 ++++++++++++++ doc/src/sgml/sslinfo.sgml | 12 +++++- src/test/ssl/sslfiles_nss.mk | 12 +++++- src/test/ssl/t/003_sslinfo.pl | 80 +++++++++++++++++------------------ 4 files changed, 93 insertions(+), 43 deletions(-) diff --git a/contrib/sslinfo/sslinfo.c b/contrib/sslinfo/sslinfo.c index 5fd46b9874..25a068fa60 100644 --- a/contrib/sslinfo/sslinfo.c +++ b/contrib/sslinfo/sslinfo.c @@ -9,9 +9,11 @@ #include "postgres.h" +#ifdef USE_OPENSSL #include #include #include +#endif #include "access/htup_details.h" #include "funcapi.h" @@ -32,6 +34,7 @@ PG_MODULE_MAGIC; +#ifdef USE_OPENSSL static Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName); static Datum ASN1_STRING_to_text(ASN1_STRING *str); @@ -42,6 +45,7 @@ typedef struct { TupleDesc tupdesc; } SSLExtensionInfoContext; +#endif /* * Indicates whether current session uses SSL @@ -142,6 +146,7 @@ ssl_client_serial(PG_FUNCTION_ARGS) } +#ifdef USE_OPENSSL /* * Converts OpenSSL ASN1_STRING structure into text * @@ -293,7 +298,23 @@ ssl_issuer_field(PG_FUNCTION_ARGS) else return result; } +#endif /* USE_OPENSSL */ +#ifdef USE_NSS +PG_FUNCTION_INFO_V1(ssl_client_dn_field); +Datum +ssl_client_dn_field(PG_FUNCTION_ARGS) +{ + PG_RETURN_NULL(); +} + +PG_FUNCTION_INFO_V1(ssl_issuer_field); +Datum +ssl_issuer_field(PG_FUNCTION_ARGS) +{ + PG_RETURN_NULL(); +} +#endif /* USE_NSS */ /* * Returns current client certificate subject as one string @@ -349,6 +370,7 @@ ssl_issuer_dn(PG_FUNCTION_ARGS) } +#ifdef USE_OPENSSL /* * Returns information about available SSL extensions. * @@ -482,3 +504,13 @@ ssl_extension_info(PG_FUNCTION_ARGS) /* All done */ SRF_RETURN_DONE(funcctx); } +#endif /* USE_OPENSSL */ + +#ifdef USE_NSS +PG_FUNCTION_INFO_V1(ssl_extension_info); +Datum +ssl_extension_info(PG_FUNCTION_ARGS) +{ + PG_RETURN_NULL(); +} +#endif /* USE_NSS */ diff --git a/doc/src/sgml/sslinfo.sgml b/doc/src/sgml/sslinfo.sgml index 2a9c45a111..f3ae2fc3b8 100644 --- a/doc/src/sgml/sslinfo.sgml +++ b/doc/src/sgml/sslinfo.sgml @@ -22,7 +22,8 @@ This extension won't build at all unless the installation was - configured with --with-ssl=openssl. + configured with SSL support, such as --with-ssl=openssl + or --with-ssl=nss. @@ -208,6 +209,9 @@ emailAddress the X.500 and X.509 standards, so you cannot just assign arbitrary meaning to them. + + This function is only available when using OpenSSL. + @@ -223,6 +227,9 @@ emailAddress Same as ssl_client_dn_field, but for the certificate issuer rather than the certificate subject. + + This function is only available when using OpenSSL. + @@ -238,6 +245,9 @@ emailAddress Provide information about extensions of client certificate: extension name, extension value, and if it is a critical extension. + + This function is only available when using OpenSSL. + diff --git a/src/test/ssl/sslfiles_nss.mk b/src/test/ssl/sslfiles_nss.mk index adb7363d63..3b4e2494a2 100644 --- a/src/test/ssl/sslfiles_nss.mk +++ b/src/test/ssl/sslfiles_nss.mk @@ -43,7 +43,8 @@ NSSFILES := ssl/nss/client_ca.crt.db \ ssl/nss/root+server_ca.crt__root+server.crldir.db \ ssl/nss/native_ca-root.db \ ssl/nss/native_server-root.db \ - ssl/nss/native_client-root.db + ssl/nss/native_client-root.db \ + ssl/nss/client_ext.crt__client_ext.key.db nssfiles: $(NSSFILES) @@ -168,6 +169,15 @@ ssl/nss/client.crt__client.key.db: ssl/client.crt openssl pkcs12 -export -out ssl/nss/client.pfx -inkey ssl/client.key -in ssl/client.crt -certfile ssl/client_ca.crt -passout pass: pk12util -i ssl/nss/client.pfx -d "sql:$@" -W '' +ssl/nss/client_ext.crt__client_ext.key.db: ssl/client_ext.crt + $(MKDIR_P) $@ + certutil -d "sql:$@" -N --empty-password + certutil -d "sql:$@" -A -n ssl/client_ext.crt -i ssl/client_ext.crt -t "CT,C,C" + certutil -d "sql:$@" -A -n client_ca.crt -i ssl/client_ca.crt -t "CT,C,C" + certutil -d "sql:$@" -A -n root+server_ca.crt -i ssl/root+server_ca.crt -t "CT,C,C" + openssl pkcs12 -export -out ssl/nss/client_ext.pfx -inkey ssl/client_ext.key -in ssl/client_ext.crt -certfile ssl/client_ca.crt -passout pass: + pk12util -i ssl/nss/client_ext.pfx -d "sql:$@" -W '' + # Client certificate with encrypted key, signed by client CA ssl/nss/client.crt__client-encrypted-pem.key.db: ssl/client.crt $(MKDIR_P) $@ diff --git a/src/test/ssl/t/003_sslinfo.pl b/src/test/ssl/t/003_sslinfo.pl index f3c6db2989..9181a74437 100644 --- a/src/test/ssl/t/003_sslinfo.pl +++ b/src/test/ssl/t/003_sslinfo.pl @@ -14,18 +14,8 @@ use lib $FindBin::RealBin; use SSL::Server; -if ($ENV{with_ssl} eq 'openssl') -{ - plan tests => 13; -} -elsif ($ENV{with_ssl} eq 'nss') -{ - plan skip_all => 'SSL not supported by this build'; -} -else -{ - plan skip_all => 'SSL not supported by this build'; -} +plan skip_all => 'SSL not supported by this build' + unless (($ENV{with_ssl} eq 'openssl') || ($ENV{with_ssl} eq 'nss')); #### Some configuration @@ -68,10 +58,11 @@ configure_test_server_for_ssl($node, $SERVERHOSTADDR, $SERVERHOSTCIDR, # We aren't using any CRL's in this suite so we can keep using server-revoked # as server certificate for simple client.crt connection much like how the # 001 test does. -switch_server_cert($node, 'server-revoked'); +switch_server_cert($node, certfile => 'server-revoked', nssdatabase => 'server-revoked.crt__server-revoked.key.db'); $common_connstr = "sslrootcert=ssl/root+server_ca.crt sslmode=require dbname=certdb hostaddr=$SERVERHOSTADDR " . + "ssldatabase=ssl/nss/client_ext.crt__client_ext.key.db " . "user=ssltestuser sslcert=ssl/client_ext.crt sslkey=$client_tmp_key"; # Make sure we can connect even though previous test suites have established this @@ -110,32 +101,39 @@ $result = $node->safe_psql("certdb", connstr => $common_connstr); is($result, 't', "ssl_client_serial() compared with pg_stat_ssl"); -# Must not use safe_psql since we expect an error here -$result = $node->psql("certdb", "SELECT ssl_client_dn_field('invalid');", - connstr => $common_connstr); -is($result, '3', "ssl_client_dn_field() for an invalid field"); - -$result = $node->safe_psql("trustdb", "SELECT ssl_client_dn_field('commonName');", - connstr => "sslrootcert=ssl/root+server_ca.crt sslmode=require " . - "dbname=trustdb hostaddr=$SERVERHOSTADDR user=ssltestuser"); -is($result, '', "ssl_client_dn_field() for connection without cert"); - -$result = $node->safe_psql("certdb", - "SELECT '/CN=' || ssl_client_dn_field('commonName') = client_dn FROM pg_stat_ssl WHERE pid = pg_backend_pid();", - connstr => $common_connstr); -is($result, 't', "ssl_client_dn_field() for commonName"); - -$result = $node->safe_psql("certdb", - "SELECT ssl_issuer_dn() = issuer_dn FROM pg_stat_ssl WHERE pid = pg_backend_pid();", - connstr => $common_connstr); -is($result, 't', "ssl_issuer_dn() for connection with cert"); - -$result = $node->safe_psql("certdb", - "SELECT '/CN=' || ssl_issuer_field('commonName') = issuer_dn FROM pg_stat_ssl WHERE pid = pg_backend_pid();", - connstr => $common_connstr); -is($result, 't', "ssl_issuer_field() for commonName"); +SKIP: +{ + skip "Functionality not implemented with NSS", 6 if ($ENV{with_ssl} eq 'nss'); + + # Must not use safe_psql since we expect an error here + $result = $node->psql("certdb", "SELECT ssl_client_dn_field('invalid');", + connstr => $common_connstr); + is($result, '3', "ssl_client_dn_field() for an invalid field"); + + $result = $node->safe_psql("trustdb", "SELECT ssl_client_dn_field('commonName');", + connstr => "sslrootcert=ssl/root+server_ca.crt sslmode=require " . + "dbname=trustdb hostaddr=$SERVERHOSTADDR user=ssltestuser"); + is($result, '', "ssl_client_dn_field() for connection without cert"); + + $result = $node->safe_psql("certdb", + "SELECT '/CN=' || ssl_client_dn_field('commonName') = client_dn FROM pg_stat_ssl WHERE pid = pg_backend_pid();", + connstr => $common_connstr); + is($result, 't', "ssl_client_dn_field() for commonName"); + + $result = $node->safe_psql("certdb", + "SELECT ssl_issuer_dn() = issuer_dn FROM pg_stat_ssl WHERE pid = pg_backend_pid();", + connstr => $common_connstr); + is($result, 't', "ssl_issuer_dn() for connection with cert"); + + $result = $node->safe_psql("certdb", + "SELECT '/CN=' || ssl_issuer_field('commonName') = issuer_dn FROM pg_stat_ssl WHERE pid = pg_backend_pid();", + connstr => $common_connstr); + is($result, 't', "ssl_issuer_field() for commonName"); + + $result = $node->safe_psql("certdb", + "SELECT value, critical FROM ssl_extension_info() WHERE name = 'basicConstraints';", + connstr => $common_connstr); + is($result, 'CA:FALSE|t', 'extract extension from cert'); +} -$result = $node->safe_psql("certdb", - "SELECT value, critical FROM ssl_extension_info() WHERE name = 'basicConstraints';", - connstr => $common_connstr); -is($result, 'CA:FALSE|t', 'extract extension from cert'); +done_testing(); -- 2.24.3 (Apple Git-128)