1 /*-------------------------------------------------------------------------
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.
9 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
10 * Portions Copyright (c) 1994, Regents of the University of California
14 * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-secure.c,v 1.18 2002/12/18 13:15:15 pgsql Exp $
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.
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.
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.
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
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.
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.
63 * The user's certificate and private key are located in
64 * $HOME/.postgresql/postgresql.crt
66 * $HOME/.postgresql/postgresql.key
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.
76 * The code currently assumes a POSIX password entry. How should
77 * Windows and Mac users be handled?
79 *-------------------------------------------------------------------------
82 #include "postgres_fe.h"
84 #include <sys/types.h>
92 #include "libpq-int.h"
99 #include <sys/socket.h>
102 #include <netinet/in.h>
103 #ifdef HAVE_NETINET_TCP_H
104 #include <netinet/tcp.h>
106 #include <arpa/inet.h>
116 #include <sys/stat.h>
119 #include <openssl/ssl.h>
120 #include <openssl/dh.h>
125 static int verify_cb(int ok, X509_STORE_CTX *ctx);
127 static int verify_peer(PGconn *);
129 static DH *load_dh_file(int keylength);
130 static DH *load_dh_buffer(const char *, size_t);
131 static DH *tmp_dh_cb(SSL *s, int is_export, int keylength);
132 static int client_cert_cb(SSL *, X509 **, EVP_PKEY **);
133 static int initialize_SSL(PGconn *);
134 static void destroy_SSL(void);
135 static int open_client_SSL(PGconn *);
136 static void close_SSL(PGconn *);
137 static const char *SSLerrmessage(void);
141 static SSL_CTX *SSL_context = NULL;
144 /* ------------------------------------------------------------ */
145 /* Hardcoded values */
146 /* ------------------------------------------------------------ */
149 * Hardcoded DH parameters, used in empheral DH keying.
150 * As discussed above, EDH protects the confidentiality of
151 * sessions even if the static private key is compromised,
152 * so we are *highly* motivated to ensure that we can use
153 * EDH even if the user... or an attacker... deletes the
154 * $HOME/.postgresql/dh*.pem files.
156 * It's not critical that users have EPH keys, but it doesn't
157 * hurt and if it's missing someone will demand it, so....
159 static const char file_dh512[] =
160 "-----BEGIN DH PARAMETERS-----\n\
161 MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak\n\
162 XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC\n\
163 -----END DH PARAMETERS-----\n";
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";
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";
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";
197 /* ------------------------------------------------------------ */
198 /* Procedures common to all secure sessions */
199 /* ------------------------------------------------------------ */
202 * Initialize global context
205 pqsecure_initialize(PGconn *conn)
210 r = initialize_SSL(conn);
217 * Destroy global context
220 pqsecure_destroy(void)
228 * Attempt to negotiate secure session.
231 pqsecure_open_client(PGconn *conn)
236 r = open_client_SSL(conn);
243 * Close secure session.
246 pqsecure_close(PGconn *conn)
255 * Read data from a secure connection.
258 pqsecure_read(PGconn *conn, void *ptr, size_t len)
265 n = SSL_read(conn->ssl, ptr, len);
266 switch (SSL_get_error(conn->ssl, n))
270 case SSL_ERROR_WANT_READ:
272 case SSL_ERROR_SYSCALL:
274 printfPQExpBuffer(&conn->errorMessage,
275 libpq_gettext("SSL SYSCALL error: %s\n"),
276 SOCK_STRERROR(SOCK_ERRNO));
279 printfPQExpBuffer(&conn->errorMessage,
280 libpq_gettext("SSL error: %s\n"), SSLerrmessage());
282 case SSL_ERROR_ZERO_RETURN:
283 pqsecure_close(conn);
284 SOCK_ERRNO = ECONNRESET;
291 n = recv(conn->sock, ptr, len, 0);
297 * Write data to a secure connection.
300 pqsecure_write(PGconn *conn, const void *ptr, size_t len)
305 pqsigfunc oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
311 n = SSL_write(conn->ssl, ptr, len);
312 switch (SSL_get_error(conn->ssl, n))
316 case SSL_ERROR_WANT_WRITE:
318 case SSL_ERROR_SYSCALL:
320 printfPQExpBuffer(&conn->errorMessage,
321 libpq_gettext("SSL SYSCALL error: %s\n"),
322 SOCK_STRERROR(SOCK_ERRNO));
325 printfPQExpBuffer(&conn->errorMessage,
326 libpq_gettext("SSL error: %s\n"), SSLerrmessage());
328 case SSL_ERROR_ZERO_RETURN:
329 pqsecure_close(conn);
330 SOCK_ERRNO = ECONNRESET;
337 n = send(conn->sock, ptr, len, 0);
340 pqsignal(SIGPIPE, oldsighandler);
346 /* ------------------------------------------------------------ */
347 /* SSL specific code */
348 /* ------------------------------------------------------------ */
351 * Certificate verification callback
353 * This callback allows us to log intermediate problems during
354 * verification, but there doesn't seem to be a clean way to get
355 * our PGconn * structure. So we can't log anything!
357 * This callback also allows us to override the default acceptance
358 * criteria (e.g., accepting self-signed or expired certs), but
359 * for now we accept the default checks.
362 verify_cb(int ok, X509_STORE_CTX *ctx)
369 * Verify that common name resolves to peer.
370 * This function is not thread-safe due to gethostbyname().
373 verify_peer(PGconn *conn)
375 struct hostent *h = NULL;
376 struct sockaddr addr;
377 struct sockaddr_in *sin;
382 /* get the address on the other side of the socket */
384 if (getpeername(conn->sock, &addr, &len) == -1)
386 printfPQExpBuffer(&conn->errorMessage,
387 libpq_gettext("error querying socket: %s\n"),
388 SOCK_STRERROR(SOCK_ERRNO));
392 /* weird, but legal case */
393 if (addr.sa_family == AF_UNIX)
396 /* what do we know about the peer's common name? */
397 if ((h = gethostbyname(conn->peer_cn)) == NULL)
399 printfPQExpBuffer(&conn->errorMessage,
400 libpq_gettext("could not get information about host (%s): %s\n"),
401 conn->peer_cn, hstrerror(h_errno));
405 /* does the address match? */
406 switch (addr.sa_family)
409 sin = (struct sockaddr_in *) & addr;
410 for (s = h->h_addr_list; *s != NULL; s++)
412 if (!memcmp(&sin->sin_addr.s_addr, *s, h->h_length))
418 printfPQExpBuffer(&conn->errorMessage,
419 libpq_gettext("unsupported protocol\n"));
424 * the prior test should be definitive, but in practice it sometimes
425 * fails. So we also check the aliases.
427 for (s = h->h_aliases; *s != NULL; s++)
429 if (strcasecmp(conn->peer_cn, *s) == 0)
433 /* generate protocol-aware error message */
434 switch (addr.sa_family)
437 sin = (struct sockaddr_in *) & addr;
438 l = ntohl(sin->sin_addr.s_addr);
439 printfPQExpBuffer(&conn->errorMessage,
441 "server common name \"%s\" does not resolve to %ld.%ld.%ld.%ld\n"),
442 conn->peer_cn, (l >> 24) % 0x100, (l >> 16) % 0x100,
443 (l >> 8) % 0x100, l % 0x100);
446 printfPQExpBuffer(&conn->errorMessage,
448 "server common name \"%s\" does not resolve to peer address\n"),
457 * Load precomputed DH parameters.
459 * To prevent "downgrade" attacks, we perform a number of checks
460 * to verify that the DBA-generated DH parameters file contains
461 * what we expect it to contain.
464 load_dh_file(int keylength)
472 if ((pwd = getpwuid(getuid())) == NULL)
475 /* attempt to open file. It's not an error if it doesn't exist. */
476 snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/dh%d.pem",
477 pwd->pw_dir, keylength);
478 if ((fp = fopen(fnbuf, "r")) == NULL)
481 /* flock(fileno(fp), LOCK_SH); */
482 dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
483 /* flock(fileno(fp), LOCK_UN); */
486 /* is the prime the correct size? */
487 if (dh != NULL && 8 * DH_size(dh) < keylength)
490 /* make sure the DH parameters are usable */
493 if (DH_check(dh, &codes))
495 if (codes & DH_CHECK_P_NOT_PRIME)
497 if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
498 (codes & DH_CHECK_P_NOT_SAFE_PRIME))
506 * Load hardcoded DH parameters.
508 * To prevent problems if the DH parameters files don't even
509 * exist, we can load DH parameters hardcoded into this file.
512 load_dh_buffer(const char *buffer, size_t len)
517 bio = BIO_new_mem_buf((char *) buffer, len);
520 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
527 * Generate an empheral DH key. Because this can take a long
528 * time to compute, we can use precomputed parameters of the
531 * Since few sites will bother to precompute these parameter
532 * files, we also provide a fallback to the parameters provided
533 * by the OpenSSL project.
535 * These values can be static (once loaded or computed) since
536 * the OpenSSL library can efficiently generate random keys from
537 * the information provided.
540 tmp_dh_cb(SSL *s, int is_export, int keylength)
543 static DH *dh = NULL;
544 static DH *dh512 = NULL;
545 static DH *dh1024 = NULL;
546 static DH *dh2048 = NULL;
547 static DH *dh4096 = NULL;
553 dh512 = load_dh_file(keylength);
555 dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
561 dh1024 = load_dh_file(keylength);
563 dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
569 dh2048 = load_dh_file(keylength);
571 dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
577 dh4096 = load_dh_file(keylength);
579 dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
585 dh = load_dh_file(keylength);
589 /* this may take a long time, but it may be necessary... */
590 if (r == NULL || 8 * DH_size(r) < keylength)
591 r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
597 * Callback used by SSL to load client cert and key.
598 * This callback is only called when the server wants a
601 * Returns 1 on success, 0 on no data, -1 on error.
604 client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
611 PGconn *conn = (PGconn *) SSL_get_app_data(ssl);
612 int (*cb) () = NULL; /* how to read user password */
614 if ((pwd = getpwuid(getuid())) == NULL)
616 printfPQExpBuffer(&conn->errorMessage,
617 libpq_gettext("could not get user information\n"));
621 /* read the user certificate */
622 snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/postgresql.crt",
624 if (stat(fnbuf, &buf) == -1)
626 if ((fp = fopen(fnbuf, "r")) == NULL)
628 printfPQExpBuffer(&conn->errorMessage,
629 libpq_gettext("could not open certificate (%s): %s\n"),
630 fnbuf, strerror(errno));
633 if (PEM_read_X509(fp, x509, NULL, NULL) == NULL)
635 printfPQExpBuffer(&conn->errorMessage,
636 libpq_gettext("could not read certificate (%s): %s\n"),
637 fnbuf, SSLerrmessage());
643 /* read the user key */
644 snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/postgresql.key",
646 if (stat(fnbuf, &buf) == -1)
648 printfPQExpBuffer(&conn->errorMessage,
649 libpq_gettext("certificate present, but not private key (%s)\n"),
654 if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) ||
655 buf.st_uid != getuid())
657 printfPQExpBuffer(&conn->errorMessage,
658 libpq_gettext("private key (%s) has wrong permissions\n"), fnbuf);
662 if ((fp = fopen(fnbuf, "r")) == NULL)
664 printfPQExpBuffer(&conn->errorMessage,
665 libpq_gettext("could not open private key file (%s): %s\n"),
666 fnbuf, strerror(errno));
670 if (fstat(fileno(fp), &buf2) == -1 ||
671 buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
673 printfPQExpBuffer(&conn->errorMessage,
674 libpq_gettext("private key (%s) changed during execution\n"), fnbuf);
678 if (PEM_read_PrivateKey(fp, pkey, cb, NULL) == NULL)
680 printfPQExpBuffer(&conn->errorMessage,
681 libpq_gettext("could not read private key (%s): %s\n"),
682 fnbuf, SSLerrmessage());
689 /* verify that the cert and key go together */
690 if (!X509_check_private_key(*x509, *pkey))
692 printfPQExpBuffer(&conn->errorMessage,
693 libpq_gettext("certificate/private key mismatch (%s): %s\n"),
694 fnbuf, SSLerrmessage());
696 EVP_PKEY_free(*pkey);
704 * Initialize global SSL context.
707 initialize_SSL(PGconn *conn)
716 SSL_load_error_strings();
717 SSL_context = SSL_CTX_new(SSLv23_method());
720 printfPQExpBuffer(&conn->errorMessage,
721 libpq_gettext("could not create SSL context: %s\n"),
727 if ((pwd = getpwuid(getuid())) != NULL)
729 snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/root.crt",
731 if (stat(fnbuf, &buf) == -1)
735 /* CLIENT CERTIFICATES NOT REQUIRED bjm 2002-09-26 */
736 printfPQExpBuffer(&conn->errorMessage,
737 libpq_gettext("could not read root certificate list (%s): %s\n"),
738 fnbuf, strerror(errno));
742 if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, 0))
744 printfPQExpBuffer(&conn->errorMessage,
745 libpq_gettext("could not read root certificate list (%s): %s\n"),
746 fnbuf, SSLerrmessage());
751 SSL_CTX_set_verify(SSL_context,
752 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);
753 SSL_CTX_set_verify_depth(SSL_context, 1);
755 /* set up empheral DH keys */
756 SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
757 SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE);
759 /* set up mechanism to provide client certificate, if available */
760 SSL_CTX_set_client_cert_cb(SSL_context, client_cert_cb);
766 * Destroy global SSL context.
773 SSL_CTX_free(SSL_context);
779 * Attempt to negotiate SSL connection.
782 open_client_SSL(PGconn *conn)
788 if (!(conn->ssl = SSL_new(SSL_context)) ||
789 !SSL_set_app_data(conn->ssl, conn) ||
790 !SSL_set_fd(conn->ssl, conn->sock) ||
791 SSL_connect(conn->ssl) <= 0)
793 printfPQExpBuffer(&conn->errorMessage,
794 libpq_gettext("could not establish SSL connection: %s\n"),
800 /* check the certificate chain of the server */
803 /* CLIENT CERTIFICATES NOT REQUIRED bjm 2002-09-26 */
805 * this eliminates simple man-in-the-middle attacks and simple
808 r = SSL_get_verify_result(conn->ssl);
811 printfPQExpBuffer(&conn->errorMessage,
812 libpq_gettext("certificate could not be validated: %s\n"),
813 X509_verify_cert_error_string(r));
819 /* pull out server distinguished and common names */
820 conn->peer = SSL_get_peer_certificate(conn->ssl);
821 if (conn->peer == NULL)
823 printfPQExpBuffer(&conn->errorMessage,
824 libpq_gettext("certificate could not be obtained: %s\n"),
830 X509_NAME_oneline(X509_get_subject_name(conn->peer),
831 conn->peer_dn, sizeof(conn->peer_dn));
832 conn->peer_dn[sizeof(conn->peer_dn) - 1] = '\0';
834 X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
835 NID_commonName, conn->peer_cn, SM_USER);
836 conn->peer_cn[SM_USER] = '\0';
838 /* verify that the common name resolves to peer */
841 /* CLIENT CERTIFICATES NOT REQUIRED bjm 2002-09-26 */
843 * this is necessary to eliminate man-in-the-middle attacks and
844 * impersonations where the attacker somehow learned the server's
847 if (verify_peer(conn) == -1)
858 * Close SSL connection.
861 close_SSL(PGconn *conn)
865 SSL_shutdown(conn->ssl);
872 * Obtain reason string for last SSL error
874 * Some caution is needed here since ERR_reason_error_string will
875 * return NULL if it doesn't recognize the error code. We don't
876 * want to return NULL ever.
881 unsigned long errcode;
882 const char *errreason;
883 static char errbuf[32];
885 errcode = ERR_get_error();
887 return "No SSL error reported";
888 errreason = ERR_reason_error_string(errcode);
889 if (errreason != NULL)
891 snprintf(errbuf, sizeof(errbuf), "SSL error code %lu", errcode);
896 * Return pointer to SSL object.
899 PQgetssl(PGconn *conn)