@@ -776,6 +776,72 @@ PGPing PQping(const char *conninfo);
776776 </listitem>
777777 </varlistentry>
778778
779+ <varlistentry id="libpq-pqsetsslkeypasshook">
780+ <term><function>PQsetSSLKeyPassHook</function><indexterm><primary>PQsetSSLKeyPassHook</primary></indexterm></term>
781+ <listitem>
782+ <para>
783+ <function>PQsetSSLKeyPassHook</function> lets an application override
784+ <literal>libpq</literal>'s <link linkend="libpq-ssl-clientcert">default
785+ handling of encrypted client certificate key files</link> using
786+ <xref linkend="libpq-connect-sslpassword"/> or interactive prompting.
787+
788+ <synopsis>
789+ void PQsetSSLKeyPassHook(PQsslKeyPassHook_type hook);
790+ </synopsis>
791+
792+ The application passes a pointer to a callback function with signature:
793+ <programlisting>
794+ int callback_fn(char *buf, int size, PGconn *conn);
795+ </programlisting>
796+ which <literal>libpq</literal> will then call <emphasis>instead of</emphasis>
797+ its default <function>PQdefaultSSLKeyPassHook</function> handler. The callback
798+ should determine the password for the key and copy it to result-buffer
799+ <literal>buf</literal> of size <literal>size</literal>. The string in <literal>
800+ buf</literal> must be null-terminated. The calback must return the length of
801+ the password stored in <literal>buf</literal> excluding the null terminator.
802+ On failure, the callback should set <literal>buf[0] = '\0'</literal> and return 0.
803+ See <function>PQdefaultSSLKeyPassHook</function> in <literal>libpq</literal>'s
804+ source code for an example.
805+ </para>
806+
807+ <para>
808+ If the user specified an explicit key location,
809+ its path will be in <literal>conn->pgsslkey</literal> when the callback
810+ is invoked. This will be empty if the default key path is being used.
811+ For keys that are engine specifiers, it is up to engine implementations
812+ whether they use the OpenSSL password callback or define their own handling.
813+ </para>
814+
815+ <para>
816+ The app callback may choose to delegate unhandled cases to
817+ <function>PQdefaultSSLKeyPassHook</function>,
818+ or call it first and try something else if it returns 0, or completely override it.
819+ </para>
820+
821+ <para>
822+ The callback <emphasis>must not</emphasis> escape normal flow control with exceptions,
823+ <function>longjmp(...)</function>, etc. It must return normally.
824+ </para>
825+
826+ </listitem>
827+ </varlistentry>
828+
829+ <varlistentry id="libpq-pqgetsslkeypasshook">
830+ <term><function>PQgetSSLKeyPassHook</function><indexterm><primary>PQgetSSLKeyPassHook</primary></indexterm></term>
831+ <listitem>
832+ <para>
833+ <function>PQgetSSLKeyPassHook</function> returns the current
834+ client certificate key password hook, or <literal>NULL</literal>
835+ if none has been set.
836+
837+ <synopsis>
838+ PQsslKeyPassHook_type PQgetSSLKeyPassHook(void);
839+ </synopsis>
840+ </para>
841+
842+ </listitem>
843+ </varlistentry>
844+
779845 </variablelist>
780846 </para>
781847
@@ -1586,6 +1652,36 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
15861652 </listitem>
15871653 </varlistentry>
15881654
1655+ <varlistentry id="libpq-connect-sslpassword" xreflabel="sslpassword">
1656+ <term><literal>sslpassword</literal></term>
1657+ <listitem>
1658+ <para>
1659+ This parameter specifies the password for the secret key specified in
1660+ <literal>sslkey</literal>, allowing client certificate private keys
1661+ to be stored in encrypted form on disk even when interactive passphrase
1662+ input is not practical.
1663+ </para>
1664+ <para>
1665+ Specifying this parameter with any non-empty value suppresses the
1666+ <literal>Enter PEM passphrase:</literal>
1667+ prompt that OpenSSL will emit by default when an encrypted client
1668+ certificate key is provided to <literal>libpq</literal>.
1669+ </para>
1670+ <para>
1671+ If the key is not encrypted this parameter is ignored. The parameter has no
1672+ effect on keys specified by OpenSSL engines unless the engine uses the
1673+ OpenSSL password callback mechanism for prompts.
1674+ </para>
1675+ <para>
1676+ There is no environment variable equivalent to this option, and no
1677+ facility for looking it up in <filename>.pgpass</filename>. It can be
1678+ used in a service file connection definition. Users with
1679+ more sophisticated uses should consider using openssl engines and
1680+ tools like PKCS#11 or USB crypto offload devices.
1681+ </para>
1682+ </listitem>
1683+ </varlistentry>
1684+
15891685 <varlistentry id="libpq-connect-sslrootcert" xreflabel="sslrootcert">
15901686 <term><literal>sslrootcert</literal></term>
15911687 <listitem>
@@ -1771,6 +1867,24 @@ char *PQpass(const PGconn *conn);
17711867 </listitem>
17721868 </varlistentry>
17731869
1870+ <varlistentry id="libpq-PQsslpassword">
1871+ <term><function>PQsslpassword</function><indexterm><primary>PQsslpassword</primary></indexterm></term>
1872+
1873+ <listitem>
1874+ <para>
1875+ Returns the password for the SSL client key.
1876+ <synopsis>
1877+ char *PQsslpassword(const PGconn *conn);
1878+ </synopsis>
1879+ </para>
1880+
1881+ <para>
1882+ <xref linkend="libpq-PQsslpassword"/> will return the SSL password specified
1883+ in the connection parameters.
1884+ </para>
1885+ </listitem>
1886+ </varlistentry>
1887+
17741888 <varlistentry id="libpq-PQhost">
17751889 <term><function>PQhost</function><indexterm><primary>PQhost</primary></indexterm></term>
17761890
@@ -7499,6 +7613,26 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
74997613 certificates on the server (<xref linkend="guc-ssl-ca-file"/>).
75007614 </para>
75017615
7616+ <para>
7617+ The certificate and key may be in PEM or ASN.1 DER format.
7618+ </para>
7619+
7620+ <para>
7621+ The key may be
7622+ stored in cleartext or encrypted with a passphrase using any algorithm supported
7623+ by OpenSSL, like AES-128. If the key is stored encrypted, then the passphrase
7624+ may be provided in the <xref linkend="libpq-connect-sslpassword"/> connection
7625+ option. If an encrypted key is supplied and the <literal>sslpassword</literal>
7626+ option is absent or blank, a password will be prompted for interactively by
7627+ OpenSSL with a
7628+ <programlisting>
7629+ Enter PEM Passphrase:
7630+ </programlisting>
7631+ prompt if a TTY is available. Applications can override the client certificate
7632+ prompt and the handling of the <literal>sslpassword</literal> parameter by supplying
7633+ their own key password callback; see <xref linkend="libpq-pqsetsslkeypasshook"/>.
7634+ </para>
7635+
75027636 <para>
75037637 For instructions on creating certificates, see <xref
75047638 linkend="ssl-certificate-creation"/>.
0 commit comments