]> granicus.if.org Git - postgresql/blob - src/backend/libpq/be-secure.c
06a5b9a6c05fd45d07c245c163c850f12dd9ad4a
[postgresql] / src / backend / libpq / be-secure.c
1 /*-------------------------------------------------------------------------
2  *
3  * be-secure.c
4  *        functions related to setting up a secure connection to the frontend.
5  *        Secure connections are expected to provide confidentiality,
6  *        message integrity and endpoint authentication.
7  *
8  *
9  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
10  * Portions Copyright (c) 1994, Regents of the University of California
11  *
12  *
13  * IDENTIFICATION
14  *        $PostgreSQL: pgsql/src/backend/libpq/be-secure.c,v 1.73 2006/10/04 00:29:53 momjian Exp $
15  *
16  *        Since the server static private key ($DataDir/server.key)
17  *        will normally be stored unencrypted so that the database
18  *        backend can restart automatically, it is important that
19  *        we select an algorithm that continues to provide confidentiality
20  *        even if the attacker has the server's private key.  Empheral
21  *        DH (EDH) keys provide this, and in fact provide Perfect Forward
22  *        Secrecy (PFS) except for situations where the session can
23  *        be hijacked during a periodic handshake/renegotiation.
24  *        Even that backdoor can be closed if client certificates
25  *        are used (since the imposter will be unable to successfully
26  *        complete renegotiation).
27  *
28  *        N.B., the static private key should still be protected to
29  *        the largest extent possible, to minimize the risk of
30  *        impersonations.
31  *
32  *        Another benefit of EDH is that it allows the backend and
33  *        clients to use DSA keys.      DSA keys can only provide digital
34  *        signatures, not encryption, and are often acceptable in
35  *        jurisdictions where RSA keys are unacceptable.
36  *
37  *        The downside to EDH is that it makes it impossible to
38  *        use ssldump(1) if there's a problem establishing an SSL
39  *        session.      In this case you'll need to temporarily disable
40  *        EDH by commenting out the callback.
41  *
42  *        ...
43  *
44  *        Because the risk of cryptanalysis increases as large
45  *        amounts of data are sent with the same session key, the
46  *        session keys are periodically renegotiated.
47  *
48  * PATCH LEVEL
49  *        milestone 1: fix basic coding errors
50  *        [*] existing SSL code pulled out of existing files.
51  *        [*] SSL_get_error() after SSL_read() and SSL_write(),
52  *                SSL_shutdown(), default to TLSv1.
53  *
54  *        milestone 2: provide endpoint authentication (server)
55  *        [*] client verifies server cert
56  *        [*] client verifies server hostname
57  *
58  *        milestone 3: improve confidentially, support perfect forward secrecy
59  *        [ ] use 'random' file, read from '/dev/urandom?'
60  *        [*] emphermal DH keys, default values
61  *        [*] periodic renegotiation
62  *        [*] private key permissions
63  *
64  *        milestone 4: provide endpoint authentication (client)
65  *        [*] server verifies client certificates
66  *
67  *        milestone 5: provide informational callbacks
68  *        [*] provide informational callbacks
69  *
70  *        other changes
71  *        [ ] tcp-wrappers
72  *        [ ] more informative psql
73  *
74  *-------------------------------------------------------------------------
75  */
76
77 #include "postgres.h"
78
79 #include <sys/stat.h>
80 #include <signal.h>
81 #include <fcntl.h>
82 #include <ctype.h>
83 #include <sys/socket.h>
84 #include <unistd.h>
85 #include <netdb.h>
86 #include <netinet/in.h>
87 #ifdef HAVE_NETINET_TCP_H
88 #include <netinet/tcp.h>
89 #include <arpa/inet.h>
90 #endif
91
92 #ifdef USE_SSL
93 #include <openssl/ssl.h>
94 #include <openssl/dh.h>
95 #endif
96
97 #include "libpq/libpq.h"
98 #include "tcop/tcopprot.h"
99
100
101 #ifdef USE_SSL
102
103 #define ROOT_CERT_FILE                  "root.crt"
104 #define ROOT_CRL_FILE                   "root.crl"
105 #define SERVER_CERT_FILE                "server.crt"
106 #define SERVER_PRIVATE_KEY_FILE "server.key"
107
108 static DH  *load_dh_file(int keylength);
109 static DH  *load_dh_buffer(const char *, size_t);
110 static DH  *tmp_dh_cb(SSL *s, int is_export, int keylength);
111 static int      verify_cb(int, X509_STORE_CTX *);
112 static void info_cb(const SSL *ssl, int type, int args);
113 static void initialize_SSL(void);
114 static void destroy_SSL(void);
115 static int      open_server_SSL(Port *);
116 static void close_SSL(Port *);
117 static const char *SSLerrmessage(void);
118 #endif
119
120 #ifdef USE_SSL
121 /*
122  *      How much data can be sent across a secure connection
123  *      (total in both directions) before we require renegotiation.
124  */
125 #define RENEGOTIATION_LIMIT (512 * 1024 * 1024)
126
127 static SSL_CTX *SSL_context = NULL;
128 #endif
129
130 /* ------------------------------------------------------------ */
131 /*                                               Hardcoded values                                               */
132 /* ------------------------------------------------------------ */
133
134 /*
135  *      Hardcoded DH parameters, used in empheral DH keying.
136  *      As discussed above, EDH protects the confidentiality of
137  *      sessions even if the static private key is compromised,
138  *      so we are *highly* motivated to ensure that we can use
139  *      EDH even if the DBA... or an attacker... deletes the
140  *      $DataDir/dh*.pem files.
141  *
142  *      We could refuse SSL connections unless a good DH parameter
143  *      file exists, but some clients may quietly renegotiate an
144  *      unsecured connection without fully informing the user.
145  *      Very uncool.
146  *
147  *      Alternately, the backend could attempt to load these files
148  *      on startup if SSL is enabled - and refuse to start if any
149  *      do not exist - but this would tend to piss off DBAs.
150  *
151  *      If you want to create your own hardcoded DH parameters
152  *      for fun and profit, review "Assigned Number for SKIP
153  *      Protocols" (http://www.skip-vpn.org/spec/numbers.html)
154  *      for suggestions.
155  */
156 #ifdef USE_SSL
157
158 static const char file_dh512[] =
159 "-----BEGIN DH PARAMETERS-----\n\
160 MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak\n\
161 XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC\n\
162 -----END DH PARAMETERS-----\n";
163
164 static const char file_dh1024[] =
165 "-----BEGIN DH PARAMETERS-----\n\
166 MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY\n\
167 jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6\n\
168 ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC\n\
169 -----END DH PARAMETERS-----\n";
170
171 static const char file_dh2048[] =
172 "-----BEGIN DH PARAMETERS-----\n\
173 MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\
174 89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50\n\
175 T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb\n\
176 zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX\n\
177 Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\
178 CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\
179 -----END DH PARAMETERS-----\n";
180
181 static const char file_dh4096[] =
182 "-----BEGIN DH PARAMETERS-----\n\
183 MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ\n\
184 l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt\n\
185 Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS\n\
186 Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98\n\
187 VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc\n\
188 alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM\n\
189 sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9\n\
190 ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte\n\
191 OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH\n\
192 AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL\n\
193 KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
194 -----END DH PARAMETERS-----\n";
195 #endif
196
197 /* ------------------------------------------------------------ */
198 /*                       Procedures common to all secure sessions                       */
199 /* ------------------------------------------------------------ */
200
201 /*
202  *      Initialize global context
203  */
204 int
205 secure_initialize(void)
206 {
207 #ifdef USE_SSL
208         initialize_SSL();
209 #endif
210
211         return 0;
212 }
213
214 /*
215  *      Destroy global context
216  */
217 void
218 secure_destroy(void)
219 {
220 #ifdef USE_SSL
221         destroy_SSL();
222 #endif
223 }
224
225 /*
226  *      Attempt to negotiate secure session.
227  */
228 int
229 secure_open_server(Port *port)
230 {
231         int                     r = 0;
232
233 #ifdef USE_SSL
234         r = open_server_SSL(port);
235 #endif
236
237         return r;
238 }
239
240 /*
241  *      Close secure session.
242  */
243 void
244 secure_close(Port *port)
245 {
246 #ifdef USE_SSL
247         if (port->ssl)
248                 close_SSL(port);
249 #endif
250 }
251
252 /*
253  *      Read data from a secure connection.
254  */
255 ssize_t
256 secure_read(Port *port, void *ptr, size_t len)
257 {
258         ssize_t         n;
259
260 #ifdef USE_SSL
261         if (port->ssl)
262         {
263                 int                     err;
264
265 rloop:
266                 n = SSL_read(port->ssl, ptr, len);
267                 err = SSL_get_error(port->ssl, n);
268                 switch (err)
269                 {
270                         case SSL_ERROR_NONE:
271                                 port->count += n;
272                                 break;
273                         case SSL_ERROR_WANT_READ:
274                         case SSL_ERROR_WANT_WRITE:
275 #ifdef WIN32
276                                 pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
277                                                                                         (err == SSL_ERROR_WANT_READ) ?
278                                                                    FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE);
279 #endif
280                                 goto rloop;
281                         case SSL_ERROR_SYSCALL:
282                                 if (n == -1)
283                                         ereport(COMMERROR,
284                                                         (errcode_for_socket_access(),
285                                                          errmsg("SSL SYSCALL error: %m")));
286                                 else
287                                 {
288                                         ereport(COMMERROR,
289                                                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
290                                                          errmsg("SSL SYSCALL error: EOF detected")));
291                                         errno = ECONNRESET;
292                                         n = -1;
293                                 }
294                                 break;
295                         case SSL_ERROR_SSL:
296                                 ereport(COMMERROR,
297                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
298                                                  errmsg("SSL error: %s", SSLerrmessage())));
299                                 /* fall through */
300                         case SSL_ERROR_ZERO_RETURN:
301                                 errno = ECONNRESET;
302                                 n = -1;
303                                 break;
304                         default:
305                                 ereport(COMMERROR,
306                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
307                                                  errmsg("unrecognized SSL error code: %d",
308                                                                 err)));
309                                 n = -1;
310                                 break;
311                 }
312         }
313         else
314 #endif
315         {
316                 prepare_for_client_read();
317
318                 n = recv(port->sock, ptr, len, 0);
319
320                 client_read_ended();
321         }
322
323         return n;
324 }
325
326 /*
327  *      Write data to a secure connection.
328  */
329 ssize_t
330 secure_write(Port *port, void *ptr, size_t len)
331 {
332         ssize_t         n;
333
334 #ifdef USE_SSL
335         if (port->ssl)
336         {
337                 int                     err;
338
339                 if (port->count > RENEGOTIATION_LIMIT)
340                 {
341                         SSL_set_session_id_context(port->ssl, (void *) &SSL_context,
342                                                                            sizeof(SSL_context));
343                         if (SSL_renegotiate(port->ssl) <= 0)
344                                 ereport(COMMERROR,
345                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
346                                                  errmsg("SSL renegotiation failure")));
347                         if (SSL_do_handshake(port->ssl) <= 0)
348                                 ereport(COMMERROR,
349                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
350                                                  errmsg("SSL renegotiation failure")));
351                         if (port->ssl->state != SSL_ST_OK)
352                                 ereport(COMMERROR,
353                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
354                                                  errmsg("SSL failed to send renegotiation request")));
355                         port->ssl->state |= SSL_ST_ACCEPT;
356                         SSL_do_handshake(port->ssl);
357                         if (port->ssl->state != SSL_ST_OK)
358                                 ereport(COMMERROR,
359                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
360                                                  errmsg("SSL renegotiation failure")));
361                         port->count = 0;
362                 }
363
364 wloop:
365                 n = SSL_write(port->ssl, ptr, len);
366                 err = SSL_get_error(port->ssl, n);
367                 switch (err)
368                 {
369                         case SSL_ERROR_NONE:
370                                 port->count += n;
371                                 break;
372                         case SSL_ERROR_WANT_READ:
373                         case SSL_ERROR_WANT_WRITE:
374 #ifdef WIN32
375                                 pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
376                                                                                         (err == SSL_ERROR_WANT_READ) ?
377                                                                    FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE);
378 #endif
379                                 goto wloop;
380                         case SSL_ERROR_SYSCALL:
381                                 if (n == -1)
382                                         ereport(COMMERROR,
383                                                         (errcode_for_socket_access(),
384                                                          errmsg("SSL SYSCALL error: %m")));
385                                 else
386                                 {
387                                         ereport(COMMERROR,
388                                                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
389                                                          errmsg("SSL SYSCALL error: EOF detected")));
390                                         errno = ECONNRESET;
391                                         n = -1;
392                                 }
393                                 break;
394                         case SSL_ERROR_SSL:
395                                 ereport(COMMERROR,
396                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
397                                                  errmsg("SSL error: %s", SSLerrmessage())));
398                                 /* fall through */
399                         case SSL_ERROR_ZERO_RETURN:
400                                 errno = ECONNRESET;
401                                 n = -1;
402                                 break;
403                         default:
404                                 ereport(COMMERROR,
405                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
406                                                  errmsg("unrecognized SSL error code: %d",
407                                                                 err)));
408                                 n = -1;
409                                 break;
410                 }
411         }
412         else
413 #endif
414                 n = send(port->sock, ptr, len, 0);
415
416         return n;
417 }
418
419 /* ------------------------------------------------------------ */
420 /*                                                SSL specific code                                             */
421 /* ------------------------------------------------------------ */
422 #ifdef USE_SSL
423
424 /*
425  * Private substitute BIO: this wraps the SSL library's standard socket BIO
426  * so that we can enable and disable interrupts just while calling recv().
427  * We cannot have interrupts occurring while the bulk of openssl runs,
428  * because it uses malloc() and possibly other non-reentrant libc facilities.
429  *
430  * As of openssl 0.9.7, we can use the reasonably clean method of interposing
431  * a wrapper around the standard socket BIO's sock_read() method.  This relies
432  * on the fact that sock_read() doesn't call anything non-reentrant, in fact
433  * not much of anything at all except recv().  If this ever changes we'd
434  * probably need to duplicate the code of sock_read() in order to push the
435  * interrupt enable/disable down yet another level.
436  */
437
438 static bool my_bio_initialized = false;
439 static BIO_METHOD my_bio_methods;
440 static int      (*std_sock_read) (BIO *h, char *buf, int size);
441
442 static int
443 my_sock_read(BIO *h, char *buf, int size)
444 {
445         int                     res;
446
447         prepare_for_client_read();
448
449         res = std_sock_read(h, buf, size);
450
451         client_read_ended();
452
453         return res;
454 }
455
456 static BIO_METHOD *
457 my_BIO_s_socket(void)
458 {
459         if (!my_bio_initialized)
460         {
461                 memcpy(&my_bio_methods, BIO_s_socket(), sizeof(BIO_METHOD));
462                 std_sock_read = my_bio_methods.bread;
463                 my_bio_methods.bread = my_sock_read;
464                 my_bio_initialized = true;
465         }
466         return &my_bio_methods;
467 }
468
469 /* This should exactly match openssl's SSL_set_fd except for using my BIO */
470 static int
471 my_SSL_set_fd(SSL *s, int fd)
472 {
473         int                     ret = 0;
474         BIO                *bio = NULL;
475
476         bio = BIO_new(my_BIO_s_socket());
477
478         if (bio == NULL)
479         {
480                 SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
481                 goto err;
482         }
483         BIO_set_fd(bio, fd, BIO_NOCLOSE);
484         SSL_set_bio(s, bio, bio);
485         ret = 1;
486 err:
487         return ret;
488 }
489
490 /*
491  *      Load precomputed DH parameters.
492  *
493  *      To prevent "downgrade" attacks, we perform a number of checks
494  *      to verify that the DBA-generated DH parameters file contains
495  *      what we expect it to contain.
496  */
497 static DH  *
498 load_dh_file(int keylength)
499 {
500         FILE       *fp;
501         char            fnbuf[MAXPGPATH];
502         DH                 *dh = NULL;
503         int                     codes;
504
505         /* attempt to open file.  It's not an error if it doesn't exist. */
506         snprintf(fnbuf, sizeof(fnbuf), "dh%d.pem", keylength);
507         if ((fp = fopen(fnbuf, "r")) == NULL)
508                 return NULL;
509
510 /*      flock(fileno(fp), LOCK_SH); */
511         dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
512 /*      flock(fileno(fp), LOCK_UN); */
513         fclose(fp);
514
515         /* is the prime the correct size? */
516         if (dh != NULL && 8 * DH_size(dh) < keylength)
517         {
518                 elog(LOG, "DH errors (%s): %d bits expected, %d bits found",
519                          fnbuf, keylength, 8 * DH_size(dh));
520                 dh = NULL;
521         }
522
523         /* make sure the DH parameters are usable */
524         if (dh != NULL)
525         {
526                 if (DH_check(dh, &codes) == 0)
527                 {
528                         elog(LOG, "DH_check error (%s): %s", fnbuf, SSLerrmessage());
529                         return NULL;
530                 }
531                 if (codes & DH_CHECK_P_NOT_PRIME)
532                 {
533                         elog(LOG, "DH error (%s): p is not prime", fnbuf);
534                         return NULL;
535                 }
536                 if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
537                         (codes & DH_CHECK_P_NOT_SAFE_PRIME))
538                 {
539                         elog(LOG,
540                                  "DH error (%s): neither suitable generator or safe prime",
541                                  fnbuf);
542                         return NULL;
543                 }
544         }
545
546         return dh;
547 }
548
549 /*
550  *      Load hardcoded DH parameters.
551  *
552  *      To prevent problems if the DH parameters files don't even
553  *      exist, we can load DH parameters hardcoded into this file.
554  */
555 static DH  *
556 load_dh_buffer(const char *buffer, size_t len)
557 {
558         BIO                *bio;
559         DH                 *dh = NULL;
560
561         bio = BIO_new_mem_buf((char *) buffer, len);
562         if (bio == NULL)
563                 return NULL;
564         dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
565         if (dh == NULL)
566                 ereport(DEBUG2,
567                                 (errmsg_internal("DH load buffer: %s",
568                                                                  SSLerrmessage())));
569         BIO_free(bio);
570
571         return dh;
572 }
573
574 /*
575  *      Generate an empheral DH key.  Because this can take a long
576  *      time to compute, we can use precomputed parameters of the
577  *      common key sizes.
578  *
579  *      Since few sites will bother to precompute these parameter
580  *      files, we also provide a fallback to the parameters provided
581  *      by the OpenSSL project.
582  *
583  *      These values can be static (once loaded or computed) since
584  *      the OpenSSL library can efficiently generate random keys from
585  *      the information provided.
586  */
587 static DH  *
588 tmp_dh_cb(SSL *s, int is_export, int keylength)
589 {
590         DH                 *r = NULL;
591         static DH  *dh = NULL;
592         static DH  *dh512 = NULL;
593         static DH  *dh1024 = NULL;
594         static DH  *dh2048 = NULL;
595         static DH  *dh4096 = NULL;
596
597         switch (keylength)
598         {
599                 case 512:
600                         if (dh512 == NULL)
601                                 dh512 = load_dh_file(keylength);
602                         if (dh512 == NULL)
603                                 dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
604                         r = dh512;
605                         break;
606
607                 case 1024:
608                         if (dh1024 == NULL)
609                                 dh1024 = load_dh_file(keylength);
610                         if (dh1024 == NULL)
611                                 dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
612                         r = dh1024;
613                         break;
614
615                 case 2048:
616                         if (dh2048 == NULL)
617                                 dh2048 = load_dh_file(keylength);
618                         if (dh2048 == NULL)
619                                 dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
620                         r = dh2048;
621                         break;
622
623                 case 4096:
624                         if (dh4096 == NULL)
625                                 dh4096 = load_dh_file(keylength);
626                         if (dh4096 == NULL)
627                                 dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
628                         r = dh4096;
629                         break;
630
631                 default:
632                         if (dh == NULL)
633                                 dh = load_dh_file(keylength);
634                         r = dh;
635         }
636
637         /* this may take a long time, but it may be necessary... */
638         if (r == NULL || 8 * DH_size(r) < keylength)
639         {
640                 ereport(DEBUG2,
641                                 (errmsg_internal("DH: generating parameters (%d bits)....",
642                                                                  keylength)));
643                 r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
644         }
645
646         return r;
647 }
648
649 /*
650  *      Certificate verification callback
651  *
652  *      This callback allows us to log intermediate problems during
653  *      verification, but for now we'll see if the final error message
654  *      contains enough information.
655  *
656  *      This callback also allows us to override the default acceptance
657  *      criteria (e.g., accepting self-signed or expired certs), but
658  *      for now we accept the default checks.
659  */
660 static int
661 verify_cb(int ok, X509_STORE_CTX *ctx)
662 {
663         return ok;
664 }
665
666 /*
667  *      This callback is used to copy SSL information messages
668  *      into the PostgreSQL log.
669  */
670 static void
671 info_cb(const SSL *ssl, int type, int args)
672 {
673         switch (type)
674         {
675                 case SSL_CB_HANDSHAKE_START:
676                         ereport(DEBUG4,
677                                         (errmsg_internal("SSL: handshake start")));
678                         break;
679                 case SSL_CB_HANDSHAKE_DONE:
680                         ereport(DEBUG4,
681                                         (errmsg_internal("SSL: handshake done")));
682                         break;
683                 case SSL_CB_ACCEPT_LOOP:
684                         ereport(DEBUG4,
685                                         (errmsg_internal("SSL: accept loop")));
686                         break;
687                 case SSL_CB_ACCEPT_EXIT:
688                         ereport(DEBUG4,
689                                         (errmsg_internal("SSL: accept exit (%d)", args)));
690                         break;
691                 case SSL_CB_CONNECT_LOOP:
692                         ereport(DEBUG4,
693                                         (errmsg_internal("SSL: connect loop")));
694                         break;
695                 case SSL_CB_CONNECT_EXIT:
696                         ereport(DEBUG4,
697                                         (errmsg_internal("SSL: connect exit (%d)", args)));
698                         break;
699                 case SSL_CB_READ_ALERT:
700                         ereport(DEBUG4,
701                                         (errmsg_internal("SSL: read alert (0x%04x)", args)));
702                         break;
703                 case SSL_CB_WRITE_ALERT:
704                         ereport(DEBUG4,
705                                         (errmsg_internal("SSL: write alert (0x%04x)", args)));
706                         break;
707         }
708 }
709
710 /*
711  *      Initialize global SSL context.
712  */
713 static void
714 initialize_SSL(void)
715 {
716         struct stat buf;
717
718         if (!SSL_context)
719         {
720                 SSL_library_init();
721                 SSL_load_error_strings();
722                 SSL_context = SSL_CTX_new(SSLv23_method());
723                 if (!SSL_context)
724                         ereport(FATAL,
725                                         (errmsg("could not create SSL context: %s",
726                                                         SSLerrmessage())));
727
728                 /*
729                  * Load and verify certificate and private key
730                  */
731                 if (!SSL_CTX_use_certificate_file(SSL_context,
732                                                                                   SERVER_CERT_FILE,
733                                                                                   SSL_FILETYPE_PEM))
734                         ereport(FATAL,
735                                         (errcode(ERRCODE_CONFIG_FILE_ERROR),
736                                   errmsg("could not load server certificate file \"%s\": %s",
737                                                  SERVER_CERT_FILE, SSLerrmessage())));
738
739                 if (stat(SERVER_PRIVATE_KEY_FILE, &buf) == -1)
740                         ereport(FATAL,
741                                         (errcode_for_file_access(),
742                                          errmsg("could not access private key file \"%s\": %m",
743                                                         SERVER_PRIVATE_KEY_FILE)));
744
745                 /*
746                  * Require no public access to key file.
747                  *
748                  * XXX temporarily suppress check when on Windows, because there may
749                  * not be proper support for Unix-y file permissions.  Need to think
750                  * of a reasonable check to apply on Windows.  (See also the data
751                  * directory permission check in postmaster.c)
752                  */
753 #if !defined(WIN32) && !defined(__CYGWIN__)
754                 if (!S_ISREG(buf.st_mode) || (buf.st_mode & (S_IRWXG | S_IRWXO)) ||
755                         buf.st_uid != geteuid())
756                         ereport(FATAL,
757                                         (errcode(ERRCODE_CONFIG_FILE_ERROR),
758                                          errmsg("unsafe permissions on private key file \"%s\"",
759                                                         SERVER_PRIVATE_KEY_FILE),
760                                          errdetail("File must be owned by the database user and must have no permissions for \"group\" or \"other\".")));
761 #endif
762
763                 if (!SSL_CTX_use_PrivateKey_file(SSL_context,
764                                                                                  SERVER_PRIVATE_KEY_FILE,
765                                                                                  SSL_FILETYPE_PEM))
766                         ereport(FATAL,
767                                         (errmsg("could not load private key file \"%s\": %s",
768                                                         SERVER_PRIVATE_KEY_FILE, SSLerrmessage())));
769
770                 if (!SSL_CTX_check_private_key(SSL_context))
771                         ereport(FATAL,
772                                         (errmsg("check of private key failed: %s",
773                                                         SSLerrmessage())));
774         }
775
776         /* set up empheral DH keys */
777         SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
778         SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2);
779
780         /* setup the allowed cipher list */
781         if (SSL_CTX_set_cipher_list(SSL_context, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH") != 1)
782                 elog(FATAL, "could not set the cipher list (no valid ciphers available)");
783
784         /*
785          * Require and check client certificates only if we have a root.crt file.
786          */
787         if (!SSL_CTX_load_verify_locations(SSL_context, ROOT_CERT_FILE, NULL))
788         {
789                 /* Not fatal - we do not require client certificates */
790                 ereport(LOG,
791                                 (errmsg("could not load root certificate file \"%s\": %s",
792                                                 ROOT_CERT_FILE, SSLerrmessage()),
793                                  errdetail("Will not verify client certificates.")));
794         }
795         else
796         {
797                 /*
798                  * Check the Certificate Revocation List (CRL) if file exists.
799                  * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,
800                  * 00.html
801                  */
802                 X509_STORE *cvstore = SSL_CTX_get_cert_store(SSL_context);
803
804                 if (cvstore)
805                 {
806                         /* Set the flags to check against the complete CRL chain */
807                         if (X509_STORE_load_locations(cvstore, ROOT_CRL_FILE, NULL) != 0)
808 /* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
809 #ifdef X509_V_FLAG_CRL_CHECK
810                                 X509_STORE_set_flags(cvstore,
811                                                   X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
812 #else
813                                 ereport(LOG,
814                                                 (errmsg("SSL Certificate Revocation List (CRL) file \"%s\" ignored",
815                                                                 ROOT_CRL_FILE),
816                                   errdetail("Installed SSL library does not support CRL.")));
817 #endif
818                         else
819                         {
820                                 /* Not fatal - we do not require CRL */
821                                 ereport(LOG,
822                                                 (errmsg("SSL Certificate Revocation List (CRL) file \"%s\" not found, skipping: %s",
823                                                                 ROOT_CRL_FILE, SSLerrmessage()),
824                                          errdetail("Will not check certificates against CRL.")));
825                         }
826                 }
827
828                 SSL_CTX_set_verify(SSL_context,
829                                                    (SSL_VERIFY_PEER |
830                                                         SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
831                                                         SSL_VERIFY_CLIENT_ONCE),
832                                                    verify_cb);
833         }
834 }
835
836 /*
837  *      Destroy global SSL context.
838  */
839 static void
840 destroy_SSL(void)
841 {
842         if (SSL_context)
843         {
844                 SSL_CTX_free(SSL_context);
845                 SSL_context = NULL;
846         }
847 }
848
849 /*
850  *      Attempt to negotiate SSL connection.
851  */
852 static int
853 open_server_SSL(Port *port)
854 {
855         int                     r;
856         int                     err;
857
858         Assert(!port->ssl);
859         Assert(!port->peer);
860
861         if (!(port->ssl = SSL_new(SSL_context)))
862         {
863                 ereport(COMMERROR,
864                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
865                                  errmsg("could not initialize SSL connection: %s",
866                                                 SSLerrmessage())));
867                 close_SSL(port);
868                 return -1;
869         }
870         if (!my_SSL_set_fd(port->ssl, port->sock))
871         {
872                 ereport(COMMERROR,
873                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
874                                  errmsg("could not set SSL socket: %s",
875                                                 SSLerrmessage())));
876                 close_SSL(port);
877                 return -1;
878         }
879
880 aloop:
881         r = SSL_accept(port->ssl);
882         if (r <= 0)
883         {
884                 err = SSL_get_error(port->ssl, r);
885                 switch (err)
886                 {
887                         case SSL_ERROR_WANT_READ:
888                         case SSL_ERROR_WANT_WRITE:
889 #ifdef WIN32
890                                 pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
891                                                                                         (err == SSL_ERROR_WANT_READ) ?
892                                            FD_READ | FD_CLOSE | FD_ACCEPT : FD_WRITE | FD_CLOSE);
893 #endif
894                                 goto aloop;
895                         case SSL_ERROR_SYSCALL:
896                                 if (r < 0)
897                                         ereport(COMMERROR,
898                                                         (errcode_for_socket_access(),
899                                                          errmsg("could not accept SSL connection: %m")));
900                                 else
901                                         ereport(COMMERROR,
902                                                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
903                                         errmsg("could not accept SSL connection: EOF detected")));
904                                 break;
905                         case SSL_ERROR_SSL:
906                                 ereport(COMMERROR,
907                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
908                                                  errmsg("could not accept SSL connection: %s",
909                                                                 SSLerrmessage())));
910                                 break;
911                         case SSL_ERROR_ZERO_RETURN:
912                                 ereport(COMMERROR,
913                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
914                                    errmsg("could not accept SSL connection: EOF detected")));
915                                 break;
916                         default:
917                                 ereport(COMMERROR,
918                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
919                                                  errmsg("unrecognized SSL error code: %d",
920                                                                 err)));
921                                 break;
922                 }
923                 close_SSL(port);
924                 return -1;
925         }
926
927         port->count = 0;
928
929         /* get client certificate, if available. */
930         port->peer = SSL_get_peer_certificate(port->ssl);
931         if (port->peer == NULL)
932         {
933                 strncpy(port->peer_dn, "(anonymous)", sizeof(port->peer_dn));
934                 strncpy(port->peer_cn, "(anonymous)", sizeof(port->peer_cn));
935         }
936         else
937         {
938                 X509_NAME_oneline(X509_get_subject_name(port->peer),
939                                                   port->peer_dn, sizeof(port->peer_dn));
940                 port->peer_dn[sizeof(port->peer_dn) - 1] = '\0';
941                 X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
942                                            NID_commonName, port->peer_cn, sizeof(port->peer_cn));
943                 port->peer_cn[sizeof(port->peer_cn) - 1] = '\0';
944         }
945         ereport(DEBUG2,
946                         (errmsg("SSL connection from \"%s\"", port->peer_cn)));
947
948         /* set up debugging/info callback */
949         SSL_CTX_set_info_callback(SSL_context, info_cb);
950
951         return 0;
952 }
953
954 /*
955  *      Close SSL connection.
956  */
957 static void
958 close_SSL(Port *port)
959 {
960         if (port->ssl)
961         {
962                 SSL_shutdown(port->ssl);
963                 SSL_free(port->ssl);
964                 port->ssl = NULL;
965         }
966
967         if (port->peer)
968         {
969                 X509_free(port->peer);
970                 port->peer = NULL;
971         }
972 }
973
974 /*
975  * Obtain reason string for last SSL error
976  *
977  * Some caution is needed here since ERR_reason_error_string will
978  * return NULL if it doesn't recognize the error code.  We don't
979  * want to return NULL ever.
980  */
981 static const char *
982 SSLerrmessage(void)
983 {
984         unsigned long errcode;
985         const char *errreason;
986         static char errbuf[32];
987
988         errcode = ERR_get_error();
989         if (errcode == 0)
990                 return _("no SSL error reported");
991         errreason = ERR_reason_error_string(errcode);
992         if (errreason != NULL)
993                 return errreason;
994         snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), errcode);
995         return errbuf;
996 }
997
998 #endif   /* USE_SSL */