27 #ifdef HAVE_NETINET_TCP_H 28 #include <netinet/tcp.h> 32 #include <openssl/ssl.h> 33 #include <openssl/dh.h> 34 #include <openssl/conf.h> 35 #ifndef OPENSSL_NO_ECDH 36 #include <openssl/ec.h> 61 static int verify_cb(
int, X509_STORE_CTX *);
63 static bool initialize_dh(SSL_CTX *context,
bool isServerStart);
84 STACK_OF(X509_NAME) * root_cert_list = NULL;
92 #ifdef HAVE_OPENSSL_INIT_SSL 93 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
97 SSL_load_error_strings();
108 context = SSL_CTX_new(SSLv23_method());
112 (
errmsg(
"could not create SSL context: %s",
121 SSL_CTX_set_mode(context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
126 (*openssl_tls_init_hook) (context, isServerStart);
134 if (SSL_CTX_use_certificate_chain_file(context,
ssl_cert_file) != 1)
137 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
138 errmsg(
"could not load server certificate file \"%s\": %s",
151 if (SSL_CTX_use_PrivateKey_file(context,
153 SSL_FILETYPE_PEM) != 1)
157 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
158 errmsg(
"private key file \"%s\" cannot be reloaded because it requires a passphrase",
162 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
163 errmsg(
"could not load private key file \"%s\": %s",
168 if (SSL_CTX_check_private_key(context) != 1)
171 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
172 errmsg(
"check of private key failed: %s",
181 if (ssl_ver_min == -1)
185 (
errmsg(
"\"%s\" setting \"%s\" not supported by this build",
186 "ssl_min_protocol_version",
195 (
errmsg(
"could not set minimum SSL protocol version")));
204 if (ssl_ver_max == -1)
208 (
errmsg(
"\"%s\" setting \"%s\" not supported by this build",
209 "ssl_max_protocol_version",
218 (
errmsg(
"could not set maximum SSL protocol version")));
231 if (ssl_ver_min > ssl_ver_max)
234 (
errmsg(
"could not set SSL protocol version range"),
235 errdetail(
"\"%s\" cannot be higher than \"%s\"",
236 "ssl_min_protocol_version",
237 "ssl_max_protocol_version")));
243 SSL_CTX_set_options(context, SSL_OP_NO_TICKET);
246 SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);
258 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
259 errmsg(
"could not set the cipher list (no valid ciphers available)")));
265 SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE);
272 if (SSL_CTX_load_verify_locations(context,
ssl_ca_file, NULL) != 1 ||
273 (root_cert_list = SSL_load_client_CA_file(
ssl_ca_file)) == NULL)
276 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
277 errmsg(
"could not load root certificate file \"%s\": %s",
290 X509_STORE *cvstore = SSL_CTX_get_cert_store(context);
295 if (X509_STORE_load_locations(cvstore,
300 X509_STORE_set_flags(cvstore,
301 X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
306 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
307 errmsg(
"could not load SSL certificate revocation list file \"%s\": %s",
314 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
315 errmsg(
"could not load SSL certificate revocation list directory \"%s\": %s",
322 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
323 errmsg(
"could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s",
338 SSL_CTX_set_verify(context,
340 SSL_VERIFY_CLIENT_ONCE),
348 SSL_CTX_set_client_CA_list(context, root_cert_list);
363 ssl_loaded_verify_locations =
true;
365 ssl_loaded_verify_locations =
false;
371 SSL_CTX_free(context);
381 ssl_loaded_verify_locations =
false;
391 bool give_proto_hint;
399 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
400 errmsg(
"could not initialize SSL connection: SSL context not set up")));
410 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
411 errmsg(
"could not initialize SSL connection: %s",
418 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
419 errmsg(
"could not set SSL socket: %s",
436 r = SSL_accept(port->ssl);
439 err = SSL_get_error(port->ssl, r);
449 ecode = ERR_get_error();
452 case SSL_ERROR_WANT_READ:
453 case SSL_ERROR_WANT_WRITE:
462 if (err == SSL_ERROR_WANT_READ)
470 case SSL_ERROR_SYSCALL:
474 errmsg(
"could not accept SSL connection: %m")));
477 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
478 errmsg(
"could not accept SSL connection: EOF detected")));
481 switch (ERR_GET_REASON(ecode))
496 case SSL_R_NO_PROTOCOLS_AVAILABLE:
497 case SSL_R_UNSUPPORTED_PROTOCOL:
498 case SSL_R_BAD_PROTOCOL_VERSION_NUMBER:
499 case SSL_R_UNKNOWN_PROTOCOL:
500 case SSL_R_UNKNOWN_SSL_VERSION:
501 case SSL_R_UNSUPPORTED_SSL_VERSION:
502 case SSL_R_WRONG_SSL_VERSION:
503 case SSL_R_WRONG_VERSION_NUMBER:
504 case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
505 #ifdef SSL_R_VERSION_TOO_HIGH 506 case SSL_R_VERSION_TOO_HIGH:
507 case SSL_R_VERSION_TOO_LOW:
509 give_proto_hint =
true;
512 give_proto_hint =
false;
516 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
517 errmsg(
"could not accept SSL connection: %s",
520 errhint(
"This may indicate that the client does not support any SSL protocol version between %s and %s.",
523 MIN_OPENSSL_TLS_VERSION,
526 MAX_OPENSSL_TLS_VERSION) : 0));
528 case SSL_ERROR_ZERO_RETURN:
530 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
531 errmsg(
"could not accept SSL connection: EOF detected")));
535 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
536 errmsg(
"unrecognized SSL error code: %d",
544 port->peer = SSL_get_peer_certificate(port->ssl);
549 if (port->peer != NULL)
553 len = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
554 NID_commonName, NULL, 0);
560 r = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
561 NID_commonName, peer_cn, len + 1);
574 if (len != strlen(peer_cn))
577 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
578 errmsg(
"SSL certificate's common name contains embedded null")));
596 SSL_shutdown(port->ssl);
604 X509_free(port->peer);
624 n = SSL_read(port->ssl, ptr, len);
625 err = SSL_get_error(port->ssl, n);
626 ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
632 case SSL_ERROR_WANT_READ:
637 case SSL_ERROR_WANT_WRITE:
642 case SSL_ERROR_SYSCALL:
652 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
657 case SSL_ERROR_ZERO_RETURN:
663 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
664 errmsg(
"unrecognized SSL error code: %d",
683 n = SSL_write(port->ssl, ptr, len);
684 err = SSL_get_error(port->ssl, n);
685 ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
691 case SSL_ERROR_WANT_READ:
696 case SSL_ERROR_WANT_WRITE:
701 case SSL_ERROR_SYSCALL:
711 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
716 case SSL_ERROR_ZERO_RETURN:
727 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
728 errmsg(
"unrecognized SSL error code: %d",
756 #ifndef HAVE_BIO_GET_DATA 757 #define BIO_get_data(bio) (bio->ptr) 758 #define BIO_set_data(bio, data) (bio->ptr = data) 771 BIO_clear_retry_flags(h);
777 BIO_set_retry_read(h);
791 BIO_clear_retry_flags(h);
797 BIO_set_retry_write(h);
809 BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
810 #ifdef HAVE_BIO_METH_NEW 813 my_bio_index = BIO_get_new_index();
814 if (my_bio_index == -1)
816 my_bio_methods = BIO_meth_new(my_bio_index,
"PostgreSQL backend socket");
824 !BIO_meth_set_create(
my_bio_methods, BIO_meth_get_create(biom)) ||
825 !BIO_meth_set_destroy(
my_bio_methods, BIO_meth_get_destroy(biom)) ||
826 !BIO_meth_set_callback_ctrl(
my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
850 BIO_METHOD *bio_method;
853 if (bio_method == NULL)
855 SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
858 bio = BIO_new(bio_method);
862 SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
867 BIO_set_fd(bio, fd, BIO_NOCLOSE);
868 SSL_set_bio(port->ssl, bio, bio);
893 errmsg(
"could not open DH parameters file \"%s\": %m",
898 dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
904 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
905 errmsg(
"could not load DH parameters file: %s",
911 if (DH_check(dh, &codes) == 0)
914 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
915 errmsg(
"invalid DH parameters: %s",
919 if (codes & DH_CHECK_P_NOT_PRIME)
922 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
923 errmsg(
"invalid DH parameters: p is not prime")));
926 if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
927 (codes & DH_CHECK_P_NOT_SAFE_PRIME))
930 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
931 errmsg(
"invalid DH parameters: neither suitable generator or safe prime")));
951 bio = BIO_new_mem_buf(
unconstify(
char *, buffer), len);
954 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
971 const char *prompt =
"Enter PEM pass phrase:";
1024 desc = SSL_state_string_long(ssl);
1028 case SSL_CB_HANDSHAKE_START:
1032 case SSL_CB_HANDSHAKE_DONE:
1036 case SSL_CB_ACCEPT_LOOP:
1040 case SSL_CB_ACCEPT_EXIT:
1044 case SSL_CB_CONNECT_LOOP:
1048 case SSL_CB_CONNECT_EXIT:
1052 case SSL_CB_READ_ALERT:
1056 case SSL_CB_WRITE_ALERT:
1081 SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
1090 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1091 errmsg(
"DH: could not load DH parameters")));
1095 if (SSL_CTX_set_tmp_dh(context, dh) != 1)
1098 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1099 errmsg(
"DH: could not set DH parameters: %s",
1117 #ifndef OPENSSL_NO_ECDH 1125 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1130 ecdh = EC_KEY_new_by_curve_name(nid);
1134 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1135 errmsg(
"ECDH: could not create key")));
1139 SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
1140 SSL_CTX_set_tmp_ecdh(context, ecdh);
1159 const char *errreason;
1160 static char errbuf[36];
1163 return _(
"no SSL error reported");
1164 errreason = ERR_reason_error_string(ecode);
1165 if (errreason != NULL)
1167 snprintf(errbuf,
sizeof(errbuf),
_(
"SSL error code %lu"), ecode);
1178 SSL_get_cipher_bits(port->ssl, &bits);
1189 return (SSL_get_current_compression(port->ssl) != NULL);
1198 return SSL_get_version(port->ssl);
1207 return SSL_get_cipher(port->ssl);
1235 ASN1_INTEGER *serial;
1239 serial = X509_get_serialNumber(port->peer);
1240 b = ASN1_INTEGER_to_BN(serial, NULL);
1241 decimal = BN_bn2dec(b);
1245 OPENSSL_free(decimal);
1251 #ifdef HAVE_X509_GET_SIGNATURE_NID 1253 be_tls_get_certificate_hash(
Port *
port,
size_t *len)
1257 const EVP_MD *algo_type = NULL;
1258 unsigned char hash[EVP_MAX_MD_SIZE];
1259 unsigned int hash_size;
1263 server_cert = SSL_get_certificate(port->ssl);
1264 if (server_cert == NULL)
1271 if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert),
1273 elog(
ERROR,
"could not determine server certificate signature algorithm");
1285 algo_type = EVP_sha256();
1288 algo_type = EVP_get_digestbynid(algo_nid);
1289 if (algo_type == NULL)
1290 elog(
ERROR,
"could not find digest for NID %s",
1291 OBJ_nid2sn(algo_nid));
1296 if (!X509_digest(server_cert, algo_type, hash, &hash_size))
1297 elog(
ERROR,
"could not generate server certificate hash");
1299 cert_hash =
palloc(hash_size);
1300 memcpy(cert_hash, hash, hash_size);
1314 BIO *membuf = BIO_new(BIO_s_mem());
1317 count = X509_NAME_entry_count(name);
1320 const char *field_name;
1329 (
errcode(ERRCODE_OUT_OF_MEMORY),
1330 errmsg(
"failed to create BIO")));
1332 (void) BIO_set_close(membuf, BIO_CLOSE);
1333 for (i = 0; i < count; i++)
1335 e = X509_NAME_get_entry(name, i);
1336 nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
1337 if (nid == NID_undef)
1339 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1340 errmsg(
"could not get NID for ASN1_OBJECT object")));
1341 v = X509_NAME_ENTRY_get_data(e);
1342 field_name = OBJ_nid2sn(nid);
1343 if (field_name == NULL)
1344 field_name = OBJ_nid2ln(nid);
1345 if (field_name == NULL)
1347 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1348 errmsg(
"could not convert NID %d to an ASN1_OBJECT structure", nid)));
1349 BIO_printf(membuf,
"/%s=", field_name);
1350 ASN1_STRING_print_ex(membuf, v,
1351 ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
1352 | ASN1_STRFLGS_UTF8_CONVERT));
1357 BIO_write(membuf, &nullterm, 1);
1358 size = BIO_get_mem_data(membuf, &sp);
1364 if (BIO_free(membuf) != 1)
1365 elog(
ERROR,
"could not free OpenSSL BIO structure");
1391 return TLS1_VERSION;
1393 #ifdef TLS1_1_VERSION 1394 return TLS1_1_VERSION;
1399 #ifdef TLS1_2_VERSION 1400 return TLS1_2_VERSION;
1405 #ifdef TLS1_3_VERSION 1406 return TLS1_3_VERSION;
1435 return "(unrecognized)";
static int ssl_protocol_version_to_openssl(int v)
ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor)
#define WL_SOCKET_WRITEABLE
int errhint(const char *fmt,...)
#define BIO_set_data(bio, data)
static bool dummy_ssl_passwd_cb_called
static BIO_METHOD * my_BIO_s_socket(void)
static DH * load_dh_file(char *filename, bool isServerStart)
#define BIO_get_data(bio)
char * pstrdup(const char *in)
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
static void info_cb(const SSL *ssl, int type, int args)
const char * GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged)
int errcode(int sqlerrcode)
#define WL_SOCKET_READABLE
static bool initialize_ecdh(SSL_CTX *context, bool isServerStart)
static int fd(const char *x, int i)
int be_tls_init(bool isServerStart)
int ssl_min_protocol_version
void pfree(void *pointer)
static int my_SSL_set_fd(Port *port, int fd)
bool be_tls_get_compression(Port *port)
ssize_t be_tls_write(Port *port, void *ptr, size_t len, int *waitfor)
int errdetail(const char *fmt,...)
int errcode_for_file_access(void)
static bool SSL_initialized
FILE * AllocateFile(const char *name, const char *mode)
static int verify_cb(int, X509_STORE_CTX *)
int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
static DH * load_dh_buffer(const char *, size_t)
void be_tls_destroy(void)
MemoryContext TopMemoryContext
static char * X509_NAME_to_cstring(X509_NAME *name)
bool ssl_passphrase_command_supports_reload
int errcode_for_socket_access(void)
#define unconstify(underlying_type, expr)
static int ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata)
int be_tls_get_cipher_bits(Port *port)
static bool ssl_is_server_start
static bool initialize_dh(SSL_CTX *context, bool isServerStart)
#define ereport(elevel,...)
int be_tls_open_server(Port *port)
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
size_t strlcpy(char *dst, const char *src, size_t siz)
int errmsg_internal(const char *fmt,...)
static BIO_METHOD * my_bio_methods
int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version)
#define Assert(condition)
static int my_sock_read(BIO *h, char *buf, int size)
char * ssl_dh_params_file
const char * be_tls_get_version(Port *port)
void be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len)
int ssl_max_protocol_version
void be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len)
int errmsg(const char *fmt,...)
static SSL_CTX * SSL_context
void * MemoryContextAlloc(MemoryContext context, Size size)
void be_tls_get_peer_serial(Port *port, char *ptr, size_t len)
static int my_sock_write(BIO *h, const char *buf, int size)
static const char * SSLerrmessage(unsigned long ecode)
void be_tls_close(Port *port)
const char * be_tls_get_cipher(Port *port)
int run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, int size)
char * ssl_passphrase_command
static const char * ssl_protocol_version_to_string(int v)
int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version)
char * pg_any_to_server(const char *s, int len, int encoding)
static int dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
static unsigned hash(unsigned *uv, int n)
openssl_tls_init_hook_typ openssl_tls_init_hook
static void default_openssl_tls_init(SSL_CTX *context, bool isServerStart)
#define WL_EXIT_ON_PM_DEATH
bool SSLPreferServerCiphers
bool check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart)