]> granicus.if.org Git - postgresql/blob - src/interfaces/libpq/fe-secure.c
e9620d03a4c839e579a66c9452dfce136de8c953
[postgresql] / src / interfaces / libpq / fe-secure.c
1 /*-------------------------------------------------------------------------
2  *
3  * fe-secure.c
4  *        functions related to setting up a secure connection to the backend.
5  *        Secure connections are expected to provide confidentiality,
6  *        message integrity and endpoint authentication.
7  *
8  *
9  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
10  * Portions Copyright (c) 1994, Regents of the University of California
11  *
12  *
13  * IDENTIFICATION
14  *        $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-secure.c,v 1.31 2003/09/27 15:32:48 momjian Exp $
15  *
16  * NOTES
17  *        The client *requires* a valid server certificate.  Since
18  *        SSH tunnels provide anonymous confidentiality, the presumption
19  *        is that sites that want endpoint authentication will use the
20  *        direct SSL support, while sites that are comfortable with
21  *        anonymous connections will use SSH tunnels.
22  *
23  *        This code verifies the server certificate, to detect simple
24  *        "man-in-the-middle" and "impersonation" attacks.      The
25  *        server certificate, or better yet the CA certificate used
26  *        to sign the server certificate, should be present in the
27  *        "$HOME/.postgresql/root.crt" file.  If this file isn't
28  *        readable, or the server certificate can't be validated,
29  *        pqsecure_open_client() will return an error code.
30  *
31  *        Additionally, the server certificate's "common name" must
32  *        resolve to the other end of the socket.  This makes it
33  *        substantially harder to pull off a "man-in-the-middle" or
34  *        "impersonation" attack even if the server's private key
35  *        has been stolen.      This check limits acceptable network
36  *        layers to Unix sockets (weird, but legal), TCPv4 and TCPv6.
37  *
38  *        Unfortunately neither the current front- or back-end handle
39  *        failure gracefully, resulting in the backend hiccupping.
40  *        This points out problems in each (the frontend shouldn't even
41  *        try to do SSL if pqsecure_initialize() fails, and the backend
42  *        shouldn't crash/recover if an SSH negotiation fails.  The
43  *        backend definitely needs to be fixed, to prevent a "denial
44  *        of service" attack, but I don't know enough about how the
45  *        backend works (especially that pre-SSL negotiation) to identify
46  *        a fix.
47  *
48  *        ...
49  *
50  *        Unlike the server's static private key, the client's
51  *        static private key ($HOME/.postgresql/postgresql.key)
52  *        should normally be stored encrypted.  However we still
53  *        support EPH since it's useful for other reasons.
54  *
55  *        ...
56  *
57  *        Client certificates are supported, if the server requests
58  *        or requires them.  Client certificates can be used for
59  *        authentication, to prevent sessions from being hijacked,
60  *        or to allow "road warriors" to access the database while
61  *        keeping it closed to everyone else.
62  *
63  *        The user's certificate and private key are located in
64  *              $HOME/.postgresql/postgresql.crt
65  *        and
66  *              $HOME/.postgresql/postgresql.key
67  *        respectively.
68  *
69  *        ...
70  *
71  *        We don't provide informational callbacks here (like
72  *        info_cb() in be-secure.c), since there's mechanism to
73  *        display that information to the client.
74  *
75  * OS DEPENDENCIES
76  *        The code currently assumes a POSIX password entry.  How should
77  *        Windows and Mac users be handled?
78  *
79  *-------------------------------------------------------------------------
80  */
81
82 #include "postgres_fe.h"
83
84 #include <sys/types.h>
85 #include <signal.h>
86 #include <fcntl.h>
87 #include <errno.h>
88 #include <ctype.h>
89 #include <string.h>
90
91 #include "libpq-fe.h"
92 #include "libpq-int.h"
93 #include "fe-auth.h"
94 #include "pqsignal.h"
95
96 #ifdef WIN32
97 #include "win32.h"
98 #else
99 #include <sys/socket.h>
100 #include <unistd.h>
101 #include <netdb.h>
102 #include <netinet/in.h>
103 #ifdef HAVE_NETINET_TCP_H
104 #include <netinet/tcp.h>
105 #endif
106 #include <arpa/inet.h>
107 #endif
108
109 #ifndef HAVE_STRDUP
110 #include "strdup.h"
111 #endif
112
113 #ifndef WIN32
114 #include <pwd.h>
115 #endif
116 #include <sys/stat.h>
117
118 #ifdef USE_SSL
119 #include <openssl/ssl.h>
120 #include <openssl/dh.h>
121 #endif   /* USE_SSL */
122
123
124 #ifdef USE_SSL
125 static int      verify_cb(int ok, X509_STORE_CTX *ctx);
126
127 #ifdef NOT_USED
128 static int      verify_peer(PGconn *);
129 #endif
130 static DH  *load_dh_file(int keylength);
131 static DH  *load_dh_buffer(const char *, size_t);
132 static DH  *tmp_dh_cb(SSL *s, int is_export, int keylength);
133 static int      client_cert_cb(SSL *, X509 **, EVP_PKEY **);
134 static int      initialize_SSL(PGconn *);
135 static void destroy_SSL(void);
136 static PostgresPollingStatusType open_client_SSL(PGconn *);
137 static void close_SSL(PGconn *);
138 static const char *SSLerrmessage(void);
139 #endif
140
141 #ifdef USE_SSL
142 static SSL_CTX *SSL_context = NULL;
143 #endif
144
145 /* ------------------------------------------------------------ */
146 /*                                               Hardcoded values                                               */
147 /* ------------------------------------------------------------ */
148
149 /*
150  *      Hardcoded DH parameters, used in empheral DH keying.
151  *      As discussed above, EDH protects the confidentiality of
152  *      sessions even if the static private key is compromised,
153  *      so we are *highly* motivated to ensure that we can use
154  *      EDH even if the user... or an attacker... deletes the
155  *      $HOME/.postgresql/dh*.pem files.
156  *
157  *      It's not critical that users have EPH keys, but it doesn't
158  *      hurt and if it's missing someone will demand it, so....
159  */
160 #ifdef USE_SSL
161
162 static const char file_dh512[] =
163 "-----BEGIN DH PARAMETERS-----\n\
164 MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak\n\
165 XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC\n\
166 -----END DH PARAMETERS-----\n";
167
168 static const char file_dh1024[] =
169 "-----BEGIN DH PARAMETERS-----\n\
170 MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY\n\
171 jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6\n\
172 ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC\n\
173 -----END DH PARAMETERS-----\n";
174
175 static const char file_dh2048[] =
176 "-----BEGIN DH PARAMETERS-----\n\
177 MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\
178 89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50\n\
179 T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb\n\
180 zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX\n\
181 Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\
182 CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\
183 -----END DH PARAMETERS-----\n";
184
185 static const char file_dh4096[] =
186 "-----BEGIN DH PARAMETERS-----\n\
187 MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ\n\
188 l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt\n\
189 Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS\n\
190 Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98\n\
191 VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc\n\
192 alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM\n\
193 sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9\n\
194 ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte\n\
195 OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH\n\
196 AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL\n\
197 KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
198 -----END DH PARAMETERS-----\n";
199 #endif
200
201 /* ------------------------------------------------------------ */
202 /*                       Procedures common to all secure sessions                       */
203 /* ------------------------------------------------------------ */
204
205 /*
206  *      Initialize global context
207  */
208 int
209 pqsecure_initialize(PGconn *conn)
210 {
211         int                     r = 0;
212
213 #ifdef USE_SSL
214         r = initialize_SSL(conn);
215 #endif
216
217         return r;
218 }
219
220 /*
221  *      Destroy global context
222  */
223 void
224 pqsecure_destroy(void)
225 {
226 #ifdef USE_SSL
227         destroy_SSL();
228 #endif
229 }
230
231 /*
232  *      Attempt to negotiate secure session.
233  */
234 PostgresPollingStatusType
235 pqsecure_open_client(PGconn *conn)
236 {
237 #ifdef USE_SSL
238         /* First time through? */
239         if (conn->ssl == NULL)
240         {
241                 if (!(conn->ssl = SSL_new(SSL_context)) ||
242                         !SSL_set_app_data(conn->ssl, conn) ||
243                         !SSL_set_fd(conn->ssl, conn->sock))
244                 {
245                         printfPQExpBuffer(&conn->errorMessage,
246                            libpq_gettext("could not establish SSL connection: %s\n"),
247                                                           SSLerrmessage());
248                         close_SSL(conn);
249                         return PGRES_POLLING_FAILED;
250                 }
251         }
252         /* Begin or continue the actual handshake */
253         return open_client_SSL(conn);
254 #else
255         /* shouldn't get here */
256         return PGRES_POLLING_FAILED;
257 #endif
258 }
259
260 /*
261  *      Close secure session.
262  */
263 void
264 pqsecure_close(PGconn *conn)
265 {
266 #ifdef USE_SSL
267         if (conn->ssl)
268                 close_SSL(conn);
269 #endif
270 }
271
272 /*
273  *      Read data from a secure connection.
274  */
275 ssize_t
276 pqsecure_read(PGconn *conn, void *ptr, size_t len)
277 {
278         ssize_t         n;
279
280 #ifdef USE_SSL
281         if (conn->ssl)
282         {
283 rloop:
284                 n = SSL_read(conn->ssl, ptr, len);
285                 switch (SSL_get_error(conn->ssl, n))
286                 {
287                         case SSL_ERROR_NONE:
288                                 break;
289                         case SSL_ERROR_WANT_READ:
290                                 n = 0;
291                                 break;
292                         case SSL_ERROR_WANT_WRITE:
293
294                                 /*
295                                  * Returning 0 here would cause caller to wait for
296                                  * read-ready, which is not correct since what SSL wants
297                                  * is wait for write-ready.  The former could get us stuck
298                                  * in an infinite wait, so don't risk it; busy-loop
299                                  * instead.
300                                  */
301                                 goto rloop;
302                         case SSL_ERROR_SYSCALL:
303                                 {
304                                         char            sebuf[256];
305
306                                         if (n == -1)
307                                                 printfPQExpBuffer(&conn->errorMessage,
308                                                                 libpq_gettext("SSL SYSCALL error: %s\n"),
309                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
310                                         else
311                                         {
312                                                 printfPQExpBuffer(&conn->errorMessage,
313                                                                                   libpq_gettext("SSL SYSCALL error: EOF detected\n"));
314
315                                                 SOCK_ERRNO_SET(ECONNRESET);
316                                                 n = -1;
317                                         }
318                                         break;
319                                 }
320                         case SSL_ERROR_SSL:
321                                 printfPQExpBuffer(&conn->errorMessage,
322                                           libpq_gettext("SSL error: %s\n"), SSLerrmessage());
323                                 /* fall through */
324                         case SSL_ERROR_ZERO_RETURN:
325                                 SOCK_ERRNO_SET(ECONNRESET);
326                                 n = -1;
327                                 break;
328                         default:
329                                 printfPQExpBuffer(&conn->errorMessage,
330                                                           libpq_gettext("Unknown SSL error code\n"));
331                                 n = -1;
332                                 break;
333                 }
334         }
335         else
336 #endif
337                 n = recv(conn->sock, ptr, len, 0);
338
339         return n;
340 }
341
342 /*
343  *      Write data to a secure connection.
344  */
345 ssize_t
346 pqsecure_write(PGconn *conn, const void *ptr, size_t len)
347 {
348         ssize_t         n;
349
350 #ifndef WIN32
351         pqsigfunc       oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
352 #endif
353
354 #ifdef USE_SSL
355         if (conn->ssl)
356         {
357                 n = SSL_write(conn->ssl, ptr, len);
358                 switch (SSL_get_error(conn->ssl, n))
359                 {
360                         case SSL_ERROR_NONE:
361                                 break;
362                         case SSL_ERROR_WANT_READ:
363
364                                 /*
365                                  * Returning 0 here causes caller to wait for write-ready,
366                                  * which is not really the right thing, but it's the best
367                                  * we can do.
368                                  */
369                                 n = 0;
370                                 break;
371                         case SSL_ERROR_WANT_WRITE:
372                                 n = 0;
373                                 break;
374                         case SSL_ERROR_SYSCALL:
375                                 {
376                                         char            sebuf[256];
377
378                                         if (n == -1)
379                                                 printfPQExpBuffer(&conn->errorMessage,
380                                                                 libpq_gettext("SSL SYSCALL error: %s\n"),
381                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
382                                         else
383                                         {
384                                                 printfPQExpBuffer(&conn->errorMessage,
385                                                                                   libpq_gettext("SSL SYSCALL error: EOF detected\n"));
386                                                 SOCK_ERRNO_SET(ECONNRESET);
387                                                 n = -1;
388                                         }
389                                         break;
390                                 }
391                         case SSL_ERROR_SSL:
392                                 printfPQExpBuffer(&conn->errorMessage,
393                                           libpq_gettext("SSL error: %s\n"), SSLerrmessage());
394                                 /* fall through */
395                         case SSL_ERROR_ZERO_RETURN:
396                                 SOCK_ERRNO_SET(ECONNRESET);
397                                 n = -1;
398                                 break;
399                         default:
400                                 printfPQExpBuffer(&conn->errorMessage,
401                                                           libpq_gettext("Unknown SSL error code\n"));
402                                 n = -1;
403                                 break;
404                 }
405         }
406         else
407 #endif
408                 n = send(conn->sock, ptr, len, 0);
409
410 #ifndef WIN32
411         pqsignal(SIGPIPE, oldsighandler);
412 #endif
413
414         return n;
415 }
416
417 /* ------------------------------------------------------------ */
418 /*                                                SSL specific code                                             */
419 /* ------------------------------------------------------------ */
420 #ifdef USE_SSL
421 /*
422  *      Certificate verification callback
423  *
424  *      This callback allows us to log intermediate problems during
425  *      verification, but there doesn't seem to be a clean way to get
426  *      our PGconn * structure.  So we can't log anything!
427  *
428  *      This callback also allows us to override the default acceptance
429  *      criteria (e.g., accepting self-signed or expired certs), but
430  *      for now we accept the default checks.
431  */
432 static int
433 verify_cb(int ok, X509_STORE_CTX *ctx)
434 {
435         return ok;
436 }
437
438 #ifdef NOT_USED
439 /*
440  *      Verify that common name resolves to peer.
441  */
442 static int
443 verify_peer(PGconn *conn)
444 {
445         struct hostent *h = NULL;
446         struct sockaddr addr;
447         struct sockaddr_in *sin;
448         socklen_t       len;
449         char      **s;
450         unsigned long l;
451
452         /* get the address on the other side of the socket */
453         len = sizeof(addr);
454         if (getpeername(conn->sock, &addr, &len) == -1)
455         {
456                 char            sebuf[256];
457
458                 printfPQExpBuffer(&conn->errorMessage,
459                                                   libpq_gettext("error querying socket: %s\n"),
460                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
461                 return -1;
462         }
463
464         /* weird, but legal case */
465         if (addr.sa_family == AF_UNIX)
466                 return 0;
467
468         {
469                 struct hostent hpstr;
470                 char            buf[BUFSIZ];
471                 int                     herrno = 0;
472                 
473                 /*
474                  *      Currently, pqGethostbyname() is used only on platforms that
475                  *      don't have getaddrinfo().  If you enable this function,
476                  *      you should convert the pqGethostbyname() function call to
477                  *      use getaddrinfo().
478                  */
479                 pqGethostbyname(conn->peer_cn, &hpstr, buf, sizeof(buf),
480                                                 &h, &herrno);
481         }
482
483         /* what do we know about the peer's common name? */
484         if (h == NULL)
485         {
486                 printfPQExpBuffer(&conn->errorMessage,
487                 libpq_gettext("could not get information about host (%s): %s\n"),
488                                                   conn->peer_cn, hstrerror(h_errno));
489                 return -1;
490         }
491
492         /* does the address match? */
493         switch (addr.sa_family)
494         {
495                 case AF_INET:
496                         sin = (struct sockaddr_in *) & addr;
497                         for (s = h->h_addr_list; *s != NULL; s++)
498                         {
499                                 if (!memcmp(&sin->sin_addr.s_addr, *s, h->h_length))
500                                         return 0;
501                         }
502                         break;
503
504                 default:
505                         printfPQExpBuffer(&conn->errorMessage,
506                                                           libpq_gettext("unsupported protocol\n"));
507                         return -1;
508         }
509
510         /*
511          * the prior test should be definitive, but in practice it sometimes
512          * fails.  So we also check the aliases.
513          */
514         for (s = h->h_aliases; *s != NULL; s++)
515         {
516                 if (strcasecmp(conn->peer_cn, *s) == 0)
517                         return 0;
518         }
519
520         /* generate protocol-aware error message */
521         switch (addr.sa_family)
522         {
523                 case AF_INET:
524                         sin = (struct sockaddr_in *) & addr;
525                         l = ntohl(sin->sin_addr.s_addr);
526                         printfPQExpBuffer(&conn->errorMessage,
527                                                           libpq_gettext(
528                                                                                         "server common name \"%s\" does not resolve to %ld.%ld.%ld.%ld\n"),
529                                          conn->peer_cn, (l >> 24) % 0x100, (l >> 16) % 0x100,
530                                                           (l >> 8) % 0x100, l % 0x100);
531                         break;
532                 default:
533                         printfPQExpBuffer(&conn->errorMessage,
534                                                           libpq_gettext(
535                                                                                         "server common name \"%s\" does not resolve to peer address\n"),
536                                                           conn->peer_cn);
537         }
538
539         return -1;
540 }
541 #endif
542
543 /*
544  *      Load precomputed DH parameters.
545  *
546  *      To prevent "downgrade" attacks, we perform a number of checks
547  *      to verify that the DBA-generated DH parameters file contains
548  *      what we expect it to contain.
549  */
550 static DH  *
551 load_dh_file(int keylength)
552 {
553 #ifdef WIN32
554     return NULL;
555 #else
556         char            pwdbuf[BUFSIZ];
557         struct passwd pwdstr;
558         struct passwd *pwd = NULL;
559         FILE       *fp;
560         char            fnbuf[2048];
561         DH                 *dh = NULL;
562         int                     codes;
563
564         if (pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0)
565                 return NULL;
566
567         /* attempt to open file.  It's not an error if it doesn't exist. */
568         snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/dh%d.pem",
569                          pwd->pw_dir, keylength);
570
571         if ((fp = fopen(fnbuf, "r")) == NULL)
572                 return NULL;
573
574 /*      flock(fileno(fp), LOCK_SH); */
575         dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
576 /*      flock(fileno(fp), LOCK_UN); */
577         fclose(fp);
578
579         /* is the prime the correct size? */
580         if (dh != NULL && 8 * DH_size(dh) < keylength)
581                 dh = NULL;
582
583         /* make sure the DH parameters are usable */
584         if (dh != NULL)
585         {
586                 if (DH_check(dh, &codes))
587                         return NULL;
588                 if (codes & DH_CHECK_P_NOT_PRIME)
589                         return NULL;
590                 if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
591                         (codes & DH_CHECK_P_NOT_SAFE_PRIME))
592                         return NULL;
593         }
594
595         return dh;
596 #endif
597 }
598
599 /*
600  *      Load hardcoded DH parameters.
601  *
602  *      To prevent problems if the DH parameters files don't even
603  *      exist, we can load DH parameters hardcoded into this file.
604  */
605 static DH  *
606 load_dh_buffer(const char *buffer, size_t len)
607 {
608         BIO                *bio;
609         DH                 *dh = NULL;
610
611         bio = BIO_new_mem_buf((char *) buffer, len);
612         if (bio == NULL)
613                 return NULL;
614         dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
615         BIO_free(bio);
616
617         return dh;
618 }
619
620 /*
621  *      Generate an empheral DH key.  Because this can take a long
622  *      time to compute, we can use precomputed parameters of the
623  *      common key sizes.
624  *
625  *      Since few sites will bother to precompute these parameter
626  *      files, we also provide a fallback to the parameters provided
627  *      by the OpenSSL project.
628  *
629  *      These values can be static (once loaded or computed) since
630  *      the OpenSSL library can efficiently generate random keys from
631  *      the information provided.
632  */
633 static DH  *
634 tmp_dh_cb(SSL *s, int is_export, int keylength)
635 {
636         DH                 *r = NULL;
637         static DH  *dh = NULL;
638         static DH  *dh512 = NULL;
639         static DH  *dh1024 = NULL;
640         static DH  *dh2048 = NULL;
641         static DH  *dh4096 = NULL;
642
643         switch (keylength)
644         {
645                 case 512:
646                         if (dh512 == NULL)
647                                 dh512 = load_dh_file(keylength);
648                         if (dh512 == NULL)
649                                 dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
650                         r = dh512;
651                         break;
652
653                 case 1024:
654                         if (dh1024 == NULL)
655                                 dh1024 = load_dh_file(keylength);
656                         if (dh1024 == NULL)
657                                 dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
658                         r = dh1024;
659                         break;
660
661                 case 2048:
662                         if (dh2048 == NULL)
663                                 dh2048 = load_dh_file(keylength);
664                         if (dh2048 == NULL)
665                                 dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
666                         r = dh2048;
667                         break;
668
669                 case 4096:
670                         if (dh4096 == NULL)
671                                 dh4096 = load_dh_file(keylength);
672                         if (dh4096 == NULL)
673                                 dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
674                         r = dh4096;
675                         break;
676
677                 default:
678                         if (dh == NULL)
679                                 dh = load_dh_file(keylength);
680                         r = dh;
681         }
682
683         /* this may take a long time, but it may be necessary... */
684         if (r == NULL || 8 * DH_size(r) < keylength)
685                 r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
686
687         return r;
688 }
689
690 /*
691  *      Callback used by SSL to load client cert and key.
692  *      This callback is only called when the server wants a
693  *      client cert.
694  *
695  *      Returns 1 on success, 0 on no data, -1 on error.
696  */
697 static int
698 client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
699 {
700 #ifdef WIN32
701    return 0;
702 #else
703         char            pwdbuf[BUFSIZ];
704         struct passwd pwdstr;
705         struct passwd *pwd = NULL;
706         struct stat buf,
707                                 buf2;
708         char            fnbuf[2048];
709         FILE       *fp;
710         PGconn     *conn = (PGconn *) SSL_get_app_data(ssl);
711         int                     (*cb) () = NULL;        /* how to read user password */
712         char            sebuf[256];
713
714
715         if (pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0)
716         {
717                 printfPQExpBuffer(&conn->errorMessage,
718                                           libpq_gettext("could not get user information\n"));
719                 return -1;
720         }
721
722         /* read the user certificate */
723         snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/postgresql.crt",
724                          pwd->pw_dir);
725         if (stat(fnbuf, &buf) == -1)
726                 return 0;
727         if ((fp = fopen(fnbuf, "r")) == NULL)
728         {
729                 printfPQExpBuffer(&conn->errorMessage,
730                                   libpq_gettext("could not open certificate (%s): %s\n"),
731                                                   fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
732                 return -1;
733         }
734         if (PEM_read_X509(fp, x509, NULL, NULL) == NULL)
735         {
736                 printfPQExpBuffer(&conn->errorMessage,
737                                   libpq_gettext("could not read certificate (%s): %s\n"),
738                                                   fnbuf, SSLerrmessage());
739                 fclose(fp);
740                 return -1;
741         }
742         fclose(fp);
743
744         /* read the user key */
745         snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/postgresql.key",
746                          pwd->pw_dir);
747         if (stat(fnbuf, &buf) == -1)
748         {
749                 printfPQExpBuffer(&conn->errorMessage,
750                 libpq_gettext("certificate present, but not private key (%s)\n"),
751                                                   fnbuf);
752                 X509_free(*x509);
753                 return 0;
754         }
755         if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) ||
756                 buf.st_uid != getuid())
757         {
758                 printfPQExpBuffer(&conn->errorMessage,
759                 libpq_gettext("private key (%s) has wrong permissions\n"), fnbuf);
760                 X509_free(*x509);
761                 return -1;
762         }
763         if ((fp = fopen(fnbuf, "r")) == NULL)
764         {
765                 printfPQExpBuffer(&conn->errorMessage,
766                          libpq_gettext("could not open private key file (%s): %s\n"),
767                                                   fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
768                 X509_free(*x509);
769                 return -1;
770         }
771         if (fstat(fileno(fp), &buf2) == -1 ||
772                 buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
773         {
774                 printfPQExpBuffer(&conn->errorMessage,
775                                                   libpq_gettext("private key (%s) changed during execution\n"), fnbuf);
776                 X509_free(*x509);
777                 return -1;
778         }
779         if (PEM_read_PrivateKey(fp, pkey, cb, NULL) == NULL)
780         {
781                 printfPQExpBuffer(&conn->errorMessage,
782                                   libpq_gettext("could not read private key (%s): %s\n"),
783                                                   fnbuf, SSLerrmessage());
784                 X509_free(*x509);
785                 fclose(fp);
786                 return -1;
787         }
788         fclose(fp);
789
790         /* verify that the cert and key go together */
791         if (!X509_check_private_key(*x509, *pkey))
792         {
793                 printfPQExpBuffer(&conn->errorMessage,
794                         libpq_gettext("certificate/private key mismatch (%s): %s\n"),
795                                                   fnbuf, SSLerrmessage());
796                 X509_free(*x509);
797                 EVP_PKEY_free(*pkey);
798                 return -1;
799         }
800
801         return 1;
802 #endif
803 }
804
805 /*
806  *      Initialize global SSL context.
807  */
808 static int
809 initialize_SSL(PGconn *conn)
810 {
811 #ifndef WIN32
812         struct stat buf;
813         char            pwdbuf[BUFSIZ];
814         struct passwd pwdstr;
815         struct passwd *pwd = NULL;
816         char            fnbuf[2048];
817 #endif
818
819         if (!SSL_context)
820         {
821                 SSL_library_init();
822                 SSL_load_error_strings();
823                 SSL_context = SSL_CTX_new(TLSv1_method());
824                 if (!SSL_context)
825                 {
826                         printfPQExpBuffer(&conn->errorMessage,
827                                          libpq_gettext("could not create SSL context: %s\n"),
828                                                           SSLerrmessage());
829                         return -1;
830                 }
831         }
832
833 #ifndef WIN32
834         if (pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0)
835         {
836                 snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/root.crt",
837                                  pwd->pw_dir);
838                 if (stat(fnbuf, &buf) == -1)
839                 {
840                         return 0;
841 #ifdef NOT_USED
842                         char            sebuf[256];
843
844                         /* CLIENT CERTIFICATES NOT REQUIRED  bjm 2002-09-26 */
845                         printfPQExpBuffer(&conn->errorMessage,
846                                                           libpq_gettext("could not read root certificate list (%s): %s\n"),
847                                                  fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
848                         return -1;
849 #endif
850                 }
851                 if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, 0))
852                 {
853                         printfPQExpBuffer(&conn->errorMessage,
854                                                           libpq_gettext("could not read root certificate list (%s): %s\n"),
855                                                           fnbuf, SSLerrmessage());
856                         return -1;
857                 }
858         }
859
860         SSL_CTX_set_verify(SSL_context,
861                    SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);
862         SSL_CTX_set_verify_depth(SSL_context, 1);
863
864         /* set up empheral DH keys */
865         SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
866         SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE);
867
868         /* set up mechanism to provide client certificate, if available */
869         SSL_CTX_set_client_cert_cb(SSL_context, client_cert_cb);
870 #endif
871
872         return 0;
873 }
874
875 /*
876  *      Destroy global SSL context.
877  */
878 static void
879 destroy_SSL(void)
880 {
881         if (SSL_context)
882         {
883                 SSL_CTX_free(SSL_context);
884                 SSL_context = NULL;
885         }
886 }
887
888 /*
889  *      Attempt to negotiate SSL connection.
890  */
891 static PostgresPollingStatusType
892 open_client_SSL(PGconn *conn)
893 {
894         int                     r;
895
896         r = SSL_connect(conn->ssl);
897         if (r <= 0)
898         {
899                 switch (SSL_get_error(conn->ssl, r))
900                 {
901                         case SSL_ERROR_WANT_READ:
902                                 return PGRES_POLLING_READING;
903
904                         case SSL_ERROR_WANT_WRITE:
905                                 return PGRES_POLLING_WRITING;
906
907                         case SSL_ERROR_SYSCALL:
908                                 {
909                                         char            sebuf[256];
910
911                                         if (r == -1)
912                                                 printfPQExpBuffer(&conn->errorMessage,
913                                                                 libpq_gettext("SSL SYSCALL error: %s\n"),
914                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
915                                         else
916                                                 printfPQExpBuffer(&conn->errorMessage,
917                                                                                   libpq_gettext("SSL SYSCALL error: EOF detected\n"));
918                                         close_SSL(conn);
919                                         return PGRES_POLLING_FAILED;
920                                 }
921                         case SSL_ERROR_SSL:
922                                 printfPQExpBuffer(&conn->errorMessage,
923                                           libpq_gettext("SSL error: %s\n"), SSLerrmessage());
924                                 close_SSL(conn);
925                                 return PGRES_POLLING_FAILED;
926
927                         default:
928                                 printfPQExpBuffer(&conn->errorMessage,
929                                                           libpq_gettext("Unknown SSL error code\n"));
930                                 close_SSL(conn);
931                                 return PGRES_POLLING_FAILED;
932                 }
933         }
934
935         /* check the certificate chain of the server */
936
937 #ifdef NOT_USED
938         /* CLIENT CERTIFICATES NOT REQUIRED  bjm 2002-09-26 */
939
940         /*
941          * this eliminates simple man-in-the-middle attacks and simple
942          * impersonations
943          */
944         r = SSL_get_verify_result(conn->ssl);
945         if (r != X509_V_OK)
946         {
947                 printfPQExpBuffer(&conn->errorMessage,
948                            libpq_gettext("certificate could not be validated: %s\n"),
949                                                   X509_verify_cert_error_string(r));
950                 close_SSL(conn);
951                 return PGRES_POLLING_FAILED;
952         }
953 #endif
954
955         /* pull out server distinguished and common names */
956         conn->peer = SSL_get_peer_certificate(conn->ssl);
957         if (conn->peer == NULL)
958         {
959                 printfPQExpBuffer(&conn->errorMessage,
960                                 libpq_gettext("certificate could not be obtained: %s\n"),
961                                                   SSLerrmessage());
962                 close_SSL(conn);
963                 return PGRES_POLLING_FAILED;
964         }
965
966         X509_NAME_oneline(X509_get_subject_name(conn->peer),
967                                           conn->peer_dn, sizeof(conn->peer_dn));
968         conn->peer_dn[sizeof(conn->peer_dn) - 1] = '\0';
969
970         X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
971                                                           NID_commonName, conn->peer_cn, SM_USER);
972         conn->peer_cn[SM_USER] = '\0';
973
974         /* verify that the common name resolves to peer */
975
976 #ifdef NOT_USED
977         /* CLIENT CERTIFICATES NOT REQUIRED  bjm 2002-09-26 */
978
979         /*
980          * this is necessary to eliminate man-in-the-middle attacks and
981          * impersonations where the attacker somehow learned the server's
982          * private key
983          */
984         if (verify_peer(conn) == -1)
985         {
986                 close_SSL(conn);
987                 return PGRES_POLLING_FAILED;
988         }
989 #endif
990
991         /* SSL handshake is complete */
992         return PGRES_POLLING_OK;
993 }
994
995 /*
996  *      Close SSL connection.
997  */
998 static void
999 close_SSL(PGconn *conn)
1000 {
1001         if (conn->ssl)
1002         {
1003                 SSL_shutdown(conn->ssl);
1004                 SSL_free(conn->ssl);
1005                 conn->ssl = NULL;
1006         }
1007 }
1008
1009 /*
1010  * Obtain reason string for last SSL error
1011  *
1012  * Some caution is needed here since ERR_reason_error_string will
1013  * return NULL if it doesn't recognize the error code.  We don't
1014  * want to return NULL ever.
1015  */
1016 static const char *
1017 SSLerrmessage(void)
1018 {
1019         unsigned long errcode;
1020         const char *errreason;
1021         static char errbuf[32];
1022
1023         errcode = ERR_get_error();
1024         if (errcode == 0)
1025                 return "No SSL error reported";
1026         errreason = ERR_reason_error_string(errcode);
1027         if (errreason != NULL)
1028                 return errreason;
1029         snprintf(errbuf, sizeof(errbuf), "SSL error code %lu", errcode);
1030         return errbuf;
1031 }
1032
1033 /*
1034  *      Return pointer to SSL object.
1035  */
1036 SSL *
1037 PQgetssl(PGconn *conn)
1038 {
1039         if (!conn)
1040                 return NULL;
1041         return conn->ssl;
1042 }
1043
1044 #endif   /* USE_SSL */