Browse code

tls: new config variable $tls(key)

- return attributes related to tls communication
- first implemented keys:
- m_subject_line - return local (my) certificate subject line
- p_subject_line - return remote (peer) certificate subject line

Daniel-Constantin Mierla authored on 24/11/2021 08:30:22
Showing 1 changed files
... ...
@@ -39,6 +39,7 @@
39 39
 #include "../../core/tcp_server.h"
40 40
 #include "../../core/tcp_conn.h"
41 41
 #include "../../core/ut.h"
42
+#include "../../core/pvapi.h"
42 43
 #include "../../core/cfg/cfg.h"
43 44
 #include "../../core/dprint.h"
44 45
 #include "../../core/strutils.h"
... ...
@@ -1256,8 +1257,84 @@ static int pv_tlsext_sn(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
1256 1257
 }
1257 1258
 
1258 1259
 
1260
+int pv_parse_tls_name(pv_spec_p sp, str *in)
1261
+{
1262
+	if(sp==NULL || in==NULL || in->len<=0)
1263
+		return -1;
1264
+
1265
+	switch(in->len) {
1266
+		case 14:
1267
+			if(strncmp(in->s, "m_subject_line", 14)==0)
1268
+				sp->pvp.pvn.u.isname.name.n = 1000;
1269
+			else if(strncmp(in->s, "p_subject_line", 14)==0)
1270
+				sp->pvp.pvn.u.isname.name.n = 5000;
1271
+			else goto error;
1272
+		break;
1273
+		default:
1274
+			goto error;
1275
+	}
1276
+	sp->pvp.pvn.type = PV_NAME_INTSTR;
1277
+	sp->pvp.pvn.u.isname.type = 0;
1259 1278
 
1279
+	return 0;
1260 1280
 
1281
+error:
1282
+	LM_ERR("unknown PV tls name %.*s\n", in->len, in->s);
1283
+	return -1;
1284
+}
1285
+
1286
+
1287
+int pv_get_tls(struct sip_msg *msg, pv_param_t *param,
1288
+		pv_value_t *res)
1289
+{
1290
+	SSL *ssl = NULL;
1291
+	tcp_connection_t *c = NULL;
1292
+	X509 *cert = NULL;
1293
+	str sv = STR_NULL;
1294
+
1295
+	if(msg==NULL || param==NULL) {
1296
+		return -1;
1297
+	}
1298
+
1299
+	c = get_cur_connection(msg);
1300
+	if (c == NULL) {
1301
+		LM_DBG("TLS connection not found\n");
1302
+		return pv_get_null(msg, param, res);
1303
+	}
1304
+	ssl = get_ssl(c);
1305
+	if (ssl == NULL) {
1306
+		goto error;
1307
+	}
1308
+	cert = (param->pvn.u.isname.name.n < 5000) ? SSL_get_certificate(ssl)
1309
+					: SSL_get_peer_certificate(ssl);
1310
+	if (cert == NULL) {
1311
+		if (param->pvn.u.isname.name.n < 5000) {
1312
+			LM_ERR("Unable to retrieve my TLS certificate from SSL structure\n");
1313
+		} else {
1314
+			LM_ERR("Unable to retrieve peer TLS certificate from SSL structure\n");
1315
+		}
1316
+		goto error;
1317
+	}
1318
+
1319
+	switch(param->pvn.u.isname.name.n)
1320
+	{
1321
+		case 1000:
1322
+		case 5000:
1323
+			sv.s = pv_get_buffer();
1324
+			sv.len = pv_get_buffer_size() - 1;
1325
+			if(X509_NAME_oneline(X509_get_subject_name(cert), sv.s, sv.len)==NULL) {
1326
+				goto error;
1327
+			}
1328
+			return pv_get_strzval(msg, param, res, sv.s);
1329
+		break;
1330
+		default:
1331
+			goto error;
1332
+	}
1333
+
1334
+error:
1335
+	tcpconn_put(c);
1336
+	return pv_get_null(msg, param, res);
1337
+}
1261 1338
 
1262 1339
 select_row_t tls_sel[] = {
1263 1340
 	/* Current cipher parameters */
... ...
@@ -1544,6 +1621,8 @@ pv_export_t tls_pv[] = {
1544 1621
 	{{"tls_peer_server_name", sizeof("tls_peer_server_name")-1},
1545 1622
 		PVT_OTHER, pv_tlsext_sn, 0,
1546 1623
 		0, 0, pv_init_iname, PV_TLSEXT_SNI },
1624
+	{ {"tls", (sizeof("tls")-1)}, PVT_OTHER, pv_get_tls,
1625
+		0, pv_parse_tls_name, 0, 0, 0},
1547 1626
 
1548 1627
 	{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
1549 1628