diff --git a/contrib/sslinfo/sslinfo.c b/contrib/sslinfo/sslinfo.c index 5ba3988e27..30cae0bb98 100644 --- a/contrib/sslinfo/sslinfo.c +++ b/contrib/sslinfo/sslinfo.c @@ -22,7 +22,6 @@ PG_MODULE_MAGIC; static Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName); -static Datum X509_NAME_to_text(X509_NAME *name); static Datum ASN1_STRING_to_text(ASN1_STRING *str); /* @@ -54,9 +53,16 @@ PG_FUNCTION_INFO_V1(ssl_version); Datum ssl_version(PG_FUNCTION_ARGS) { - if (MyProcPort->ssl == NULL) + const char *version; + + if (!MyProcPort->ssl_in_use) PG_RETURN_NULL(); - PG_RETURN_TEXT_P(cstring_to_text(SSL_get_version(MyProcPort->ssl))); + + version = be_tls_get_version(MyProcPort); + if (version == NULL) + PG_RETURN_NULL(); + + PG_RETURN_TEXT_P(cstring_to_text(version)); } @@ -67,9 +73,16 @@ PG_FUNCTION_INFO_V1(ssl_cipher); Datum ssl_cipher(PG_FUNCTION_ARGS) { - if (MyProcPort->ssl == NULL) + const char *cipher; + + if (!MyProcPort->ssl_in_use) PG_RETURN_NULL(); - PG_RETURN_TEXT_P(cstring_to_text(SSL_get_cipher(MyProcPort->ssl))); + + cipher = be_tls_get_cipher(MyProcPort); + if (cipher == NULL) + PG_RETURN_NULL(); + + PG_RETURN_TEXT_P(cstring_to_text(cipher)); } @@ -83,7 +96,7 @@ PG_FUNCTION_INFO_V1(ssl_client_cert_present); Datum ssl_client_cert_present(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL(MyProcPort->peer != NULL); + PG_RETURN_BOOL(MyProcPort->peer_cert_valid); } @@ -99,25 +112,21 @@ PG_FUNCTION_INFO_V1(ssl_client_serial); Datum ssl_client_serial(PG_FUNCTION_ARGS) { + char decimal[NAMEDATALEN]; Datum result; - Port *port = MyProcPort; - X509 *peer = port->peer; - ASN1_INTEGER *serial = NULL; - BIGNUM *b; - char *decimal; - if (!peer) + if (!MyProcPort->ssl_in_use || !MyProcPort->peer_cert_valid) + PG_RETURN_NULL(); + + be_tls_get_peer_serial(MyProcPort, decimal, NAMEDATALEN); + + if (!*decimal) PG_RETURN_NULL(); - serial = X509_get_serialNumber(peer); - b = ASN1_INTEGER_to_BN(serial, NULL); - decimal = BN_bn2dec(b); - BN_free(b); result = DirectFunctionCall3(numeric_in, CStringGetDatum(decimal), ObjectIdGetDatum(0), Int32GetDatum(-1)); - OPENSSL_free(decimal); return result; } @@ -228,7 +237,7 @@ ssl_client_dn_field(PG_FUNCTION_ARGS) text *fieldname = PG_GETARG_TEXT_PP(0); Datum result; - if (!(MyProcPort->peer)) + if (!MyProcPort->ssl_in_use || !MyProcPort->peer_cert_valid) PG_RETURN_NULL(); result = X509_NAME_field_to_text(X509_get_subject_name(MyProcPort->peer), fieldname); @@ -275,76 +284,6 @@ ssl_issuer_field(PG_FUNCTION_ARGS) } -/* - * Equivalent of X509_NAME_oneline that respects encoding - * - * This function converts X509_NAME structure to the text variable - * converting all textual data into current database encoding. - * - * Parameter: X509_NAME *name X509_NAME structure to be converted - * - * Returns: text datum which contains string representation of - * X509_NAME - */ -static Datum -X509_NAME_to_text(X509_NAME *name) -{ - BIO *membuf = BIO_new(BIO_s_mem()); - int i, - nid, - count = X509_NAME_entry_count(name); - X509_NAME_ENTRY *e; - ASN1_STRING *v; - const char *field_name; - size_t size; - char nullterm; - char *sp; - char *dp; - text *result; - - if (membuf == NULL) - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("could not create OpenSSL BIO structure"))); - - (void) BIO_set_close(membuf, BIO_CLOSE); - for (i = 0; i < count; i++) - { - e = X509_NAME_get_entry(name, i); - nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e)); - if (nid == NID_undef) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("could not get NID for ASN1_OBJECT object"))); - v = X509_NAME_ENTRY_get_data(e); - field_name = OBJ_nid2sn(nid); - if (field_name == NULL) - field_name = OBJ_nid2ln(nid); - if (field_name == NULL) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid))); - BIO_printf(membuf, "/%s=", field_name); - ASN1_STRING_print_ex(membuf, v, - ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB) - | ASN1_STRFLGS_UTF8_CONVERT)); - } - - /* ensure null termination of the BIO's content */ - nullterm = '\0'; - BIO_write(membuf, &nullterm, 1); - size = BIO_get_mem_data(membuf, &sp); - dp = pg_any_to_server(sp, size - 1, PG_UTF8); - result = cstring_to_text(dp); - if (dp != sp) - pfree(dp); - if (BIO_free(membuf) != 1) - elog(ERROR, "could not free OpenSSL BIO structure"); - - PG_RETURN_TEXT_P(result); -} - - /* * Returns current client certificate subject as one string * @@ -358,9 +297,17 @@ PG_FUNCTION_INFO_V1(ssl_client_dn); Datum ssl_client_dn(PG_FUNCTION_ARGS) { - if (!(MyProcPort->peer)) + char subject[NAMEDATALEN]; + + if (!MyProcPort->ssl_in_use || !MyProcPort->peer_cert_valid) PG_RETURN_NULL(); - return X509_NAME_to_text(X509_get_subject_name(MyProcPort->peer)); + + be_tls_get_peer_subject_name(MyProcPort, subject, NAMEDATALEN); + + if (!*subject) + PG_RETURN_NULL(); + + PG_RETURN_TEXT_P(cstring_to_text(subject)); } @@ -377,9 +324,17 @@ PG_FUNCTION_INFO_V1(ssl_issuer_dn); Datum ssl_issuer_dn(PG_FUNCTION_ARGS) { - if (!(MyProcPort->peer)) + char issuer[NAMEDATALEN]; + + if (!MyProcPort->ssl_in_use || !MyProcPort->peer_cert_valid) PG_RETURN_NULL(); - return X509_NAME_to_text(X509_get_issuer_name(MyProcPort->peer)); + + be_tls_get_peer_issuer_name(MyProcPort, issuer, NAMEDATALEN); + + if (!*issuer) + PG_RETURN_NULL(); + + PG_RETURN_TEXT_P(cstring_to_text(issuer)); } diff --git a/doc/src/sgml/sslinfo.sgml b/doc/src/sgml/sslinfo.sgml index e16f61b41d..3213c039ca 100644 --- a/doc/src/sgml/sslinfo.sgml +++ b/doc/src/sgml/sslinfo.sgml @@ -53,8 +53,8 @@ - Returns the name of the protocol used for the SSL connection (e.g., TLSv1.0 - TLSv1.1, or TLSv1.2). + Returns the name of the protocol used for the SSL connection (e.g., TLSv1.0, + TLSv1.1, TLSv1.2 or TLSv1.3).