|
57 | 57 | * include <wincrypt.h>, but some other Windows headers do.)
|
58 | 58 | */
|
59 | 59 | #include "common/openssl.h"
|
| 60 | +#include <openssl/ssl.h> |
60 | 61 | #include <openssl/conf.h>
|
61 | 62 | #ifdef USE_SSL_ENGINE
|
62 | 63 | #include <openssl/engine.h>
|
@@ -684,6 +685,49 @@ pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn,
|
684 | 685 | /* See pqcomm.h comments on OpenSSL implementation of ALPN (RFC 7301) */
|
685 | 686 | static unsigned char alpn_protos[] = PG_ALPN_PROTOCOL_VECTOR;
|
686 | 687 |
|
| 688 | +#ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK |
| 689 | +/* |
| 690 | +* SSL Key Logging callback |
| 691 | +* |
| 692 | +* This callback lets the user store all key material to a file for debugging |
| 693 | +* purposes. The file will be written using the NSS keylog format. LibreSSL |
| 694 | +* 3.5 introduced stub function to set the callback for OpenSSL compatibility |
| 695 | +* but the callback is never invoked. |
| 696 | +*/ |
| 697 | +static void |
| 698 | +SSL_CTX_keylog_cb(const SSL *ssl, const char *line) |
| 699 | +{ |
| 700 | +int fd; |
| 701 | +mode_t old_umask; |
| 702 | +ssize_t rc; |
| 703 | +PGconn *conn = SSL_get_app_data(ssl); |
| 704 | + |
| 705 | +if (conn == NULL) |
| 706 | +return; |
| 707 | + |
| 708 | +old_umask = umask(077); |
| 709 | +fd = open(conn->sslkeylogfile, O_WRONLY | O_APPEND | O_CREAT, 0600); |
| 710 | +umask(old_umask); |
| 711 | + |
| 712 | +if (fd == -1) |
| 713 | +{ |
| 714 | +libpq_append_conn_error(conn, "could not open ssl keylog file %s: %s", |
| 715 | +conn->sslkeylogfile, pg_strerror(errno)); |
| 716 | +return; |
| 717 | +} |
| 718 | + |
| 719 | +/* line is guaranteed by OpenSSL to be NUL terminated */ |
| 720 | +rc = write(fd, line, strlen(line)); |
| 721 | +if (rc < 0) |
| 722 | +libpq_append_conn_error(conn, "could not write to ssl keylog file %s: %s", |
| 723 | +conn->sslkeylogfile, pg_strerror(errno)); |
| 724 | +else |
| 725 | +rc = write(fd, "\n", 1); |
| 726 | +(void) rc; /* silence compiler warnings */ |
| 727 | +close(fd); |
| 728 | +} |
| 729 | +#endif |
| 730 | + |
687 | 731 | /*
|
688 | 732 | * Create per-connection SSL object, and load the client certificate,
|
689 | 733 | * private key, and trusted CA certs.
|
@@ -1000,6 +1044,20 @@ initialize_SSL(PGconn *conn)
|
1000 | 1044 | }
|
1001 | 1045 | conn->ssl_in_use = true;
|
1002 | 1046 |
|
| 1047 | +if (conn->sslkeylogfile && strlen(conn->sslkeylogfile) > 0) |
| 1048 | +{ |
| 1049 | +#ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK |
| 1050 | +SSL_CTX_set_keylog_callback(SSL_context, SSL_CTX_keylog_cb); |
| 1051 | +#else |
| 1052 | +#ifdef LIBRESSL_VERSION_NUMBER |
| 1053 | +fprintf(stderr, libpq_gettext("WARNING: sslkeylogfile support requires OpenSSL\n")); |
| 1054 | +#else |
| 1055 | +fprintf(stderr, libpq_gettext("WARNING: libpq was not built with sslkeylogfile support\n")); |
| 1056 | +#endif |
| 1057 | +#endif |
| 1058 | +} |
| 1059 | + |
| 1060 | + |
1003 | 1061 | /*
|
1004 | 1062 | * SSL contexts are reference counted by OpenSSL. We can free it as soon
|
1005 | 1063 | * as we have created the SSL object, and it will stick around for as long
|
|
0 commit comments