Branch data Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * fe-secure-openssl.c
4 : : * OpenSSL support
5 : : *
6 : : *
7 : : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
8 : : * Portions Copyright (c) 1994, Regents of the University of California
9 : : *
10 : : *
11 : : * IDENTIFICATION
12 : : * src/interfaces/libpq/fe-secure-openssl.c
13 : : *
14 : : * NOTES
15 : : *
16 : : * We don't provide informational callbacks here (like
17 : : * info_cb() in be-secure-openssl.c), since there's no good mechanism to
18 : : * display such information to the user.
19 : : *
20 : : *-------------------------------------------------------------------------
21 : : */
22 : :
23 : : #include "postgres_fe.h"
24 : :
25 : : #include <signal.h>
26 : : #include <fcntl.h>
27 : : #include <ctype.h>
28 : : #include <limits.h>
29 : :
30 : : #include "libpq-fe.h"
31 : : #include "fe-auth.h"
32 : : #include "fe-secure-common.h"
33 : : #include "libpq-int.h"
34 : :
35 : : #ifdef WIN32
36 : : #include "win32.h"
37 : : #else
38 : : #include <sys/socket.h>
39 : : #include <unistd.h>
40 : : #include <netdb.h>
41 : : #include <netinet/in.h>
42 : : #include <netinet/tcp.h>
43 : : #include <arpa/inet.h>
44 : : #endif
45 : :
46 : : #include <sys/stat.h>
47 : :
48 : : #ifdef WIN32
49 : : #include "pthread-win32.h"
50 : : #else
51 : : #include <pthread.h>
52 : : #endif
53 : :
54 : : /*
55 : : * These SSL-related #includes must come after all system-provided headers.
56 : : * This ensures that OpenSSL can take care of conflicts with Windows'
57 : : * <wincrypt.h> by #undef'ing the conflicting macros. (We don't directly
58 : : * include <wincrypt.h>, but some other Windows headers do.)
59 : : */
60 : : #include "common/openssl.h"
61 : : #include <openssl/ssl.h>
62 : : #include <openssl/conf.h>
63 : : #ifdef USE_SSL_ENGINE
64 : : #include <openssl/engine.h>
65 : : #endif
66 : : #include <openssl/x509v3.h>
67 : :
68 : :
69 : : static int verify_cb(int ok, X509_STORE_CTX *ctx);
70 : : static int openssl_verify_peer_name_matches_certificate_name(PGconn *conn,
71 : : const ASN1_STRING *name_entry,
72 : : char **store_name);
73 : : static int openssl_verify_peer_name_matches_certificate_ip(PGconn *conn,
74 : : ASN1_OCTET_STRING *addr_entry,
75 : : char **store_name);
76 : : static int initialize_SSL(PGconn *conn);
77 : : static PostgresPollingStatusType open_client_SSL(PGconn *conn);
78 : : static char *SSLerrmessage(unsigned long ecode);
79 : : static void SSLerrfree(char *buf);
80 : : static int PQssl_passwd_cb(char *buf, int size, int rwflag, void *userdata);
81 : :
82 : : static int pgconn_bio_read(BIO *h, char *buf, int size);
83 : : static int pgconn_bio_write(BIO *h, const char *buf, int size);
84 : : static BIO_METHOD *pgconn_bio_method(void);
85 : : static int ssl_set_pgconn_bio(PGconn *conn);
86 : :
87 : : static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER;
88 : :
89 : : static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL;
90 : : static int ssl_protocol_version_to_openssl(const char *protocol);
91 : :
92 : : /* ------------------------------------------------------------ */
93 : : /* Procedures common to all secure sessions */
94 : : /* ------------------------------------------------------------ */
95 : :
96 : : PostgresPollingStatusType
97 : 306 : pgtls_open_client(PGconn *conn)
98 : : {
99 : : /* First time through? */
100 [ + + ]: 306 : if (conn->ssl == NULL)
101 : : {
102 : : /*
103 : : * Create a connection-specific SSL object, and load client
104 : : * certificate, private key, and trusted CA certs.
105 : : */
106 [ + + ]: 174 : if (initialize_SSL(conn) != 0)
107 : : {
108 : : /* initialize_SSL already put a message in conn->errorMessage */
109 : 5 : pgtls_close(conn);
110 : 5 : return PGRES_POLLING_FAILED;
111 : : }
112 : : }
113 : :
114 : : /* Begin or continue the actual handshake */
115 : 301 : return open_client_SSL(conn);
116 : : }
117 : :
118 : : ssize_t
119 : 368 : pgtls_read(PGconn *conn, void *ptr, size_t len)
120 : : {
121 : : ssize_t n;
122 : 368 : int result_errno = 0;
123 : : char sebuf[PG_STRERROR_R_BUFLEN];
124 : : int err;
125 : : unsigned long ecode;
126 : :
127 : 368 : rloop:
128 : :
129 : : /*
130 : : * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
131 : : * queue. In general, the current thread's error queue must be empty
132 : : * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
133 : : * not work reliably. Since the possibility exists that other OpenSSL
134 : : * clients running in the same thread but not under our control will fail
135 : : * to call ERR_get_error() themselves (after their own I/O operations),
136 : : * pro-actively clear the per-thread error queue now.
137 : : */
138 : 368 : SOCK_ERRNO_SET(0);
139 : 368 : ERR_clear_error();
140 : 368 : n = SSL_read(conn->ssl, ptr, len);
141 : 368 : err = SSL_get_error(conn->ssl, n);
142 : :
143 : : /*
144 : : * Other clients of OpenSSL may fail to call ERR_get_error(), but we
145 : : * always do, so as to not cause problems for OpenSSL clients that don't
146 : : * call ERR_clear_error() defensively. Be sure that this happens by
147 : : * calling now. SSL_get_error() relies on the OpenSSL per-thread error
148 : : * queue being intact, so this is the earliest possible point
149 : : * ERR_get_error() may be called.
150 : : */
151 [ + + - + ]: 368 : ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
152 [ + + - - : 368 : switch (err)
+ - - ]
153 : : {
154 : 250 : case SSL_ERROR_NONE:
155 [ - + ]: 250 : if (n < 0)
156 : : {
157 : : /* Not supposed to happen, so we don't translate the msg */
158 : 0 : appendPQExpBufferStr(&conn->errorMessage,
159 : : "SSL_read failed but did not provide error information\n");
160 : : /* assume the connection is broken */
161 : 0 : result_errno = ECONNRESET;
162 : : }
163 : 250 : break;
164 : 109 : case SSL_ERROR_WANT_READ:
165 : 109 : n = 0;
166 : 109 : break;
167 : 0 : case SSL_ERROR_WANT_WRITE:
168 : :
169 : : /*
170 : : * Returning 0 here would cause caller to wait for read-ready,
171 : : * which is not correct since what SSL wants is wait for
172 : : * write-ready. The former could get us stuck in an infinite
173 : : * wait, so don't risk it; busy-loop instead.
174 : : */
175 : 0 : goto rloop;
176 : 0 : case SSL_ERROR_SYSCALL:
177 [ # # # # ]: 0 : if (n < 0 && SOCK_ERRNO != 0)
178 : : {
179 : 0 : result_errno = SOCK_ERRNO;
180 [ # # # # ]: 0 : if (result_errno == EPIPE ||
181 : : result_errno == ECONNRESET)
182 : 0 : libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
183 : : "\tThis probably means the server terminated abnormally\n"
184 : : "\tbefore or while processing the request.");
185 : : else
186 : 0 : libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
187 : : SOCK_STRERROR(result_errno,
188 : : sebuf, sizeof(sebuf)));
189 : : }
190 : : else
191 : : {
192 : 0 : libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
193 : : /* assume the connection is broken */
194 : 0 : result_errno = ECONNRESET;
195 : 0 : n = -1;
196 : : }
197 : 0 : break;
198 : 9 : case SSL_ERROR_SSL:
199 : : {
200 : 9 : char *errm = SSLerrmessage(ecode);
201 : :
202 : 9 : libpq_append_conn_error(conn, "SSL error: %s", errm);
203 : 9 : SSLerrfree(errm);
204 : : /* assume the connection is broken */
205 : 9 : result_errno = ECONNRESET;
206 : 9 : n = -1;
207 : 9 : break;
208 : : }
209 : 0 : case SSL_ERROR_ZERO_RETURN:
210 : :
211 : : /*
212 : : * Per OpenSSL documentation, this error code is only returned for
213 : : * a clean connection closure, so we should not report it as a
214 : : * server crash.
215 : : */
216 : 0 : libpq_append_conn_error(conn, "SSL connection has been closed unexpectedly");
217 : 0 : result_errno = ECONNRESET;
218 : 0 : n = -1;
219 : 0 : break;
220 : 0 : default:
221 : 0 : libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
222 : : /* assume the connection is broken */
223 : 0 : result_errno = ECONNRESET;
224 : 0 : n = -1;
225 : 0 : break;
226 : : }
227 : :
228 : : /* ensure we return the intended errno to caller */
229 : 368 : SOCK_ERRNO_SET(result_errno);
230 : :
231 : 368 : return n;
232 : : }
233 : :
234 : : ssize_t
235 : 641 : pgtls_bytes_pending(PGconn *conn)
236 : : {
237 : : int pending;
238 : :
239 : : /*
240 : : * OpenSSL readahead is documented to break SSL_pending(). Plus, we can't
241 : : * afford to have OpenSSL take bytes off the socket without processing
242 : : * them; that breaks the postconditions for pqsecure_drain_pending().
243 : : */
244 : : Assert(!SSL_get_read_ahead(conn->ssl));
245 : :
246 : 641 : pending = SSL_pending(conn->ssl);
247 [ - + ]: 641 : if (pending < 0)
248 : : {
249 : : /* shouldn't be possible */
250 : : Assert(false);
251 : 0 : libpq_append_conn_error(conn, "OpenSSL reports negative bytes pending");
252 : 0 : return -1;
253 : : }
254 [ - + ]: 641 : else if (pending == INT_MAX)
255 : : {
256 : : /*
257 : : * If we ever found a legitimate way to hit this, we'd need to loop
258 : : * around in the caller to call pgtls_bytes_pending() again. Throw an
259 : : * error rather than complicate the code in that way, because
260 : : * SSL_read() should be bounded to the size of a single TLS record,
261 : : * and conn->inBuffer can't currently go past INT_MAX in size anyway.
262 : : */
263 : 0 : libpq_append_conn_error(conn, "OpenSSL reports INT_MAX bytes pending");
264 : 0 : return -1;
265 : : }
266 : :
267 : 641 : return (ssize_t) pending;
268 : : }
269 : :
270 : : ssize_t
271 : 367 : pgtls_write(PGconn *conn, const void *ptr, size_t len)
272 : : {
273 : : ssize_t n;
274 : 367 : int result_errno = 0;
275 : : char sebuf[PG_STRERROR_R_BUFLEN];
276 : : int err;
277 : : unsigned long ecode;
278 : :
279 : 367 : SOCK_ERRNO_SET(0);
280 : 367 : ERR_clear_error();
281 : 367 : n = SSL_write(conn->ssl, ptr, len);
282 : 367 : err = SSL_get_error(conn->ssl, n);
283 [ + - - + ]: 367 : ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
284 [ + - - - : 367 : switch (err)
- - - ]
285 : : {
286 : 367 : case SSL_ERROR_NONE:
287 [ - + ]: 367 : if (n < 0)
288 : : {
289 : : /* Not supposed to happen, so we don't translate the msg */
290 : 0 : appendPQExpBufferStr(&conn->errorMessage,
291 : : "SSL_write failed but did not provide error information\n");
292 : : /* assume the connection is broken */
293 : 0 : result_errno = ECONNRESET;
294 : : }
295 : 367 : break;
296 : 0 : case SSL_ERROR_WANT_READ:
297 : :
298 : : /*
299 : : * Returning 0 here causes caller to wait for write-ready, which
300 : : * is not really the right thing, but it's the best we can do.
301 : : */
302 : 0 : n = 0;
303 : 0 : break;
304 : 0 : case SSL_ERROR_WANT_WRITE:
305 : 0 : n = 0;
306 : 0 : break;
307 : 0 : case SSL_ERROR_SYSCALL:
308 : :
309 : : /*
310 : : * If errno is still zero then assume it's a read EOF situation,
311 : : * and report EOF. (This seems possible because SSL_write can
312 : : * also do reads.)
313 : : */
314 [ # # # # ]: 0 : if (n < 0 && SOCK_ERRNO != 0)
315 : : {
316 : 0 : result_errno = SOCK_ERRNO;
317 [ # # # # ]: 0 : if (result_errno == EPIPE || result_errno == ECONNRESET)
318 : 0 : libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
319 : : "\tThis probably means the server terminated abnormally\n"
320 : : "\tbefore or while processing the request.");
321 : : else
322 : 0 : libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
323 : : SOCK_STRERROR(result_errno,
324 : : sebuf, sizeof(sebuf)));
325 : : }
326 : : else
327 : : {
328 : 0 : libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
329 : : /* assume the connection is broken */
330 : 0 : result_errno = ECONNRESET;
331 : 0 : n = -1;
332 : : }
333 : 0 : break;
334 : 0 : case SSL_ERROR_SSL:
335 : : {
336 : 0 : char *errm = SSLerrmessage(ecode);
337 : :
338 : 0 : libpq_append_conn_error(conn, "SSL error: %s", errm);
339 : 0 : SSLerrfree(errm);
340 : : /* assume the connection is broken */
341 : 0 : result_errno = ECONNRESET;
342 : 0 : n = -1;
343 : 0 : break;
344 : : }
345 : 0 : case SSL_ERROR_ZERO_RETURN:
346 : :
347 : : /*
348 : : * Per OpenSSL documentation, this error code is only returned for
349 : : * a clean connection closure, so we should not report it as a
350 : : * server crash.
351 : : */
352 : 0 : libpq_append_conn_error(conn, "SSL connection has been closed unexpectedly");
353 : 0 : result_errno = ECONNRESET;
354 : 0 : n = -1;
355 : 0 : break;
356 : 0 : default:
357 : 0 : libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
358 : : /* assume the connection is broken */
359 : 0 : result_errno = ECONNRESET;
360 : 0 : n = -1;
361 : 0 : break;
362 : : }
363 : :
364 : : /* ensure we return the intended errno to caller */
365 : 367 : SOCK_ERRNO_SET(result_errno);
366 : :
367 : 367 : return n;
368 : : }
369 : :
370 : : char *
371 : 5 : pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len)
372 : : {
373 : : X509 *peer_cert;
374 : : const EVP_MD *algo_type;
375 : : unsigned char hash[EVP_MAX_MD_SIZE]; /* size for SHA-512 */
376 : : unsigned int hash_size;
377 : : int algo_nid;
378 : : char *cert_hash;
379 : :
380 : 5 : *len = 0;
381 : :
382 [ - + ]: 5 : if (!conn->peer)
383 : 0 : return NULL;
384 : :
385 : 5 : peer_cert = conn->peer;
386 : :
387 : : /*
388 : : * Get the signature algorithm of the certificate to determine the hash
389 : : * algorithm to use for the result. Prefer X509_get_signature_info(),
390 : : * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
391 : : */
392 : : #if HAVE_X509_GET_SIGNATURE_INFO
393 [ - + ]: 5 : if (!X509_get_signature_info(peer_cert, &algo_nid, NULL, NULL, NULL))
394 : : #else
395 : : if (!OBJ_find_sigid_algs(X509_get_signature_nid(peer_cert),
396 : : &algo_nid, NULL))
397 : : #endif
398 : : {
399 : 0 : libpq_append_conn_error(conn, "could not determine server certificate signature algorithm");
400 : 0 : return NULL;
401 : : }
402 : :
403 : : /*
404 : : * The TLS server's certificate bytes need to be hashed with SHA-256 if
405 : : * its signature algorithm is MD5 or SHA-1 as per RFC 5929
406 : : * (https://tools.ietf.org/html/rfc5929#section-4.1). If something else
407 : : * is used, the same hash as the signature algorithm is used.
408 : : */
409 [ - + ]: 5 : switch (algo_nid)
410 : : {
411 : 0 : case NID_md5:
412 : : case NID_sha1:
413 : 0 : algo_type = EVP_sha256();
414 : 0 : break;
415 : 5 : default:
416 : 5 : algo_type = EVP_get_digestbynid(algo_nid);
417 [ - + ]: 5 : if (algo_type == NULL)
418 : : {
419 : 0 : libpq_append_conn_error(conn, "could not find digest for NID %s",
420 : : OBJ_nid2sn(algo_nid));
421 : 0 : return NULL;
422 : : }
423 : 5 : break;
424 : : }
425 : :
426 [ - + ]: 5 : if (!X509_digest(peer_cert, algo_type, hash, &hash_size))
427 : : {
428 : 0 : libpq_append_conn_error(conn, "could not generate peer certificate hash");
429 : 0 : return NULL;
430 : : }
431 : :
432 : : /* save result */
433 : 5 : cert_hash = malloc(hash_size);
434 [ - + ]: 5 : if (cert_hash == NULL)
435 : : {
436 : 0 : libpq_append_conn_error(conn, "out of memory");
437 : 0 : return NULL;
438 : : }
439 : 5 : memcpy(cert_hash, hash, hash_size);
440 : 5 : *len = hash_size;
441 : :
442 : 5 : return cert_hash;
443 : : }
444 : :
445 : : /* ------------------------------------------------------------ */
446 : : /* OpenSSL specific code */
447 : : /* ------------------------------------------------------------ */
448 : :
449 : : /*
450 : : * Certificate verification callback
451 : : *
452 : : * This callback allows us to log intermediate problems during
453 : : * verification, but there doesn't seem to be a clean way to get
454 : : * our PGconn * structure. So we can't log anything!
455 : : *
456 : : * This callback also allows us to override the default acceptance
457 : : * criteria (e.g., accepting self-signed or expired certs), but
458 : : * for now we accept the default checks.
459 : : */
460 : : static int
461 : 357 : verify_cb(int ok, X509_STORE_CTX *ctx)
462 : : {
463 : 357 : return ok;
464 : : }
465 : :
466 : : #ifdef HAVE_SSL_CTX_SET_CERT_CB
467 : : /*
468 : : * Certificate selection callback
469 : : *
470 : : * This callback lets us choose the client certificate we send to the server
471 : : * after seeing its CertificateRequest. We only support sending a single
472 : : * hard-coded certificate via sslcert, so we don't actually set any certificates
473 : : * here; we just use it to record whether or not the server has actually asked
474 : : * for one and whether we have one to send.
475 : : */
476 : : static int
477 : 133 : cert_cb(SSL *ssl, void *arg)
478 : : {
479 : 133 : PGconn *conn = arg;
480 : :
481 : 133 : conn->ssl_cert_requested = true;
482 : :
483 : : /* Do we have a certificate loaded to send back? */
484 [ + + ]: 133 : if (SSL_get_certificate(ssl))
485 : 41 : conn->ssl_cert_sent = true;
486 : :
487 : : /*
488 : : * Tell OpenSSL that the callback succeeded; we're not required to
489 : : * actually make any changes to the SSL handle.
490 : : */
491 : 133 : return 1;
492 : : }
493 : : #endif
494 : :
495 : : /*
496 : : * OpenSSL-specific wrapper around
497 : : * pq_verify_peer_name_matches_certificate_name(), converting the ASN1_STRING
498 : : * into a plain C string.
499 : : */
500 : : static int
501 : 34 : openssl_verify_peer_name_matches_certificate_name(PGconn *conn,
502 : : const ASN1_STRING *name_entry,
503 : : char **store_name)
504 : : {
505 : : int len;
506 : : const unsigned char *namedata;
507 : :
508 : : /* Should not happen... */
509 [ - + ]: 34 : if (name_entry == NULL)
510 : : {
511 : 0 : libpq_append_conn_error(conn, "SSL certificate's name entry is missing");
512 : 0 : return -1;
513 : : }
514 : :
515 : : /*
516 : : * GEN_DNS can be only IA5String, equivalent to US ASCII.
517 : : */
518 : 34 : namedata = ASN1_STRING_get0_data(name_entry);
519 : 34 : len = ASN1_STRING_length(name_entry);
520 : :
521 : : /* OK to cast from unsigned to plain char, since it's all ASCII. */
522 : 34 : return pq_verify_peer_name_matches_certificate_name(conn, (const char *) namedata, len, store_name);
523 : : }
524 : :
525 : : /*
526 : : * OpenSSL-specific wrapper around
527 : : * pq_verify_peer_name_matches_certificate_ip(), converting the
528 : : * ASN1_OCTET_STRING into a plain C string.
529 : : */
530 : : static int
531 : 24 : openssl_verify_peer_name_matches_certificate_ip(PGconn *conn,
532 : : ASN1_OCTET_STRING *addr_entry,
533 : : char **store_name)
534 : : {
535 : : int len;
536 : : const unsigned char *addrdata;
537 : :
538 : : /* Should not happen... */
539 [ - + ]: 24 : if (addr_entry == NULL)
540 : : {
541 : 0 : libpq_append_conn_error(conn, "SSL certificate's address entry is missing");
542 : 0 : return -1;
543 : : }
544 : :
545 : : /*
546 : : * GEN_IPADD is an OCTET STRING containing an IP address in network byte
547 : : * order.
548 : : */
549 : 24 : addrdata = ASN1_STRING_get0_data(addr_entry);
550 : 24 : len = ASN1_STRING_length(addr_entry);
551 : :
552 : 24 : return pq_verify_peer_name_matches_certificate_ip(conn, addrdata, len, store_name);
553 : : }
554 : :
555 : : static bool
556 : 36 : is_ip_address(const char *host)
557 : : {
558 : : struct in_addr dummy4;
559 : : #ifdef HAVE_INET_PTON
560 : : struct in6_addr dummy6;
561 : : #endif
562 : :
563 : 36 : return inet_aton(host, &dummy4)
564 : : #ifdef HAVE_INET_PTON
565 [ + + + + ]: 36 : || (inet_pton(AF_INET6, host, &dummy6) == 1)
566 : : #endif
567 : : ;
568 : : }
569 : :
570 : : /*
571 : : * Verify that the server certificate matches the hostname we connected to.
572 : : *
573 : : * The certificate's Common Name and Subject Alternative Names are considered.
574 : : */
575 : : int
576 : 36 : pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn,
577 : : int *names_examined,
578 : : char **first_name)
579 : : {
580 : : STACK_OF(GENERAL_NAME) * peer_san;
581 : : int i;
582 : 36 : int rc = 0;
583 : 36 : char *host = conn->connhost[conn->whichhost].host;
584 : : int host_type;
585 : 36 : bool check_cn = true;
586 : :
587 : : Assert(host && host[0]); /* should be guaranteed by caller */
588 : :
589 : : /*
590 : : * We try to match the NSS behavior here, which is a slight departure from
591 : : * the spec but seems to make more intuitive sense:
592 : : *
593 : : * If connhost contains a DNS name, and the certificate's SANs contain any
594 : : * dNSName entries, then we'll ignore the Subject Common Name entirely;
595 : : * otherwise, we fall back to checking the CN. (This behavior matches the
596 : : * RFC.)
597 : : *
598 : : * If connhost contains an IP address, and the SANs contain iPAddress
599 : : * entries, we again ignore the CN. Otherwise, we allow the CN to match,
600 : : * EVEN IF there is a dNSName in the SANs. (RFC 6125 prohibits this: "A
601 : : * client MUST NOT seek a match for a reference identifier of CN-ID if the
602 : : * presented identifiers include a DNS-ID, SRV-ID, URI-ID, or any
603 : : * application-specific identifier types supported by the client.")
604 : : *
605 : : * NOTE: Prior versions of libpq did not consider iPAddress entries at
606 : : * all, so this new behavior might break a certificate that has different
607 : : * IP addresses in the Subject CN and the SANs.
608 : : */
609 [ + + ]: 36 : if (is_ip_address(host))
610 : 16 : host_type = GEN_IPADD;
611 : : else
612 : 20 : host_type = GEN_DNS;
613 : :
614 : : /*
615 : : * First, get the Subject Alternative Names (SANs) from the certificate,
616 : : * and compare them against the originally given hostname.
617 : : */
618 : : peer_san = (STACK_OF(GENERAL_NAME) *)
619 : 36 : X509_get_ext_d2i(conn->peer, NID_subject_alt_name, NULL, NULL);
620 : :
621 [ + + ]: 36 : if (peer_san)
622 : : {
623 : 29 : int san_len = sk_GENERAL_NAME_num(peer_san);
624 : :
625 [ + + ]: 61 : for (i = 0; i < san_len; i++)
626 : : {
627 : 50 : const GENERAL_NAME *name = sk_GENERAL_NAME_value(peer_san, i);
628 : 50 : char *alt_name = NULL;
629 : :
630 [ + + ]: 50 : if (name->type == host_type)
631 : : {
632 : : /*
633 : : * This SAN is of the same type (IP or DNS) as our host name,
634 : : * so don't allow a fallback check of the CN.
635 : : */
636 : 43 : check_cn = false;
637 : : }
638 : :
639 [ + + ]: 50 : if (name->type == GEN_DNS)
640 : : {
641 : 26 : (*names_examined)++;
642 : 26 : rc = openssl_verify_peer_name_matches_certificate_name(conn,
643 : 26 : name->d.dNSName,
644 : : &alt_name);
645 : : }
646 [ + - ]: 24 : else if (name->type == GEN_IPADD)
647 : : {
648 : 24 : (*names_examined)++;
649 : 24 : rc = openssl_verify_peer_name_matches_certificate_ip(conn,
650 : 24 : name->d.iPAddress,
651 : : &alt_name);
652 : : }
653 : :
654 [ + - ]: 50 : if (alt_name)
655 : : {
656 [ + + ]: 50 : if (!*first_name)
657 : 29 : *first_name = alt_name;
658 : : else
659 : 21 : free(alt_name);
660 : : }
661 : :
662 [ + + ]: 50 : if (rc != 0)
663 : : {
664 : : /*
665 : : * Either we hit an error or a match, and either way we should
666 : : * not fall back to the CN.
667 : : */
668 : 18 : check_cn = false;
669 : 18 : break;
670 : : }
671 : : }
672 : 29 : sk_GENERAL_NAME_pop_free(peer_san, GENERAL_NAME_free);
673 : : }
674 : :
675 : : /*
676 : : * If there is no subjectAltName extension of the matching type, check the
677 : : * Common Name.
678 : : *
679 : : * (Per RFC 2818 and RFC 6125, if the subjectAltName extension of type
680 : : * dNSName is present, the CN must be ignored. We break this rule if host
681 : : * is an IP address; see the comment above.)
682 : : */
683 [ + + ]: 36 : if (check_cn)
684 : : {
685 : : const X509_NAME *subject_name;
686 : :
687 : 10 : subject_name = X509_get_subject_name(conn->peer);
688 [ + - ]: 10 : if (subject_name != NULL)
689 : : {
690 : : int cn_index;
691 : :
692 : 10 : cn_index = X509_NAME_get_index_by_NID(unconstify(X509_NAME *, subject_name),
693 : : NID_commonName, -1);
694 [ + + ]: 10 : if (cn_index >= 0)
695 : : {
696 : 8 : char *common_name = NULL;
697 : :
698 : 8 : (*names_examined)++;
699 : 8 : rc = openssl_verify_peer_name_matches_certificate_name(conn,
700 : 8 : X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, cn_index)),
701 : : &common_name);
702 : :
703 [ + - ]: 8 : if (common_name)
704 : : {
705 [ + + ]: 8 : if (!*first_name)
706 : 6 : *first_name = common_name;
707 : : else
708 : 2 : free(common_name);
709 : : }
710 : : }
711 : : }
712 : : }
713 : :
714 : 36 : return rc;
715 : : }
716 : :
717 : : /* See pqcomm.h comments on OpenSSL implementation of ALPN (RFC 7301) */
718 : : static unsigned char alpn_protos[] = PG_ALPN_PROTOCOL_VECTOR;
719 : :
720 : : #ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK
721 : : /*
722 : : * SSL Key Logging callback
723 : : *
724 : : * This callback lets the user store all key material to a file for debugging
725 : : * purposes. The file will be written using the NSS keylog format. LibreSSL
726 : : * 3.5 introduced stub function to set the callback for OpenSSL compatibility
727 : : * but the callback is never invoked.
728 : : *
729 : : * Error messages added to the connection object won't be printed anywhere if
730 : : * the connection is successful. Errors in processing keylogging are printed
731 : : * to stderr to overcome this.
732 : : */
733 : : static void
734 : 10 : SSL_CTX_keylog_cb(const SSL *ssl, const char *line)
735 : : {
736 : : int fd;
737 : : ssize_t rc;
738 : 10 : PGconn *conn = SSL_get_app_data(ssl);
739 : :
740 [ - + ]: 10 : if (conn == NULL)
741 : 0 : return;
742 : :
743 : 10 : fd = open(conn->sslkeylogfile, O_WRONLY | O_APPEND | O_CREAT, 0600);
744 : :
745 [ + + ]: 10 : if (fd == -1)
746 : : {
747 : 5 : fprintf(stderr, libpq_gettext("WARNING: could not open SSL key logging file \"%s\": %m\n"),
748 : : conn->sslkeylogfile);
749 : 5 : return;
750 : : }
751 : :
752 : : /* line is guaranteed by OpenSSL to be NUL terminated */
753 : 5 : rc = write(fd, line, strlen(line));
754 [ - + ]: 5 : if (rc < 0)
755 : 0 : fprintf(stderr, libpq_gettext("WARNING: could not write to SSL key logging file \"%s\": %m\n"),
756 : : conn->sslkeylogfile);
757 : : else
758 : 5 : rc = write(fd, "\n", 1);
759 : : (void) rc; /* silence compiler warnings */
760 : 5 : close(fd);
761 : : }
762 : : #endif
763 : :
764 : : /*
765 : : * Create per-connection SSL object, and load the client certificate,
766 : : * private key, and trusted CA certs.
767 : : *
768 : : * Returns 0 if OK, -1 on failure (with a message in conn->errorMessage).
769 : : */
770 : : static int
771 : 174 : initialize_SSL(PGconn *conn)
772 : : {
773 : : SSL_CTX *SSL_context;
774 : : struct stat buf;
775 : : char homedir[MAXPGPATH];
776 : : char fnbuf[MAXPGPATH];
777 : : char sebuf[PG_STRERROR_R_BUFLEN];
778 : : bool have_homedir;
779 : : bool have_cert;
780 : : bool have_rootcert;
781 : :
782 : : /*
783 : : * We'll need the home directory if any of the relevant parameters are
784 : : * defaulted. If pqGetHomeDirectory fails, act as though none of the
785 : : * files could be found.
786 : : */
787 [ + + + - ]: 174 : if (!(conn->sslcert && strlen(conn->sslcert) > 0) ||
788 [ + + + - ]: 128 : !(conn->sslkey && strlen(conn->sslkey) > 0) ||
789 [ + + + - ]: 120 : !(conn->sslrootcert && strlen(conn->sslrootcert) > 0) ||
790 [ + + + + ]: 113 : !((conn->sslcrl && strlen(conn->sslcrl) > 0) ||
791 [ + + - + ]: 4 : (conn->sslcrldir && strlen(conn->sslcrldir) > 0)))
792 : 63 : have_homedir = pqGetHomeDirectory(homedir, sizeof(homedir));
793 : : else /* won't need it */
794 : 111 : have_homedir = false;
795 : :
796 : : /*
797 : : * Create a new SSL_CTX object.
798 : : *
799 : : * We used to share a single SSL_CTX between all connections, but it was
800 : : * complicated if connections used different certificates. So now we
801 : : * create a separate context for each connection, and accept the overhead.
802 : : */
803 : 174 : SSL_context = SSL_CTX_new(SSLv23_method());
804 [ - + ]: 174 : if (!SSL_context)
805 : : {
806 : 0 : char *err = SSLerrmessage(ERR_get_error());
807 : :
808 : 0 : libpq_append_conn_error(conn, "could not create SSL context: %s", err);
809 : 0 : SSLerrfree(err);
810 : 0 : return -1;
811 : : }
812 : :
813 : : /*
814 : : * Delegate the client cert password prompt to the libpq wrapper callback
815 : : * if any is defined.
816 : : *
817 : : * If the application hasn't installed its own and the sslpassword
818 : : * parameter is non-null, we install ours now to make sure we supply
819 : : * PGconn->sslpassword to OpenSSL instead of letting it prompt on stdin.
820 : : *
821 : : * This will replace OpenSSL's default PEM_def_callback (which prompts on
822 : : * stdin), but we're only setting it for this SSL context so it's
823 : : * harmless.
824 : : */
825 [ + - ]: 174 : if (PQsslKeyPassHook
826 [ + + + - ]: 174 : || (conn->sslpassword && strlen(conn->sslpassword) > 0))
827 : : {
828 : 3 : SSL_CTX_set_default_passwd_cb(SSL_context, PQssl_passwd_cb);
829 : 3 : SSL_CTX_set_default_passwd_cb_userdata(SSL_context, conn);
830 : : }
831 : :
832 : : #ifdef HAVE_SSL_CTX_SET_CERT_CB
833 : : /* Set up a certificate selection callback. */
834 : 174 : SSL_CTX_set_cert_cb(SSL_context, cert_cb, conn);
835 : : #endif
836 : :
837 : : /* Disable old protocol versions */
838 : 174 : SSL_CTX_set_options(SSL_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
839 : :
840 : : /* Set the minimum and maximum protocol versions if necessary */
841 [ + - ]: 174 : if (conn->ssl_min_protocol_version &&
842 [ + - ]: 174 : strlen(conn->ssl_min_protocol_version) != 0)
843 : : {
844 : : int ssl_min_ver;
845 : :
846 : 174 : ssl_min_ver = ssl_protocol_version_to_openssl(conn->ssl_min_protocol_version);
847 : :
848 [ - + ]: 174 : if (ssl_min_ver == -1)
849 : : {
850 : 0 : libpq_append_conn_error(conn, "invalid value \"%s\" for minimum SSL protocol version",
851 : : conn->ssl_min_protocol_version);
852 : 0 : SSL_CTX_free(SSL_context);
853 : 0 : return -1;
854 : : }
855 : :
856 [ - + ]: 174 : if (!SSL_CTX_set_min_proto_version(SSL_context, ssl_min_ver))
857 : : {
858 : 0 : char *err = SSLerrmessage(ERR_get_error());
859 : :
860 : 0 : libpq_append_conn_error(conn, "could not set minimum SSL protocol version: %s", err);
861 : 0 : SSLerrfree(err);
862 : 0 : SSL_CTX_free(SSL_context);
863 : 0 : return -1;
864 : : }
865 : : }
866 : :
867 [ + + ]: 174 : if (conn->ssl_max_protocol_version &&
868 [ + - ]: 2 : strlen(conn->ssl_max_protocol_version) != 0)
869 : : {
870 : : int ssl_max_ver;
871 : :
872 : 2 : ssl_max_ver = ssl_protocol_version_to_openssl(conn->ssl_max_protocol_version);
873 : :
874 [ - + ]: 2 : if (ssl_max_ver == -1)
875 : : {
876 : 0 : libpq_append_conn_error(conn, "invalid value \"%s\" for maximum SSL protocol version",
877 : : conn->ssl_max_protocol_version);
878 : 0 : SSL_CTX_free(SSL_context);
879 : 0 : return -1;
880 : : }
881 : :
882 [ - + ]: 2 : if (!SSL_CTX_set_max_proto_version(SSL_context, ssl_max_ver))
883 : : {
884 : 0 : char *err = SSLerrmessage(ERR_get_error());
885 : :
886 : 0 : libpq_append_conn_error(conn, "could not set maximum SSL protocol version: %s", err);
887 : 0 : SSLerrfree(err);
888 : 0 : SSL_CTX_free(SSL_context);
889 : 0 : return -1;
890 : : }
891 : : }
892 : :
893 : : /*
894 : : * Disable OpenSSL's moving-write-buffer sanity check, because it causes
895 : : * unnecessary failures in nonblocking send cases.
896 : : */
897 : 174 : SSL_CTX_set_mode(SSL_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
898 : :
899 : : /*
900 : : * If the root cert file exists, load it so we can perform certificate
901 : : * verification. If sslmode is "verify-full" we will also do further
902 : : * verification after the connection has been completed.
903 : : */
904 [ + + + - ]: 174 : if (conn->sslrootcert && strlen(conn->sslrootcert) > 0)
905 : 150 : strlcpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
906 [ + - ]: 24 : else if (have_homedir)
907 : 24 : snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
908 : : else
909 : 0 : fnbuf[0] = '\0';
910 : :
911 [ + + ]: 174 : if (strcmp(fnbuf, "system") == 0)
912 : : {
913 : : /*
914 : : * The "system" sentinel value indicates that we should load whatever
915 : : * root certificates are installed for use by OpenSSL; these locations
916 : : * differ by platform. Note that the default system locations may be
917 : : * further overridden by the SSL_CERT_DIR and SSL_CERT_FILE
918 : : * environment variables.
919 : : */
920 [ - + ]: 3 : if (SSL_CTX_set_default_verify_paths(SSL_context) != 1)
921 : : {
922 : 0 : char *err = SSLerrmessage(ERR_get_error());
923 : :
924 : 0 : libpq_append_conn_error(conn, "could not load system root certificate paths: %s",
925 : : err);
926 : 0 : SSLerrfree(err);
927 : 0 : SSL_CTX_free(SSL_context);
928 : 0 : return -1;
929 : : }
930 : 3 : have_rootcert = true;
931 : : }
932 [ + - + + ]: 342 : else if (fnbuf[0] != '\0' &&
933 : 171 : stat(fnbuf, &buf) == 0)
934 : 132 : {
935 : : X509_STORE *cvstore;
936 : :
937 [ - + ]: 132 : if (SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL) != 1)
938 : : {
939 : 0 : char *err = SSLerrmessage(ERR_get_error());
940 : :
941 : 0 : libpq_append_conn_error(conn, "could not read root certificate file \"%s\": %s",
942 : : fnbuf, err);
943 : 0 : SSLerrfree(err);
944 : 0 : SSL_CTX_free(SSL_context);
945 : 0 : return -1;
946 : : }
947 : :
948 [ + - ]: 132 : if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL)
949 : : {
950 : 132 : char *fname = NULL;
951 : 132 : char *dname = NULL;
952 : :
953 [ + + + + ]: 132 : if (conn->sslcrl && strlen(conn->sslcrl) > 0)
954 : 102 : fname = conn->sslcrl;
955 [ + + + - ]: 132 : if (conn->sslcrldir && strlen(conn->sslcrldir) > 0)
956 : 104 : dname = conn->sslcrldir;
957 : :
958 : : /* defaults to use the default CRL file */
959 [ + + + + : 132 : if (!fname && !dname && have_homedir)
+ - ]
960 : : {
961 : 28 : snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE);
962 : 28 : fname = fnbuf;
963 : : }
964 : :
965 : : /* Set the flags to check against the complete CRL chain */
966 [ + + + - : 264 : if ((fname || dname) &&
+ + ]
967 : 132 : X509_STORE_load_locations(cvstore, fname, dname) == 1)
968 : : {
969 : 5 : X509_STORE_set_flags(cvstore,
970 : : X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
971 : : }
972 : :
973 : : /* if not found, silently ignore; we do not require CRL */
974 : 132 : ERR_clear_error();
975 : : }
976 : 132 : have_rootcert = true;
977 : : }
978 : : else
979 : : {
980 : : /*
981 : : * stat() failed; assume root file doesn't exist. If sslmode is
982 : : * verify-ca or verify-full, this is an error. Otherwise, continue
983 : : * without performing any server cert verification.
984 : : */
985 [ + + ]: 39 : if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
986 : : {
987 : : /*
988 : : * The only way to reach here with an empty filename is if
989 : : * pqGetHomeDirectory failed. That's a sufficiently unusual case
990 : : * that it seems worth having a specialized error message for it.
991 : : */
992 [ - + ]: 3 : if (fnbuf[0] == '\0')
993 : 0 : libpq_append_conn_error(conn, "could not get home directory to locate root certificate file\n"
994 : : "Either provide the file, use the system's trusted roots with sslrootcert=system, or change sslmode to disable server certificate verification.");
995 : : else
996 : 3 : libpq_append_conn_error(conn, "root certificate file \"%s\" does not exist\n"
997 : : "Either provide the file, use the system's trusted roots with sslrootcert=system, or change sslmode to disable server certificate verification.", fnbuf);
998 : 3 : SSL_CTX_free(SSL_context);
999 : 3 : return -1;
1000 : : }
1001 : 36 : have_rootcert = false;
1002 : : }
1003 : :
1004 : : /* Read the client certificate file */
1005 [ + + + - ]: 171 : if (conn->sslcert && strlen(conn->sslcert) > 0)
1006 : 126 : strlcpy(fnbuf, conn->sslcert, sizeof(fnbuf));
1007 [ + - ]: 45 : else if (have_homedir)
1008 : 45 : snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
1009 : : else
1010 : 0 : fnbuf[0] = '\0';
1011 : :
1012 [ + + ]: 171 : if (conn->sslcertmode[0] == 'd') /* disable */
1013 : : {
1014 : : /* don't send a client cert even if we have one */
1015 : 7 : have_cert = false;
1016 : : }
1017 [ - + ]: 164 : else if (fnbuf[0] == '\0')
1018 : : {
1019 : : /* no home directory, proceed without a client cert */
1020 : 0 : have_cert = false;
1021 : : }
1022 [ + + ]: 164 : else if (stat(fnbuf, &buf) != 0)
1023 : : {
1024 : : /*
1025 : : * If file is not present, just go on without a client cert; server
1026 : : * might or might not accept the connection. Any other error,
1027 : : * however, is grounds for complaint.
1028 : : */
1029 [ - + - - ]: 119 : if (errno != ENOENT && errno != ENOTDIR)
1030 : : {
1031 : 0 : libpq_append_conn_error(conn, "could not open certificate file \"%s\": %s",
1032 : 0 : fnbuf, strerror_r(errno, sebuf, sizeof(sebuf)));
1033 : 0 : SSL_CTX_free(SSL_context);
1034 : 0 : return -1;
1035 : : }
1036 : 119 : have_cert = false;
1037 : : }
1038 : : else
1039 : : {
1040 : : /*
1041 : : * Cert file exists, so load it. Since OpenSSL doesn't provide the
1042 : : * equivalent of "SSL_use_certificate_chain_file", we have to load it
1043 : : * into the SSL context, rather than the SSL object.
1044 : : */
1045 [ - + ]: 45 : if (SSL_CTX_use_certificate_chain_file(SSL_context, fnbuf) != 1)
1046 : : {
1047 : 0 : char *err = SSLerrmessage(ERR_get_error());
1048 : :
1049 : 0 : libpq_append_conn_error(conn, "could not read certificate file \"%s\": %s",
1050 : : fnbuf, err);
1051 : 0 : SSLerrfree(err);
1052 : 0 : SSL_CTX_free(SSL_context);
1053 : 0 : return -1;
1054 : : }
1055 : :
1056 : : /* need to load the associated private key, too */
1057 : 45 : have_cert = true;
1058 : : }
1059 : :
1060 : : /*
1061 : : * The SSL context is now loaded with the correct root and client
1062 : : * certificates. Create a connection-specific SSL object. The private key
1063 : : * is loaded directly into the SSL object. (We could load the private key
1064 : : * into the context, too, but we have done it this way historically, and
1065 : : * it doesn't really matter.)
1066 : : */
1067 [ + - + - ]: 342 : if (!(conn->ssl = SSL_new(SSL_context)) ||
1068 [ - + ]: 342 : !SSL_set_app_data(conn->ssl, conn) ||
1069 : 171 : !ssl_set_pgconn_bio(conn))
1070 : : {
1071 : 0 : char *err = SSLerrmessage(ERR_get_error());
1072 : :
1073 : 0 : libpq_append_conn_error(conn, "could not establish SSL connection: %s", err);
1074 : 0 : SSLerrfree(err);
1075 : 0 : SSL_CTX_free(SSL_context);
1076 : 0 : return -1;
1077 : : }
1078 : 171 : conn->ssl_in_use = true;
1079 : :
1080 : : /*
1081 : : * If SSL key logging is requested, set up the callback if a compatible
1082 : : * version of OpenSSL is used and libpq was compiled to support it.
1083 : : */
1084 [ + + + - ]: 171 : if (conn->sslkeylogfile && strlen(conn->sslkeylogfile) > 0)
1085 : : {
1086 : : #ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK
1087 : 2 : SSL_CTX_set_keylog_callback(SSL_context, SSL_CTX_keylog_cb);
1088 : : #else
1089 : : #ifdef LIBRESSL_VERSION_NUMBER
1090 : : fprintf(stderr, libpq_gettext("WARNING: sslkeylogfile support requires OpenSSL\n"));
1091 : : #else
1092 : : fprintf(stderr, libpq_gettext("WARNING: libpq was not built with sslkeylogfile support\n"));
1093 : : #endif
1094 : : #endif
1095 : : }
1096 : :
1097 : : /*
1098 : : * SSL contexts are reference counted by OpenSSL. We can free it as soon
1099 : : * as we have created the SSL object, and it will stick around for as long
1100 : : * as it's actually needed.
1101 : : */
1102 : 171 : SSL_CTX_free(SSL_context);
1103 : 171 : SSL_context = NULL;
1104 : :
1105 : : /*
1106 : : * Set Server Name Indication (SNI), if enabled by connection parameters.
1107 : : * Per RFC 6066, do not set it if the host is a literal IP address (IPv4
1108 : : * or IPv6).
1109 : : */
1110 [ + - + + ]: 171 : if (conn->sslsni && conn->sslsni[0] == '1')
1111 : : {
1112 : 166 : const char *host = conn->connhost[conn->whichhost].host;
1113 : :
1114 [ + - + - ]: 166 : if (host && host[0] &&
1115 [ + + ]: 166 : !(strspn(host, "0123456789.") == strlen(host) ||
1116 [ + + ]: 159 : strchr(host, ':')))
1117 : : {
1118 [ - + ]: 152 : if (SSL_set_tlsext_host_name(conn->ssl, host) != 1)
1119 : : {
1120 : 0 : char *err = SSLerrmessage(ERR_get_error());
1121 : :
1122 : 0 : libpq_append_conn_error(conn, "could not set SSL Server Name Indication (SNI): %s", err);
1123 : 0 : SSLerrfree(err);
1124 : 0 : return -1;
1125 : : }
1126 : : }
1127 : : }
1128 : :
1129 : : /* Set ALPN */
1130 : : {
1131 : : int retval;
1132 : :
1133 : 171 : retval = SSL_set_alpn_protos(conn->ssl, alpn_protos, sizeof(alpn_protos));
1134 : :
1135 [ - + ]: 171 : if (retval != 0)
1136 : : {
1137 : 0 : char *err = SSLerrmessage(ERR_get_error());
1138 : :
1139 : 0 : libpq_append_conn_error(conn, "could not set SSL ALPN extension: %s", err);
1140 : 0 : SSLerrfree(err);
1141 : 0 : return -1;
1142 : : }
1143 : : }
1144 : :
1145 : : /*
1146 : : * Read the SSL key. If a key is specified, treat it as an engine:key
1147 : : * combination if there is colon present - we don't support files with
1148 : : * colon in the name. The exception is if the second character is a colon,
1149 : : * in which case it can be a Windows filename with drive specification.
1150 : : */
1151 [ + + + - : 171 : if (have_cert && conn->sslkey && strlen(conn->sslkey) > 0)
+ - ]
1152 : : {
1153 : : #ifdef USE_SSL_ENGINE
1154 [ - + ]: 90 : if (strchr(conn->sslkey, ':')
1155 : : #ifdef WIN32
1156 : : && conn->sslkey[1] != ':'
1157 : : #endif
1158 : : )
1159 : : {
1160 : : /* Colon, but not in second character, treat as engine:key */
1161 : 0 : char *engine_str = strdup(conn->sslkey);
1162 : : char *engine_colon;
1163 : : EVP_PKEY *pkey;
1164 : :
1165 [ # # ]: 0 : if (engine_str == NULL)
1166 : : {
1167 : 0 : libpq_append_conn_error(conn, "out of memory");
1168 : 0 : return -1;
1169 : : }
1170 : :
1171 : : /* cannot return NULL because we already checked before strdup */
1172 : 0 : engine_colon = strchr(engine_str, ':');
1173 : :
1174 : 0 : *engine_colon = '\0'; /* engine_str now has engine name */
1175 : 0 : engine_colon++; /* engine_colon now has key name */
1176 : :
1177 : 0 : conn->engine = ENGINE_by_id(engine_str);
1178 [ # # ]: 0 : if (conn->engine == NULL)
1179 : : {
1180 : 0 : char *err = SSLerrmessage(ERR_get_error());
1181 : :
1182 : 0 : libpq_append_conn_error(conn, "could not load SSL engine \"%s\": %s",
1183 : : engine_str, err);
1184 : 0 : SSLerrfree(err);
1185 : 0 : free(engine_str);
1186 : 0 : return -1;
1187 : : }
1188 : :
1189 [ # # ]: 0 : if (ENGINE_init(conn->engine) == 0)
1190 : : {
1191 : 0 : char *err = SSLerrmessage(ERR_get_error());
1192 : :
1193 : 0 : libpq_append_conn_error(conn, "could not initialize SSL engine \"%s\": %s",
1194 : : engine_str, err);
1195 : 0 : SSLerrfree(err);
1196 : 0 : ENGINE_free(conn->engine);
1197 : 0 : conn->engine = NULL;
1198 : 0 : free(engine_str);
1199 : 0 : return -1;
1200 : : }
1201 : :
1202 : 0 : pkey = ENGINE_load_private_key(conn->engine, engine_colon,
1203 : : NULL, NULL);
1204 [ # # ]: 0 : if (pkey == NULL)
1205 : : {
1206 : 0 : char *err = SSLerrmessage(ERR_get_error());
1207 : :
1208 : 0 : libpq_append_conn_error(conn, "could not read private SSL key \"%s\" from engine \"%s\": %s",
1209 : : engine_colon, engine_str, err);
1210 : 0 : SSLerrfree(err);
1211 : 0 : ENGINE_finish(conn->engine);
1212 : 0 : ENGINE_free(conn->engine);
1213 : 0 : conn->engine = NULL;
1214 : 0 : free(engine_str);
1215 : 0 : return -1;
1216 : : }
1217 [ # # ]: 0 : if (SSL_use_PrivateKey(conn->ssl, pkey) != 1)
1218 : : {
1219 : 0 : char *err = SSLerrmessage(ERR_get_error());
1220 : :
1221 : 0 : libpq_append_conn_error(conn, "could not load private SSL key \"%s\" from engine \"%s\": %s",
1222 : : engine_colon, engine_str, err);
1223 : 0 : SSLerrfree(err);
1224 : 0 : ENGINE_finish(conn->engine);
1225 : 0 : ENGINE_free(conn->engine);
1226 : 0 : conn->engine = NULL;
1227 : 0 : free(engine_str);
1228 : 0 : return -1;
1229 : : }
1230 : :
1231 : 0 : free(engine_str);
1232 : :
1233 : 0 : fnbuf[0] = '\0'; /* indicate we're not going to load from a
1234 : : * file */
1235 : : }
1236 : : else
1237 : : #endif /* USE_SSL_ENGINE */
1238 : : {
1239 : : /* PGSSLKEY is not an engine, treat it as a filename */
1240 : 45 : strlcpy(fnbuf, conn->sslkey, sizeof(fnbuf));
1241 : : }
1242 : : }
1243 [ + + ]: 126 : else if (have_homedir)
1244 : : {
1245 : : /* No PGSSLKEY specified, load default file */
1246 : 53 : snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
1247 : : }
1248 : : else
1249 : 73 : fnbuf[0] = '\0';
1250 : :
1251 [ + + + - ]: 171 : if (have_cert && fnbuf[0] != '\0')
1252 : : {
1253 : : /* read the client key from file */
1254 : :
1255 [ - + ]: 45 : if (stat(fnbuf, &buf) != 0)
1256 : : {
1257 [ # # ]: 0 : if (errno == ENOENT)
1258 : 0 : libpq_append_conn_error(conn, "certificate present, but not private key file \"%s\"",
1259 : : fnbuf);
1260 : : else
1261 : 0 : libpq_append_conn_error(conn, "could not stat private key file \"%s\": %m",
1262 : : fnbuf);
1263 : 0 : return -1;
1264 : : }
1265 : :
1266 : : /* Key file must be a regular file */
1267 [ - + ]: 45 : if (!S_ISREG(buf.st_mode))
1268 : : {
1269 : 0 : libpq_append_conn_error(conn, "private key file \"%s\" is not a regular file",
1270 : : fnbuf);
1271 : 0 : return -1;
1272 : : }
1273 : :
1274 : : /*
1275 : : * Refuse to load world-readable key files. We accept root-owned
1276 : : * files with mode 0640 or less, so that we can access system-wide
1277 : : * certificates if we have a supplementary group membership that
1278 : : * allows us to read 'em. For files with non-root ownership, require
1279 : : * mode 0600 or less. We need not check the file's ownership exactly;
1280 : : * if we're able to read it despite it having such restrictive
1281 : : * permissions, it must have the right ownership.
1282 : : *
1283 : : * Note: be very careful about tightening these rules. Some people
1284 : : * expect, for example, that a client process running as root should
1285 : : * be able to use a non-root-owned key file.
1286 : : *
1287 : : * Note that roughly similar checks are performed in
1288 : : * src/backend/libpq/be-secure-common.c so any changes here may need
1289 : : * to be made there as well. However, this code caters for the case
1290 : : * of current user == root, while that code does not.
1291 : : *
1292 : : * Ideally we would do similar permissions checks on Windows, but it
1293 : : * is not clear how that would work since Unix-style permissions may
1294 : : * not be available.
1295 : : */
1296 : : #if !defined(WIN32) && !defined(__CYGWIN__)
1297 [ - + + + ]: 90 : if (buf.st_uid == 0 ?
1298 : 0 : buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO) :
1299 : 45 : buf.st_mode & (S_IRWXG | S_IRWXO))
1300 : : {
1301 : 1 : libpq_append_conn_error(conn,
1302 : : "private key file \"%s\" has group or world access; file must have permissions u=rw (0600) or less if owned by the current user, or permissions u=rw,g=r (0640) or less if owned by root",
1303 : : fnbuf);
1304 : 1 : return -1;
1305 : : }
1306 : : #endif
1307 : :
1308 [ + + ]: 44 : if (SSL_use_PrivateKey_file(conn->ssl, fnbuf, SSL_FILETYPE_PEM) != 1)
1309 : : {
1310 : 3 : char *err = SSLerrmessage(ERR_get_error());
1311 : :
1312 : : /*
1313 : : * We'll try to load the file in DER (binary ASN.1) format, and if
1314 : : * that fails too, report the original error. This could mask
1315 : : * issues where there's something wrong with a DER-format cert,
1316 : : * but we'd have to duplicate openssl's format detection to be
1317 : : * smarter than this. We can't just probe for a leading -----BEGIN
1318 : : * because PEM can have leading non-matching lines and blanks.
1319 : : * OpenSSL doesn't expose its get_name(...) and its PEM routines
1320 : : * don't differentiate between failure modes in enough detail to
1321 : : * let us tell the difference between "not PEM, try DER" and
1322 : : * "wrong password".
1323 : : */
1324 [ + + ]: 3 : if (SSL_use_PrivateKey_file(conn->ssl, fnbuf, SSL_FILETYPE_ASN1) != 1)
1325 : : {
1326 : 1 : libpq_append_conn_error(conn, "could not load private key file \"%s\": %s",
1327 : : fnbuf, err);
1328 : 1 : SSLerrfree(err);
1329 : 1 : return -1;
1330 : : }
1331 : :
1332 : 2 : SSLerrfree(err);
1333 : : }
1334 : : }
1335 : :
1336 : : /* verify that the cert and key go together */
1337 [ + + - + ]: 212 : if (have_cert &&
1338 : 43 : SSL_check_private_key(conn->ssl) != 1)
1339 : : {
1340 : 0 : char *err = SSLerrmessage(ERR_get_error());
1341 : :
1342 : 0 : libpq_append_conn_error(conn, "certificate does not match private key file \"%s\": %s",
1343 : : fnbuf, err);
1344 : 0 : SSLerrfree(err);
1345 : 0 : return -1;
1346 : : }
1347 : :
1348 : : /*
1349 : : * If a root cert was loaded, also set our certificate verification
1350 : : * callback.
1351 : : */
1352 [ + + ]: 169 : if (have_rootcert)
1353 : 133 : SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, verify_cb);
1354 : :
1355 : : /*
1356 : : * Set compression option if necessary.
1357 : : */
1358 [ + - + - ]: 169 : if (conn->sslcompression && conn->sslcompression[0] == '0')
1359 : 169 : SSL_set_options(conn->ssl, SSL_OP_NO_COMPRESSION);
1360 : : else
1361 : 0 : SSL_clear_options(conn->ssl, SSL_OP_NO_COMPRESSION);
1362 : :
1363 : 169 : return 0;
1364 : : }
1365 : :
1366 : : /*
1367 : : * Attempt to negotiate SSL connection.
1368 : : */
1369 : : static PostgresPollingStatusType
1370 : 301 : open_client_SSL(PGconn *conn)
1371 : : {
1372 : : int r;
1373 : :
1374 : 301 : SOCK_ERRNO_SET(0);
1375 : 301 : ERR_clear_error();
1376 : 301 : r = SSL_connect(conn->ssl);
1377 [ + + ]: 301 : if (r <= 0)
1378 : : {
1379 : 153 : int save_errno = SOCK_ERRNO;
1380 : 153 : int err = SSL_get_error(conn->ssl, r);
1381 : : unsigned long ecode;
1382 : :
1383 : 153 : ecode = ERR_get_error();
1384 [ + - + + : 153 : switch (err)
- ]
1385 : : {
1386 : 132 : case SSL_ERROR_WANT_READ:
1387 : 132 : return PGRES_POLLING_READING;
1388 : :
1389 : 0 : case SSL_ERROR_WANT_WRITE:
1390 : 0 : return PGRES_POLLING_WRITING;
1391 : :
1392 : 1 : case SSL_ERROR_SYSCALL:
1393 : : {
1394 : : char sebuf[PG_STRERROR_R_BUFLEN];
1395 : : unsigned long vcode;
1396 : :
1397 : 1 : vcode = SSL_get_verify_result(conn->ssl);
1398 : :
1399 : : /*
1400 : : * If we get an X509 error here for failing to load the
1401 : : * local issuer cert, without an error in the socket layer
1402 : : * it means that verification failed due to a missing
1403 : : * system CA pool without it being a protocol error. We
1404 : : * inspect the sslrootcert setting to ensure that the user
1405 : : * was using the system CA pool. For other errors, log
1406 : : * them using the normal SYSCALL logging.
1407 : : */
1408 [ - + - - ]: 1 : if (save_errno == 0 &&
1409 : 0 : vcode == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY &&
1410 [ # # ]: 0 : strcmp(conn->sslrootcert, "system") == 0)
1411 : 0 : libpq_append_conn_error(conn, "SSL error: certificate verify failed: %s",
1412 : : X509_verify_cert_error_string(vcode));
1413 [ + - + - ]: 1 : else if (r == -1 && save_errno != 0)
1414 : 1 : libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
1415 : : SOCK_STRERROR(save_errno, sebuf, sizeof(sebuf)));
1416 : : else
1417 : 0 : libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
1418 : 1 : pgtls_close(conn);
1419 : 1 : return PGRES_POLLING_FAILED;
1420 : : }
1421 : 20 : case SSL_ERROR_SSL:
1422 : : {
1423 : 20 : char *err = SSLerrmessage(ecode);
1424 : :
1425 : 20 : libpq_append_conn_error(conn, "SSL error: %s", err);
1426 : 20 : SSLerrfree(err);
1427 [ - + ]: 20 : switch (ERR_GET_REASON(ecode))
1428 : : {
1429 : : /*
1430 : : * UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
1431 : : * TLSV1_ALERT_PROTOCOL_VERSION have been observed
1432 : : * when trying to communicate with an old OpenSSL
1433 : : * library, or when the client and server specify
1434 : : * disjoint protocol ranges.
1435 : : * NO_PROTOCOLS_AVAILABLE occurs if there's a
1436 : : * local misconfiguration (which can happen
1437 : : * despite our checks, if openssl.cnf injects a
1438 : : * limit we didn't account for). It's not very
1439 : : * clear what would make OpenSSL return the other
1440 : : * codes listed here, but a hint about protocol
1441 : : * versions seems like it's appropriate for all.
1442 : : */
1443 : 0 : case SSL_R_NO_PROTOCOLS_AVAILABLE:
1444 : : case SSL_R_UNSUPPORTED_PROTOCOL:
1445 : : case SSL_R_BAD_PROTOCOL_VERSION_NUMBER:
1446 : : case SSL_R_UNKNOWN_PROTOCOL:
1447 : : case SSL_R_UNKNOWN_SSL_VERSION:
1448 : : case SSL_R_UNSUPPORTED_SSL_VERSION:
1449 : : case SSL_R_WRONG_SSL_VERSION:
1450 : : case SSL_R_WRONG_VERSION_NUMBER:
1451 : : case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
1452 : : #ifdef SSL_R_VERSION_TOO_HIGH
1453 : : case SSL_R_VERSION_TOO_HIGH:
1454 : : case SSL_R_VERSION_TOO_LOW:
1455 : : #endif
1456 : 0 : libpq_append_conn_error(conn, "This may indicate that the server does not support any SSL protocol version between %s and %s.",
1457 [ # # ]: 0 : conn->ssl_min_protocol_version ?
1458 : : conn->ssl_min_protocol_version :
1459 : : MIN_OPENSSL_TLS_VERSION,
1460 [ # # ]: 0 : conn->ssl_max_protocol_version ?
1461 : : conn->ssl_max_protocol_version :
1462 : : MAX_OPENSSL_TLS_VERSION);
1463 : 0 : break;
1464 : 20 : default:
1465 : 20 : break;
1466 : : }
1467 : 20 : pgtls_close(conn);
1468 : 20 : return PGRES_POLLING_FAILED;
1469 : : }
1470 : :
1471 : 0 : default:
1472 : 0 : libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
1473 : 0 : pgtls_close(conn);
1474 : 0 : return PGRES_POLLING_FAILED;
1475 : : }
1476 : : }
1477 : :
1478 : : /* ALPN is mandatory with direct SSL connections */
1479 [ + - + + ]: 148 : if (conn->current_enc_method == ENC_SSL && conn->sslnegotiation[0] == 'd')
1480 : : {
1481 : : const unsigned char *selected;
1482 : : unsigned int len;
1483 : :
1484 : 3 : SSL_get0_alpn_selected(conn->ssl, &selected, &len);
1485 : :
1486 [ - + ]: 3 : if (selected == NULL)
1487 : : {
1488 : 0 : libpq_append_conn_error(conn, "direct SSL connection was established without ALPN protocol negotiation extension");
1489 : 0 : pgtls_close(conn);
1490 : 0 : return PGRES_POLLING_FAILED;
1491 : : }
1492 : :
1493 : : /*
1494 : : * We only support one protocol so that's what the negotiation should
1495 : : * always choose, but doesn't hurt to check.
1496 : : */
1497 [ + - ]: 3 : if (len != strlen(PG_ALPN_PROTOCOL) ||
1498 [ - + ]: 3 : memcmp(selected, PG_ALPN_PROTOCOL, strlen(PG_ALPN_PROTOCOL)) != 0)
1499 : : {
1500 : 0 : libpq_append_conn_error(conn, "SSL connection was established with unexpected ALPN protocol");
1501 : 0 : pgtls_close(conn);
1502 : 0 : return PGRES_POLLING_FAILED;
1503 : : }
1504 : : }
1505 : :
1506 : : /*
1507 : : * We already checked the server certificate in initialize_SSL() using
1508 : : * SSL_CTX_set_verify(), if root.crt exists.
1509 : : */
1510 : :
1511 : : /* get server certificate */
1512 : 148 : conn->peer = SSL_get_peer_certificate(conn->ssl);
1513 [ - + ]: 148 : if (conn->peer == NULL)
1514 : : {
1515 : 0 : char *err = SSLerrmessage(ERR_get_error());
1516 : :
1517 : 0 : libpq_append_conn_error(conn, "certificate could not be obtained: %s", err);
1518 : 0 : SSLerrfree(err);
1519 : 0 : pgtls_close(conn);
1520 : 0 : return PGRES_POLLING_FAILED;
1521 : : }
1522 : :
1523 [ + + ]: 148 : if (!pq_verify_peer_name_matches_certificate(conn))
1524 : : {
1525 : 13 : pgtls_close(conn);
1526 : 13 : return PGRES_POLLING_FAILED;
1527 : : }
1528 : :
1529 : : /* SSL handshake is complete */
1530 : 135 : return PGRES_POLLING_OK;
1531 : : }
1532 : :
1533 : : void
1534 : 32943 : pgtls_close(PGconn *conn)
1535 : : {
1536 [ + + ]: 32943 : if (conn->ssl_in_use)
1537 : : {
1538 [ + - ]: 171 : if (conn->ssl)
1539 : : {
1540 : : /*
1541 : : * We can't destroy everything SSL-related here due to the
1542 : : * possible later calls to OpenSSL routines which may need our
1543 : : * thread callbacks, so set a flag here and check at the end.
1544 : : */
1545 : :
1546 : 171 : SSL_shutdown(conn->ssl);
1547 : 171 : SSL_free(conn->ssl);
1548 : 171 : conn->ssl = NULL;
1549 : 171 : conn->ssl_in_use = false;
1550 : 171 : conn->ssl_handshake_started = false;
1551 : : }
1552 : :
1553 [ + + ]: 171 : if (conn->peer)
1554 : : {
1555 : 148 : X509_free(conn->peer);
1556 : 148 : conn->peer = NULL;
1557 : : }
1558 : :
1559 : : #ifdef USE_SSL_ENGINE
1560 [ - + ]: 171 : if (conn->engine)
1561 : : {
1562 : 0 : ENGINE_finish(conn->engine);
1563 : 0 : ENGINE_free(conn->engine);
1564 : 0 : conn->engine = NULL;
1565 : : }
1566 : : #endif
1567 : : }
1568 : 32943 : }
1569 : :
1570 : :
1571 : : /*
1572 : : * Obtain reason string for passed SSL errcode
1573 : : *
1574 : : * ERR_get_error() is used by caller to get errcode to pass here.
1575 : : * The result must be freed after use, using SSLerrfree.
1576 : : *
1577 : : * Some caution is needed here since ERR_reason_error_string will return NULL
1578 : : * if it doesn't recognize the error code, or (in OpenSSL >= 3) if the code
1579 : : * represents a system errno value. We don't want to return NULL ever.
1580 : : */
1581 : : static char ssl_nomem[] = "out of memory allocating error description";
1582 : :
1583 : : #define SSL_ERR_LEN 128
1584 : :
1585 : : static char *
1586 : 32 : SSLerrmessage(unsigned long ecode)
1587 : : {
1588 : : const char *errreason;
1589 : : char *errbuf;
1590 : :
1591 : 32 : errbuf = malloc(SSL_ERR_LEN);
1592 [ - + ]: 32 : if (!errbuf)
1593 : 0 : return ssl_nomem;
1594 [ - + ]: 32 : if (ecode == 0)
1595 : : {
1596 : 0 : snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("no SSL error reported"));
1597 : 0 : return errbuf;
1598 : : }
1599 : 32 : errreason = ERR_reason_error_string(ecode);
1600 [ + - ]: 32 : if (errreason != NULL)
1601 : : {
1602 : 32 : strlcpy(errbuf, errreason, SSL_ERR_LEN);
1603 : 32 : return errbuf;
1604 : : }
1605 : :
1606 : : /*
1607 : : * Server aborted the connection with TLS "no_application_protocol" alert.
1608 : : * The ERR_reason_error_string() function doesn't give any error string
1609 : : * for that for some reason, so do it ourselves. See
1610 : : * https://github.com/openssl/openssl/issues/24300. This is available in
1611 : : * OpenSSL 1.1.0 and later, as well as in LibreSSL 3.4.3 (OpenBSD 7.0) and
1612 : : * later.
1613 : : */
1614 : : #ifdef SSL_AD_NO_APPLICATION_PROTOCOL
1615 [ # # # # ]: 0 : if (ERR_GET_LIB(ecode) == ERR_LIB_SSL &&
1616 : 0 : ERR_GET_REASON(ecode) == SSL_AD_REASON_OFFSET + SSL_AD_NO_APPLICATION_PROTOCOL)
1617 : : {
1618 : 0 : snprintf(errbuf, SSL_ERR_LEN, "no application protocol");
1619 : 0 : return errbuf;
1620 : : }
1621 : : #endif
1622 : :
1623 : : /*
1624 : : * In OpenSSL 3.0.0 and later, ERR_reason_error_string does not map system
1625 : : * errno values anymore. (See OpenSSL source code for the explanation.)
1626 : : * We can cover that shortcoming with this bit of code. Older OpenSSL
1627 : : * versions don't have the ERR_SYSTEM_ERROR macro, but that's okay because
1628 : : * they don't have the shortcoming either.
1629 : : */
1630 : : #ifdef ERR_SYSTEM_ERROR
1631 [ # # ]: 0 : if (ERR_SYSTEM_ERROR(ecode))
1632 : : {
1633 : 0 : strerror_r(ERR_GET_REASON(ecode), errbuf, SSL_ERR_LEN);
1634 : 0 : return errbuf;
1635 : : }
1636 : : #endif
1637 : :
1638 : : /* No choice but to report the numeric ecode */
1639 : 0 : snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("SSL error code %lu"), ecode);
1640 : 0 : return errbuf;
1641 : : }
1642 : :
1643 : : static void
1644 : 32 : SSLerrfree(char *buf)
1645 : : {
1646 [ + - ]: 32 : if (buf != ssl_nomem)
1647 : 32 : free(buf);
1648 : 32 : }
1649 : :
1650 : : /* ------------------------------------------------------------ */
1651 : : /* SSL information functions */
1652 : : /* ------------------------------------------------------------ */
1653 : :
1654 : : /*
1655 : : * Return pointer to OpenSSL object.
1656 : : */
1657 : : void *
1658 : 0 : PQgetssl(PGconn *conn)
1659 : : {
1660 [ # # ]: 0 : if (!conn)
1661 : 0 : return NULL;
1662 : 0 : return conn->ssl;
1663 : : }
1664 : :
1665 : : void *
1666 : 0 : PQsslStruct(PGconn *conn, const char *struct_name)
1667 : : {
1668 [ # # ]: 0 : if (!conn)
1669 : 0 : return NULL;
1670 [ # # ]: 0 : if (strcmp(struct_name, "OpenSSL") == 0)
1671 : 0 : return conn->ssl;
1672 : 0 : return NULL;
1673 : : }
1674 : :
1675 : : const char *const *
1676 : 0 : PQsslAttributeNames(PGconn *conn)
1677 : : {
1678 : : static const char *const openssl_attrs[] = {
1679 : : "library",
1680 : : "key_bits",
1681 : : "cipher",
1682 : : "compression",
1683 : : "protocol",
1684 : : "alpn",
1685 : : NULL
1686 : : };
1687 : : static const char *const empty_attrs[] = {NULL};
1688 : :
1689 [ # # ]: 0 : if (!conn)
1690 : : {
1691 : : /* Return attributes of default SSL library */
1692 : 0 : return openssl_attrs;
1693 : : }
1694 : :
1695 : : /* No attrs for unencrypted connection */
1696 [ # # ]: 0 : if (conn->ssl == NULL)
1697 : 0 : return empty_attrs;
1698 : :
1699 : 0 : return openssl_attrs;
1700 : : }
1701 : :
1702 : : const char *
1703 : 1 : PQsslAttribute(PGconn *conn, const char *attribute_name)
1704 : : {
1705 [ + - ]: 1 : if (!conn)
1706 : : {
1707 : : /* PQsslAttribute(NULL, "library") reports the default SSL library */
1708 [ + - ]: 1 : if (strcmp(attribute_name, "library") == 0)
1709 : 1 : return "OpenSSL";
1710 : 0 : return NULL;
1711 : : }
1712 : :
1713 : : /* All attributes read as NULL for a non-encrypted connection */
1714 [ # # ]: 0 : if (conn->ssl == NULL)
1715 : 0 : return NULL;
1716 : :
1717 [ # # ]: 0 : if (strcmp(attribute_name, "library") == 0)
1718 : 0 : return "OpenSSL";
1719 : :
1720 [ # # ]: 0 : if (strcmp(attribute_name, "key_bits") == 0)
1721 : : {
1722 : : static char sslbits_str[12];
1723 : : int sslbits;
1724 : :
1725 : 0 : SSL_get_cipher_bits(conn->ssl, &sslbits);
1726 : 0 : snprintf(sslbits_str, sizeof(sslbits_str), "%d", sslbits);
1727 : 0 : return sslbits_str;
1728 : : }
1729 : :
1730 [ # # ]: 0 : if (strcmp(attribute_name, "cipher") == 0)
1731 : 0 : return SSL_get_cipher(conn->ssl);
1732 : :
1733 [ # # ]: 0 : if (strcmp(attribute_name, "compression") == 0)
1734 [ # # ]: 0 : return SSL_get_current_compression(conn->ssl) ? "on" : "off";
1735 : :
1736 [ # # ]: 0 : if (strcmp(attribute_name, "protocol") == 0)
1737 : 0 : return SSL_get_version(conn->ssl);
1738 : :
1739 [ # # ]: 0 : if (strcmp(attribute_name, "alpn") == 0)
1740 : : {
1741 : : const unsigned char *data;
1742 : : unsigned int len;
1743 : : static char alpn_str[256]; /* alpn doesn't support longer than 255
1744 : : * bytes */
1745 : :
1746 : 0 : SSL_get0_alpn_selected(conn->ssl, &data, &len);
1747 [ # # # # : 0 : if (data == NULL || len == 0 || len > sizeof(alpn_str) - 1)
# # ]
1748 : 0 : return "";
1749 : 0 : memcpy(alpn_str, data, len);
1750 : 0 : alpn_str[len] = 0;
1751 : 0 : return alpn_str;
1752 : : }
1753 : :
1754 : 0 : return NULL; /* unknown attribute */
1755 : : }
1756 : :
1757 : : /*
1758 : : * Private substitute BIO: this does the sending and receiving using
1759 : : * pqsecure_raw_write() and pqsecure_raw_read() instead, to allow those
1760 : : * functions to disable SIGPIPE and give better error messages on I/O errors.
1761 : : *
1762 : : * These functions are closely modelled on the standard socket BIO in OpenSSL;
1763 : : * see sock_read() and sock_write() in OpenSSL's crypto/bio/bss_sock.c.
1764 : : */
1765 : :
1766 : : /* protected by ssl_config_mutex */
1767 : : static BIO_METHOD *pgconn_bio_method_ptr;
1768 : :
1769 : : static int
1770 : 3228 : pgconn_bio_read(BIO *h, char *buf, int size)
1771 : : {
1772 : 3228 : PGconn *conn = (PGconn *) BIO_get_data(h);
1773 : : int res;
1774 : :
1775 : 3228 : res = (int) pqsecure_raw_read(conn, buf, size);
1776 : 3228 : BIO_clear_retry_flags(h);
1777 : 3228 : conn->last_read_was_eof = res == 0;
1778 [ + + ]: 3228 : if (res < 0)
1779 : : {
1780 : : /* If we were interrupted, tell caller to retry */
1781 [ + + ]: 242 : switch (SOCK_ERRNO)
1782 : : {
1783 : : #ifdef EAGAIN
1784 : 241 : case EAGAIN:
1785 : : #endif
1786 : : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
1787 : : case EWOULDBLOCK:
1788 : : #endif
1789 : : case EINTR:
1790 : 241 : BIO_set_retry_read(h);
1791 : 241 : break;
1792 : :
1793 : 1 : default:
1794 : 1 : break;
1795 : : }
1796 : : }
1797 : :
1798 [ + + ]: 3228 : if (res > 0)
1799 : 2984 : conn->ssl_handshake_started = true;
1800 : :
1801 : 3228 : return res;
1802 : : }
1803 : :
1804 : : static int
1805 : 985 : pgconn_bio_write(BIO *h, const char *buf, int size)
1806 : : {
1807 : : int res;
1808 : :
1809 : 985 : res = (int) pqsecure_raw_write((PGconn *) BIO_get_data(h), buf, size);
1810 : 985 : BIO_clear_retry_flags(h);
1811 [ - + ]: 985 : if (res < 0)
1812 : : {
1813 : : /* If we were interrupted, tell caller to retry */
1814 [ # # ]: 0 : switch (SOCK_ERRNO)
1815 : : {
1816 : : #ifdef EAGAIN
1817 : 0 : case EAGAIN:
1818 : : #endif
1819 : : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
1820 : : case EWOULDBLOCK:
1821 : : #endif
1822 : : case EINTR:
1823 : 0 : BIO_set_retry_write(h);
1824 : 0 : break;
1825 : :
1826 : 0 : default:
1827 : 0 : break;
1828 : : }
1829 : : }
1830 : :
1831 : 985 : return res;
1832 : : }
1833 : :
1834 : : static long
1835 : 959 : pgconn_bio_ctrl(BIO *h, int cmd, long num, void *ptr)
1836 : : {
1837 : : long res;
1838 : 959 : PGconn *conn = (PGconn *) BIO_get_data(h);
1839 : :
1840 [ + + + ]: 959 : switch (cmd)
1841 : : {
1842 : 3 : case BIO_CTRL_EOF:
1843 : :
1844 : : /*
1845 : : * This should not be needed. pgconn_bio_read already has a way to
1846 : : * signal EOF to OpenSSL. However, OpenSSL made an undocumented,
1847 : : * backwards-incompatible change and now expects EOF via BIO_ctrl.
1848 : : * See https://github.com/openssl/openssl/issues/8208
1849 : : */
1850 : 3 : res = conn->last_read_was_eof;
1851 : 3 : break;
1852 : 618 : case BIO_CTRL_FLUSH:
1853 : : /* libssl expects all BIOs to support BIO_flush. */
1854 : 618 : res = 1;
1855 : 618 : break;
1856 : 338 : default:
1857 : 338 : res = 0;
1858 : 338 : break;
1859 : : }
1860 : :
1861 : 959 : return res;
1862 : : }
1863 : :
1864 : : static BIO_METHOD *
1865 : 171 : pgconn_bio_method(void)
1866 : : {
1867 : : BIO_METHOD *res;
1868 : :
1869 [ - + ]: 171 : if (pthread_mutex_lock(&ssl_config_mutex))
1870 : 0 : return NULL;
1871 : :
1872 : 171 : res = pgconn_bio_method_ptr;
1873 : :
1874 [ + - ]: 171 : if (!pgconn_bio_method_ptr)
1875 : : {
1876 : : int my_bio_index;
1877 : :
1878 : 171 : my_bio_index = BIO_get_new_index();
1879 [ - + ]: 171 : if (my_bio_index == -1)
1880 : 0 : goto err;
1881 : 171 : my_bio_index |= BIO_TYPE_SOURCE_SINK;
1882 : 171 : res = BIO_meth_new(my_bio_index, "libpq socket");
1883 [ - + ]: 171 : if (!res)
1884 : 0 : goto err;
1885 : :
1886 : : /*
1887 : : * As of this writing, these functions never fail. But check anyway,
1888 : : * like OpenSSL's own examples do.
1889 : : */
1890 [ + - + - ]: 342 : if (!BIO_meth_set_write(res, pgconn_bio_write) ||
1891 [ - + ]: 342 : !BIO_meth_set_read(res, pgconn_bio_read) ||
1892 : 171 : !BIO_meth_set_ctrl(res, pgconn_bio_ctrl))
1893 : : {
1894 : 0 : goto err;
1895 : : }
1896 : : }
1897 : :
1898 : 171 : pgconn_bio_method_ptr = res;
1899 : 171 : pthread_mutex_unlock(&ssl_config_mutex);
1900 : 171 : return res;
1901 : :
1902 : 0 : err:
1903 [ # # ]: 0 : if (res)
1904 : 0 : BIO_meth_free(res);
1905 : 0 : pthread_mutex_unlock(&ssl_config_mutex);
1906 : 0 : return NULL;
1907 : : }
1908 : :
1909 : : static int
1910 : 171 : ssl_set_pgconn_bio(PGconn *conn)
1911 : : {
1912 : : BIO *bio;
1913 : : BIO_METHOD *bio_method;
1914 : :
1915 : 171 : bio_method = pgconn_bio_method();
1916 [ - + ]: 171 : if (bio_method == NULL)
1917 : 0 : return 0;
1918 : :
1919 : 171 : bio = BIO_new(bio_method);
1920 [ - + ]: 171 : if (bio == NULL)
1921 : 0 : return 0;
1922 : :
1923 : 171 : BIO_set_data(bio, conn);
1924 : 171 : BIO_set_init(bio, 1);
1925 : :
1926 : 171 : SSL_set_bio(conn->ssl, bio, bio);
1927 : 171 : return 1;
1928 : : }
1929 : :
1930 : : /*
1931 : : * This is the default handler to return a client cert password from
1932 : : * conn->sslpassword. Apps may install it explicitly if they want to
1933 : : * prevent openssl from ever prompting on stdin.
1934 : : */
1935 : : int
1936 : 2 : PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn)
1937 : : {
1938 [ + - + - ]: 2 : if (conn && conn->sslpassword)
1939 : : {
1940 [ - + ]: 2 : if (strlen(conn->sslpassword) + 1 > size)
1941 : 0 : fprintf(stderr, libpq_gettext("WARNING: sslpassword truncated\n"));
1942 : 2 : strncpy(buf, conn->sslpassword, size);
1943 : 2 : buf[size - 1] = '\0';
1944 : 2 : return strlen(buf);
1945 : : }
1946 : : else
1947 : : {
1948 : 0 : buf[0] = '\0';
1949 : 0 : return 0;
1950 : : }
1951 : : }
1952 : :
1953 : : PQsslKeyPassHook_OpenSSL_type
1954 : 0 : PQgetSSLKeyPassHook_OpenSSL(void)
1955 : : {
1956 : 0 : return PQsslKeyPassHook;
1957 : : }
1958 : :
1959 : : void
1960 : 0 : PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook)
1961 : : {
1962 : 0 : PQsslKeyPassHook = hook;
1963 : 0 : }
1964 : :
1965 : : /*
1966 : : * Supply a password to decrypt a client certificate.
1967 : : *
1968 : : * This must match OpenSSL type pem_password_cb.
1969 : : */
1970 : : static int
1971 : 2 : PQssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
1972 : : {
1973 : 2 : PGconn *conn = userdata;
1974 : :
1975 [ - + ]: 2 : if (PQsslKeyPassHook)
1976 : 0 : return PQsslKeyPassHook(buf, size, conn);
1977 : : else
1978 : 2 : return PQdefaultSSLKeyPassHook_OpenSSL(buf, size, conn);
1979 : : }
1980 : :
1981 : : /*
1982 : : * Convert TLS protocol version string to OpenSSL values
1983 : : *
1984 : : * If a version is passed that is not supported by the current OpenSSL version,
1985 : : * then we return -1. If a non-negative value is returned, subsequent code can
1986 : : * assume it is working with a supported version.
1987 : : *
1988 : : * Note: this is rather similar to the backend routine in be-secure-openssl.c,
1989 : : * so make sure to update both routines if changing this one.
1990 : : */
1991 : : static int
1992 : 176 : ssl_protocol_version_to_openssl(const char *protocol)
1993 : : {
1994 [ - + ]: 176 : if (pg_strcasecmp("TLSv1", protocol) == 0)
1995 : 0 : return TLS1_VERSION;
1996 : :
1997 : : #ifdef TLS1_1_VERSION
1998 [ - + ]: 176 : if (pg_strcasecmp("TLSv1.1", protocol) == 0)
1999 : 0 : return TLS1_1_VERSION;
2000 : : #endif
2001 : :
2002 : : #ifdef TLS1_2_VERSION
2003 [ + - ]: 176 : if (pg_strcasecmp("TLSv1.2", protocol) == 0)
2004 : 176 : return TLS1_2_VERSION;
2005 : : #endif
2006 : :
2007 : : #ifdef TLS1_3_VERSION
2008 [ # # ]: 0 : if (pg_strcasecmp("TLSv1.3", protocol) == 0)
2009 : 0 : return TLS1_3_VERSION;
2010 : : #endif
2011 : :
2012 : 0 : return -1;
2013 : : }
|