From ef9e113d60eae797327ce5a9d7b1553afc743720 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
Date: Thu, 17 Aug 2017 14:43:53 +0200
Subject: [PATCH 3/4] WIP: A first stab at documentation for Secure Transport

This is a rough first stab at amending the documentation to support
having multiple SSL backends, and adding Secure Transport specific
information.
---
 doc/src/sgml/config.sgml  |  20 ++++++++
 doc/src/sgml/libpq.sgml   |  52 ++++++++++++++-----
 doc/src/sgml/runtime.sgml | 127 +++++++++++++++++++++++++++++++++-------------
 3 files changed, 152 insertions(+), 47 deletions(-)

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 2b6255ed95..22942d5680 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1046,6 +1046,26 @@ include_dir 'conf.d'
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-ssl-keychain-file" xreflabel="ssl_keychain_file">
+      <term><varname>ssl_keychain_file</varname> (<type>string</type>)
+      <indexterm>
+       <primary><varname>ssl_keychain_file</> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        Specifies the name of the file containing the a Keychain. Relative
+        paths are relative to the current users system Keychain folder
+        (typically <filename>Library/Keychains</>).
+        Absolute paths can be used to use a Keychain located elsewhere.
+        This parameter can only be set in the <filename>postgresql.conf</>
+        file or on the server command line.
+        This parameter is only available when the server has been configured
+        with support for Secure Transport.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-ssl-ciphers" xreflabel="ssl_ciphers">
       <term><varname>ssl_ciphers</varname> (<type>string</type>)
       <indexterm>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index ad5e9b95b4..0f204be205 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1338,13 +1338,14 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
       <term><literal>sslcompression</literal></term>
       <listitem>
        <para>
+        This requires <productname>OpenSSL</> 1.0.0 or later, when using
+        other SSL libraries this setting will be ignored.
         If set to 1 (default), data sent over SSL connections will be
         compressed.
-        If set to 0, compression will be disabled (this requires
-        <productname>OpenSSL</> 1.0.0 or later).
+        If set to 0, compression will be disabled.
         This parameter is ignored if a connection without SSL is made,
-        or if the version of <productname>OpenSSL</> used does not support
-        it.
+        if the version of <productname>OpenSSL</> used does not support
+        it or an SSL library other than <productname>OpenSSL</> is used.
        </para>
        <para>
         Compression uses CPU time, but can improve throughput if
@@ -1405,7 +1406,11 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
         revocation list (CRL).  Certificates listed in this file, if it
         exists, will be rejected while attempting to authenticate the
         server's certificate.  The default is
-        <filename>~/.postgresql/root.crl</>.
+        <filename>~/.postgresql/root.crl</>. This setting is invalid
+        when using <productname>Secure Transport</>, which require the
+        CRL to be imported into the default Keychain. In order to not
+        cause unintentional silent ignore, the server will abort if
+        this parameter is configured.
        </para>
       </listitem>
      </varlistentry>
@@ -2041,8 +2046,8 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name);
          <term><literal>library</literal></term>
           <listitem>
            <para>
-            Name of the SSL implementation in use. (Currently, only
-            <literal>"OpenSSL"</literal> is implemented)
+            Name of the SSL implementation in use. Possible values are
+            <literal>"OpenSSL"</literal> and <literal>"SecureTransport"</literal>.
            </para>
           </listitem>
          </varlistentry>
@@ -7524,9 +7529,14 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
    <productname>PostgreSQL</> has native support for using <acronym>SSL</>
    connections to encrypt client/server communications for increased
    security. See <xref linkend="ssl-tcp"> for details about the server-side
-   <acronym>SSL</> functionality.
+   <acronym>SSL</> functionality. Multiple SSL libraries are supported, one
+   of which is enabled at build time.
+   Table <xref linkend="supported-ssl-libraries"> lists the supported SSL
+   libraries.
   </para>
 
+  <sect2>
+   <title>Using OpenSSL</title>
   <para>
    <application>libpq</application> reads the system-wide
    <productname>OpenSSL</productname> configuration file. By default, this
@@ -7536,6 +7546,20 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
    <envar>OPENSSL_CONF</envar> to the name of the desired configuration
    file.
   </para>
+  </sect2>
+
+  <sect2>
+   <title>Using Secure Transport</title>
+  <para>
+   libpq will use the default <productname>Keychain</productname>, as well
+   as a custom one if configured, when using
+   <productname>Secure Transport</productname>. Certificates and keys can be
+   loaded from either PEM files, or from the Keychain. To load an identity
+   from a Keychain, the <literal>ssl_cert</> parameter is prefixed with
+   <literal>keychain:</> followed by the certificate common name rather than
+   the filename.
+  </para>
+  </sect2>
 
  <sect2 id="libq-ssl-certificates">
   <title>Client Verification of Server Certificates</title>
@@ -7582,10 +7606,13 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
   </para>
 
   <para>
-   Certificate Revocation List (CRL) entries are also checked
-   if the file <filename>~/.postgresql/root.crl</filename> exists
+   Certificate Revocation List (<acronym>CRL</>) entries are also checked. When libpq
+   is built using <productname>OpenSSL</>
+   the file <filename>~/.postgresql/root.crl</filename> is used
    (<filename>%APPDATA%\postgresql\root.crl</filename> on Microsoft
-   Windows).
+   Windows). When using <productname>Secure Transport</> the CRL must be
+   imported in the Keychain holding the server certificate to perform certificate
+   revocation checks automatically.
   </para>
 
   <para>
@@ -7863,7 +7890,8 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
      <row>
       <entry><filename>~/.postgresql/root.crl</></entry>
       <entry>certificates revoked by certificate authorities</entry>
-      <entry>server certificate must not be on this list</entry>
+      <entry>any certificate in this list will be rejected; server certificate
+      must not be on this list</entry>
      </row>
 
     </tbody>
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 6d57525515..a23715b8c6 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -2169,12 +2169,42 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
   <para>
    <productname>PostgreSQL</> has native support for using
    <acronym>SSL</> connections to encrypt client/server communications
-   for increased security. This requires that
-   <productname>OpenSSL</productname> is installed on both client and
+   for increased security. This requires that a supported SSL library
+   is installed on both client and
    server systems and that support in <productname>PostgreSQL</> is
-   enabled at build time (see <xref linkend="installation">).
+   enabled at build time (see <xref linkend="installation">). Clients are
+   not required to use the same SSL library as the server, all supported
+   libraries are compatible.
+   Table <xref linkend="supported-ssl-libraries"> lists the supported SSL
+   libraries.
   </para>
 
+  <table id="supported-ssl-libraries">
+   <title>Supported SSL libraries</title>
+   <tgroup cols="2">
+    <thead>
+     <row>
+      <entry>Library</entry>
+      <entry>Platform</entry>
+     </row>
+    </thead>
+
+    <tbody>
+
+     <row>
+      <entry><productname>OpenSSL</productname></entry>
+      <entry>All platforms supported by <productname>PostgreSQL</productname></entry>
+     </row>
+
+     <row>
+      <entry><productname>Secure Transport</productname></entry>
+      <entry><productname>Apple macOS 10.11 El Capitan+</productname></entry>
+     </row>
+
+    </tbody>
+   </tgroup>
+  </table>
+
   <para>
    With <acronym>SSL</> support compiled in, the
    <productname>PostgreSQL</> server can be started with
@@ -2189,41 +2219,13 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
   </para>
 
   <para>
-   <productname>PostgreSQL</productname> reads the system-wide
-   <productname>OpenSSL</productname> configuration file. By default, this
-   file is named <filename>openssl.cnf</filename> and is located in the
-   directory reported by <literal>openssl version -d</>.
-   This default can be overridden by setting environment variable
-   <envar>OPENSSL_CONF</envar> to the name of the desired configuration file.
-  </para>
-
-  <para>
-   <productname>OpenSSL</productname> supports a wide range of ciphers
-   and authentication algorithms, of varying strength.  While a list of
-   ciphers can be specified in the <productname>OpenSSL</productname>
-   configuration file, you can specify ciphers specifically for use by
-   the database server by modifying <xref linkend="guc-ssl-ciphers"> in
-   <filename>postgresql.conf</>.
-  </para>
-
-  <note>
-   <para>
-    It is possible to have authentication without encryption overhead by
-    using <literal>NULL-SHA</> or <literal>NULL-MD5</> ciphers.  However,
-    a man-in-the-middle could read and pass communications between client
-    and server.  Also, encryption overhead is minimal compared to the
-    overhead of authentication.  For these reasons NULL ciphers are not
-    recommended.
-   </para>
-  </note>
-
-  <para>
-   To start in <acronym>SSL</> mode, files containing the server certificate
-   and private key must exist.  By default, these files are expected to be
+   To start in <acronym>SSL</> mode, a server certificate
+   and private key must exist.  By default, these are expected to be in files
    named <filename>server.crt</> and <filename>server.key</>, 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">
-   and <xref linkend="guc-ssl-key-file">.
+   and <xref linkend="guc-ssl-key-file">. See the notes on the library used
+   for specifics on how certificates and keys can be specified.
   </para>
 
   <para>
@@ -2258,6 +2260,55 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
    <filename>root.crt</filename> files.
   </para>
 
+  <note>
+   <para>
+    It is possible to have authentication without encryption overhead by
+    using NULL ciphers (<literal>NULL-SHA</> or <literal>NULL-MD5</> in
+    <productname>OpenSSL</productname> for example).  However,
+    a man-in-the-middle could read and pass communications between client
+    and server.  Also, encryption overhead is minimal compared to the
+    overhead of authentication.  For these reasons NULL ciphers are not
+    recommended.
+   </para>
+  </note>
+
+  <sect2 id="ssl-library-openssl">
+   <title>Using OpenSSL</title>
+
+  <para>
+   <productname>PostgreSQL</productname> reads the system-wide
+   <productname>OpenSSL</productname> configuration file. By default, this
+   file is named <filename>openssl.cnf</filename> and is located in the
+   directory reported by <literal>openssl version -d</>.
+   This default can be overridden by setting environment variable
+   <envar>OPENSSL_CONF</envar> to the name of the desired configuration file.
+  </para>
+
+  <para>
+   <productname>OpenSSL</productname> supports a wide range of ciphers
+   and authentication algorithms, of varying strength.  While a list of
+   ciphers can be specified in the <productname>OpenSSL</productname>
+   configuration file, you can specify ciphers specifically for use by
+   the database server by modifying <xref linkend="guc-ssl-ciphers"> in
+   <filename>postgresql.conf</>.
+  </para>
+  </sect2>
+
+  <sect2 id="ssl-library-secure-transport">
+   <title>Using Secure Transport</title>
+   
+  <para>
+   <productname>Secure Transport</productname> can use certificates and
+   keys either stored in files, or load them as an identity from a
+   <productname>Keychain</productname>. To load an identity, the default
+   <productname>Keychain</productname> as well as the
+   <productname>Keychain</productname> specified by the
+   <xref linkeend="guc-ssl-keychain-file"> parameter is searched. The identity
+   is specified by prefixing <xref linkend="guc-ssl-cert-file"> with
+   <literal>keychain:</> and specifying the common name of the certificate.
+  </para>
+  </sect2>
+  
   <sect2 id="ssl-client-certificates">
    <title>Using Client Certificates</title>
 
@@ -2363,6 +2414,12 @@ 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-keychain-file"></entry>
+      <entry>server identities</entry>
+      <entry>searched for server identities (certificate and key)</entry>
+     </row>
+
     </tbody>
    </tgroup>
   </table>
-- 
2.14.1.145.gb3622a4ee

