From a7944b4896ad3461f8d866e514ba8c38e9b18690 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Wed, 28 Oct 2020 11:26:31 +0100
Subject: [PATCH v19 4/5] NSS Documentation

---
 doc/src/sgml/acronyms.sgml     | 43 +++++++++++++++++++
 doc/src/sgml/config.sgml       | 28 ++++++++++--
 doc/src/sgml/installation.sgml | 30 ++++++++++++-
 doc/src/sgml/libpq.sgml        | 27 ++++++++++--
 doc/src/sgml/runtime.sgml      | 78 ++++++++++++++++++++++++++++++++--
 5 files changed, 195 insertions(+), 11 deletions(-)

diff --git a/doc/src/sgml/acronyms.sgml b/doc/src/sgml/acronyms.sgml
index 4e5ec983c0..4f6f0cf353 100644
--- a/doc/src/sgml/acronyms.sgml
+++ b/doc/src/sgml/acronyms.sgml
@@ -441,6 +441,28 @@
     </listitem>
    </varlistentry>
 
+   <varlistentry>
+    <term><acronym>NSPR</acronym></term>
+    <listitem>
+     <para>
+      <ulink
+      url="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSPR">
+      Netscape Portable Runtime</ulink>
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term><acronym>NSS</acronym></term>
+    <listitem>
+     <para>
+      <ulink
+      url="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS">
+      Network Security Services</ulink>
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry>
     <term><acronym>ODBC</acronym></term>
     <listitem>
@@ -539,6 +561,17 @@
     </listitem>
    </varlistentry>
 
+   <varlistentry>
+    <term><acronym>PKCS#12</acronym></term>
+    <listitem>
+     <para>
+      <ulink
+      url="https://en.wikipedia.org/wiki/PKCS_12">
+      Public-Key Cryptography Standards #12</ulink>
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry>
     <term><acronym>PL</acronym></term>
     <listitem>
@@ -684,6 +717,16 @@
     </listitem>
    </varlistentry>
 
+   <varlistentry>
+    <term><acronym>TLS</acronym></term>
+    <listitem>
+     <para>
+      <ulink url="https://sv.wikipedia.org/wiki/Transport_Layer_Security">
+      Transport Layer Security</ulink>
+     </para>
+    </listitem>
+   </varlistentry>
+
    <varlistentry>
     <term><acronym>TOAST</acronym></term>
     <listitem>
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index f043433e31..f7ae3b1be1 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1208,6 +1208,23 @@ include_dir 'conf.d'
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-ssl-database" xreflabel="ssl_database">
+      <term><varname>ssl_database</varname> (<type>string</type>)
+      <indexterm>
+       <primary><varname>ssl_database</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Specifies the name of the file containing the server certificates and
+        keys when using <productname>NSS</productname> for <acronym>SSL</acronym>
+        connections. This parameter can only be set in the
+        <filename>postgresql.conf</filename> file or on the server command
+        line.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-ssl-ciphers" xreflabel="ssl_ciphers">
       <term><varname>ssl_ciphers</varname> (<type>string</type>)
       <indexterm>
@@ -1224,7 +1241,9 @@ include_dir 'conf.d'
         connections using TLS version 1.2 and lower are affected.  There is
         currently no setting that controls the cipher choices used by TLS
         version 1.3 connections.  The default value is
-        <literal>HIGH:MEDIUM:+3DES:!aNULL</literal>.  The default is usually a
+        <literal>HIGH:MEDIUM:+3DES:!aNULL</literal> for servers which have
+        been built with <productname>OpenSSL</productname> as the
+        <acronym>SSL</acronym> library.  The default is usually a
         reasonable choice unless you have specific security requirements.
        </para>
 
@@ -1426,8 +1445,11 @@ include_dir 'conf.d'
        <para>
         Sets an external command to be invoked when a passphrase for
         decrypting an SSL file such as a private key needs to be obtained.  By
-        default, this parameter is empty, which means the built-in prompting
-        mechanism is used.
+        default, this parameter is empty. When the server is using
+        <productname>OpenSSL</productname>, this means the built-in prompting
+        mechanism is used. When using <productname>NSS</productname>, there is
+        no default prompting so a blank callback will be used returning an
+        empty password.
        </para>
        <para>
         The command must print the passphrase to the standard output and exit
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index 0ac1cb9999..bd09124fb0 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -250,7 +250,7 @@ su - postgres
 
     <listitem>
      <para>
-      You need <productname>OpenSSL</productname>, if you want to support
+      You need a supported <acronym>SSL</acronym> library, if you want to support
       encrypted client connections.  <productname>OpenSSL</productname> is
       also required for random number generation on platforms that do not
       have <filename>/dev/urandom</filename> (except Windows).  The minimum
@@ -966,6 +966,31 @@ build-postgresql:
        </listitem>
       </varlistentry>
 
+      <varlistentry>
+       <term><option>--with-nss</option>
+       <indexterm>
+        <primary>NSS</primary>
+        <secondary>NSPR</secondary>
+        <seealso>SSL</seealso>
+       </indexterm>
+       </term>
+       <listitem>
+        <para>
+         Build with support for <acronym>SSL</acronym> (encrypted)
+         connections using <productname>NSS</productname>. This requires the
+         <productname>NSS</productname> package to be installed. Additionally,
+         <productname>NSS</productname> requires <productname>NSPR</productname>
+         to be installed. <filename>configure</filename> will check for the
+         required header files and libraries to make sure that your
+         <productname>NSS</productname> installation is sufficient before
+         proceeding.
+        </para>
+        <para>
+         This option is incompatible with <literal>--with-openssl</literal>.
+        </para>
+       </listitem>
+      </varlistentry>
+
       <varlistentry>
        <term><option>--with-openssl</option>
        <indexterm>
@@ -982,6 +1007,9 @@ build-postgresql:
          your <productname>OpenSSL</productname> installation is sufficient
          before proceeding.
         </para>
+        <para>
+         This option is incompatible with <literal>--with-nss</literal>.
+        </para>
        </listitem>
       </varlistentry>
 
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 73c6a6ea4d..e420ced087 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -2459,6 +2459,8 @@ void *PQsslStruct(const PGconn *conn, const char *struct_name);
       </para>
       <para>
        The struct(s) available depend on the SSL implementation in use.
+      </para>
+      <para>
        For <productname>OpenSSL</productname>, there is one struct,
        available under the name "OpenSSL", and it returns a pointer to the
        <productname>OpenSSL</productname> <literal>SSL</literal> struct.
@@ -2482,9 +2484,14 @@ void *PQsslStruct(const PGconn *conn, const char *struct_name);
 ]]></programlisting>
       </para>
       <para>
-       This structure can be used to verify encryption levels, check server
-       certificates, and more. Refer to the <productname>OpenSSL</productname>
-       documentation for information about this structure.
+       For <productname>NSS</productname>, there is one struct available under
+       the name "NSS", and it returns a pointer to the
+       <productname>NSS</productname> <literal>PRFileDesc</literal>.
+      </para>
+      <para>
+       These structures can be used to verify encryption levels, check server
+       certificates, and more. Refer to the <acronym>SSL</acronym> library
+       documentation for information about these structures.
       </para>
      </listitem>
     </varlistentry>
@@ -2511,6 +2518,10 @@ void *PQgetssl(const PGconn *conn);
        <xref linkend="libpq-PQsslInUse"/> instead, and for more details about the
        connection, use <xref linkend="libpq-PQsslAttribute"/>.
       </para>
+      <para>
+       This function returns <literal>NULL</literal> when <acronym>SSL</acronym>
+       librariaes other than <productname>OpenSSL</productname> are used.
+      </para>
      </listitem>
     </varlistentry>
 
@@ -7943,6 +7954,11 @@ void PQinitOpenSSL(int do_ssl, int do_crypto);
        before first opening a database connection.  Also be sure that you
        have done that initialization before opening a database connection.
       </para>
+
+      <para>
+       This function does nothing when using <productname>NSS</productname> as
+       the <acronym>SSL</acronym> library.
+      </para>
      </listitem>
     </varlistentry>
 
@@ -7969,6 +7985,11 @@ void PQinitSSL(int do_ssl);
        might be preferable for applications that need to work with older
        versions of <application>libpq</application>.
       </para>
+
+      <para>
+       This function does nothing when using <productname>NSS</productname> as
+       the <acronym>SSL</acronym> library.
+      </para>
      </listitem>
     </varlistentry>
    </variablelist>
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 17e938148c..daa99cea74 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -2183,15 +2183,21 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
 
   <indexterm zone="ssl-tcp">
    <primary>SSL</primary>
+   <secondary>TLS</secondary>
   </indexterm>
 
   <para>
    <productname>PostgreSQL</productname> has native support for using
    <acronym>SSL</acronym> connections to encrypt client/server communications
    for increased security. This requires that
-   <productname>OpenSSL</productname> is installed on both client and
+   a supported TLS library is installed on both client and
    server systems and that support in <productname>PostgreSQL</productname> is
    enabled at build time (see <xref linkend="installation"/>).
+   Supported libraries are <productname>OpenSSL</productname> and
+   <productname>NSS</productname>. The terms <acronym>SSL</acronym> and
+   <acronym>TLS</acronym> are often used interchangeably to mean a secure
+   connection using a <acronym>TLS</acronym> protocol, even though
+   <acronym>SSL</acronym> protocols are no longer supported.
   </para>
 
   <sect2 id="ssl-setup">
@@ -2211,8 +2217,13 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
   </para>
 
   <para>
-   To start in <acronym>SSL</acronym> mode, files containing the server certificate
-   and private key must exist.  By default, these files are expected to be
+   To start in <acronym>SSL</acronym> mode, a server certificate
+   and private key must exist. The below sections on the different libraries
+   will discuss how to configure these.
+  </para>
+   
+  <para>
+   By default, these files are expected to be
    named <filename>server.crt</filename> and <filename>server.key</filename>, respectively, in
    the server's data directory, but other names and locations can be specified
    using the configuration parameters <xref linkend="guc-ssl-cert-file"/>
@@ -2302,6 +2313,18 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
   </note>
   </sect2>
 
+  <sect2 id="ssl-nss-config">
+   <title>NSS Configuration</title>
+
+  <para>
+   <productname>PostgreSQL</productname> will look for certificates and keys
+   in the <productname>NSS</productname> database specified by the parameter
+   <xref linkend="guc-ssl-database"/> in <filename>postgresql.conf</filename>.
+   The parameters for certificate and key filenames are used to identify the
+   nicknames in the database.
+  </para>
+  </sect2>
+
   <sect2 id="ssl-client-certificates">
    <title>Using Client Certificates</title>
 
@@ -2376,7 +2399,7 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
   </sect2>
 
   <sect2 id="ssl-server-files">
-   <title>SSL Server File Usage</title>
+   <title>SSL Server File Parameter Usage</title>
 
    <para>
     <xref linkend="ssl-file-usage"/> summarizes the files that are
@@ -2423,6 +2446,14 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
       <entry>client certificate must not be on this list</entry>
      </row>
 
+     <row>
+      <entry><xref linkend="guc-ssl-database"/></entry>
+      <entry>certificate database</entry>
+      <entry>contains server certificates, keys and revocation lists; only
+      used when <productname>PostgreSQL</productname> is built with support
+      for <productname>NSS</productname>.</entry>
+     </row>
+
     </tbody>
    </tgroup>
   </table>
@@ -2550,6 +2581,45 @@ openssl x509 -req -in server.csr -text -days 365 \
    </para>
   </sect2>
 
+  <sect2 id="nss-certificate-database">
+   <title>NSS Certificate Databases</title>
+
+   <para>
+    When using <productname>NSS</productname>, all certificates and keys must
+    be loaded into an <productname>NSS</productname> certificate database.
+   </para>
+
+   <para>
+    To create a new <productname>NSS</productname> certificate database and
+    load the certificates created in <xref linkend="ssl-certificate-creation" />,
+    use the following <productname>NSS</productname> commands:
+<programlisting>
+certutil -d "sql:server.db" -N --empty-password
+certutil -d "sql:server.db" -A -n server.crt -i server.crt -t "CT,C,C"
+certutil -d "sql:server.db" -A -n root.crt -i root.crt -t "CT,C,C"
+</programlisting>
+    This will give the certificate the filename as the nickname identifier in
+    the database which is created as <filename>server.db</filename>.
+   </para>
+   <para>
+    Then load the server key, which require converting it to
+    <acronym>PKCS#12</acronym> format using the
+    <productname>OpenSSL</productname> tools:
+<programlisting>
+openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt \
+  -certfile root.crt -passout pass:
+pk12util -i server.pfx -d server.db -W ''
+</programlisting>
+   </para>
+   <para>
+    Finally a certificate revocation list can be loaded with the following
+    commands:
+<programlisting>
+crlutil -I -i server.crl -d server.db -B
+</programlisting>
+   </para>
+  </sect2>
+
  </sect1>
 
  <sect1 id="gssapi-enc">
-- 
2.21.1 (Apple Git-122.3)

