Thread: SSL enhancement patch ver.2

SSL enhancement patch ver.2

From
"Victor B. Wagner"
Date:
This patch adds following functionality to PostgreSQL

1. If PostgreSQL is compiled with OpenSSL version 0.9.7 and above,
both backend and libpq read site-wide OpenSSL configuration file as
described in OPENSSL_config functon manual page.

This allows to use hardware crypto acceleration modules (engines) and,
in future version 0.9.9 would allow to use additional cryptoalgorithms
(i.e. national standards) which are not included in core OpenSSL.

All other configuration parameters which are supported by OpenSSL
library also are taken into account.


2. New configuration option "ssl_ciphers" is added to postgresql.conf.
This option allows to change list of ciphers, acceptable by backend
during SSL connection. Changing list of ciphers can be desirable to
tighten or relax security of particular installation, and allows quick
fix on configuration file level in case if vulnerability is discovered
in one of cryptoalgorithms or their OpenSSL implementation - cipher
suites which use such algorithm can be easily disabled.


3. If libpq compiled with OpenSSL 0.9.7 and above, compiled with engine
support, it is possible to store secret key of client certificate on the
hardware token, supported by one of OpenSSL engines (Hardware Security
Module). Name of engine which supports token and engine-specific key ID
are specifyed using environment variable PGSSLKEY.

This allows use of hardware tokens such as smartcards to identify
clients, connecting to database.

This functionality can be used in installations with high security
requirements or in situations where several people can use same terminal
(such as cash register in shops or malls).

If PostgreSQL is compiled with version of OpenSSL which do not support
engines or doesn't have OPENSSL_config function, related functionality
is excluded by preprocessor conditionals, based on value of
SSLEAY_VERSION_NUMBER preprocessor symbol which is defined by all
versions of OpenSSL.


Attachment

Re: SSL enhancement patch ver.2

From
Bruce Momjian
Date:
This has been saved for the 8.3 release:

    http://momjian.postgresql.org/cgi-bin/pgpatches_hold

---------------------------------------------------------------------------

Victor B. Wagner wrote:
> This patch adds following functionality to PostgreSQL
>
> 1. If PostgreSQL is compiled with OpenSSL version 0.9.7 and above,
> both backend and libpq read site-wide OpenSSL configuration file as
> described in OPENSSL_config functon manual page.
>
> This allows to use hardware crypto acceleration modules (engines) and,
> in future version 0.9.9 would allow to use additional cryptoalgorithms
> (i.e. national standards) which are not included in core OpenSSL.
>
> All other configuration parameters which are supported by OpenSSL
> library also are taken into account.
>
>
> 2. New configuration option "ssl_ciphers" is added to postgresql.conf.
> This option allows to change list of ciphers, acceptable by backend
> during SSL connection. Changing list of ciphers can be desirable to
> tighten or relax security of particular installation, and allows quick
> fix on configuration file level in case if vulnerability is discovered
> in one of cryptoalgorithms or their OpenSSL implementation - cipher
> suites which use such algorithm can be easily disabled.
>
>
> 3. If libpq compiled with OpenSSL 0.9.7 and above, compiled with engine
> support, it is possible to store secret key of client certificate on the
> hardware token, supported by one of OpenSSL engines (Hardware Security
> Module). Name of engine which supports token and engine-specific key ID
> are specifyed using environment variable PGSSLKEY.
>
> This allows use of hardware tokens such as smartcards to identify
> clients, connecting to database.
>
> This functionality can be used in installations with high security
> requirements or in situations where several people can use same terminal
> (such as cash register in shops or malls).
>
> If PostgreSQL is compiled with version of OpenSSL which do not support
> engines or doesn't have OPENSSL_config function, related functionality
> is excluded by preprocessor conditionals, based on value of
> SSLEAY_VERSION_NUMBER preprocessor symbol which is defined by all
> versions of OpenSSL.
>

[ Attachment, skipping... ]

>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: don't forget to increase your free space map settings

--
  Bruce Momjian   bruce@momjian.us
  EnterpriseDB    http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: SSL enhancement patch ver.2

From
Bruce Momjian
Date:
Your patch has been added to the PostgreSQL unapplied patches list at:

    http://momjian.postgresql.org/cgi-bin/pgpatches

It will be applied as soon as one of the PostgreSQL committers reviews
and approves it.

---------------------------------------------------------------------------


Victor B. Wagner wrote:
> This patch adds following functionality to PostgreSQL
>
> 1. If PostgreSQL is compiled with OpenSSL version 0.9.7 and above,
> both backend and libpq read site-wide OpenSSL configuration file as
> described in OPENSSL_config functon manual page.
>
> This allows to use hardware crypto acceleration modules (engines) and,
> in future version 0.9.9 would allow to use additional cryptoalgorithms
> (i.e. national standards) which are not included in core OpenSSL.
>
> All other configuration parameters which are supported by OpenSSL
> library also are taken into account.
>
>
> 2. New configuration option "ssl_ciphers" is added to postgresql.conf.
> This option allows to change list of ciphers, acceptable by backend
> during SSL connection. Changing list of ciphers can be desirable to
> tighten or relax security of particular installation, and allows quick
> fix on configuration file level in case if vulnerability is discovered
> in one of cryptoalgorithms or their OpenSSL implementation - cipher
> suites which use such algorithm can be easily disabled.
>
>
> 3. If libpq compiled with OpenSSL 0.9.7 and above, compiled with engine
> support, it is possible to store secret key of client certificate on the
> hardware token, supported by one of OpenSSL engines (Hardware Security
> Module). Name of engine which supports token and engine-specific key ID
> are specifyed using environment variable PGSSLKEY.
>
> This allows use of hardware tokens such as smartcards to identify
> clients, connecting to database.
>
> This functionality can be used in installations with high security
> requirements or in situations where several people can use same terminal
> (such as cash register in shops or malls).
>
> If PostgreSQL is compiled with version of OpenSSL which do not support
> engines or doesn't have OPENSSL_config function, related functionality
> is excluded by preprocessor conditionals, based on value of
> SSLEAY_VERSION_NUMBER preprocessor symbol which is defined by all
> versions of OpenSSL.
>

[ Attachment, skipping... ]

>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: don't forget to increase your free space map settings

--
  Bruce Momjian  <bruce@momjian.us>          http://momjian.us
  EnterpriseDB                               http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: SSL enhancement patch ver.2

From
Bruce Momjian
Date:
Victor B. Wagner wrote:
> This patch adds following functionality to PostgreSQL
>
> 1. If PostgreSQL is compiled with OpenSSL version 0.9.7 and above,
> both backend and libpq read site-wide OpenSSL configuration file as
> described in OPENSSL_config functon manual page.
>
> This allows to use hardware crypto acceleration modules (engines) and,
> in future version 0.9.9 would allow to use additional cryptoalgorithms
> (i.e. national standards) which are not included in core OpenSSL.
>
> All other configuration parameters which are supported by OpenSSL
> library also are taken into account.
>
>
> 2. New configuration option "ssl_ciphers" is added to postgresql.conf.
> This option allows to change list of ciphers, acceptable by backend
> during SSL connection. Changing list of ciphers can be desirable to
> tighten or relax security of particular installation, and allows quick
> fix on configuration file level in case if vulnerability is discovered
> in one of cryptoalgorithms or their OpenSSL implementation - cipher
> suites which use such algorithm can be easily disabled.

Why are you adding "ssl_ciphers" to postgresql.conf?  Can't you control
that from the site-wide OpenSSL configuration file added above?

--
  Bruce Momjian  <bruce@momjian.us>          http://momjian.us
  EnterpriseDB                               http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: SSL enhancement patch ver.2

From
Bruce Momjian
Date:
Never mind, I found the answer:

    http://archives.postgresql.org/pgsql-hackers/2006-08/msg01931.php

Working on the patch now.

---------------------------------------------------------------------------

Bruce Momjian wrote:
> Victor B. Wagner wrote:
> > This patch adds following functionality to PostgreSQL
> >
> > 1. If PostgreSQL is compiled with OpenSSL version 0.9.7 and above,
> > both backend and libpq read site-wide OpenSSL configuration file as
> > described in OPENSSL_config functon manual page.
> >
> > This allows to use hardware crypto acceleration modules (engines) and,
> > in future version 0.9.9 would allow to use additional cryptoalgorithms
> > (i.e. national standards) which are not included in core OpenSSL.
> >
> > All other configuration parameters which are supported by OpenSSL
> > library also are taken into account.
> >
> >
> > 2. New configuration option "ssl_ciphers" is added to postgresql.conf.
> > This option allows to change list of ciphers, acceptable by backend
> > during SSL connection. Changing list of ciphers can be desirable to
> > tighten or relax security of particular installation, and allows quick
> > fix on configuration file level in case if vulnerability is discovered
> > in one of cryptoalgorithms or their OpenSSL implementation - cipher
> > suites which use such algorithm can be easily disabled.
>
> Why are you adding "ssl_ciphers" to postgresql.conf?  Can't you control
> that from the site-wide OpenSSL configuration file added above?
>
> --
>   Bruce Momjian  <bruce@momjian.us>          http://momjian.us
>   EnterpriseDB                               http://www.enterprisedb.com
>
>   + If your life is a hard drive, Christ can be your backup. +
>
> ---------------------------(end of broadcast)---------------------------
> TIP 2: Don't 'kill -9' the postmaster

--
  Bruce Momjian  <bruce@momjian.us>          http://momjian.us
  EnterpriseDB                               http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

Re: SSL enhancement patch ver.2

From
Bruce Momjian
Date:
Patch applied --- SSL improvements:

        o read global SSL configuration file
        o add GUC "ssl_ciphers" to control allowed ciphers
        o add libpq environment variable PGSSLKEY to control SSL
      hardware keys

I adjusted the documentation wording and some of the single-letter
variable names you used --- the applied verison is attached.  Thanks.

---------------------------------------------------------------------------

Victor B. Wagner wrote:
> This patch adds following functionality to PostgreSQL
>
> 1. If PostgreSQL is compiled with OpenSSL version 0.9.7 and above,
> both backend and libpq read site-wide OpenSSL configuration file as
> described in OPENSSL_config functon manual page.
>
> This allows to use hardware crypto acceleration modules (engines) and,
> in future version 0.9.9 would allow to use additional cryptoalgorithms
> (i.e. national standards) which are not included in core OpenSSL.
>
> All other configuration parameters which are supported by OpenSSL
> library also are taken into account.
>
>
> 2. New configuration option "ssl_ciphers" is added to postgresql.conf.
> This option allows to change list of ciphers, acceptable by backend
> during SSL connection. Changing list of ciphers can be desirable to
> tighten or relax security of particular installation, and allows quick
> fix on configuration file level in case if vulnerability is discovered
> in one of cryptoalgorithms or their OpenSSL implementation - cipher
> suites which use such algorithm can be easily disabled.
>
>
> 3. If libpq compiled with OpenSSL 0.9.7 and above, compiled with engine
> support, it is possible to store secret key of client certificate on the
> hardware token, supported by one of OpenSSL engines (Hardware Security
> Module). Name of engine which supports token and engine-specific key ID
> are specifyed using environment variable PGSSLKEY.
>
> This allows use of hardware tokens such as smartcards to identify
> clients, connecting to database.
>
> This functionality can be used in installations with high security
> requirements or in situations where several people can use same terminal
> (such as cash register in shops or malls).
>
> If PostgreSQL is compiled with version of OpenSSL which do not support
> engines or doesn't have OPENSSL_config function, related functionality
> is excluded by preprocessor conditionals, based on value of
> SSLEAY_VERSION_NUMBER preprocessor symbol which is defined by all
> versions of OpenSSL.
>

[ Attachment, skipping... ]

>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: don't forget to increase your free space map settings

--
  Bruce Momjian  <bruce@momjian.us>          http://momjian.us
  EnterpriseDB                               http://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +
Index: doc/src/sgml/config.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/config.sgml,v
retrieving revision 1.110
diff -c -c -r1.110 config.sgml
*** doc/src/sgml/config.sgml    8 Feb 2007 15:46:03 -0000    1.110
--- doc/src/sgml/config.sgml    16 Feb 2007 01:26:20 -0000
***************
*** 569,574 ****
--- 569,588 ----
        </listitem>
       </varlistentry>

+      <varlistentry id="guc-ssl-ciphers" xreflabel="ssl-ciphers">
+       <term><varname>ssl_ciphers> (<type>string</type>)</term>
+       <indexterm>
+        <primary><varname>ssl_ciphers</> configuration parameter</primary>
+       </indexterm>
+       <listitem>
+        <para>
+         Specifies a list of <acronym>SSL</> ciphers which can be used to
+         establish secure connections. See the <application>openssl</>
+         manual page for a list of supported ciphers.
+        </para>
+       </listitem>
+      </varlistentry>
+
       <varlistentry id="guc-password-encryption" xreflabel="password_encryption">
        <term><varname>password_encryption</varname> (<type>boolean</type>)</term>
        <indexterm>
Index: doc/src/sgml/libpq.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v
retrieving revision 1.228
diff -c -c -r1.228 libpq.sgml
*** doc/src/sgml/libpq.sgml    6 Feb 2007 03:03:11 -0000    1.228
--- doc/src/sgml/libpq.sgml    16 Feb 2007 01:26:22 -0000
***************
*** 4175,4180 ****
--- 4175,4192 ----
  <listitem>
  <para>
  <indexterm>
+ <primary><envar>PGSSLKEY</envar></primary>
+ </indexterm>
+ <envar>PGSSLKEY</envar>
+ specifies the hardware token which stores the secret key for the client
+ certificate, instead of a file. The value of this variable should consist
+ of a colon-separated engine name (engines are <productname>OpenSSL</>
+ loadable modules) and an engine-specific key identifier.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <indexterm>
   <primary><envar>PGKRBSRVNAME</envar></primary>
  </indexterm>
  <envar>PGKRBSRVNAME</envar> sets the Kerberos service name to use when
***************
*** 4438,4457 ****
     for increased security. See <xref linkend="ssl-tcp"> for details
     about the server-side <acronym>SSL</> functionality.
    </para>
!
    <para>
     If the server demands a client certificate,
     <application>libpq</application>
     will send the certificate stored in file
     <filename>~/.postgresql/postgresql.crt</> within the user's home directory.
     A matching private key file <filename>~/.postgresql/postgresql.key</>
!    must also be present, and must not be world-readable.
     (On Microsoft Windows these files are named
     <filename>%APPDATA%\postgresql\postgresql.crt</filename> and
     <filename>%APPDATA%\postgresql\postgresql.key</filename>.)
    </para>

    <para>
     If the file <filename>~/.postgresql/root.crt</> is present in the user's
     home directory,
     <application>libpq</application> will use the certificate list stored
--- 4450,4494 ----
     for increased security. See <xref linkend="ssl-tcp"> for details
     about the server-side <acronym>SSL</> functionality.
    </para>
!   <para>
!   <application>libpq</application> 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 <application>openssl</>:
!   <programlisting>
!   openssl version -d
!   </programlisting>
!   The default can be overriden by setting environment variable
!   <envar>OPENSSL_CONF</envar> to the name of the desired configuration
!   file.
!   </para>
    <para>
     If the server demands a client certificate,
     <application>libpq</application>
     will send the certificate stored in file
     <filename>~/.postgresql/postgresql.crt</> within the user's home directory.
     A matching private key file <filename>~/.postgresql/postgresql.key</>
!    must also be present, and must not be world-readable, unless the secret
!    key is stored in a hardware token, as specified by
!    <envar>PGSSLKEY</envar>.
     (On Microsoft Windows these files are named
     <filename>%APPDATA%\postgresql\postgresql.crt</filename> and
     <filename>%APPDATA%\postgresql\postgresql.key</filename>.)
    </para>

    <para>
+    If the environment variable <envar>PGSSLKEY</envar> is set, its value
+    should consist of a colon-separated engine name and key identifier. In
+    this case, <application>libpq</application> will load the specified
+    engine, i.e. the <productname>OpenSSL</> module which supports special
+    hardware and reference the key with the specified identifier.
+    Identifiers are engine-specific. Typically, cryptography hardware tokens
+    do not reveal secret keys to the application. Instead, applications
+    delegate all cryptography operations which require the secret key to
+    the hardware token.
+   </para>
+
+   <para>
     If the file <filename>~/.postgresql/root.crt</> is present in the user's
     home directory,
     <application>libpq</application> will use the certificate list stored
Index: doc/src/sgml/runtime.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v
retrieving revision 1.376
diff -c -c -r1.376 runtime.sgml
*** doc/src/sgml/runtime.sgml    1 Feb 2007 00:28:18 -0000    1.376
--- doc/src/sgml/runtime.sgml    16 Feb 2007 01:26:23 -0000
***************
*** 1516,1521 ****
--- 1516,1540 ----
    </para>

    <para>
+    <productname>OpenSSL</productname> supports a wide range of ciphers
+    and authentication algorithms, whose strength varies significantly.
+    You can restrict the list of ciphers which can be used to connect to
+    your server using the <xref linkend="guc-ssl-ciphers"> parameter.
+   </para>
+
+   <para>
+    <productname>PostgreSQL</productname> reads a 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 <application>openssl</>:
+    <programlisting>
+    openssl version -d
+    </programlisting>
+    This default can be overriden by setting environment variable
+    <envar>OPENSSL_CONF</envar> to the name of desired configuration file.
+   </para>
+
+   <para>
     For details on how to create your server private key and certificate,
     refer to the <productname>OpenSSL</> documentation. A
     self-signed certificate can be used for testing, but a
***************
*** 1528,1535 ****
  <programlisting>
  openssl req -new -text -out server.req
  </programlisting>
!    Fill out the information that <command>openssl</> asks for. Make sure
!    that you enter the local host name as <quote>Common Name</>; the challenge
     password can be left blank. The program will generate a key that is
     passphrase protected; it will not accept a passphrase that is less
     than four characters long. To remove the passphrase (as you must if
--- 1547,1554 ----
  <programlisting>
  openssl req -new -text -out server.req
  </programlisting>
!    Fill out the information that <application>openssl</> asks for. Make sure
!    you enter the local host name as <quote>Common Name</>; the challenge
     password can be left blank. The program will generate a key that is
     passphrase protected; it will not accept a passphrase that is less
     than four characters long. To remove the passphrase (as you must if
Index: src/backend/libpq/be-secure.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/libpq/be-secure.c,v
retrieving revision 1.77
diff -c -c -r1.77 be-secure.c
*** src/backend/libpq/be-secure.c    7 Feb 2007 00:52:35 -0000    1.77
--- src/backend/libpq/be-secure.c    16 Feb 2007 01:26:24 -0000
***************
*** 92,97 ****
--- 92,101 ----
  #ifdef USE_SSL
  #include <openssl/ssl.h>
  #include <openssl/dh.h>
+ #if SSLEAY_VERSION_NUMBER >= 0x0907000L
+ #include <openssl/conf.h>
+ #endif
+
  #endif

  #include "libpq/libpq.h"
***************
*** 125,130 ****
--- 129,138 ----
  #define RENEGOTIATION_LIMIT (512 * 1024 * 1024)

  static SSL_CTX *SSL_context = NULL;
+
+ /* GUC variable controlling SSL cipher list*/
+ extern char *SSLCipherSuites;
+
  #endif

  /* ------------------------------------------------------------ */
***************
*** 719,724 ****
--- 727,735 ----

      if (!SSL_context)
      {
+ #if SSLEAY_VERSION_NUMBER >= 0x0907000L
+         OPENSSL_config(NULL);
+ #endif
          SSL_library_init();
          SSL_load_error_strings();
          SSL_context = SSL_CTX_new(SSLv23_method());
***************
*** 780,786 ****
      SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2);

      /* setup the allowed cipher list */
!     if (SSL_CTX_set_cipher_list(SSL_context, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH") != 1)
          elog(FATAL, "could not set the cipher list (no valid ciphers available)");

      /*
--- 791,797 ----
      SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2);

      /* setup the allowed cipher list */
!     if (SSL_CTX_set_cipher_list(SSL_context, SSLCipherSuites) != 1)
          elog(FATAL, "could not set the cipher list (no valid ciphers available)");

      /*
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v
retrieving revision 1.521
diff -c -c -r1.521 postmaster.c
*** src/backend/postmaster/postmaster.c    13 Feb 2007 19:18:54 -0000    1.521
--- src/backend/postmaster/postmaster.c    16 Feb 2007 01:26:25 -0000
***************
*** 186,191 ****
--- 186,192 ----

  /* still more option variables */
  bool        EnableSSL = false;
+ char       *SSLCipherSuites;
  bool        SilentMode = false; /* silent mode (-S) */

  int            PreAuthDelay = 0;
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.374
diff -c -c -r1.374 guc.c
*** src/backend/utils/misc/guc.c    14 Feb 2007 03:08:44 -0000    1.374
--- src/backend/utils/misc/guc.c    16 Feb 2007 01:26:28 -0000
***************
*** 2314,2319 ****
--- 2314,2329 ----
          NULL, assign_temp_tablespaces, NULL
      },

+     {
+         {"ssl_ciphers", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+             gettext_noop("Sets the list of allowed SSL ciphers."),
+             NULL,
+             GUC_SUPERUSER_ONLY
+         },
+         &SSLCipherSuites,
+         "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH", NULL, NULL
+     },
+
      /* End-of-list marker */
      {
          {NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL
Index: src/backend/utils/misc/postgresql.conf.sample
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/misc/postgresql.conf.sample,v
retrieving revision 1.207
diff -c -c -r1.207 postgresql.conf.sample
*** src/backend/utils/misc/postgresql.conf.sample    25 Jan 2007 15:05:15 -0000    1.207
--- src/backend/utils/misc/postgresql.conf.sample    16 Feb 2007 01:26:28 -0000
***************
*** 74,79 ****
--- 74,80 ----

  #authentication_timeout = 1min        # 1s-600s
  #ssl = off                # (change requires restart)
+ #ssl_ciphers = 'ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH' # List of ciphers to use
  #password_encryption = on
  #db_user_namespace = off

Index: src/include/postmaster/postmaster.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/postmaster/postmaster.h,v
retrieving revision 1.15
diff -c -c -r1.15 postmaster.h
*** src/include/postmaster/postmaster.h    5 Jan 2007 22:19:57 -0000    1.15
--- src/include/postmaster/postmaster.h    16 Feb 2007 01:26:28 -0000
***************
*** 15,20 ****
--- 15,21 ----

  /* GUC options */
  extern bool EnableSSL;
+ extern char *SSLCipherSuites;
  extern bool SilentMode;
  extern int    ReservedBackends;
  extern int    PostPortNumber;
Index: src/interfaces/libpq/fe-secure.c
===================================================================
RCS file: /cvsroot/pgsql/src/interfaces/libpq/fe-secure.c,v
retrieving revision 1.92
diff -c -c -r1.92 fe-secure.c
*** src/interfaces/libpq/fe-secure.c    8 Feb 2007 11:10:27 -0000    1.92
--- src/interfaces/libpq/fe-secure.c    16 Feb 2007 01:26:29 -0000
***************
*** 111,116 ****
--- 111,122 ----

  #ifdef USE_SSL
  #include <openssl/ssl.h>
+ #if (SSLEAY_VERSION_NUMBER >= 0x00907000L)
+ #include <openssl/conf.h>
+ #endif
+ #if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
+ #include <openssl/engine.h>
+ #endif
  #endif   /* USE_SSL */


***************
*** 606,659 ****
      }
      fclose(fp);

!     /* read the user key */
!     snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
!     if (stat(fnbuf, &buf) == -1)
!     {
!         printfPQExpBuffer(&conn->errorMessage,
!                           libpq_gettext("certificate present, but not private key file \"%s\"\n"),
!                           fnbuf);
!         return 0;
!     }
! #ifndef WIN32
!     if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) ||
!         buf.st_uid != geteuid())
!     {
!         printfPQExpBuffer(&conn->errorMessage,
!             libpq_gettext("private key file \"%s\" has wrong permissions\n"),
!                           fnbuf);
!         return 0;
!     }
! #endif
!     if ((fp = fopen(fnbuf, "r")) == NULL)
!     {
!         printfPQExpBuffer(&conn->errorMessage,
!                libpq_gettext("could not open private key file \"%s\": %s\n"),
!                           fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
!         return 0;
!     }
! #ifndef WIN32
!     if (fstat(fileno(fp), &buf2) == -1 ||
!         buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
      {
!         printfPQExpBuffer(&conn->errorMessage,
!                           libpq_gettext("private key file \"%s\" changed during execution\n"), fnbuf);
!         return 0;
      }
  #endif
-     if (PEM_read_PrivateKey(fp, pkey, NULL, NULL) == NULL)
      {
!         char       *err = SSLerrmessage();

!         printfPQExpBuffer(&conn->errorMessage,
!                libpq_gettext("could not read private key file \"%s\": %s\n"),
!                           fnbuf, err);
!         SSLerrfree(err);
          fclose(fp);
-         return 0;
      }
-     fclose(fp);
-
      /* verify that the cert and key go together */
      if (!X509_check_private_key(*x509, *pkey))
      {
--- 612,710 ----
      }
      fclose(fp);

! #if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
!     if (getenv("PGSSLKEY"))
      {
!         /* read the user key from engine */
!         char    *engine_env = getenv("PGSSLKEY");
!         char    *engine_colon = strchr(engine_env, ':');
!         char    *engine_str;
!         ENGINE    *engine_ptr = NULL;
!
!         if (!engine_colon)
!         {
!             printfPQExpBuffer(&conn->errorMessage,
!                 libpq_gettext("invalid value of PGSSLKEY environment variable\n"));
!             return 0;
!         }
!
!         engine_str = malloc(engine_colon - engine_env + 1);
!         strlcpy(engine_str, engine_env, engine_colon - engine_env + 1);
!         if ((engine_ptr = ENGINE_by_id(engine_str)) == NULL)
!         {
!             char      *err = SSLerrmessage();
!
!             printfPQExpBuffer(&conn->errorMessage,
!                 libpq_gettext("could not load SSL engine \"%s\":%s\n"), engine_str, err);
!             free(engine_str);
!             SSLerrfree(err);
!             return 0;
!         }
!         if ((*pkey = ENGINE_load_private_key(engine_ptr,
!                         engine_colon + 1, NULL, NULL)) == NULL)
!         {
!             char      *err = SSLerrmessage();
!
!             printfPQExpBuffer(&conn->errorMessage,
!                 libpq_gettext("could not read private SSL key %s from engine \"%s\": %s\n"),
!                             engine_colon + 1, engine_str, err);
!             SSLerrfree(err);
!             free(engine_str);
!             return 0;
!         }
!         free(engine_str);
      }
+     else
  #endif
      {
!         /* read the user key from file*/
!         snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
!         if (stat(fnbuf, &buf) == -1)
!         {
!             printfPQExpBuffer(&conn->errorMessage,
!                             libpq_gettext("certificate present, but not private key file \"%s\"\n"),
!                             fnbuf);
!             return 0;
!         }
!     #ifndef WIN32
!         if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) ||
!             buf.st_uid != geteuid())
!         {
!             printfPQExpBuffer(&conn->errorMessage,
!                 libpq_gettext("private key file \"%s\" has wrong permissions\n"),
!                             fnbuf);
!             return 0;
!         }
!     #endif
!         if ((fp = fopen(fnbuf, "r")) == NULL)
!         {
!             printfPQExpBuffer(&conn->errorMessage,
!                 libpq_gettext("could not open private key file \"%s\": %s\n"),
!                             fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
!             return 0;
!         }
!     #ifndef WIN32
!         if (fstat(fileno(fp), &buf2) == -1 ||
!             buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
!         {
!             printfPQExpBuffer(&conn->errorMessage,
!                             libpq_gettext("private key file \"%s\" changed during execution\n"), fnbuf);
!             return 0;
!         }
!     #endif
!         if (PEM_read_PrivateKey(fp, pkey, NULL, NULL) == NULL)
!         {
!             char       *err = SSLerrmessage();

!             printfPQExpBuffer(&conn->errorMessage,
!                 libpq_gettext("could not read private key file \"%s\": %s\n"),
!                             fnbuf, err);
!             SSLerrfree(err);
!             fclose(fp);
!             return 0;
!         }
          fclose(fp);
      }
      /* verify that the cert and key go together */
      if (!X509_check_private_key(*x509, *pkey))
      {
***************
*** 737,742 ****
--- 788,796 ----
      {
          if (pq_initssllib)
          {
+ #if (SSLEAY_VERSION_NUMBER >= 0x00907000L)
+             OPENSSL_config(NULL);
+ #endif
              SSL_library_init();
              SSL_load_error_strings();
          }