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-2001, 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.2 2002/06/14 04:31:49 momjian 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 * secure_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 secure_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.
56 * The code currently assumes a POSIX password entry. How should
57 * Windows and Mac users be handled?
60 * milestone 1: fix basic coding errors
61 * [*] existing SSL code pulled out of existing files.
62 * [*] SSL_get_error() after SSL_read() and SSL_write(),
63 * SSL_shutdown(), default to TLSv1.
65 * milestone 2: provide endpoint authentication (server)
66 * [*] client verifies server cert
67 * [*] client verifies server hostname
69 * milestone 3: improve confidentially, support perfect forward secrecy
70 * [ ] use 'random' file, read from '/dev/urandom?'
71 * [*] emphermal DH keys, default values
73 * milestone 4: provide endpoint authentication (client)
74 * [ ] server verifies client certificates
76 * milestone 5: provide informational callbacks
77 * [ ] provide informational callbacks
81 * [ ] more informative psql
83 *-------------------------------------------------------------------------
86 #include "postgres_fe.h"
88 #include <sys/types.h>
96 #include "libpq-int.h"
103 #include <sys/socket.h>
106 #include <netinet/in.h>
107 #ifdef HAVE_NETINET_TCP_H
108 #include <netinet/tcp.h>
110 #include <arpa/inet.h>
118 #include <sys/stat.h>
121 #include <openssl/ssl.h>
122 #include <openssl/e_os.h>
125 int secure_initialize(PGconn *);
126 void secure_destroy(void);
127 int secure_open_client(PGconn *);
128 void secure_close(PGconn *);
129 ssize_t secure_read(PGconn *, void *ptr, size_t len);
130 ssize_t secure_write(PGconn *, const void *ptr, size_t len);
133 static int verify_cb(int ok, X509_STORE_CTX *ctx);
134 static int verify_peer(PGconn *);
135 static DH *load_dh_file(int keylength);
136 static DH *load_dh_buffer(const char *, size_t);
137 static DH *tmp_dh_cb(SSL *s, int is_export, int keylength);
138 static int initialize_SSL(PGconn *);
139 static void destroy_SSL(void);
140 static int open_client_SSL(PGconn *);
141 static void close_SSL(PGconn *);
142 static const char *SSLerrmessage(void);
146 static SSL_CTX *SSL_context = NULL;
149 /* ------------------------------------------------------------ */
150 /* Hardcoded values */
151 /* ------------------------------------------------------------ */
154 * Hardcoded DH parameters, used in empheral DH keying.
155 * As discussed above, EDH protects the confidentiality of
156 * sessions even if the static private key is compromised,
157 * so we are *highly* motivated to ensure that we can use
158 * EDH even if the user... or an attacker... deletes the
159 * $HOME/.postgresql/dh*.pem files.
161 * It's not critical that users have EPH keys, but it doesn't
162 * hurt and if it's missing someone will demand it, so....
164 static const char file_dh512[] =
165 "-----BEGIN DH PARAMETERS-----\n\
166 MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak\n\
167 XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC\n\
168 -----END DH PARAMETERS-----\n";
170 static const char file_dh1024[] =
171 "-----BEGIN DH PARAMETERS-----\n\
172 MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY\n\
173 jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6\n\
174 ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC\n\
175 -----END DH PARAMETERS-----\n";
177 static const char file_dh2048[] =
178 "-----BEGIN DH PARAMETERS-----\n\
179 MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\
180 89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50\n\
181 T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb\n\
182 zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX\n\
183 Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\
184 CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\
185 -----END DH PARAMETERS-----\n";
187 static const char file_dh4096[] =
188 "-----BEGIN DH PARAMETERS-----\n\
189 MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ\n\
190 l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt\n\
191 Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS\n\
192 Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98\n\
193 VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc\n\
194 alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM\n\
195 sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9\n\
196 ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte\n\
197 OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH\n\
198 AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL\n\
199 KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
200 -----END DH PARAMETERS-----\n";
202 /* ------------------------------------------------------------ */
203 /* Procedures common to all secure sessions */
204 /* ------------------------------------------------------------ */
207 * Initialize global context
210 secure_initialize (PGconn *conn)
215 r = initialize_SSL(conn);
222 * Destroy global context
225 secure_destroy (void)
233 * Attempt to negotiate secure session.
236 secure_open_client (PGconn *conn)
241 r = open_client_SSL(conn);
248 * Close secure session.
251 secure_close (PGconn *conn)
260 * Read data from a secure connection.
263 secure_read (PGconn *conn, void *ptr, size_t len)
270 n = SSL_read(conn->ssl, ptr, len);
271 switch (SSL_get_error(conn->ssl, n))
275 case SSL_ERROR_WANT_READ:
277 case SSL_ERROR_SYSCALL:
278 SOCK_ERRNO = get_last_socket_error();
279 printfPQExpBuffer(&conn->errorMessage,
280 libpq_gettext("SSL SYSCALL error: %s\n"),
281 SOCK_STRERROR(SOCK_ERRNO));
284 printfPQExpBuffer(&conn->errorMessage,
285 libpq_gettext("SSL error: %s\n"), SSLerrmessage());
287 case SSL_ERROR_ZERO_RETURN:
289 SOCK_ERRNO = ECONNRESET;
296 n = recv(conn->sock, ptr, len, 0);
302 * Write data to a secure connection.
305 secure_write (PGconn *conn, const void *ptr, size_t len)
310 pqsigfunc oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
316 n = SSL_write(conn->ssl, ptr, len);
317 switch (SSL_get_error(conn->ssl, n))
321 case SSL_ERROR_WANT_WRITE:
323 case SSL_ERROR_SYSCALL:
324 SOCK_ERRNO = get_last_socket_error();
325 printfPQExpBuffer(&conn->errorMessage,
326 libpq_gettext("SSL SYSCALL error: %s\n"),
327 SOCK_STRERROR(SOCK_ERRNO));
330 printfPQExpBuffer(&conn->errorMessage,
331 libpq_gettext("SSL error: %s\n"), SSLerrmessage());
333 case SSL_ERROR_ZERO_RETURN:
335 SOCK_ERRNO = ECONNRESET;
342 n = send(conn->sock, ptr, len, 0);
345 pqsignal(SIGPIPE, oldsighandler);
351 /* ------------------------------------------------------------ */
352 /* SSL specific code */
353 /* ------------------------------------------------------------ */
356 * Certificate verification callback
358 * This callback allows us to log intermediate problems during
359 * verification, but there doesn't seem to be a clean way to get
360 * our PGconn * structure. So we can't log anything!
362 * This callback also allows us to override the default acceptance
363 * criteria (e.g., accepting self-signed or expired certs), but
364 * for now we accept the default checks.
367 verify_cb (int ok, X509_STORE_CTX *ctx)
373 * Verify that common name resolves to peer.
374 * This function is not thread-safe due to gethostbyname2().
377 verify_peer (PGconn *conn)
379 struct hostent *h = NULL;
380 struct sockaddr addr;
381 struct sockaddr_in *sin;
382 struct sockaddr_in6 *sin6;
387 /* get the address on the other side of the socket */
389 if (getpeername(conn->sock, &addr, &len) == -1)
391 printfPQExpBuffer(&conn->errorMessage,
392 libpq_gettext("error querying socket: %s\n"),
393 SOCK_STRERROR(SOCK_ERRNO));
397 /* weird, but legal case */
398 if (addr.sa_family == AF_UNIX)
401 /* what do we know about the peer's common name? */
402 if ((h = gethostbyname2(conn->peer_cn, addr.sa_family)) == NULL)
404 printfPQExpBuffer(&conn->errorMessage,
405 libpq_gettext("error getting information about host (%s): %s\n"),
406 conn->peer_cn, hstrerror(h_errno));
410 /* does the address match? */
411 switch (addr.sa_family)
414 sin = (struct sockaddr_in *) &addr;
415 for (s = h->h_addr_list; *s != NULL; s++)
417 if (!memcmp(&sin->sin_addr.s_addr, *s, h->h_length))
423 sin6 = (struct sockaddr_in6 *) &addr;
424 for (s = h->h_addr_list; *s != NULL; s++)
426 if (!memcmp(sin6->sin6_addr.in6_u.u6_addr8, *s, h->h_length))
432 printfPQExpBuffer(&conn->errorMessage,
433 libpq_gettext("sorry, this protocol not yet supported\n"));
437 /* the prior test should be definitive, but in practice
438 * it sometimes fails. So we also check the aliases. */
439 for (s = h->h_aliases; *s != NULL; s++)
441 if (strcasecmp(conn->peer_cn, *s) == 0)
445 /* generate protocol-aware error message */
446 switch (addr.sa_family)
449 sin = (struct sockaddr_in *) &addr;
450 l = ntohl(sin->sin_addr.s_addr);
451 printfPQExpBuffer(&conn->errorMessage,
453 "server common name '%s' does not resolve to %ld.%ld.%ld.%ld\n"),
454 conn->peer_cn, (l >> 24) % 0x100, (l >> 16) % 0x100,
455 (l >> 8) % 0x100, l % 0x100);
458 printfPQExpBuffer(&conn->errorMessage,
460 "server common name '%s' does not resolve to peer address\n"),
468 * Load precomputed DH parameters.
470 * To prevent "downgrade" attacks, we perform a number of checks
471 * to verify that the DBA-generated DH parameters file contains
472 * what we expect it to contain.
475 load_dh_file (int keylength)
483 if ((pwd = getpwuid(getuid())) == NULL)
486 /* attempt to open file. It's not an error if it doesn't exist. */
487 snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/dh%d.pem",
488 pwd->pw_dir, keylength);
489 if ((fp = fopen(fnbuf, "r")) == NULL)
492 /* flock(fileno(fp), LOCK_SH); */
493 dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
494 /* flock(fileno(fp), LOCK_UN); */
497 /* is the prime the correct size? */
498 if (dh != NULL && 8*DH_size(dh) < keylength)
503 /* make sure the DH parameters are usable */
506 if (DH_check(dh, &codes))
510 if (codes & DH_CHECK_P_NOT_PRIME)
514 if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
515 (codes & DH_CHECK_P_NOT_SAFE_PRIME))
525 * Load hardcoded DH parameters.
527 * To prevent problems if the DH parameters files don't even
528 * exist, we can load DH parameters hardcoded into this file.
531 load_dh_buffer (const char *buffer, size_t len)
536 bio = BIO_new_mem_buf((char *) buffer, len);
539 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
546 * Generate an empheral DH key. Because this can take a long
547 * time to compute, we can use precomputed parameters of the
550 * Since few sites will bother to precompute these parameter
551 * files, we also provide a fallback to the parameters provided
552 * by the OpenSSL project.
554 * These values can be static (once loaded or computed) since
555 * the OpenSSL library can efficiently generate random keys from
556 * the information provided.
559 tmp_dh_cb (SSL *s, int is_export, int keylength)
562 static DH *dh = NULL;
563 static DH *dh512 = NULL;
564 static DH *dh1024 = NULL;
565 static DH *dh2048 = NULL;
566 static DH *dh4096 = NULL;
572 dh512 = load_dh_file(keylength);
574 dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
580 dh1024 = load_dh_file(keylength);
582 dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
588 dh2048 = load_dh_file(keylength);
590 dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
596 dh4096 = load_dh_file(keylength);
598 dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
604 dh = load_dh_file(keylength);
608 /* this may take a long time, but it may be necessary... */
609 if (r == NULL || 8*DH_size(r) < keylength)
611 r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
618 * Initialize global SSL context.
621 initialize_SSL (PGconn *conn)
630 SSL_load_error_strings();
631 SSL_context = SSL_CTX_new(TLSv1_method());
634 printfPQExpBuffer(&conn->errorMessage,
635 libpq_gettext("could not create SSL context: %s\n"),
641 if ((pwd = getpwuid(getuid())) != NULL)
643 snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/root.crt",
645 if (stat(fnbuf, &buf) == -1)
647 printfPQExpBuffer(&conn->errorMessage,
648 libpq_gettext("could not read root cert list(%s): %s"),
649 fnbuf, strerror(errno));
652 if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, 0))
654 printfPQExpBuffer(&conn->errorMessage,
655 libpq_gettext("could not read root cert list (%s): %s"),
656 fnbuf, SSLerrmessage());
661 SSL_CTX_set_verify(SSL_context,
662 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);
663 SSL_CTX_set_verify_depth(SSL_context, 1);
665 /* set up empheral DH keys */
666 SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
667 SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE);
673 * Destroy global SSL context.
680 SSL_CTX_free(SSL_context);
686 * Attempt to negotiate SSL connection.
689 open_client_SSL (PGconn *conn)
693 if (!(conn->ssl = SSL_new(SSL_context)) ||
694 !SSL_set_fd(conn->ssl, conn->sock) ||
695 SSL_connect(conn->ssl) <= 0)
697 printfPQExpBuffer(&conn->errorMessage,
698 libpq_gettext("could not establish SSL connection: %s\n"),
704 /* check the certificate chain of the server */
705 /* this eliminates simple man-in-the-middle attacks and
706 * simple impersonations */
707 r = SSL_get_verify_result(conn->ssl);
710 printfPQExpBuffer(&conn->errorMessage,
711 libpq_gettext("certificate could not be validated: %s\n"),
712 X509_verify_cert_error_string(r));
717 /* pull out server distinguished and common names */
718 conn->peer = SSL_get_peer_certificate(conn->ssl);
719 if (conn->peer == NULL)
721 printfPQExpBuffer(&conn->errorMessage,
722 libpq_gettext("certificate could not be obtained: %s\n"),
728 X509_NAME_oneline(X509_get_subject_name(conn->peer),
729 conn->peer_dn, sizeof(conn->peer_dn));
730 conn->peer_dn[sizeof(conn->peer_dn)-1] = '\0';
732 X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
733 NID_commonName, conn->peer_cn, SM_USER);
734 conn->peer_cn[SM_USER] = '\0';
736 /* verify that the common name resolves to peer */
737 /* this is necessary to eliminate man-in-the-middle attacks
738 * and impersonations where the attacker somehow learned
739 * the server's private key */
740 if (verify_peer(conn) == -1)
750 * Close SSL connection.
753 close_SSL (PGconn *conn)
757 SSL_shutdown(conn->ssl);
764 * Obtain reason string for last SSL error
766 * Some caution is needed here since ERR_reason_error_string will
767 * return NULL if it doesn't recognize the error code. We don't
768 * want to return NULL ever.
773 unsigned long errcode;
774 const char *errreason;
775 static char errbuf[32];
777 errcode = ERR_get_error();
779 return "No SSL error reported";
780 errreason = ERR_reason_error_string(errcode);
781 if (errreason != NULL)
783 snprintf(errbuf, sizeof(errbuf), "SSL error code %lu", errcode);
788 * Return pointer to SSL object.
791 PQgetssl(PGconn *conn)