Skip to content

Commit 5d1833f

Browse files
committed
Use be_tls_* API for SSL information in sslinfo
sslinfo was passing the Port->ssl member directly to OpenSSL in order to extract information regarding the connection. This breaks the API provided by the backend TLS implementation, as well as duplicates code for no benefit. Rewrite to make use of the backend API as much as possible. Author: Daniel Gustafsson <daniel@yesql.se>
1 parent 3165426 commit 5d1833f

File tree

2 files changed

+49
-94
lines changed

2 files changed

+49
-94
lines changed

contrib/sslinfo/sslinfo.c

+47-92
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
PG_MODULE_MAGIC;
2323

2424
static Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName);
25-
static Datum X509_NAME_to_text(X509_NAME *name);
2625
static Datum ASN1_STRING_to_text(ASN1_STRING *str);
2726

2827
/*
@@ -54,9 +53,16 @@ PG_FUNCTION_INFO_V1(ssl_version);
5453
Datum
5554
ssl_version(PG_FUNCTION_ARGS)
5655
{
57-
if (MyProcPort->ssl == NULL)
56+
const char *version;
57+
58+
if (!MyProcPort->ssl_in_use)
59+
PG_RETURN_NULL();
60+
61+
version = be_tls_get_version(MyProcPort);
62+
if (version == NULL)
5863
PG_RETURN_NULL();
59-
PG_RETURN_TEXT_P(cstring_to_text(SSL_get_version(MyProcPort->ssl)));
64+
65+
PG_RETURN_TEXT_P(cstring_to_text(version));
6066
}
6167

6268

@@ -67,9 +73,16 @@ PG_FUNCTION_INFO_V1(ssl_cipher);
6773
Datum
6874
ssl_cipher(PG_FUNCTION_ARGS)
6975
{
70-
if (MyProcPort->ssl == NULL)
76+
const char *cipher;
77+
78+
if (!MyProcPort->ssl_in_use)
79+
PG_RETURN_NULL();
80+
81+
cipher = be_tls_get_cipher(MyProcPort);
82+
if (cipher == NULL)
7183
PG_RETURN_NULL();
72-
PG_RETURN_TEXT_P(cstring_to_text(SSL_get_cipher(MyProcPort->ssl)));
84+
85+
PG_RETURN_TEXT_P(cstring_to_text(cipher));
7386
}
7487

7588

@@ -83,7 +96,7 @@ PG_FUNCTION_INFO_V1(ssl_client_cert_present);
8396
Datum
8497
ssl_client_cert_present(PG_FUNCTION_ARGS)
8598
{
86-
PG_RETURN_BOOL(MyProcPort->peer != NULL);
99+
PG_RETURN_BOOL(MyProcPort->peer_cert_valid);
87100
}
88101

89102

@@ -99,25 +112,21 @@ PG_FUNCTION_INFO_V1(ssl_client_serial);
99112
Datum
100113
ssl_client_serial(PG_FUNCTION_ARGS)
101114
{
115+
char decimal[NAMEDATALEN];
102116
Datum result;
103-
Port *port = MyProcPort;
104-
X509 *peer = port->peer;
105-
ASN1_INTEGER *serial = NULL;
106-
BIGNUM *b;
107-
char *decimal;
108117

109-
if (!peer)
118+
if (!MyProcPort->ssl_in_use || !MyProcPort->peer_cert_valid)
119+
PG_RETURN_NULL();
120+
121+
be_tls_get_peer_serial(MyProcPort, decimal, NAMEDATALEN);
122+
123+
if (!*decimal)
110124
PG_RETURN_NULL();
111-
serial = X509_get_serialNumber(peer);
112-
b = ASN1_INTEGER_to_BN(serial, NULL);
113-
decimal = BN_bn2dec(b);
114125

115-
BN_free(b);
116126
result = DirectFunctionCall3(numeric_in,
117127
CStringGetDatum(decimal),
118128
ObjectIdGetDatum(0),
119129
Int32GetDatum(-1));
120-
OPENSSL_free(decimal);
121130
return result;
122131
}
123132

@@ -228,7 +237,7 @@ ssl_client_dn_field(PG_FUNCTION_ARGS)
228237
text *fieldname = PG_GETARG_TEXT_PP(0);
229238
Datum result;
230239

231-
if (!(MyProcPort->peer))
240+
if (!MyProcPort->ssl_in_use || !MyProcPort->peer_cert_valid)
232241
PG_RETURN_NULL();
233242

234243
result = X509_NAME_field_to_text(X509_get_subject_name(MyProcPort->peer), fieldname);
@@ -275,76 +284,6 @@ ssl_issuer_field(PG_FUNCTION_ARGS)
275284
}
276285

277286

278-
/*
279-
* Equivalent of X509_NAME_oneline that respects encoding
280-
*
281-
* This function converts X509_NAME structure to the text variable
282-
* converting all textual data into current database encoding.
283-
*
284-
* Parameter: X509_NAME *name X509_NAME structure to be converted
285-
*
286-
* Returns: text datum which contains string representation of
287-
* X509_NAME
288-
*/
289-
static Datum
290-
X509_NAME_to_text(X509_NAME *name)
291-
{
292-
BIO *membuf = BIO_new(BIO_s_mem());
293-
int i,
294-
nid,
295-
count = X509_NAME_entry_count(name);
296-
X509_NAME_ENTRY *e;
297-
ASN1_STRING *v;
298-
const char *field_name;
299-
size_t size;
300-
char nullterm;
301-
char *sp;
302-
char *dp;
303-
text *result;
304-
305-
if (membuf == NULL)
306-
ereport(ERROR,
307-
(errcode(ERRCODE_OUT_OF_MEMORY),
308-
errmsg("could not create OpenSSL BIO structure")));
309-
310-
(void) BIO_set_close(membuf, BIO_CLOSE);
311-
for (i = 0; i < count; i++)
312-
{
313-
e = X509_NAME_get_entry(name, i);
314-
nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
315-
if (nid == NID_undef)
316-
ereport(ERROR,
317-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
318-
errmsg("could not get NID for ASN1_OBJECT object")));
319-
v = X509_NAME_ENTRY_get_data(e);
320-
field_name = OBJ_nid2sn(nid);
321-
if (field_name == NULL)
322-
field_name = OBJ_nid2ln(nid);
323-
if (field_name == NULL)
324-
ereport(ERROR,
325-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
326-
errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid)));
327-
BIO_printf(membuf, "/%s=", field_name);
328-
ASN1_STRING_print_ex(membuf, v,
329-
((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
330-
| ASN1_STRFLGS_UTF8_CONVERT));
331-
}
332-
333-
/* ensure null termination of the BIO's content */
334-
nullterm = '\0';
335-
BIO_write(membuf, &nullterm, 1);
336-
size = BIO_get_mem_data(membuf, &sp);
337-
dp = pg_any_to_server(sp, size - 1, PG_UTF8);
338-
result = cstring_to_text(dp);
339-
if (dp != sp)
340-
pfree(dp);
341-
if (BIO_free(membuf) != 1)
342-
elog(ERROR, "could not free OpenSSL BIO structure");
343-
344-
PG_RETURN_TEXT_P(result);
345-
}
346-
347-
348287
/*
349288
* Returns current client certificate subject as one string
350289
*
@@ -358,9 +297,17 @@ PG_FUNCTION_INFO_V1(ssl_client_dn);
358297
Datum
359298
ssl_client_dn(PG_FUNCTION_ARGS)
360299
{
361-
if (!(MyProcPort->peer))
300+
char subject[NAMEDATALEN];
301+
302+
if (!MyProcPort->ssl_in_use || !MyProcPort->peer_cert_valid)
303+
PG_RETURN_NULL();
304+
305+
be_tls_get_peer_subject_name(MyProcPort, subject, NAMEDATALEN);
306+
307+
if (!*subject)
362308
PG_RETURN_NULL();
363-
return X509_NAME_to_text(X509_get_subject_name(MyProcPort->peer));
309+
310+
PG_RETURN_TEXT_P(cstring_to_text(subject));
364311
}
365312

366313

@@ -377,9 +324,17 @@ PG_FUNCTION_INFO_V1(ssl_issuer_dn);
377324
Datum
378325
ssl_issuer_dn(PG_FUNCTION_ARGS)
379326
{
380-
if (!(MyProcPort->peer))
327+
char issuer[NAMEDATALEN];
328+
329+
if (!MyProcPort->ssl_in_use || !MyProcPort->peer_cert_valid)
381330
PG_RETURN_NULL();
382-
return X509_NAME_to_text(X509_get_issuer_name(MyProcPort->peer));
331+
332+
be_tls_get_peer_issuer_name(MyProcPort, issuer, NAMEDATALEN);
333+
334+
if (!*issuer)
335+
PG_RETURN_NULL();
336+
337+
PG_RETURN_TEXT_P(cstring_to_text(issuer));
383338
}
384339

385340

doc/src/sgml/sslinfo.sgml

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@
5353
</term>
5454
<listitem>
5555
<para>
56-
Returns the name of the protocol used for the SSL connection (e.g., TLSv1.0
57-
TLSv1.1, or TLSv1.2).
56+
Returns the name of the protocol used for the SSL connection (e.g., TLSv1.0,
57+
TLSv1.1, TLSv1.2 or TLSv1.3).
5858
</para>
5959
</listitem>
6060
</varlistentry>

0 commit comments

Comments
 (0)