47 #include <openssl/conf.h>
48 #include <openssl/dh.h>
49 #ifndef OPENSSL_NO_ECDH
50 #include <openssl/ec.h>
52 #include <openssl/x509v3.h>
68 static int verify_cb(
int ok, X509_STORE_CTX *ctx);
70 static bool initialize_dh(SSL_CTX *context,
bool isServerStart);
101 #ifdef HAVE_OPENSSL_INIT_SSL
102 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
104 OPENSSL_config(NULL);
106 SSL_load_error_strings();
121 context = SSL_CTX_new(SSLv23_method());
125 (
errmsg(
"could not create SSL context: %s",
134 SSL_CTX_set_mode(context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
139 (*openssl_tls_init_hook) (context, isServerStart);
147 if (SSL_CTX_use_certificate_chain_file(context,
ssl_cert_file) != 1)
150 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
151 errmsg(
"could not load server certificate file \"%s\": %s",
164 if (SSL_CTX_use_PrivateKey_file(context,
166 SSL_FILETYPE_PEM) != 1)
170 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
171 errmsg(
"private key file \"%s\" cannot be reloaded because it requires a passphrase",
175 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
176 errmsg(
"could not load private key file \"%s\": %s",
181 if (SSL_CTX_check_private_key(context) != 1)
184 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
185 errmsg(
"check of private key failed: %s",
194 if (ssl_ver_min == -1)
198 (
errmsg(
"%s setting \"%s\" not supported by this build",
199 "ssl_min_protocol_version",
208 (
errmsg(
"could not set minimum SSL protocol version")));
217 if (ssl_ver_max == -1)
221 (
errmsg(
"%s setting \"%s\" not supported by this build",
222 "ssl_max_protocol_version",
231 (
errmsg(
"could not set maximum SSL protocol version")));
244 if (ssl_ver_min > ssl_ver_max)
247 (
errmsg(
"could not set SSL protocol version range"),
249 "ssl_min_protocol_version",
250 "ssl_max_protocol_version")));
256 SSL_CTX_set_options(context, SSL_OP_NO_TICKET);
259 SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);
262 SSL_CTX_set_options(context, SSL_OP_NO_COMPRESSION);
264 #ifdef SSL_OP_NO_RENEGOTIATION
271 SSL_CTX_set_options(context, SSL_OP_NO_RENEGOTIATION);
284 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
285 errmsg(
"could not set the cipher list (no valid ciphers available)")));
291 SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE);
298 STACK_OF(X509_NAME) * root_cert_list;
300 if (SSL_CTX_load_verify_locations(context,
ssl_ca_file, NULL) != 1 ||
301 (root_cert_list = SSL_load_client_CA_file(
ssl_ca_file)) == NULL)
304 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
305 errmsg(
"could not load root certificate file \"%s\": %s",
317 SSL_CTX_set_client_CA_list(context, root_cert_list);
324 SSL_CTX_set_verify(context,
326 SSL_VERIFY_CLIENT_ONCE),
337 X509_STORE *cvstore = SSL_CTX_get_cert_store(context);
342 if (X509_STORE_load_locations(cvstore,
347 X509_STORE_set_flags(cvstore,
348 X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
353 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
354 errmsg(
"could not load SSL certificate revocation list file \"%s\": %s",
361 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
362 errmsg(
"could not load SSL certificate revocation list directory \"%s\": %s",
369 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
370 errmsg(
"could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s",
390 ssl_loaded_verify_locations =
true;
392 ssl_loaded_verify_locations =
false;
399 SSL_CTX_free(context);
409 ssl_loaded_verify_locations =
false;
419 bool give_proto_hint;
427 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
428 errmsg(
"could not initialize SSL connection: SSL context not set up")));
438 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
439 errmsg(
"could not initialize SSL connection: %s",
446 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
447 errmsg(
"could not set SSL socket: %s",
451 port->ssl_in_use =
true;
464 r = SSL_accept(
port->ssl);
467 err = SSL_get_error(
port->ssl, r);
477 ecode = ERR_get_error();
480 case SSL_ERROR_WANT_READ:
481 case SSL_ERROR_WANT_WRITE:
490 if (
err == SSL_ERROR_WANT_READ)
496 WAIT_EVENT_SSL_OPEN_SERVER);
498 case SSL_ERROR_SYSCALL:
502 errmsg(
"could not accept SSL connection: %m")));
505 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
506 errmsg(
"could not accept SSL connection: EOF detected")));
509 switch (ERR_GET_REASON(ecode))
524 case SSL_R_NO_PROTOCOLS_AVAILABLE:
525 case SSL_R_UNSUPPORTED_PROTOCOL:
526 case SSL_R_BAD_PROTOCOL_VERSION_NUMBER:
527 case SSL_R_UNKNOWN_PROTOCOL:
528 case SSL_R_UNKNOWN_SSL_VERSION:
529 case SSL_R_UNSUPPORTED_SSL_VERSION:
530 case SSL_R_WRONG_SSL_VERSION:
531 case SSL_R_WRONG_VERSION_NUMBER:
532 case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
533 #ifdef SSL_R_VERSION_TOO_HIGH
534 case SSL_R_VERSION_TOO_HIGH:
535 case SSL_R_VERSION_TOO_LOW:
537 give_proto_hint =
true;
540 give_proto_hint =
false;
544 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
545 errmsg(
"could not accept SSL connection: %s",
549 errhint(
"This may indicate that the client does not support any SSL protocol version between %s and %s.",
552 MIN_OPENSSL_TLS_VERSION,
555 MAX_OPENSSL_TLS_VERSION) : 0));
558 case SSL_ERROR_ZERO_RETURN:
560 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
561 errmsg(
"could not accept SSL connection: EOF detected")));
565 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
566 errmsg(
"unrecognized SSL error code: %d",
574 port->peer = SSL_get_peer_certificate(
port->ssl);
577 port->peer_cn = NULL;
578 port->peer_dn = NULL;
579 port->peer_cert_valid =
false;
580 if (
port->peer != NULL)
583 X509_NAME *x509name = X509_get_subject_name(
port->peer);
586 BUF_MEM *bio_buf = NULL;
588 len = X509_NAME_get_text_by_NID(x509name, NID_commonName, NULL, 0);
594 r = X509_NAME_get_text_by_NID(x509name, NID_commonName, peer_cn,
608 if (
len != strlen(peer_cn))
611 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
612 errmsg(
"SSL certificate's common name contains embedded null")));
617 port->peer_cn = peer_cn;
620 bio = BIO_new(BIO_s_mem());
623 if (
port->peer_cn != NULL)
626 port->peer_cn = NULL;
638 if (X509_NAME_print_ex(bio, x509name, 0, XN_FLAG_RFC2253) == -1 ||
639 BIO_get_mem_ptr(bio, &bio_buf) <= 0)
642 if (
port->peer_cn != NULL)
645 port->peer_cn = NULL;
650 memcpy(peer_dn, bio_buf->data, bio_buf->length);
651 len = bio_buf->length;
654 if (
len != strlen(peer_dn))
657 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
658 errmsg(
"SSL certificate's distinguished name contains embedded null")));
660 if (
port->peer_cn != NULL)
663 port->peer_cn = NULL;
668 port->peer_dn = peer_dn;
670 port->peer_cert_valid =
true;
681 SSL_shutdown(
port->ssl);
684 port->ssl_in_use =
false;
689 X509_free(
port->peer);
696 port->peer_cn = NULL;
702 port->peer_dn = NULL;
715 n = SSL_read(
port->ssl, ptr,
len);
716 err = SSL_get_error(
port->ssl, n);
717 ecode = (
err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
723 case SSL_ERROR_WANT_READ:
728 case SSL_ERROR_WANT_WRITE:
733 case SSL_ERROR_SYSCALL:
743 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
748 case SSL_ERROR_ZERO_RETURN:
754 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
755 errmsg(
"unrecognized SSL error code: %d",
774 n = SSL_write(
port->ssl, ptr,
len);
775 err = SSL_get_error(
port->ssl, n);
776 ecode = (
err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
782 case SSL_ERROR_WANT_READ:
787 case SSL_ERROR_WANT_WRITE:
792 case SSL_ERROR_SYSCALL:
802 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
807 case SSL_ERROR_ZERO_RETURN:
818 (
errcode(ERRCODE_PROTOCOL_VIOLATION),
819 errmsg(
"unrecognized SSL error code: %d",
855 BIO_clear_retry_flags(h);
861 BIO_set_retry_read(h);
875 BIO_clear_retry_flags(h);
881 BIO_set_retry_write(h);
893 BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
894 #ifdef HAVE_BIO_METH_NEW
897 my_bio_index = BIO_get_new_index();
898 if (my_bio_index == -1)
900 my_bio_index |= (BIO_TYPE_DESCRIPTOR | BIO_TYPE_SOURCE_SINK);
901 my_bio_methods = BIO_meth_new(my_bio_index,
"PostgreSQL backend socket");
909 !BIO_meth_set_create(
my_bio_methods, BIO_meth_get_create(biom)) ||
910 !BIO_meth_set_destroy(
my_bio_methods, BIO_meth_get_destroy(biom)) ||
911 !BIO_meth_set_callback_ctrl(
my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
935 BIO_METHOD *bio_method;
938 if (bio_method == NULL)
940 SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
943 bio = BIO_new(bio_method);
947 SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
950 BIO_set_app_data(bio,
port);
952 BIO_set_fd(bio,
fd, BIO_NOCLOSE);
953 SSL_set_bio(
port->ssl, bio, bio);
978 errmsg(
"could not open DH parameters file \"%s\": %m",
983 dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
989 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
990 errmsg(
"could not load DH parameters file: %s",
996 if (DH_check(dh, &codes) == 0)
999 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1000 errmsg(
"invalid DH parameters: %s",
1005 if (codes & DH_CHECK_P_NOT_PRIME)
1008 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1009 errmsg(
"invalid DH parameters: p is not prime")));
1013 if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
1014 (codes & DH_CHECK_P_NOT_SAFE_PRIME))
1017 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1018 errmsg(
"invalid DH parameters: neither suitable generator or safe prime")));
1042 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
1059 const char *prompt =
"Enter PEM pass phrase:";
1095 size_t namelen = strlen(
name);
1096 char *truncated =
name;
1113 truncated[0] = truncated[1] = truncated[2] =
'.';
1137 const char *errstring;
1148 depth = X509_STORE_CTX_get_error_depth(ctx);
1149 errcode = X509_STORE_CTX_get_error(ctx);
1150 errstring = X509_verify_cert_error_string(
errcode);
1154 _(
"Client certificate verification failed at depth %d: %s."),
1157 cert = X509_STORE_CTX_get_current_cert(ctx);
1185 sn = X509_get_serialNumber(cert);
1186 b = ASN1_INTEGER_to_BN(sn, NULL);
1187 serialno = BN_bn2dec(
b);
1191 _(
"Failed certificate data (unverified): subject \"%s\", serial number %s, issuer \"%s\"."),
1192 sub_prepared, serialno ? serialno :
_(
"unknown"),
1196 OPENSSL_free(serialno);
1197 pfree(iss_prepared);
1198 pfree(sub_prepared);
1216 desc = SSL_state_string_long(ssl);
1220 case SSL_CB_HANDSHAKE_START:
1224 case SSL_CB_HANDSHAKE_DONE:
1228 case SSL_CB_ACCEPT_LOOP:
1232 case SSL_CB_ACCEPT_EXIT:
1236 case SSL_CB_CONNECT_LOOP:
1240 case SSL_CB_CONNECT_EXIT:
1244 case SSL_CB_READ_ALERT:
1248 case SSL_CB_WRITE_ALERT:
1273 SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
1282 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1283 errmsg(
"DH: could not load DH parameters")));
1287 if (SSL_CTX_set_tmp_dh(context, dh) != 1)
1290 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1291 errmsg(
"DH: could not set DH parameters: %s",
1309 #ifndef OPENSSL_NO_ECDH
1317 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1322 ecdh = EC_KEY_new_by_curve_name(nid);
1326 (
errcode(ERRCODE_CONFIG_FILE_ERROR),
1327 errmsg(
"ECDH: could not create key")));
1331 SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
1332 SSL_CTX_set_tmp_ecdh(context, ecdh);
1351 const char *errreason;
1352 static char errbuf[36];
1355 return _(
"no SSL error reported");
1356 errreason = ERR_reason_error_string(ecode);
1357 if (errreason != NULL)
1359 snprintf(errbuf,
sizeof(errbuf),
_(
"SSL error code %lu"), ecode);
1370 SSL_get_cipher_bits(
port->ssl, &bits);
1381 return SSL_get_version(
port->ssl);
1390 return SSL_get_cipher(
port->ssl);
1418 ASN1_INTEGER *serial;
1422 serial = X509_get_serialNumber(
port->peer);
1423 b = ASN1_INTEGER_to_BN(serial, NULL);
1439 const EVP_MD *algo_type = NULL;
1440 unsigned char hash[EVP_MAX_MD_SIZE];
1441 unsigned int hash_size;
1445 server_cert = SSL_get_certificate(
port->ssl);
1446 if (server_cert == NULL)
1454 #if HAVE_X509_GET_SIGNATURE_INFO
1455 if (!X509_get_signature_info(server_cert, &algo_nid, NULL, NULL, NULL))
1457 if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert),
1460 elog(
ERROR,
"could not determine server certificate signature algorithm");
1472 algo_type = EVP_sha256();
1475 algo_type = EVP_get_digestbynid(algo_nid);
1476 if (algo_type == NULL)
1477 elog(
ERROR,
"could not find digest for NID %s",
1478 OBJ_nid2sn(algo_nid));
1483 if (!X509_digest(server_cert, algo_type,
hash, &hash_size))
1484 elog(
ERROR,
"could not generate server certificate hash");
1486 cert_hash =
palloc(hash_size);
1487 memcpy(cert_hash,
hash, hash_size);
1500 BIO *membuf = BIO_new(BIO_s_mem());
1503 count = X509_NAME_entry_count(
name);
1506 const char *field_name;
1515 (
errcode(ERRCODE_OUT_OF_MEMORY),
1516 errmsg(
"could not create BIO")));
1518 (void) BIO_set_close(membuf, BIO_CLOSE);
1519 for (
i = 0;
i < count;
i++)
1521 e = X509_NAME_get_entry(
name,
i);
1522 nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(
e));
1523 if (nid == NID_undef)
1525 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1526 errmsg(
"could not get NID for ASN1_OBJECT object")));
1527 v = X509_NAME_ENTRY_get_data(
e);
1528 field_name = OBJ_nid2sn(nid);
1529 if (field_name == NULL)
1530 field_name = OBJ_nid2ln(nid);
1531 if (field_name == NULL)
1533 (
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1534 errmsg(
"could not convert NID %d to an ASN1_OBJECT structure", nid)));
1535 BIO_printf(membuf,
"/%s=", field_name);
1536 ASN1_STRING_print_ex(membuf, v,
1537 ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
1538 | ASN1_STRFLGS_UTF8_CONVERT));
1543 BIO_write(membuf, &nullterm, 1);
1544 size = BIO_get_mem_data(membuf, &sp);
1550 if (BIO_free(membuf) != 1)
1551 elog(
ERROR,
"could not free OpenSSL BIO structure");
1578 return TLS1_VERSION;
1580 #ifdef TLS1_1_VERSION
1581 return TLS1_1_VERSION;
1586 #ifdef TLS1_2_VERSION
1587 return TLS1_2_VERSION;
1592 #ifdef TLS1_3_VERSION
1593 return TLS1_3_VERSION;
1622 return "(unrecognized)";
bool check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart)
int run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, int size)
static const char * ssl_protocol_version_to_string(int v)
static const char * cert_errdetail
const char * be_tls_get_version(Port *port)
static void info_cb(const SSL *ssl, int type, int args)
static const char * SSLerrmessage(unsigned long ecode)
void be_tls_destroy(void)
int be_tls_init(bool isServerStart)
openssl_tls_init_hook_typ openssl_tls_init_hook
int be_tls_get_cipher_bits(Port *port)
int be_tls_open_server(Port *port)
char * be_tls_get_certificate_hash(Port *port, size_t *len)
static DH * load_dh_buffer(const char *buffer, size_t len)
static BIO_METHOD * my_bio_methods
static int dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
static int my_SSL_set_fd(Port *port, int fd)
static void default_openssl_tls_init(SSL_CTX *context, bool isServerStart)
static char * prepare_cert_name(char *name)
void be_tls_get_peer_serial(Port *port, char *ptr, size_t len)
static int ssl_protocol_version_to_openssl(int v)
static BIO_METHOD * my_BIO_s_socket(void)
static bool initialize_dh(SSL_CTX *context, bool isServerStart)
void be_tls_close(Port *port)
void be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len)
ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor)
static char * X509_NAME_to_cstring(X509_NAME *name)
ssize_t be_tls_write(Port *port, void *ptr, size_t len, int *waitfor)
static int ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata)
static SSL_CTX * SSL_context
static bool ssl_is_server_start
const char * be_tls_get_cipher(Port *port)
static bool SSL_initialized
static int verify_cb(int ok, X509_STORE_CTX *ctx)
static bool initialize_ecdh(SSL_CTX *context, bool isServerStart)
static bool dummy_ssl_passwd_cb_called
static DH * load_dh_file(char *filename, bool isServerStart)
static int my_sock_write(BIO *h, const char *buf, int size)
void be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len)
static int my_sock_read(BIO *h, char *buf, int size)
char * ssl_dh_params_file
int ssl_min_protocol_version
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
bool SSLPreferServerCiphers
int ssl_max_protocol_version
char * ssl_passphrase_command
bool ssl_passphrase_command_supports_reload
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
#define unconstify(underlying_type, expr)
static void PGresult * res
elog(ERROR, "%s: %s", p2, msg)
int errcode_for_socket_access(void)
int errmsg_internal(const char *fmt,...)
int errdetail_internal(const char *fmt,...)
int errcode_for_file_access(void)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void err(int eval, const char *fmt,...)
FILE * AllocateFile(const char *name, const char *mode)
const char * GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged)
int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
#define WL_SOCKET_READABLE
#define WL_EXIT_ON_PM_DEATH
#define WL_SOCKET_WRITEABLE
Assert(fmt[strlen(fmt) - 1] !='\n')
char * pg_any_to_server(const char *s, int len, int encoding)
char * pstrdup(const char *in)
void pfree(void *pointer)
MemoryContext TopMemoryContext
void * MemoryContextAlloc(MemoryContext context, Size size)
size_t strlcpy(char *dst, const char *src, size_t siz)
static int fd(const char *x, int i)
int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version)
int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version)
static unsigned hash(unsigned *uv, int n)
char * pg_clean_ascii(const char *str, int alloc_flags)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)