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