]> granicus.if.org Git - postgresql/blob - src/backend/libpq/be-secure.c
75e3240f9122986d9d7e4d3d9f9e03252e7d95ee
[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.68 2006/05/06 01:31:38 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 "miscadmin.h"
99 #include "tcop/tcopprot.h"
100
101
102 #ifdef USE_SSL
103
104 #define ROOT_CERT_FILE                  "root.crt"
105 #define ROOT_CRL_FILE                   "root.crl"
106 #define SERVER_CERT_FILE                "server.crt"
107 #define SERVER_PRIVATE_KEY_FILE "server.key"
108
109 static DH  *load_dh_file(int keylength);
110 static DH  *load_dh_buffer(const char *, size_t);
111 static DH  *tmp_dh_cb(SSL *s, int is_export, int keylength);
112 static int      verify_cb(int, X509_STORE_CTX *);
113 static void info_cb(const SSL *ssl, int type, int args);
114 static void     initialize_SSL(void);
115 static void destroy_SSL(void);
116 static int      open_server_SSL(Port *);
117 static void close_SSL(Port *);
118 static const char *SSLerrmessage(void);
119 #endif
120
121 #ifdef USE_SSL
122 /*
123  *      How much data can be sent across a secure connection
124  *      (total in both directions) before we require renegotiation.
125  */
126 #define RENEGOTIATION_LIMIT (512 * 1024 * 1024)
127
128 static SSL_CTX *SSL_context = NULL;
129 #endif
130
131 /* ------------------------------------------------------------ */
132 /*                                               Hardcoded values                                               */
133 /* ------------------------------------------------------------ */
134
135 /*
136  *      Hardcoded DH parameters, used in empheral DH keying.
137  *      As discussed above, EDH protects the confidentiality of
138  *      sessions even if the static private key is compromised,
139  *      so we are *highly* motivated to ensure that we can use
140  *      EDH even if the DBA... or an attacker... deletes the
141  *      $DataDir/dh*.pem files.
142  *
143  *      We could refuse SSL connections unless a good DH parameter
144  *      file exists, but some clients may quietly renegotiate an
145  *      unsecured connection without fully informing the user.
146  *      Very uncool.
147  *
148  *      Alternately, the backend could attempt to load these files
149  *      on startup if SSL is enabled - and refuse to start if any
150  *      do not exist - but this would tend to piss off DBAs.
151  *
152  *      If you want to create your own hardcoded DH parameters
153  *      for fun and profit, review "Assigned Number for SKIP
154  *      Protocols" (http://www.skip-vpn.org/spec/numbers.html)
155  *      for suggestions.
156  */
157 #ifdef USE_SSL
158
159 static const char file_dh512[] =
160 "-----BEGIN DH PARAMETERS-----\n\
161 MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak\n\
162 XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC\n\
163 -----END DH PARAMETERS-----\n";
164
165 static const char file_dh1024[] =
166 "-----BEGIN DH PARAMETERS-----\n\
167 MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY\n\
168 jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6\n\
169 ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC\n\
170 -----END DH PARAMETERS-----\n";
171
172 static const char file_dh2048[] =
173 "-----BEGIN DH PARAMETERS-----\n\
174 MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\
175 89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50\n\
176 T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb\n\
177 zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX\n\
178 Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\
179 CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\
180 -----END DH PARAMETERS-----\n";
181
182 static const char file_dh4096[] =
183 "-----BEGIN DH PARAMETERS-----\n\
184 MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ\n\
185 l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt\n\
186 Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS\n\
187 Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98\n\
188 VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc\n\
189 alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM\n\
190 sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9\n\
191 ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte\n\
192 OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH\n\
193 AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL\n\
194 KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
195 -----END DH PARAMETERS-----\n";
196 #endif
197
198 /* ------------------------------------------------------------ */
199 /*                       Procedures common to all secure sessions                       */
200 /* ------------------------------------------------------------ */
201
202 /*
203  *      Initialize global context
204  */
205 int
206 secure_initialize(void)
207 {
208 #ifdef USE_SSL
209         initialize_SSL();
210 #endif
211
212         return 0;
213 }
214
215 /*
216  *      Destroy global context
217  */
218 void
219 secure_destroy(void)
220 {
221 #ifdef USE_SSL
222         destroy_SSL();
223 #endif
224 }
225
226 /*
227  *      Attempt to negotiate secure session.
228  */
229 int
230 secure_open_server(Port *port)
231 {
232         int                     r = 0;
233
234 #ifdef USE_SSL
235         r = open_server_SSL(port);
236 #endif
237
238         return r;
239 }
240
241 /*
242  *      Close secure session.
243  */
244 void
245 secure_close(Port *port)
246 {
247 #ifdef USE_SSL
248         if (port->ssl)
249                 close_SSL(port);
250 #endif
251 }
252
253 /*
254  *      Read data from a secure connection.
255  */
256 ssize_t
257 secure_read(Port *port, void *ptr, size_t len)
258 {
259         ssize_t         n;
260
261 #ifdef USE_SSL
262         if (port->ssl)
263         {
264                 int                     err;
265
266 rloop:
267                 n = SSL_read(port->ssl, ptr, len);
268                 err = SSL_get_error(port->ssl, n);
269                 switch (err)
270                 {
271                         case SSL_ERROR_NONE:
272                                 port->count += n;
273                                 break;
274                         case SSL_ERROR_WANT_READ:
275                         case SSL_ERROR_WANT_WRITE:
276 #ifdef WIN32
277                                 pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
278                                                                                         (err == SSL_ERROR_WANT_READ) ?
279                                                                    FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE);
280 #endif
281                                 goto rloop;
282                         case SSL_ERROR_SYSCALL:
283                                 if (n == -1)
284                                         ereport(COMMERROR,
285                                                         (errcode_for_socket_access(),
286                                                          errmsg("SSL SYSCALL error: %m")));
287                                 else
288                                 {
289                                         ereport(COMMERROR,
290                                                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
291                                                          errmsg("SSL SYSCALL error: EOF detected")));
292                                         errno = ECONNRESET;
293                                         n = -1;
294                                 }
295                                 break;
296                         case SSL_ERROR_SSL:
297                                 ereport(COMMERROR,
298                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
299                                                  errmsg("SSL error: %s", SSLerrmessage())));
300                                 /* fall through */
301                         case SSL_ERROR_ZERO_RETURN:
302                                 errno = ECONNRESET;
303                                 n = -1;
304                                 break;
305                         default:
306                                 ereport(COMMERROR,
307                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
308                                                  errmsg("unrecognized SSL error code: %d",
309                                                                 err)));
310                                 n = -1;
311                                 break;
312                 }
313         }
314         else
315 #endif
316         {
317                 prepare_for_client_read();
318
319                 n = recv(port->sock, ptr, len, 0);
320
321                 client_read_ended();
322         }
323
324         return n;
325 }
326
327 /*
328  *      Write data to a secure connection.
329  */
330 ssize_t
331 secure_write(Port *port, void *ptr, size_t len)
332 {
333         ssize_t         n;
334
335 #ifdef USE_SSL
336         if (port->ssl)
337         {
338                 int                     err;
339
340                 if (port->count > RENEGOTIATION_LIMIT)
341                 {
342                         SSL_set_session_id_context(port->ssl, (void *) &SSL_context,
343                                                                            sizeof(SSL_context));
344                         if (SSL_renegotiate(port->ssl) <= 0)
345                                 ereport(COMMERROR,
346                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
347                                                  errmsg("SSL renegotiation failure")));
348                         if (SSL_do_handshake(port->ssl) <= 0)
349                                 ereport(COMMERROR,
350                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
351                                                  errmsg("SSL renegotiation failure")));
352                         if (port->ssl->state != SSL_ST_OK)
353                                 ereport(COMMERROR,
354                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
355                                                  errmsg("SSL failed to send renegotiation request")));
356                         port->ssl->state |= SSL_ST_ACCEPT;
357                         SSL_do_handshake(port->ssl);
358                         if (port->ssl->state != SSL_ST_OK)
359                                 ereport(COMMERROR,
360                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
361                                                  errmsg("SSL renegotiation failure")));
362                         port->count = 0;
363                 }
364
365 wloop:
366                 n = SSL_write(port->ssl, ptr, len);
367                 err = SSL_get_error(port->ssl, n);
368                 switch (err)
369                 {
370                         case SSL_ERROR_NONE:
371                                 port->count += n;
372                                 break;
373                         case SSL_ERROR_WANT_READ:
374                         case SSL_ERROR_WANT_WRITE:
375 #ifdef WIN32
376                                 pgwin32_waitforsinglesocket(SSL_get_fd(port->ssl),
377                                                                                         (err == SSL_ERROR_WANT_READ) ?
378                                                                    FD_READ | FD_CLOSE : FD_WRITE | FD_CLOSE);
379 #endif
380                                 goto wloop;
381                         case SSL_ERROR_SYSCALL:
382                                 if (n == -1)
383                                         ereport(COMMERROR,
384                                                         (errcode_for_socket_access(),
385                                                          errmsg("SSL SYSCALL error: %m")));
386                                 else
387                                 {
388                                         ereport(COMMERROR,
389                                                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
390                                                          errmsg("SSL SYSCALL error: EOF detected")));
391                                         errno = ECONNRESET;
392                                         n = -1;
393                                 }
394                                 break;
395                         case SSL_ERROR_SSL:
396                                 ereport(COMMERROR,
397                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
398                                                  errmsg("SSL error: %s", SSLerrmessage())));
399                                 /* fall through */
400                         case SSL_ERROR_ZERO_RETURN:
401                                 errno = ECONNRESET;
402                                 n = -1;
403                                 break;
404                         default:
405                                 ereport(COMMERROR,
406                                                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
407                                                  errmsg("unrecognized SSL error code: %d",
408                                                                 err)));
409                                 n = -1;
410                                 break;
411                 }
412         }
413         else
414 #endif
415                 n = send(port->sock, ptr, len, 0);
416
417         return n;
418 }
419
420 /* ------------------------------------------------------------ */
421 /*                                                SSL specific code                                             */
422 /* ------------------------------------------------------------ */
423 #ifdef USE_SSL
424
425 /*
426  * Private substitute BIO: this wraps the SSL library's standard socket BIO
427  * so that we can enable and disable interrupts just while calling recv().
428  * We cannot have interrupts occurring while the bulk of openssl runs,
429  * because it uses malloc() and possibly other non-reentrant libc facilities.
430  *
431  * As of openssl 0.9.7, we can use the reasonably clean method of interposing
432  * a wrapper around the standard socket BIO's sock_read() method.  This relies
433  * on the fact that sock_read() doesn't call anything non-reentrant, in fact
434  * not much of anything at all except recv().  If this ever changes we'd
435  * probably need to duplicate the code of sock_read() in order to push the
436  * interrupt enable/disable down yet another level.
437  */
438
439 static bool my_bio_initialized = false;
440 static BIO_METHOD my_bio_methods;
441 static int      (*std_sock_read) (BIO *h, char *buf, int size);
442
443 static int
444 my_sock_read(BIO *h, char *buf, int size)
445 {
446         int                     res;
447
448         prepare_for_client_read();
449
450         res = std_sock_read(h, buf, size);
451
452         client_read_ended();
453
454         return res;
455 }
456
457 static BIO_METHOD *
458 my_BIO_s_socket(void)
459 {
460         if (!my_bio_initialized)
461         {
462                 memcpy(&my_bio_methods, BIO_s_socket(), sizeof(BIO_METHOD));
463                 std_sock_read = my_bio_methods.bread;
464                 my_bio_methods.bread = my_sock_read;
465                 my_bio_initialized = true;
466         }
467         return &my_bio_methods;
468 }
469
470 /* This should exactly match openssl's SSL_set_fd except for using my BIO */
471 static int
472 my_SSL_set_fd(SSL *s, int fd)
473 {
474         int                     ret = 0;
475         BIO                *bio = NULL;
476
477         bio = BIO_new(my_BIO_s_socket());
478
479         if (bio == NULL)
480         {
481                 SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
482                 goto err;
483         }
484         BIO_set_fd(bio, fd, BIO_NOCLOSE);
485         SSL_set_bio(s, bio, bio);
486         ret = 1;
487 err:
488         return ret;
489 }
490
491 /*
492  *      Load precomputed DH parameters.
493  *
494  *      To prevent "downgrade" attacks, we perform a number of checks
495  *      to verify that the DBA-generated DH parameters file contains
496  *      what we expect it to contain.
497  */
498 static DH  *
499 load_dh_file(int keylength)
500 {
501         FILE       *fp;
502         char            fnbuf[MAXPGPATH];
503         DH                 *dh = NULL;
504         int                     codes;
505
506         /* attempt to open file.  It's not an error if it doesn't exist. */
507         snprintf(fnbuf, sizeof(fnbuf), "dh%d.pem", keylength);
508         if ((fp = fopen(fnbuf, "r")) == NULL)
509                 return NULL;
510
511 /*      flock(fileno(fp), LOCK_SH); */
512         dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
513 /*      flock(fileno(fp), LOCK_UN); */
514         fclose(fp);
515
516         /* is the prime the correct size? */
517         if (dh != NULL && 8 * DH_size(dh) < keylength)
518         {
519                 elog(LOG, "DH errors (%s): %d bits expected, %d bits found",
520                          fnbuf, keylength, 8 * DH_size(dh));
521                 dh = NULL;
522         }
523
524         /* make sure the DH parameters are usable */
525         if (dh != NULL)
526         {
527                 if (DH_check(dh, &codes))
528                 {
529                         elog(LOG, "DH_check error (%s): %s", fnbuf, SSLerrmessage());
530                         return NULL;
531                 }
532                 if (codes & DH_CHECK_P_NOT_PRIME)
533                 {
534                         elog(LOG, "DH error (%s): p is not prime", fnbuf);
535                         return NULL;
536                 }
537                 if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
538                         (codes & DH_CHECK_P_NOT_SAFE_PRIME))
539                 {
540                         elog(LOG,
541                                  "DH error (%s): neither suitable generator or safe prime",
542                                  fnbuf);
543                         return NULL;
544                 }
545         }
546
547         return dh;
548 }
549
550 /*
551  *      Load hardcoded DH parameters.
552  *
553  *      To prevent problems if the DH parameters files don't even
554  *      exist, we can load DH parameters hardcoded into this file.
555  */
556 static DH  *
557 load_dh_buffer(const char *buffer, size_t len)
558 {
559         BIO                *bio;
560         DH                 *dh = NULL;
561
562         bio = BIO_new_mem_buf((char *) buffer, len);
563         if (bio == NULL)
564                 return NULL;
565         dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
566         if (dh == NULL)
567                 ereport(DEBUG2,
568                                 (errmsg_internal("DH load buffer: %s",
569                                                                  SSLerrmessage())));
570         BIO_free(bio);
571
572         return dh;
573 }
574
575 /*
576  *      Generate an empheral DH key.  Because this can take a long
577  *      time to compute, we can use precomputed parameters of the
578  *      common key sizes.
579  *
580  *      Since few sites will bother to precompute these parameter
581  *      files, we also provide a fallback to the parameters provided
582  *      by the OpenSSL project.
583  *
584  *      These values can be static (once loaded or computed) since
585  *      the OpenSSL library can efficiently generate random keys from
586  *      the information provided.
587  */
588 static DH  *
589 tmp_dh_cb(SSL *s, int is_export, int keylength)
590 {
591         DH                 *r = NULL;
592         static DH  *dh = NULL;
593         static DH  *dh512 = NULL;
594         static DH  *dh1024 = NULL;
595         static DH  *dh2048 = NULL;
596         static DH  *dh4096 = NULL;
597
598         switch (keylength)
599         {
600                 case 512:
601                         if (dh512 == NULL)
602                                 dh512 = load_dh_file(keylength);
603                         if (dh512 == NULL)
604                                 dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
605                         r = dh512;
606                         break;
607
608                 case 1024:
609                         if (dh1024 == NULL)
610                                 dh1024 = load_dh_file(keylength);
611                         if (dh1024 == NULL)
612                                 dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
613                         r = dh1024;
614                         break;
615
616                 case 2048:
617                         if (dh2048 == NULL)
618                                 dh2048 = load_dh_file(keylength);
619                         if (dh2048 == NULL)
620                                 dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
621                         r = dh2048;
622                         break;
623
624                 case 4096:
625                         if (dh4096 == NULL)
626                                 dh4096 = load_dh_file(keylength);
627                         if (dh4096 == NULL)
628                                 dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
629                         r = dh4096;
630                         break;
631
632                 default:
633                         if (dh == NULL)
634                                 dh = load_dh_file(keylength);
635                         r = dh;
636         }
637
638         /* this may take a long time, but it may be necessary... */
639         if (r == NULL || 8 * DH_size(r) < keylength)
640         {
641                 ereport(DEBUG2,
642                                 (errmsg_internal("DH: generating parameters (%d bits)....",
643                                                                  keylength)));
644                 r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
645         }
646
647         return r;
648 }
649
650 /*
651  *      Certificate verification callback
652  *
653  *      This callback allows us to log intermediate problems during
654  *      verification, but for now we'll see if the final error message
655  *      contains enough information.
656  *
657  *      This callback also allows us to override the default acceptance
658  *      criteria (e.g., accepting self-signed or expired certs), but
659  *      for now we accept the default checks.
660  */
661 static int
662 verify_cb(int ok, X509_STORE_CTX *ctx)
663 {
664         return ok;
665 }
666
667 /*
668  *      This callback is used to copy SSL information messages
669  *      into the PostgreSQL log.
670  */
671 static void
672 info_cb(const SSL *ssl, int type, int args)
673 {
674         switch (type)
675         {
676                 case SSL_CB_HANDSHAKE_START:
677                         ereport(DEBUG4,
678                                         (errmsg_internal("SSL: handshake start")));
679                         break;
680                 case SSL_CB_HANDSHAKE_DONE:
681                         ereport(DEBUG4,
682                                         (errmsg_internal("SSL: handshake done")));
683                         break;
684                 case SSL_CB_ACCEPT_LOOP:
685                         ereport(DEBUG4,
686                                         (errmsg_internal("SSL: accept loop")));
687                         break;
688                 case SSL_CB_ACCEPT_EXIT:
689                         ereport(DEBUG4,
690                                         (errmsg_internal("SSL: accept exit (%d)", args)));
691                         break;
692                 case SSL_CB_CONNECT_LOOP:
693                         ereport(DEBUG4,
694                                         (errmsg_internal("SSL: connect loop")));
695                         break;
696                 case SSL_CB_CONNECT_EXIT:
697                         ereport(DEBUG4,
698                                         (errmsg_internal("SSL: connect exit (%d)", args)));
699                         break;
700                 case SSL_CB_READ_ALERT:
701                         ereport(DEBUG4,
702                                         (errmsg_internal("SSL: read alert (0x%04x)", args)));
703                         break;
704                 case SSL_CB_WRITE_ALERT:
705                         ereport(DEBUG4,
706                                         (errmsg_internal("SSL: write alert (0x%04x)", args)));
707                         break;
708         }
709 }
710
711 /*
712  *      Initialize global SSL context.
713  */
714 static void
715 initialize_SSL(void)
716 {
717         struct stat buf;
718
719         if (!SSL_context)
720         {
721                 SSL_library_init();
722                 SSL_load_error_strings();
723                 SSL_context = SSL_CTX_new(SSLv23_method());
724                 if (!SSL_context)
725                         ereport(FATAL,
726                                         (errmsg("could not create SSL context: %s",
727                                                         SSLerrmessage())));
728
729                 /*
730                  * Load and verify certificate and private key
731                  */
732                 if (!SSL_CTX_use_certificate_file(SSL_context,
733                                                                                   SERVER_CERT_FILE,
734                                                                                   SSL_FILETYPE_PEM))
735                         ereport(FATAL,
736                                         (errcode(ERRCODE_CONFIG_FILE_ERROR),
737                                   errmsg("could not load server certificate file \"%s\": %s",
738                                                  SERVER_CERT_FILE, SSLerrmessage())));
739
740                 if (stat(SERVER_PRIVATE_KEY_FILE, &buf) == -1)
741                         ereport(FATAL,
742                                         (errcode_for_file_access(),
743                                          errmsg("could not access private key file \"%s\": %m",
744                                                         SERVER_PRIVATE_KEY_FILE)));
745
746                 /*
747                  * Require no public access to key file.
748                  *
749                  * XXX temporarily suppress check when on Windows, because there may
750                  * not be proper support for Unix-y file permissions.  Need to think
751                  * of a reasonable check to apply on Windows.  (See also the data
752                  * directory permission check in postmaster.c)
753                  */
754 #if !defined(WIN32) && !defined(__CYGWIN__)
755                 if (!S_ISREG(buf.st_mode) || (buf.st_mode & (S_IRWXG | S_IRWXO)) ||
756                         buf.st_uid != geteuid())
757                         ereport(FATAL,
758                                         (errcode(ERRCODE_CONFIG_FILE_ERROR),
759                                          errmsg("unsafe permissions on private key file \"%s\"",
760                                                         SERVER_PRIVATE_KEY_FILE),
761                                          errdetail("File must be owned by the database user and must have no permissions for \"group\" or \"other\".")));
762 #endif
763
764                 if (!SSL_CTX_use_PrivateKey_file(SSL_context,
765                                                                                  SERVER_PRIVATE_KEY_FILE,
766                                                                                  SSL_FILETYPE_PEM))
767                         ereport(FATAL,
768                                         (errmsg("could not load private key file \"%s\": %s",
769                                                         SERVER_PRIVATE_KEY_FILE, SSLerrmessage())));
770
771                 if (!SSL_CTX_check_private_key(SSL_context))
772                         ereport(FATAL,
773                                         (errmsg("check of private key failed: %s",
774                                                         SSLerrmessage())));
775         }
776
777         /* set up empheral DH keys */
778         SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
779         SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2);
780
781         /* setup the allowed cipher list */
782         if (SSL_CTX_set_cipher_list(SSL_context, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH") != 1)
783                 elog(FATAL, "could not set the cipher list (no valid ciphers available)");
784
785         /*
786          * Require and check client certificates only if we have a root.crt file.
787          */
788         if (!SSL_CTX_load_verify_locations(SSL_context, ROOT_CERT_FILE, NULL))
789         {
790                 /* Not fatal - we do not require client certificates */
791                 ereport(LOG,
792                                 (errmsg("could not load root certificate file \"%s\": %s",
793                                                 ROOT_CERT_FILE, SSLerrmessage()),
794                                  errdetail("Will not verify client certificates.")));
795         }
796         else
797         {
798                 /*
799                  *      Check the Certificate Revocation List (CRL) if file exists.
800                  *      http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,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 */