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.13 2002/09/22 20:57:21 petere 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/e_os.h>
125 static int verify_cb(int ok, X509_STORE_CTX *ctx);
126 static int verify_peer(PGconn *);
127 static DH *load_dh_file(int keylength);
128 static DH *load_dh_buffer(const char *, size_t);
129 static DH *tmp_dh_cb(SSL *s, int is_export, int keylength);
130 static int client_cert_cb(SSL *, X509 **, EVP_PKEY **);
131 static int initialize_SSL(PGconn *);
132 static void destroy_SSL(void);
133 static int open_client_SSL(PGconn *);
134 static void close_SSL(PGconn *);
135 static const char *SSLerrmessage(void);
139 static SSL_CTX *SSL_context = NULL;
142 /* ------------------------------------------------------------ */
143 /* Hardcoded values */
144 /* ------------------------------------------------------------ */
147 * Hardcoded DH parameters, used in empheral DH keying.
148 * As discussed above, EDH protects the confidentiality of
149 * sessions even if the static private key is compromised,
150 * so we are *highly* motivated to ensure that we can use
151 * EDH even if the user... or an attacker... deletes the
152 * $HOME/.postgresql/dh*.pem files.
154 * It's not critical that users have EPH keys, but it doesn't
155 * hurt and if it's missing someone will demand it, so....
157 static const char file_dh512[] =
158 "-----BEGIN DH PARAMETERS-----\n\
159 MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak\n\
160 XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC\n\
161 -----END DH PARAMETERS-----\n";
163 static const char file_dh1024[] =
164 "-----BEGIN DH PARAMETERS-----\n\
165 MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY\n\
166 jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6\n\
167 ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC\n\
168 -----END DH PARAMETERS-----\n";
170 static const char file_dh2048[] =
171 "-----BEGIN DH PARAMETERS-----\n\
172 MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\
173 89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50\n\
174 T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb\n\
175 zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX\n\
176 Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\
177 CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\
178 -----END DH PARAMETERS-----\n";
180 static const char file_dh4096[] =
181 "-----BEGIN DH PARAMETERS-----\n\
182 MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ\n\
183 l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt\n\
184 Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS\n\
185 Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98\n\
186 VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc\n\
187 alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM\n\
188 sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9\n\
189 ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte\n\
190 OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH\n\
191 AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL\n\
192 KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
193 -----END DH PARAMETERS-----\n";
195 /* ------------------------------------------------------------ */
196 /* Procedures common to all secure sessions */
197 /* ------------------------------------------------------------ */
200 * Initialize global context
203 pqsecure_initialize(PGconn *conn)
208 r = initialize_SSL(conn);
215 * Destroy global context
218 pqsecure_destroy(void)
226 * Attempt to negotiate secure session.
229 pqsecure_open_client(PGconn *conn)
234 r = open_client_SSL(conn);
241 * Close secure session.
244 pqsecure_close(PGconn *conn)
253 * Read data from a secure connection.
256 pqsecure_read(PGconn *conn, void *ptr, size_t len)
263 n = SSL_read(conn->ssl, ptr, len);
264 switch (SSL_get_error(conn->ssl, n))
268 case SSL_ERROR_WANT_READ:
270 case SSL_ERROR_SYSCALL:
271 SOCK_ERRNO = get_last_socket_error();
272 printfPQExpBuffer(&conn->errorMessage,
273 libpq_gettext("SSL SYSCALL error: %s\n"),
274 SOCK_STRERROR(SOCK_ERRNO));
277 printfPQExpBuffer(&conn->errorMessage,
278 libpq_gettext("SSL error: %s\n"), SSLerrmessage());
280 case SSL_ERROR_ZERO_RETURN:
281 pqsecure_close(conn);
282 SOCK_ERRNO = ECONNRESET;
289 n = recv(conn->sock, ptr, len, 0);
295 * Write data to a secure connection.
298 pqsecure_write(PGconn *conn, const void *ptr, size_t len)
303 pqsigfunc oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
309 n = SSL_write(conn->ssl, ptr, len);
310 switch (SSL_get_error(conn->ssl, n))
314 case SSL_ERROR_WANT_WRITE:
316 case SSL_ERROR_SYSCALL:
317 SOCK_ERRNO = get_last_socket_error();
318 printfPQExpBuffer(&conn->errorMessage,
319 libpq_gettext("SSL SYSCALL error: %s\n"),
320 SOCK_STRERROR(SOCK_ERRNO));
323 printfPQExpBuffer(&conn->errorMessage,
324 libpq_gettext("SSL error: %s\n"), SSLerrmessage());
326 case SSL_ERROR_ZERO_RETURN:
327 pqsecure_close(conn);
328 SOCK_ERRNO = ECONNRESET;
335 n = send(conn->sock, ptr, len, 0);
338 pqsignal(SIGPIPE, oldsighandler);
344 /* ------------------------------------------------------------ */
345 /* SSL specific code */
346 /* ------------------------------------------------------------ */
349 * Certificate verification callback
351 * This callback allows us to log intermediate problems during
352 * verification, but there doesn't seem to be a clean way to get
353 * our PGconn * structure. So we can't log anything!
355 * This callback also allows us to override the default acceptance
356 * criteria (e.g., accepting self-signed or expired certs), but
357 * for now we accept the default checks.
360 verify_cb(int ok, X509_STORE_CTX *ctx)
366 * Verify that common name resolves to peer.
367 * This function is not thread-safe due to gethostbyname().
370 verify_peer(PGconn *conn)
372 struct hostent *h = NULL;
373 struct sockaddr addr;
374 struct sockaddr_in *sin;
379 /* get the address on the other side of the socket */
381 if (getpeername(conn->sock, &addr, &len) == -1)
383 printfPQExpBuffer(&conn->errorMessage,
384 libpq_gettext("error querying socket: %s\n"),
385 SOCK_STRERROR(SOCK_ERRNO));
389 /* weird, but legal case */
390 if (addr.sa_family == AF_UNIX)
393 /* what do we know about the peer's common name? */
394 if ((h = gethostbyname(conn->peer_cn)) == NULL)
396 printfPQExpBuffer(&conn->errorMessage,
397 libpq_gettext("could not get information about host (%s): %s\n"),
398 conn->peer_cn, hstrerror(h_errno));
402 /* does the address match? */
403 switch (addr.sa_family)
406 sin = (struct sockaddr_in *) & addr;
407 for (s = h->h_addr_list; *s != NULL; s++)
409 if (!memcmp(&sin->sin_addr.s_addr, *s, h->h_length))
415 printfPQExpBuffer(&conn->errorMessage,
416 libpq_gettext("unsupported protocol\n"));
421 * the prior test should be definitive, but in practice it sometimes
422 * fails. So we also check the aliases.
424 for (s = h->h_aliases; *s != NULL; s++)
426 if (strcasecmp(conn->peer_cn, *s) == 0)
430 /* generate protocol-aware error message */
431 switch (addr.sa_family)
434 sin = (struct sockaddr_in *) & addr;
435 l = ntohl(sin->sin_addr.s_addr);
436 printfPQExpBuffer(&conn->errorMessage,
438 "server common name \"%s\" does not resolve to %ld.%ld.%ld.%ld\n"),
439 conn->peer_cn, (l >> 24) % 0x100, (l >> 16) % 0x100,
440 (l >> 8) % 0x100, l % 0x100);
443 printfPQExpBuffer(&conn->errorMessage,
445 "server common name \"%s\" does not resolve to peer address\n"),
453 * Load precomputed DH parameters.
455 * To prevent "downgrade" attacks, we perform a number of checks
456 * to verify that the DBA-generated DH parameters file contains
457 * what we expect it to contain.
460 load_dh_file(int keylength)
468 if ((pwd = getpwuid(getuid())) == NULL)
471 /* attempt to open file. It's not an error if it doesn't exist. */
472 snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/dh%d.pem",
473 pwd->pw_dir, keylength);
474 if ((fp = fopen(fnbuf, "r")) == NULL)
477 /* flock(fileno(fp), LOCK_SH); */
478 dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
479 /* flock(fileno(fp), LOCK_UN); */
482 /* is the prime the correct size? */
483 if (dh != NULL && 8 * DH_size(dh) < keylength)
486 /* make sure the DH parameters are usable */
489 if (DH_check(dh, &codes))
491 if (codes & DH_CHECK_P_NOT_PRIME)
493 if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
494 (codes & DH_CHECK_P_NOT_SAFE_PRIME))
502 * Load hardcoded DH parameters.
504 * To prevent problems if the DH parameters files don't even
505 * exist, we can load DH parameters hardcoded into this file.
508 load_dh_buffer(const char *buffer, size_t len)
513 bio = BIO_new_mem_buf((char *) buffer, len);
516 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
523 * Generate an empheral DH key. Because this can take a long
524 * time to compute, we can use precomputed parameters of the
527 * Since few sites will bother to precompute these parameter
528 * files, we also provide a fallback to the parameters provided
529 * by the OpenSSL project.
531 * These values can be static (once loaded or computed) since
532 * the OpenSSL library can efficiently generate random keys from
533 * the information provided.
536 tmp_dh_cb(SSL *s, int is_export, int keylength)
539 static DH *dh = NULL;
540 static DH *dh512 = NULL;
541 static DH *dh1024 = NULL;
542 static DH *dh2048 = NULL;
543 static DH *dh4096 = NULL;
549 dh512 = load_dh_file(keylength);
551 dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
557 dh1024 = load_dh_file(keylength);
559 dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
565 dh2048 = load_dh_file(keylength);
567 dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
573 dh4096 = load_dh_file(keylength);
575 dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
581 dh = load_dh_file(keylength);
585 /* this may take a long time, but it may be necessary... */
586 if (r == NULL || 8 * DH_size(r) < keylength)
587 r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
593 * Callback used by SSL to load client cert and key.
594 * This callback is only called when the server wants a
597 * Returns 1 on success, 0 on no data, -1 on error.
600 client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
607 PGconn *conn = (PGconn *) SSL_get_app_data(ssl);
608 int (*cb) () = NULL; /* how to read user password */
610 if ((pwd = getpwuid(getuid())) == NULL)
612 printfPQExpBuffer(&conn->errorMessage,
613 libpq_gettext("could not get user information\n"));
617 /* read the user certificate */
618 snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/postgresql.crt",
620 if (stat(fnbuf, &buf) == -1)
622 if ((fp = fopen(fnbuf, "r")) == NULL)
624 printfPQExpBuffer(&conn->errorMessage,
625 libpq_gettext("could not open certificate (%s): %s\n"),
626 fnbuf, strerror(errno));
629 if (PEM_read_X509(fp, x509, NULL, NULL) == NULL)
631 printfPQExpBuffer(&conn->errorMessage,
632 libpq_gettext("could not read certificate (%s): %s\n"),
633 fnbuf, SSLerrmessage());
639 /* read the user key */
640 snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/postgresql.key",
642 if (stat(fnbuf, &buf) == -1)
644 printfPQExpBuffer(&conn->errorMessage,
645 libpq_gettext("certificate present, but not private key (%s)\n"),
650 if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) ||
651 buf.st_uid != getuid())
653 printfPQExpBuffer(&conn->errorMessage,
654 libpq_gettext("private key (%s) has wrong permissions\n"), fnbuf);
658 if ((fp = fopen(fnbuf, "r")) == NULL)
660 printfPQExpBuffer(&conn->errorMessage,
661 libpq_gettext("could not open private key file (%s): %s\n"),
662 fnbuf, strerror(errno));
666 if (fstat(fileno(fp), &buf2) == -1 ||
667 buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
669 printfPQExpBuffer(&conn->errorMessage,
670 libpq_gettext("private key (%s) changed during execution\n"), fnbuf);
674 if (PEM_read_PrivateKey(fp, pkey, cb, NULL) == NULL)
676 printfPQExpBuffer(&conn->errorMessage,
677 libpq_gettext("could not read private key (%s): %s\n"),
678 fnbuf, SSLerrmessage());
685 /* verify that the cert and key go together */
686 if (!X509_check_private_key(*x509, *pkey))
688 printfPQExpBuffer(&conn->errorMessage,
689 libpq_gettext("certificate/private key mismatch (%s): %s\n"),
690 fnbuf, SSLerrmessage());
692 EVP_PKEY_free(*pkey);
700 * Initialize global SSL context.
703 initialize_SSL(PGconn *conn)
712 SSL_load_error_strings();
713 SSL_context = SSL_CTX_new(TLSv1_method());
716 printfPQExpBuffer(&conn->errorMessage,
717 libpq_gettext("could not create SSL context: %s\n"),
723 if ((pwd = getpwuid(getuid())) != NULL)
725 snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/root.crt",
727 if (stat(fnbuf, &buf) == -1)
729 printfPQExpBuffer(&conn->errorMessage,
730 libpq_gettext("could not read root certificate list (%s): %s\n"),
731 fnbuf, strerror(errno));
734 if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, 0))
736 printfPQExpBuffer(&conn->errorMessage,
737 libpq_gettext("could not read root certificate list (%s): %s\n"),
738 fnbuf, SSLerrmessage());
743 SSL_CTX_set_verify(SSL_context,
744 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);
745 SSL_CTX_set_verify_depth(SSL_context, 1);
747 /* set up empheral DH keys */
748 SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
749 SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE);
751 /* set up mechanism to provide client certificate, if available */
752 SSL_CTX_set_client_cert_cb(SSL_context, client_cert_cb);
758 * Destroy global SSL context.
765 SSL_CTX_free(SSL_context);
771 * Attempt to negotiate SSL connection.
774 open_client_SSL(PGconn *conn)
778 if (!(conn->ssl = SSL_new(SSL_context)) ||
779 !SSL_set_app_data(conn->ssl, conn) ||
780 !SSL_set_fd(conn->ssl, conn->sock) ||
781 SSL_connect(conn->ssl) <= 0)
783 printfPQExpBuffer(&conn->errorMessage,
784 libpq_gettext("could not establish SSL connection: %s\n"),
790 /* check the certificate chain of the server */
793 * this eliminates simple man-in-the-middle attacks and simple
796 r = SSL_get_verify_result(conn->ssl);
799 printfPQExpBuffer(&conn->errorMessage,
800 libpq_gettext("certificate could not be validated: %s\n"),
801 X509_verify_cert_error_string(r));
806 /* pull out server distinguished and common names */
807 conn->peer = SSL_get_peer_certificate(conn->ssl);
808 if (conn->peer == NULL)
810 printfPQExpBuffer(&conn->errorMessage,
811 libpq_gettext("certificate could not be obtained: %s\n"),
817 X509_NAME_oneline(X509_get_subject_name(conn->peer),
818 conn->peer_dn, sizeof(conn->peer_dn));
819 conn->peer_dn[sizeof(conn->peer_dn) - 1] = '\0';
821 X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
822 NID_commonName, conn->peer_cn, SM_USER);
823 conn->peer_cn[SM_USER] = '\0';
825 /* verify that the common name resolves to peer */
828 * this is necessary to eliminate man-in-the-middle attacks and
829 * impersonations where the attacker somehow learned the server's
832 if (verify_peer(conn) == -1)
842 * Close SSL connection.
845 close_SSL(PGconn *conn)
849 SSL_shutdown(conn->ssl);
856 * Obtain reason string for last SSL error
858 * Some caution is needed here since ERR_reason_error_string will
859 * return NULL if it doesn't recognize the error code. We don't
860 * want to return NULL ever.
865 unsigned long errcode;
866 const char *errreason;
867 static char errbuf[32];
869 errcode = ERR_get_error();
871 return "No SSL error reported";
872 errreason = ERR_reason_error_string(errcode);
873 if (errreason != NULL)
875 snprintf(errbuf, sizeof(errbuf), "SSL error code %lu", errcode);
880 * Return pointer to SSL object.
883 PQgetssl(PGconn *conn)