1 /*
2  * TLS module - select interface
3  *
4  * Copyright (C) 2005 iptelorg GmbH
5  * Copyright (C) 2006 enum.at
6  *
7  * This file is part of Kamailio, a free SIP server.
8  *
9  * Kamailio is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version
13  *
14  * Kamailio is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  * Exception: permission to copy, modify, propagate, and distribute a work
24  * formed by combining OpenSSL toolkit software and the code in this file,
25  * such as linking with software components and libraries released under
26  * OpenSSL project license.
27  */
28 
29 /** Kamailio TLS support :: Select interface.
30  * @file
31  * @ingroup tls
32  * Module: @ref tls
33  */
34 
35 
36 #include <openssl/ssl.h>
37 #include <openssl/x509v3.h>
38 #include "../../core/globals.h"
39 #include "../../core/tcp_server.h"
40 #include "../../core/tcp_conn.h"
41 #include "../../core/ut.h"
42 #include "../../core/cfg/cfg.h"
43 #include "../../core/dprint.h"
44 #include "../../core/strutils.h"
45 #include "tls_server.h"
46 #include "tls_select.h"
47 #include "tls_mod.h"
48 #include "tls_init.h" /* features macros */
49 #include "tls_cfg.h"
50 
51 enum {
52 	CERT_LOCAL = 1,   /* Select local certificate */
53 	CERT_PEER,        /* Select peer certificate */
54 	CERT_SUBJECT,     /* Select subject part of certificate */
55 	CERT_ISSUER,      /* Select issuer part of certificate */
56 	CERT_VERIFIED,    /* Test for verified certificate */
57 	CERT_REVOKED,     /* Test for revoked certificate */
58 	CERT_EXPIRED,     /* Expiration certificate test */
59 	CERT_SELFSIGNED,  /* self-signed certificate test */
60 	CERT_NOTBEFORE,   /* Select validity end from certificate */
61 	CERT_NOTAFTER,    /* Select validity start from certificate */
62 	CERT_RAW,         /* Select raw PEM-encoded certificate */
63 	CERT_URLENCODED,  /* Select urlencoded PEM-encoded certificate */
64 	COMP_CN,          /* Common name */
65 	COMP_O,           /* Organization name */
66 	COMP_OU,          /* Organization unit */
67 	COMP_C,           /* Country name */
68 	COMP_ST,          /* State */
69 	COMP_L,           /* Locality/town */
70 	COMP_HOST,        /* hostname from subject/alternative */
71 	COMP_URI,         /* URI from subject/alternative */
72 	COMP_E,           /* Email address */
73 	COMP_IP,          /* IP from subject/alternative */
74 	COMP_UID,         /* UserID*/
75 	TLSEXT_SN         /* Server name of the peer */
76 };
77 
78 
79 enum {
80 	PV_CERT_LOCAL      = 1<<0,   /* Select local certificate */
81 	PV_CERT_PEER       = 1<<1,   /* Select peer certificate */
82 	PV_CERT_SUBJECT    = 1<<2,   /* Select subject part of certificate */
83 	PV_CERT_ISSUER     = 1<<3,   /* Select issuer part of certificate */
84 
85 	PV_CERT_VERIFIED   = 1<<4,   /* Test for verified certificate */
86 	PV_CERT_REVOKED    = 1<<5,   /* Test for revoked certificate */
87 	PV_CERT_EXPIRED    = 1<<6,   /* Expiration certificate test */
88 	PV_CERT_SELFSIGNED = 1<<7,   /* self-signed certificate test */
89 	PV_CERT_NOTBEFORE  = 1<<8,   /* Select validity end from certificate */
90 	PV_CERT_NOTAFTER   = 1<<9,   /* Select validity start from certificate */
91 	PV_CERT_RAW        = 1<<10,  /* Select raw PEM-encoded certificate */
92 	PV_CERT_URLENCODED = 1<<11,  /* Select urlencoded PEM-encoded certificate */
93 
94 	PV_COMP_CN = 1<<12,          /* Common name */
95 	PV_COMP_O  = 1<<13,          /* Organization name */
96 	PV_COMP_OU = 1<<14,          /* Organization unit */
97 	PV_COMP_C  = 1<<15,          /* Country name */
98 	PV_COMP_ST = 1<<16,          /* State */
99 	PV_COMP_L  = 1<<17,          /* Locality/town */
100 
101 	PV_COMP_HOST = 1<<18,        /* hostname from subject/alternative */
102 	PV_COMP_URI  = 1<<19,        /* URI from subject/alternative */
103 	PV_COMP_E    = 1<<20,        /* Email address */
104 	PV_COMP_IP   = 1<<21,        /* IP from subject/alternative */
105 	PV_COMP_UID  = 1<<22,        /* UserID*/
106 
107 	PV_TLSEXT_SNI = 1<<23,       /* Peer's server name (TLS extension) */
108 };
109 
110 
111 
112 static struct tcp_connection* _tls_pv_con = 0;
113 
114 
tls_set_pv_con(struct tcp_connection * c)115 void tls_set_pv_con(struct tcp_connection *c)
116 {
117 	_tls_pv_con = c;
118 }
119 
get_cur_connection(struct sip_msg * msg)120 struct tcp_connection* get_cur_connection(struct sip_msg* msg)
121 {
122 	struct tcp_connection* c;
123 
124 	if(_tls_pv_con != 0)
125 		return _tls_pv_con;
126 
127 	if (msg->rcv.proto != PROTO_TLS) {
128 		ERR("Transport protocol is not TLS (bug in config)\n");
129 		return 0;
130 	}
131 
132 	c = tcpconn_get(msg->rcv.proto_reserved1, 0, 0, 0,
133 					cfg_get(tls, tls_cfg, con_lifetime));
134 	if (c && c->type != PROTO_TLS) {
135 		ERR("Connection found but is not TLS\n");
136 		tcpconn_put(c);
137 		return 0;
138 	}
139 	return c;
140 }
141 
142 
get_ssl(struct tcp_connection * c)143 static SSL* get_ssl(struct tcp_connection* c)
144 {
145 	struct tls_extra_data* extra;
146 
147 	if (!c || !c->extra_data) {
148 		ERR("Unable to extract SSL data from TLS connection\n");
149 		return 0;
150 	}
151 	extra = (struct tls_extra_data*)c->extra_data;
152 	return extra->ssl;
153 }
154 
155 
get_cert(X509 ** cert,struct tcp_connection ** c,struct sip_msg * msg,int my)156 static int get_cert(X509** cert, struct tcp_connection** c, struct sip_msg* msg, int my)
157 {
158 	SSL* ssl;
159 
160 	*cert = 0;
161 	*c = get_cur_connection(msg);
162 	if (!(*c)) {
163 		INFO("TLS connection not found\n");
164 		return -1;
165 	}
166 	ssl = get_ssl(*c);
167 	if (!ssl) goto err;
168 	*cert = my ? SSL_get_certificate(ssl) : SSL_get_peer_certificate(ssl);
169 	if (!*cert) {
170 		if (my) {
171 			ERR("Unable to retrieve my TLS certificate from SSL structure\n");
172 		} else {
173 			ERR("Unable to retrieve peer TLS certificate from SSL structure\n");
174 		}
175 		goto err;
176 	}
177 
178 	return 0;
179 
180  err:
181 	tcpconn_put(*c);
182 	return -1;
183 }
184 
185 
get_cipher(str * res,sip_msg_t * msg)186 static int get_cipher(str* res, sip_msg_t* msg)
187 {
188 	str cipher;
189 	static char buf[1024];
190 
191 	struct tcp_connection* c;
192 	SSL* ssl;
193 
194 	c = get_cur_connection(msg);
195 	if (!c) {
196 		INFO("TLS connection not found in select_cipher\n");
197 		goto err;
198 	}
199 	ssl = get_ssl(c);
200 	if (!ssl) goto err;
201 
202 	cipher.s = (char*)SSL_CIPHER_get_name(SSL_get_current_cipher(ssl));
203 	cipher.len = cipher.s ? strlen(cipher.s) : 0;
204 	if (cipher.len >= 1024) {
205 		ERR("Cipher name too long\n");
206 		goto err;
207 	}
208 	if(cipher.s!=NULL && cipher.len>0) {
209 		memcpy(buf, cipher.s, cipher.len);
210 	} else {
211 		buf[0] = '\0';
212 	}
213 	res->s = buf;
214 	res->len = cipher.len;
215 	tcpconn_put(c);
216 	return 0;
217 
218  err:
219 	if (c) tcpconn_put(c);
220 	return -1;
221 }
222 
sel_cipher(str * res,select_t * s,sip_msg_t * msg)223 static int sel_cipher(str* res, select_t* s, sip_msg_t* msg)
224 {
225 	return get_cipher(res, msg);
226 }
227 
228 
pv_cipher(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)229 static int pv_cipher(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
230 {
231 	if (get_cipher(&res->rs, msg) < 0) {
232 		return pv_get_null(msg, param, res);
233 	}
234 	res->flags = PV_VAL_STR;
235 	return 0;
236 }
237 
238 
get_bits(str * res,int * i,sip_msg_t * msg)239 static int get_bits(str* res, int* i, sip_msg_t* msg)
240 {
241 	str bits;
242 	int b;
243 	static char buf[1024];
244 
245 	struct tcp_connection* c;
246 	SSL* ssl;
247 
248 	c = get_cur_connection(msg);
249 	if (!c) {
250 		INFO("TLS connection not found in select_bits\n");
251 		goto err;
252 	}
253 	ssl = get_ssl(c);
254 	if (!ssl) goto err;
255 
256 	b = SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl), 0);
257 	bits.s = int2str(b, &bits.len);
258 	if (bits.len >= 1024) {
259 		ERR("Bits string too long\n");
260 		goto err;
261 	}
262 	memcpy(buf, bits.s, bits.len);
263 	res->s = buf;
264 	res->len = bits.len;
265 	if (i) *i = b;
266 	tcpconn_put(c);
267 	return 0;
268 
269  err:
270 	if (c) tcpconn_put(c);
271 	return -1;
272 }
273 
274 
sel_bits(str * res,select_t * s,sip_msg_t * msg)275 static int sel_bits(str* res, select_t* s, sip_msg_t* msg)
276 {
277 	return get_bits(res, NULL, msg);
278 }
279 
pv_bits(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)280 static int pv_bits(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
281 {
282 	if (get_bits(&res->rs, &res->ri, msg) < 0) {
283 		return pv_get_null(msg, param, res);
284 	}
285 	res->flags = PV_VAL_STR | PV_VAL_INT;
286 	return 0;
287 }
288 
289 
get_version(str * res,sip_msg_t * msg)290 static int get_version(str* res, sip_msg_t* msg)
291 {
292 	str version;
293 	static char buf[1024];
294 
295 	struct tcp_connection* c;
296 	SSL* ssl;
297 
298 	c = get_cur_connection(msg);
299 	if (!c) {
300 		INFO("TLS connection not found in select_version\n");
301 		goto err;
302 	}
303 	ssl = get_ssl(c);
304 	if (!ssl) goto err;
305 
306 	version.s = (char*)SSL_get_version(ssl);
307 	version.len = version.s ? strlen(version.s) : 0;
308 	if (version.len >= 1024) {
309 		ERR("Version string too long\n");
310 		goto err;
311 	}
312 	if(version.s!=NULL && version.len>0) {
313 		memcpy(buf, version.s, version.len);
314 	} else {
315 		buf[0] = '\0';
316 	}
317 	res->s = buf;
318 	res->len = version.len;
319 	tcpconn_put(c);
320         return 0;
321 
322  err:
323 	if (c) tcpconn_put(c);
324 	return -1;
325 }
326 
327 
sel_version(str * res,select_t * s,sip_msg_t * msg)328 static int sel_version(str* res, select_t* s, sip_msg_t* msg)
329 {
330 	return get_version(res, msg);
331 }
332 
333 
pv_version(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)334 static int pv_version(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
335 {
336 	if (get_version(&res->rs, msg) < 0) {
337 		return pv_get_null(msg, param, res);
338 	}
339 	res->flags = PV_VAL_STR;
340 	return 0;
341 }
342 
343 
344 
get_desc(str * res,sip_msg_t * msg)345 static int get_desc(str* res, sip_msg_t* msg)
346 {
347 	static char buf[128];
348 
349 	struct tcp_connection* c;
350 	SSL* ssl;
351 
352 	c = get_cur_connection(msg);
353 	if (!c) {
354 		INFO("TLS connection not found in select_desc\n");
355 		goto err;
356 	}
357 	ssl = get_ssl(c);
358 	if (!ssl) goto err;
359 
360 	buf[0] = '\0';
361 	SSL_CIPHER_description(SSL_get_current_cipher(ssl), buf, 128);
362 	res->s = buf;
363 	res->len = strlen(buf);
364 	tcpconn_put(c);
365 	return 0;
366 
367  err:
368 	if (c) tcpconn_put(c);
369 	return -1;
370 }
371 
372 
sel_desc(str * res,select_t * s,sip_msg_t * msg)373 static int sel_desc(str* res, select_t* s, sip_msg_t* msg)
374 {
375 	return get_desc(res, msg);
376 }
377 
pv_desc(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)378 static int pv_desc(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
379 {
380 	if (get_desc(&res->rs, msg) < 0) {
381 		return pv_get_null(msg, param, res);
382 	}
383 	res->flags = PV_VAL_STR;
384 	return 0;
385 }
386 
387 
388 
get_cert_version(str * res,int local,sip_msg_t * msg)389 static int get_cert_version(str* res, int local, sip_msg_t* msg)
390 {
391 	static char buf[INT2STR_MAX_LEN];
392 	X509* cert;
393 	struct tcp_connection* c;
394 	char* version;
395 
396 	if (get_cert(&cert, &c, msg, local) < 0) return -1;
397 	version = int2str(X509_get_version(cert), &res->len);
398 	memcpy(buf, version, res->len);
399 	res->s = buf;
400 	if (!local) X509_free(cert);
401 	tcpconn_put(c);
402 	return 0;
403 }
404 
sel_cert_version(str * res,select_t * s,sip_msg_t * msg)405 static int sel_cert_version(str* res, select_t* s, sip_msg_t* msg)
406 {
407 	int local;
408 
409 	switch(s->params[s->n - 2].v.i) {
410 	case CERT_PEER: local = 0; break;
411 	case CERT_LOCAL: local = 1; break;
412 	default:
413 		BUG("Bug in call to sel_cert_version\n");
414 		return -1;
415 	}
416 
417 	return get_cert_version(res, local, msg);
418 }
419 
pv_cert_version(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)420 static int pv_cert_version(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
421 {
422 	int local;
423 
424 	if (param->pvn.u.isname.name.n & PV_CERT_PEER) {
425 		local = 0;
426 	} else if (param->pvn.u.isname.name.n & PV_CERT_LOCAL) {
427 		local = 1;
428 	} else {
429 		BUG("bug in call to pv_cert_version\n");
430 		return pv_get_null(msg, param, res);
431 	}
432 
433 	if (get_cert_version(&res->rs, local, msg) < 0) {
434 		return pv_get_null(msg, param, res);
435 	}
436 	res->flags = PV_VAL_STR;
437 	return 0;
438 }
439 
440 
441 
442 /*
443  * Check whether peer certificate exists and verify the result
444  * of certificate verification
445  */
check_cert(str * res,int * ires,int local,int err,sip_msg_t * msg)446 static int check_cert(str* res, int* ires, int local, int err, sip_msg_t* msg)
447 {
448 	static str succ = STR_STATIC_INIT("1");
449 	static str fail = STR_STATIC_INIT("0");
450 
451 	struct tcp_connection* c;
452 	SSL* ssl;
453 	X509* cert = 0;
454 
455 	c = get_cur_connection(msg);
456 	if (!c) return -1;
457 
458 	ssl = get_ssl(c);
459 	if (!ssl) goto error;
460 
461 	if (local) {
462 		DBG("Verification of local certificates not supported\n");
463 		goto error;
464 	} else {
465 		if ((cert = SSL_get_peer_certificate(ssl)) && SSL_get_verify_result(ssl) == err) {
466 			*res = succ;
467 			if (ires) *ires = 1;
468 		} else {
469 			*res = fail;
470 			if (ires) *ires = 0;
471 		}
472 	}
473 
474 	if (cert) X509_free(cert);
475 	tcpconn_put(c);
476 	return 0;
477 
478  error:
479 	if (c) tcpconn_put(c);
480 	return -1;
481 }
482 
483 
sel_check_cert(str * res,select_t * s,sip_msg_t * msg)484 static int sel_check_cert(str* res, select_t* s, sip_msg_t* msg)
485 {
486 	int local, err;
487 
488 	switch(s->params[s->n - 2].v.i) {
489 	case CERT_PEER: local = 0; break;
490 	case CERT_LOCAL: local = 1; break;
491 	default:
492 		BUG("Bug in call to sel_cert_version\n");
493 		return -1;
494 	}
495 
496 	switch (s->params[s->n - 1].v.i) {
497 	case CERT_VERIFIED:   err = X509_V_OK;                              break;
498 	case CERT_REVOKED:    err = X509_V_ERR_CERT_REVOKED;                break;
499 	case CERT_EXPIRED:    err = X509_V_ERR_CERT_HAS_EXPIRED;            break;
500 	case CERT_SELFSIGNED: err = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; break;
501 	default:
502 		BUG("Unexpected parameter value \"%d\"\n", s->params[s->n - 1].v.i);
503 		return -1;
504 	}
505 
506 	return check_cert(res, NULL, local, err, msg);
507 }
508 
pv_check_cert(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)509 static int pv_check_cert(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
510 {
511 	int err;
512 
513 	switch (param->pvn.u.isname.name.n) {
514 	case PV_CERT_VERIFIED:   err = X509_V_OK;                              break;
515 	case PV_CERT_REVOKED:    err = X509_V_ERR_CERT_REVOKED;                break;
516 	case PV_CERT_EXPIRED:    err = X509_V_ERR_CERT_HAS_EXPIRED;            break;
517 	case PV_CERT_SELFSIGNED: err = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; break;
518 	default:
519 		BUG("unexpected parameter value \"%d\"\n", param->pvn.u.isname.name.n);
520 		return pv_get_null(msg, param, res);
521 	}
522 
523 
524 	if (check_cert(&res->rs, &res->ri, 0, err, msg) < 0) {
525 		return pv_get_null(msg, param, res);
526 	}
527 
528 	res->flags = PV_VAL_STR | PV_VAL_INT;
529 	return 0;
530 }
531 
532 
533 
534 
get_validity(str * res,int local,int bound,sip_msg_t * msg)535 static int get_validity(str* res, int local, int bound, sip_msg_t* msg)
536 {
537 #define NOT_BEFORE 0
538 #define NOT_AFTER 1
539 	static char buf[1024];
540 	X509* cert;
541 	struct tcp_connection* c;
542 	BUF_MEM* p;
543 	BIO* mem = 0;
544 	ASN1_TIME* date;
545 
546 	if (get_cert(&cert, &c, msg, local) < 0) return -1;
547 
548 	switch (bound) {
549 	case NOT_BEFORE: date = X509_get_notBefore(cert); break;
550 	case NOT_AFTER:  date = X509_get_notAfter(cert);  break;
551 	default:
552 		BUG("Unexpected parameter value \"%d\"\n", bound);
553 		goto err;
554 	}
555 
556 	mem = BIO_new(BIO_s_mem());
557 	if (!mem) {
558 		ERR("Error while creating memory BIO\n");
559 		goto err;
560 	}
561 
562 	if (!ASN1_TIME_print(mem, date)) {
563 		ERR("Error while printing certificate date/time\n");
564 		goto err;
565 	}
566 
567 	BIO_get_mem_ptr(mem, &p);
568 	if (p->length >= 1024) {
569 		ERR("Date/time too long\n");
570 		goto err;
571 	}
572 	memcpy(buf, p->data, p->length);
573 	res->s = buf;
574 	res->len = p->length;
575 
576 	BIO_free(mem);
577 	if (!local) X509_free(cert);
578 	tcpconn_put(c);
579 	return 0;
580  err:
581 	if (mem) BIO_free(mem);
582 	if (!local) X509_free(cert);
583 	tcpconn_put(c);
584 	return -1;
585 }
586 
sel_validity(str * res,select_t * s,sip_msg_t * msg)587 static int sel_validity(str* res, select_t* s, sip_msg_t* msg)
588 {
589 	int local, bound;
590 
591 	switch(s->params[s->n - 2].v.i) {
592 	case CERT_PEER:  local = 0; break;
593 	case CERT_LOCAL: local = 1; break;
594 	default:
595 		BUG("Could not determine certificate\n");
596 		return -1;
597 	}
598 
599 	switch (s->params[s->n - 1].v.i) {
600 	case CERT_NOTBEFORE: bound = NOT_BEFORE; break;
601 	case CERT_NOTAFTER:  bound = NOT_AFTER; break;
602 	default:
603 		BUG("Unexpected parameter value \"%d\"\n", s->params[s->n - 1].v.i);
604 		return -1;
605 	}
606 
607 	return get_validity(res, local, bound, msg);
608 }
609 
610 
pv_validity(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)611 static int pv_validity(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
612 {
613 	int bound;
614 
615 	switch (param->pvn.u.isname.name.n) {
616 	case PV_CERT_NOTBEFORE: bound = NOT_BEFORE; break;
617 	case PV_CERT_NOTAFTER:  bound = NOT_AFTER;  break;
618 	default:
619 		BUG("unexpected parameter value \"%d\"\n", param->pvn.u.isname.name.n);
620 		return pv_get_null(msg, param, res);
621 	}
622 
623 	if (get_validity(&res->rs, 0, bound, msg) < 0) {
624 		return pv_get_null(msg, param, res);
625 	}
626 
627 	res->flags = PV_VAL_STR;
628 	return 0;
629 }
630 
631 
get_sn(str * res,int * ires,int local,sip_msg_t * msg)632 static int get_sn(str* res, int* ires, int local, sip_msg_t* msg)
633 {
634 	static char buf[INT2STR_MAX_LEN];
635 	X509* cert;
636 	struct tcp_connection* c;
637 	char* sn;
638 	int num;
639 
640 	if (get_cert(&cert, &c, msg, local) < 0) return -1;
641 
642 	num = ASN1_INTEGER_get(X509_get_serialNumber(cert));
643 	sn = int2str(num, &res->len);
644 	memcpy(buf, sn, res->len);
645 	res->s = buf;
646 	if (ires) *ires = num;
647 	if (!local) X509_free(cert);
648 	tcpconn_put(c);
649 	return 0;
650 }
651 
sel_sn(str * res,select_t * s,sip_msg_t * msg)652 static int sel_sn(str* res, select_t* s, sip_msg_t* msg)
653 {
654 	int local;
655 
656 	switch(s->params[s->n - 2].v.i) {
657 	case CERT_PEER:  local = 0; break;
658 	case CERT_LOCAL: local = 1; break;
659 	default:
660 		BUG("Could not determine certificate\n");
661 		return -1;
662 	}
663 
664 	return get_sn(res, NULL, local, msg);
665 }
666 
667 
pv_sn(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)668 static int pv_sn(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
669 {
670 	int local;
671 
672 	if (param->pvn.u.isname.name.n & PV_CERT_PEER) {
673 		local = 0;
674 	} else if (param->pvn.u.isname.name.n & PV_CERT_LOCAL) {
675 		local = 1;
676 	} else {
677 		BUG("could not determine certificate\n");
678 		return pv_get_null(msg, param, res);
679 	}
680 
681 	if (get_sn(&res->rs, &res->ri, local, msg) < 0) {
682 		return pv_get_null(msg, param, res);
683 	}
684 
685 	res->flags = PV_VAL_STR | PV_VAL_INT;
686 	return 0;
687 }
688 
689 
cert_to_buf(X509 * cert,char ** bufptr,size_t * len)690 static int cert_to_buf(X509 *cert, char **bufptr, size_t *len)
691 {
692 #define MAX_CERT_SIZE 16384
693 	static char buf[MAX_CERT_SIZE];
694 	BIO     *mem = NULL;
695 
696 	mem = BIO_new(BIO_s_mem());
697 	if (!mem) {
698 		ERR("Error while creating memory BIO\n");
699 		goto err;
700 	}
701 
702 	/* Write a certificate to a BIO */
703 	if (!PEM_write_bio_X509(mem, cert)) {
704 		goto err;
705 	}
706 
707 	*len = BIO_pending(mem);
708 	if (*len > MAX_CERT_SIZE) {
709 		ERR("certificate is too long\n");
710 		goto err;
711 	}
712 
713 	if (BIO_read(mem, buf, *len) <= 0) {
714 		ERR("problem reading data out of BIO");
715 		goto err;
716 	}
717 
718 	*bufptr = buf;
719 
720 	BIO_free(mem);
721 	return 0;
722 err:
723 
724 	if (mem) BIO_free(mem);
725 	return -1;
726 }
727 
728 
get_ssl_cert(str * res,int local,int urlencoded,sip_msg_t * msg)729 static int get_ssl_cert(str* res, int local, int urlencoded, sip_msg_t* msg)
730 {
731 	char *buf = NULL;
732 	/* buf2 holds the urlencoded version of buf, which can be up to 3 times its size */
733 	static char buf2[MAX_CERT_SIZE*3+1];
734 	X509* cert;
735 	struct tcp_connection* c;
736 	size_t   len;
737 	str     temp_str;
738 
739 	if (get_cert(&cert, &c, msg, local) < 0) return -1;
740 
741 	if (cert_to_buf(cert, &buf, &len) < 0) {
742 		ERR("cert to buf failed\n");
743 		goto err;
744 	}
745 
746 	if (urlencoded)
747 	{
748 		temp_str.len = len;
749 		temp_str.s = buf;
750 		res->s = buf2;
751 		res->len = MAX_CERT_SIZE*3+1;
752 
753 		if (urlencode(&temp_str, res) < 0) {
754 			ERR("Problem with urlencode()\n");
755 			goto err;
756 		}
757 	}
758 	else
759 	{
760 		res->s = buf;
761 		res->len = len;
762 	}
763 
764 	if (!local) X509_free(cert);
765 	tcpconn_put(c);
766 	return 0;
767 
768  err:
769 	if (!local) X509_free(cert);
770 	tcpconn_put(c);
771 	return -1;
772 }
773 
774 
sel_ssl_cert(str * res,select_t * s,sip_msg_t * msg)775 static int sel_ssl_cert(str* res, select_t* s, sip_msg_t* msg)
776 {
777 	int i, local = 0, urlencoded = 0;
778 
779 	for(i = 1; i <= s->n - 1; i++) {
780 		switch(s->params[i].v.i) {
781 		case CERT_PEER:       local = 0; break;
782 		case CERT_LOCAL:      local = 1; break;
783 		case CERT_RAW:        urlencoded = 0; break;
784 		case CERT_URLENCODED: urlencoded = 1; break;
785 		default:
786 			BUG("Bug in call to sel_ssl_cert\n");
787 			return -1;
788 		}
789 	}
790 
791 	return get_ssl_cert(res, local, urlencoded, msg);
792 }
793 
794 
pv_ssl_cert(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)795 static int pv_ssl_cert(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
796 {
797 	int local, urlencoded;
798 
799 	if (param->pvn.u.isname.name.n & PV_CERT_PEER) {
800 		local = 0;
801 	} else if (param->pvn.u.isname.name.n & PV_CERT_LOCAL) {
802 		local = 1;
803 	} else {
804 		BUG("bug in call to pv_ssl_cert\n");
805 		return pv_get_null(msg, param, res);
806 	}
807 
808 	if (param->pvn.u.isname.name.n & PV_CERT_RAW) {
809 		urlencoded = 0;
810 	} else if (param->pvn.u.isname.name.n & PV_CERT_URLENCODED) {
811 		urlencoded = 1;
812 	} else {
813 		BUG("bug in call to pv_ssl_cert\n");
814 		return pv_get_null(msg, param, res);
815 	}
816 
817 	if (get_ssl_cert(&res->rs, local, urlencoded, msg) < 0) {
818 		return pv_get_null(msg, param, res);
819 	}
820 	res->flags = PV_VAL_STR;
821 	return 0;
822 }
823 
824 
825 #if (OPENSSL_VERSION_NUMBER >= 0x10100001L)
826 /* NB: SSL_get0_verified_chain() was introduced in OpenSSL 1.1.0 */
get_verified_cert_chain(STACK_OF (X509)** chain,struct tcp_connection ** c,struct sip_msg * msg)827 static int get_verified_cert_chain(STACK_OF(X509)** chain, struct tcp_connection** c, struct sip_msg* msg)
828 {
829 	SSL* ssl;
830 
831 	*chain = 0;
832 	*c = get_cur_connection(msg);
833 	if (!(*c)) {
834 		INFO("TLS connection not found\n");
835 		return -1;
836 	}
837 	ssl = get_ssl(*c);
838 	if (!ssl) goto err;
839 	*chain = SSL_get0_verified_chain(ssl);
840 	if (!*chain) {
841 		ERR("Unable to retrieve peer TLS verified chain from SSL structure\n");
842 		goto err;
843 	}
844 
845 	return 0;
846 err:
847 	tcpconn_put(*c);
848 	return -1;
849 }
850 
851 
sel_ssl_verified_cert_chain(str * res,select_t * s,sip_msg_t * msg)852 static int sel_ssl_verified_cert_chain(str* res, select_t* s, sip_msg_t* msg)
853 {
854 	char *buf = NULL;
855 	struct tcp_connection* c;
856 	size_t   len;
857 	STACK_OF(X509)* chain;
858 	X509* cert;
859 	int i;
860 
861 	if (get_verified_cert_chain(&chain, &c, msg) < 0) return -1;
862 
863 	if (s->params[s->n-1].type == SEL_PARAM_INT) {
864 		i = s->params[s->n-1].v.i;
865 	} else
866 		return -1;
867 
868 	if (i < 0 || i >= sk_X509_num(chain))
869 		return -1;
870 
871 	cert = sk_X509_value(chain, i);
872 	if (!cert)
873 		return -1;
874 
875 	if (cert_to_buf(cert, &buf, &len) < 0) {
876 		ERR("cert to buf failed\n");
877 		goto err;
878 	}
879 
880 	res->s = buf;
881 	res->len = len;
882 
883 	tcpconn_put(c);
884 	return 0;
885 
886 err:
887 	tcpconn_put(c);
888 	return -1;
889 }
890 #endif /* (OPENSSL_VERSION_NUMBER >= 0x10100001L) */
891 
892 
get_comp(str * res,int local,int issuer,int nid,sip_msg_t * msg)893 static int get_comp(str* res, int local, int issuer, int nid, sip_msg_t* msg)
894 {
895 	static char buf[1024];
896 	X509* cert;
897 	struct tcp_connection* c;
898 	X509_NAME* name;
899 	X509_NAME_ENTRY* e;
900 	ASN1_STRING* asn1;
901 	int index, text_len;
902 	char* elem;
903 	unsigned char* text_s;
904 
905 	text_s = 0;
906 
907 	if (get_cert(&cert, &c, msg, local) < 0) return -1;
908 
909 	name = issuer ? X509_get_issuer_name(cert) : X509_get_subject_name(cert);
910 	if (!name) {
911 		ERR("Cannot extract subject or issuer name from peer certificate\n");
912 		goto err;
913 	}
914 
915 	index = X509_NAME_get_index_by_NID(name, nid, -1);
916 	if (index == -1) {
917 		switch(nid) {
918 		case NID_commonName:             elem = "CommonName";              break;
919 		case NID_organizationName:       elem = "OrganizationName";        break;
920 		case NID_organizationalUnitName: elem = "OrganizationalUnitUname"; break;
921 		case NID_countryName:            elem = "CountryName";             break;
922 		case NID_stateOrProvinceName:    elem = "StateOrProvinceName";     break;
923 		case NID_localityName:           elem = "LocalityName";            break;
924 		case NID_userId:                 elem = "UserID";                  break;
925 		default:                         elem = "Unknown";                 break;
926 		}
927 		DBG("Element %s not found in certificate subject/issuer\n", elem);
928 		goto err;
929 	}
930 
931 	e = X509_NAME_get_entry(name, index);
932 	asn1 = X509_NAME_ENTRY_get_data(e);
933 	text_len = ASN1_STRING_to_UTF8(&text_s, asn1);
934 	if (text_len < 0 || text_len >= 1024) {
935 		ERR("Error converting ASN1 string\n");
936 		goto err;
937 	}
938 	memcpy(buf, text_s, text_len);
939 	res->s = buf;
940 	res->len = text_len;
941 
942 	OPENSSL_free(text_s);
943 	if (!local) X509_free(cert);
944 	tcpconn_put(c);
945 	return 0;
946 
947  err:
948 	if (text_s) OPENSSL_free(text_s);
949 	if (!local) X509_free(cert);
950 	tcpconn_put(c);
951 	return -1;
952 }
953 
954 
sel_comp(str * res,select_t * s,sip_msg_t * msg)955 static int sel_comp(str* res, select_t* s, sip_msg_t* msg)
956 {
957 	int i, local = 0, issuer = 0;
958 	int nid = NID_commonName;
959 
960 	for(i = 1; i <= s->n - 1; i++) {
961 		switch(s->params[i].v.i) {
962 		case CERT_LOCAL:   local = 1;                        break;
963 		case CERT_PEER:    local = 0;                        break;
964 		case CERT_SUBJECT: issuer = 0;                       break;
965 		case CERT_ISSUER:  issuer = 1;                       break;
966 		case COMP_CN:      nid = NID_commonName;             break;
967 		case COMP_O:       nid = NID_organizationName;       break;
968 		case COMP_OU:      nid = NID_organizationalUnitName; break;
969 		case COMP_C:       nid = NID_countryName;            break;
970 		case COMP_ST:      nid = NID_stateOrProvinceName;    break;
971 		case COMP_L:       nid = NID_localityName;           break;
972 		case COMP_UID:     nid = NID_userId;                 break;
973 		default:
974 			BUG("Bug in sel_comp: %d\n", s->params[s->n - 1].v.i);
975 			return -1;
976 		}
977 	}
978 
979 	return get_comp(res, local, issuer, nid, msg);
980 }
981 
982 
pv_comp(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)983 static int pv_comp(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
984 {
985 	int ind_local, local = 0, issuer = 0, nid = NID_commonName;
986 
987 	/* copy callback value as we modify it */
988 	ind_local = param->pvn.u.isname.name.n;
989 	DBG("ind_local = %x", ind_local);
990 
991 	if (ind_local & PV_CERT_PEER) {
992 		local = 0;
993 		ind_local = ind_local ^ PV_CERT_PEER;
994 	} else if (ind_local & PV_CERT_LOCAL) {
995 		local = 1;
996 		ind_local = ind_local ^ PV_CERT_LOCAL;
997 	} else {
998 		BUG("could not determine certificate\n");
999 		return pv_get_null(msg, param, res);
1000 	}
1001 
1002 	if (ind_local & PV_CERT_SUBJECT) {
1003 		issuer = 0;
1004 		ind_local = ind_local ^ PV_CERT_SUBJECT;
1005 	} else if (ind_local & PV_CERT_ISSUER) {
1006 		issuer = 1;
1007 		ind_local = ind_local ^ PV_CERT_ISSUER;
1008 	} else {
1009 		BUG("could not determine subject or issuer\n");
1010 		return pv_get_null(msg, param, res);
1011 	}
1012 
1013 	switch(ind_local) {
1014 		case PV_COMP_CN:  nid = NID_commonName;             break;
1015 		case PV_COMP_O:   nid = NID_organizationName;       break;
1016 		case PV_COMP_OU:  nid = NID_organizationalUnitName; break;
1017 		case PV_COMP_C:   nid = NID_countryName;            break;
1018 		case PV_COMP_ST:  nid = NID_stateOrProvinceName;    break;
1019 		case PV_COMP_L:   nid = NID_localityName;           break;
1020 		case PV_COMP_UID: nid = NID_userId;                 break;
1021 		default:          nid = NID_undef;
1022 	}
1023 
1024 	if (get_comp(&res->rs, local, issuer, nid, msg) < 0) {
1025 		return pv_get_null(msg, param, res);
1026 	}
1027 
1028 	res->flags = PV_VAL_STR;
1029 	return 0;
1030 }
1031 
1032 
get_alt(str * res,int local,int type,sip_msg_t * msg)1033 static int get_alt(str* res, int local, int type, sip_msg_t* msg)
1034 {
1035 	static char buf[1024];
1036 	int n, found = 0;
1037 	STACK_OF(GENERAL_NAME)* names = 0;
1038 	GENERAL_NAME* nm;
1039 	X509* cert;
1040 	struct tcp_connection* c;
1041 	str text;
1042 	struct ip_addr ip;
1043 
1044 	if (get_cert(&cert, &c, msg, local) < 0) return -1;
1045 
1046 	names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1047 	if (!names) {
1048 		DBG("Cannot get certificate alternative subject\n");
1049 		goto err;
1050 
1051 	}
1052 
1053 	for (n = 0; n < sk_GENERAL_NAME_num(names); n++) {
1054 		nm = sk_GENERAL_NAME_value(names, n);
1055 		if (nm->type != type) continue;
1056 		switch(type) {
1057 		case GEN_EMAIL:
1058 		case GEN_DNS:
1059 		case GEN_URI:
1060 			text.s = (char*)nm->d.ia5->data;
1061 			text.len = nm->d.ia5->length;
1062 			if (text.len >= 1024) {
1063 				ERR("Alternative subject text too long\n");
1064 				goto err;
1065 			}
1066 			memcpy(buf, text.s, text.len);
1067 			res->s = buf;
1068 			res->len = text.len;
1069 			found = 1;
1070 			break;
1071 
1072 		case GEN_IPADD:
1073 			ip.len = nm->d.iPAddress->length;
1074 			ip.af = (ip.len == 16) ? AF_INET6 : AF_INET;
1075 			memcpy(ip.u.addr, nm->d.iPAddress->data, ip.len);
1076 			text.s = ip_addr2a(&ip);
1077 			text.len = strlen(text.s);
1078 			memcpy(buf, text.s, text.len);
1079 			res->s = buf;
1080 			res->len = text.len;
1081 			found = 1;
1082 			break;
1083 		}
1084 		break;
1085 	}
1086 	if (!found) goto err;
1087 
1088 	if (names) sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
1089 	if (!local) X509_free(cert);
1090 	tcpconn_put(c);
1091 	return 0;
1092  err:
1093 	if (names) sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
1094 	if (!local) X509_free(cert);
1095 	tcpconn_put(c);
1096 	return -1;
1097 }
1098 
sel_alt(str * res,select_t * s,sip_msg_t * msg)1099 static int sel_alt(str* res, select_t* s, sip_msg_t* msg)
1100 {
1101 	int type = GEN_URI, local = 0, i;
1102 
1103 	for(i = 1; i <= s->n - 1; i++) {
1104 		switch(s->params[i].v.i) {
1105 		case CERT_LOCAL: local = 1; break;
1106 		case CERT_PEER:  local = 0; break;
1107 		case COMP_E:     type = GEN_EMAIL; break;
1108 		case COMP_HOST:  type = GEN_DNS;   break;
1109 		case COMP_URI:   type = GEN_URI;   break;
1110 		case COMP_IP:    type = GEN_IPADD; break;
1111 		default:
1112 			BUG("Bug in sel_alt: %d\n", s->params[s->n - 1].v.i);
1113 			return -1;
1114 		}
1115 	}
1116 
1117 	return get_alt(res, local, type, msg);
1118 }
1119 
1120 
pv_alt(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)1121 static int pv_alt(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
1122 {
1123 	int ind_local, local = 0, type = GEN_URI;
1124 
1125 	ind_local = param->pvn.u.isname.name.n;
1126 
1127 	if (ind_local & PV_CERT_PEER) {
1128 		local = 0;
1129 		ind_local = ind_local ^ PV_CERT_PEER;
1130 	} else if (ind_local & PV_CERT_LOCAL) {
1131 		local = 1;
1132 		ind_local = ind_local ^ PV_CERT_LOCAL;
1133 	} else {
1134 		BUG("could not determine certificate\n");
1135 		return pv_get_null(msg, param, res);
1136 	}
1137 
1138 	switch(ind_local) {
1139 		case PV_COMP_E:    type = GEN_EMAIL; break;
1140 		case PV_COMP_HOST: type = GEN_DNS;   break;
1141 		case PV_COMP_URI:  type = GEN_URI;   break;
1142 		case PV_COMP_IP:   type = GEN_IPADD; break;
1143 		default:
1144 			BUG("ind_local=%d\n", ind_local);
1145 			return pv_get_null(msg, param, res);
1146 	}
1147 
1148 	if (get_alt(&res->rs, local, type, msg) < 0) {
1149 		return pv_get_null(msg, param, res);
1150 	}
1151 
1152 	res->flags = PV_VAL_STR;
1153 	return 0;
1154 }
1155 
1156 
sel_tls(str * res,select_t * s,struct sip_msg * msg)1157 static int sel_tls(str* res, select_t* s, struct sip_msg* msg)
1158 {
1159 	return sel_desc(res, s, msg);
1160 }
1161 
1162 
sel_name(str * res,select_t * s,struct sip_msg * msg)1163 static int sel_name(str* res, select_t* s, struct sip_msg* msg)
1164 {
1165 	return sel_comp(res, s, msg);
1166 }
1167 
1168 
sel_cert(str * res,select_t * s,struct sip_msg * msg)1169 static int sel_cert(str* res, select_t* s, struct sip_msg* msg)
1170 {
1171 	return sel_comp(res, s, msg);
1172 }
1173 
1174 
1175 #ifdef OPENSSL_NO_TLSEXT
get_tlsext_sn(str * res,sip_msg_t * msg)1176 static int get_tlsext_sn(str* res, sip_msg_t* msg)
1177 {
1178 	ERR("TLS extension 'server name' is not available! "
1179 		"please install openssl with TLS extension support and recompile "
1180 		"the server\n");
1181 	return -1;
1182 }
1183 #else
get_tlsext_sn(str * res,sip_msg_t * msg)1184 static int get_tlsext_sn(str* res, sip_msg_t* msg)
1185 {
1186 	static char buf[1024];
1187 	struct tcp_connection* c;
1188 	str server_name;
1189 	SSL* ssl;
1190 
1191 	c = get_cur_connection(msg);
1192 	if (!c) {
1193 		INFO("TLS connection not found in select_desc\n");
1194 		goto error;
1195 	}
1196 	ssl = get_ssl(c);
1197 	if (!ssl) goto error;
1198 
1199 	buf[0] = '\0';
1200 
1201 	server_name.s = (char*)SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
1202 	if (server_name.s) {
1203 		server_name.len = strlen(server_name.s);
1204 		DBG("received server_name (TLS extension): '%.*s'\n",
1205 			STR_FMT(&server_name));
1206 	} else {
1207 		DBG("SSL_get_servername returned NULL\n");
1208 		goto error;
1209 	}
1210 
1211 	/* copy server_name into the buffer. If the buffer is too small copy only
1212 	 * the last bytes as these are the more important ones and prefix with
1213 	 * '+' */
1214 	if (server_name.len > sizeof(buf)) {
1215 		ERR("server_name to big for buffer\n");
1216 		buf[0] = '+';
1217 		memcpy(buf + 1, server_name.s + 1 + server_name.len - sizeof(buf),
1218 			   sizeof(buf) - 1);
1219 		res->len = sizeof(buf);
1220 	} else {
1221 		memcpy(buf, server_name.s, server_name.len);
1222 		res->len = server_name.len;
1223 	}
1224 	res->s = buf;
1225 
1226 	tcpconn_put(c);
1227 	return 0;
1228 
1229 error:
1230 	if (c) tcpconn_put(c);
1231 	return -1;
1232 }
1233 #endif
1234 
1235 
sel_tlsext_sn(str * res,select_t * s,sip_msg_t * msg)1236 static int sel_tlsext_sn(str* res, select_t* s, sip_msg_t* msg)
1237 {
1238 	return get_tlsext_sn(res, msg);
1239 }
1240 
1241 
pv_tlsext_sn(sip_msg_t * msg,pv_param_t * param,pv_value_t * res)1242 static int pv_tlsext_sn(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
1243 {
1244 	if (param->pvn.u.isname.name.n != PV_TLSEXT_SNI) {
1245 		BUG("unexpected parameter value \"%d\"\n",
1246 			param->pvn.u.isname.name.n);
1247 		return pv_get_null(msg, param, res);
1248 	}
1249 
1250 	if (get_tlsext_sn(&res->rs, msg) < 0) {
1251 		return pv_get_null(msg, param, res);
1252 	}
1253 
1254 	res->flags = PV_VAL_STR;
1255 	return 0;
1256 }
1257 
1258 
1259 
1260 
1261 
1262 select_row_t tls_sel[] = {
1263 	/* Current cipher parameters */
1264 	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("tls"), sel_tls, 0},
1265 
1266 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("version"),     sel_version, 0},
1267 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("desc"),        sel_desc,    0},
1268 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("description"), sel_desc,    0},
1269 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("cipher"),      sel_cipher,  0},
1270 
1271 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("serverName"), sel_tlsext_sn,  0},
1272 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("server_name"), sel_tlsext_sn,  0},
1273 
1274 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("peer"),        sel_cert,    DIVERSION | CERT_PEER},
1275 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("my"),          sel_cert,    DIVERSION | CERT_LOCAL},
1276 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("me"),          sel_cert,    DIVERSION | CERT_LOCAL},
1277 	{ sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("myself"),      sel_cert,    DIVERSION | CERT_LOCAL},
1278 
1279 	{ sel_cipher, SEL_PARAM_STR, STR_STATIC_INIT("bits"), sel_bits, 0},
1280 
1281 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("subject"), sel_name, DIVERSION | CERT_SUBJECT},
1282 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("subj"),    sel_name, DIVERSION | CERT_SUBJECT},
1283 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("issuer"),  sel_name, DIVERSION | CERT_ISSUER},
1284 
1285 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("verified"),    sel_check_cert, DIVERSION | CERT_VERIFIED},
1286 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("revoked"),     sel_check_cert, DIVERSION | CERT_REVOKED},
1287 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("expired"),     sel_check_cert, DIVERSION | CERT_EXPIRED},
1288 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("self_signed"), sel_check_cert, DIVERSION | CERT_SELFSIGNED},
1289 
1290 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("version"), sel_cert_version, 0},
1291 
1292 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("rawCert"), sel_ssl_cert, DIVERSION | CERT_RAW},
1293 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("raw_cert"), sel_ssl_cert, DIVERSION | CERT_RAW},
1294 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("URLEncodedCert"), sel_ssl_cert, DIVERSION | CERT_URLENCODED},
1295 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("urlencoded_cert"), sel_ssl_cert, DIVERSION | CERT_URLENCODED},
1296 
1297 #if (OPENSSL_VERSION_NUMBER >= 0x10100001L)
1298 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("verified_cert_chain"), sel_ssl_verified_cert_chain, CONSUME_NEXT_INT},
1299 #endif
1300 
1301 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("sn"),            sel_sn, 0},
1302 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("serialNumber"),  sel_sn, 0},
1303 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("serial_number"), sel_sn, 0},
1304 
1305 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("notBefore"),  sel_validity, DIVERSION | CERT_NOTBEFORE},
1306 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("not_before"), sel_validity, DIVERSION | CERT_NOTBEFORE},
1307 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("notAfter"),   sel_validity, DIVERSION | CERT_NOTAFTER},
1308 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("not_after"),  sel_validity, DIVERSION | CERT_NOTAFTER},
1309 
1310 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("email"),         sel_alt, DIVERSION | COMP_E},
1311 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("emailAddress"),  sel_alt, DIVERSION | COMP_E},
1312 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("email_address"), sel_alt, DIVERSION | COMP_E},
1313 
1314 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("host"),     sel_alt, DIVERSION | COMP_HOST},
1315 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("hostname"), sel_alt, DIVERSION | COMP_HOST},
1316 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("dns"),      sel_alt, DIVERSION | COMP_HOST},
1317 
1318 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("uri"), sel_alt, DIVERSION | COMP_URI},
1319 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("url"), sel_alt, DIVERSION | COMP_URI},
1320 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("urn"), sel_alt, DIVERSION | COMP_URI},
1321 
1322 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("ip"),         sel_alt, DIVERSION | COMP_IP},
1323 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("IPAddress"),  sel_alt, DIVERSION | COMP_IP},
1324 	{ sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("ip_address"), sel_alt, DIVERSION | COMP_IP},
1325 
1326 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("cn"),          sel_comp, DIVERSION | COMP_CN},
1327 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("commonName"),  sel_comp, DIVERSION | COMP_CN},
1328 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("common_name"), sel_comp, DIVERSION | COMP_CN},
1329 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("name"),        sel_comp, DIVERSION | COMP_CN},
1330 
1331 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("l"),             sel_comp, DIVERSION | COMP_L},
1332 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("localityName"),  sel_comp, DIVERSION | COMP_L},
1333 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("locality_name"), sel_comp, DIVERSION | COMP_L},
1334 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("locality"),      sel_comp, DIVERSION | COMP_L},
1335 
1336 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("c"),            sel_comp, DIVERSION | COMP_C},
1337 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("countryName"),  sel_comp, DIVERSION | COMP_C},
1338 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("country_name"), sel_comp, DIVERSION | COMP_C},
1339 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("country"),      sel_comp, DIVERSION | COMP_C},
1340 
1341 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("st"),                     sel_comp, DIVERSION | COMP_ST},
1342 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("stateOrProvinceName"),    sel_comp, DIVERSION | COMP_ST},
1343 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("state_or_province_name"), sel_comp, DIVERSION | COMP_ST},
1344 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("state"),                  sel_comp, DIVERSION | COMP_ST},
1345 
1346 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("o"),                 sel_comp, DIVERSION | COMP_O},
1347 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("organizationName"),  sel_comp, DIVERSION | COMP_O},
1348 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("organization_name"), sel_comp, DIVERSION | COMP_O},
1349 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("organization"),      sel_comp, DIVERSION | COMP_O},
1350 
1351 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("ou"),                       sel_comp, DIVERSION | COMP_OU},
1352 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("organizationalUnitName"),   sel_comp, DIVERSION | COMP_OU},
1353 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("organizational_unit_name"), sel_comp, DIVERSION | COMP_OU},
1354 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("unit"),                     sel_comp, DIVERSION | COMP_OU},
1355 
1356 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("uid"),               sel_comp, DIVERSION | COMP_UID},
1357 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("uniqueIdentifier"),  sel_comp, DIVERSION | COMP_UID},
1358 	{ sel_name, SEL_PARAM_STR, STR_STATIC_INIT("unique_identifier"), sel_comp, DIVERSION | COMP_UID},
1359 
1360 	{ NULL, SEL_PARAM_INT, STR_NULL, NULL, 0}
1361 };
1362 
1363 
1364 /*
1365  *  pseudo variables
1366  */
1367 pv_export_t tls_pv[] = {
1368 	/* TLS session parameters */
1369 	{{"tls_version", sizeof("tls_version")-1},
1370 		PVT_OTHER, pv_version, 0,
1371 		0, 0, 0, 0 },
1372 	{{"tls_description", sizeof("tls_description")-1},
1373 		PVT_OTHER, pv_desc, 0,
1374 		0, 0, 0, 0 },
1375 	{{"tls_cipher_info", sizeof("tls_cipher_info")-1},
1376 		PVT_OTHER, pv_cipher, 0,
1377 		0, 0, 0, 0 },
1378 	{{"tls_cipher_bits", sizeof("tls_cipher_bits")-1},
1379 		PVT_OTHER,  pv_bits, 0,
1380 		0, 0, 0, 0 },
1381 	/* raw and urlencoded versions of peer and local certificates */
1382 	{{"tls_peer_raw_cert", sizeof("tls_peer_raw_cert")-1},
1383 		PVT_OTHER, pv_ssl_cert, 0,
1384 		0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_RAW},
1385 	{{"tls_my_raw_cert", sizeof("tls_my_raw_cert")-1},
1386 		PVT_OTHER, pv_ssl_cert, 0,
1387 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_RAW},
1388 	{{"tls_peer_urlencoded_cert", sizeof("tls_peer_urlencoded_cert")-1},
1389 		PVT_OTHER, pv_ssl_cert, 0,
1390 		0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_URLENCODED},
1391 	{{"tls_my_urlencoded_cert", sizeof("tls_my_urlencoded_cert")-1},
1392 		PVT_OTHER, pv_ssl_cert, 0,
1393 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_URLENCODED},
1394 	/* general certificate parameters for peer and local */
1395 	{{"tls_peer_version", sizeof("tls_peer_version")-1},
1396 		PVT_OTHER, pv_cert_version, 0,
1397 		0, 0, pv_init_iname, PV_CERT_PEER  },
1398 	{{"tls_my_version", sizeof("tls_my_version")-1},
1399 		PVT_OTHER, pv_cert_version, 0,
1400 		0, 0, pv_init_iname, PV_CERT_LOCAL },
1401 	{{"tls_peer_serial", sizeof("tls_peer_serial")-1},
1402 		PVT_OTHER, pv_sn, 0,
1403 		0, 0, pv_init_iname, PV_CERT_PEER  },
1404 	{{"tls_my_serial", sizeof("tls_my_serial")-1},
1405 		PVT_OTHER, pv_sn,0,
1406 		0, 0, pv_init_iname, PV_CERT_LOCAL },
1407 	/* certificate parameters for peer and local, for subject and issuer*/
1408 	{{"tls_peer_subject", sizeof("tls_peer_subject")-1},
1409 		PVT_OTHER, pv_comp, 0,
1410 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_SUBJECT },
1411 	{{"tls_peer_issuer", sizeof("tls_peer_issuer")-1},
1412 		PVT_OTHER, pv_comp, 0,
1413 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_ISSUER  },
1414 	{{"tls_my_subject", sizeof("tls_my_subject")-1},
1415 		PVT_OTHER, pv_comp, 0,
1416 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT },
1417 	{{"tls_my_issuer", sizeof("tls_my_issuer")-1},
1418 		PVT_OTHER, pv_comp, 0,
1419 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER  },
1420 	{{"tls_peer_subject_cn", sizeof("tls_peer_subject_cn")-1},
1421 		PVT_OTHER, pv_comp, 0,
1422 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_SUBJECT | PV_COMP_CN },
1423 	{{"tls_peer_issuer_cn", sizeof("tls_peer_issuer_cn")-1},
1424 		PVT_OTHER, pv_comp, 0,
1425 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_ISSUER  | PV_COMP_CN },
1426 	{{"tls_my_subject_cn", sizeof("tls_my_subject_cn")-1},
1427 		PVT_OTHER, pv_comp, 0,
1428 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT | PV_COMP_CN },
1429 	{{"tls_my_issuer_cn", sizeof("tls_my_issuer_cn")-1},
1430 		PVT_OTHER, pv_comp, 0,
1431 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER  | PV_COMP_CN },
1432 	{{"tls_peer_subject_locality", sizeof("tls_peer_subject_locality")-1},
1433 		PVT_OTHER, pv_comp, 0,
1434 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_SUBJECT | PV_COMP_L },
1435 	{{"tls_peer_issuer_locality", sizeof("tls_peer_issuer_locality")-1},
1436 		PVT_OTHER, pv_comp, 0,
1437 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_ISSUER  | PV_COMP_L },
1438 	{{"tls_my_subject_locality", sizeof("tls_my_subject_locality")-1},
1439 		PVT_OTHER, pv_comp, 0,
1440 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT | PV_COMP_L },
1441 	{{"tls_my_issuer_locality", sizeof("tls_my_issuer_locality")-1},
1442 		PVT_OTHER, pv_comp, 0,
1443 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER  | PV_COMP_L },
1444 	{{"tls_peer_subject_country", sizeof("tls_peer_subject_country")-1},
1445 		PVT_OTHER, pv_comp, 0,
1446 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_SUBJECT | PV_COMP_C },
1447 	{{"tls_peer_issuer_country", sizeof("tls_peer_issuer_country")-1},
1448 		PVT_OTHER, pv_comp, 0,
1449 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_ISSUER  | PV_COMP_C },
1450 	{{"tls_my_subject_country", sizeof("tls_my_subject_country")-1},
1451 		PVT_OTHER, pv_comp, 0,
1452 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT | PV_COMP_C },
1453 	{{"tls_my_issuer_country", sizeof("tls_my_issuer_country")-1},
1454 		PVT_OTHER, pv_comp, 0,
1455 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER  | PV_COMP_C },
1456 	{{"tls_peer_subject_state", sizeof("tls_peer_subject_state")-1},
1457 		PVT_OTHER, pv_comp, 0,
1458 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_SUBJECT | PV_COMP_ST },
1459 	{{"tls_peer_issuer_state", sizeof("tls_peer_issuer_state")-1},
1460 		PVT_OTHER, pv_comp, 0,
1461 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_ISSUER  | PV_COMP_ST },
1462 	{{"tls_my_subject_state", sizeof("tls_my_subject_state")-1},
1463 		PVT_OTHER, pv_comp, 0,
1464 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT | PV_COMP_ST },
1465 	{{"tls_my_issuer_state", sizeof("tls_my_issuer_state")-1},
1466 		PVT_OTHER, pv_comp, 0,
1467 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER  | PV_COMP_ST },
1468 	{{"tls_peer_subject_organization", sizeof("tls_peer_subject_organization")-1},
1469 		PVT_OTHER, pv_comp, 0,
1470 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_SUBJECT | PV_COMP_O },
1471 	{{"tls_peer_issuer_organization", sizeof("tls_peer_issuer_organization")-1},
1472 		PVT_OTHER, pv_comp, 0,
1473 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_ISSUER  | PV_COMP_O },
1474 	{{"tls_my_subject_organization", sizeof("tls_my_subject_organization")-1},
1475 		PVT_OTHER, pv_comp, 0,
1476 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT | PV_COMP_O },
1477 	{{"tls_my_issuer_organization", sizeof("tls_my_issuer_organization")-1},
1478 		PVT_OTHER, pv_comp, 0,
1479 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER  | PV_COMP_O },
1480 	{{"tls_peer_subject_unit", sizeof("tls_peer_subject_unit")-1},
1481 		PVT_OTHER, pv_comp, 0,
1482 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_SUBJECT | PV_COMP_OU },
1483 	{{"tls_peer_issuer_unit", sizeof("tls_peer_issuer_unit")-1},
1484 		PVT_OTHER, pv_comp, 0,
1485 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_CERT_ISSUER  | PV_COMP_OU },
1486 	{{"tls_my_subject_unit", sizeof("tls_my_subject_unit")-1},
1487 		PVT_OTHER, pv_comp, 0,
1488 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT | PV_COMP_OU },
1489 	{{"tls_my_issuer_unit", sizeof("tls_my_issuer_unit")-1},
1490 		PVT_OTHER, pv_comp, 0,
1491 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER  | PV_COMP_OU },
1492 	/* unique identifier for peer and local */
1493 	{{"tls_peer_subject_uid", sizeof("tls_peer_subject_uid")-1},
1494 		PVT_OTHER, pv_comp, 0,
1495 		0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_SUBJECT | PV_COMP_UID },
1496 	{{"tls_my_subject_uid", sizeof("tls_my_subject_uid")-1},
1497 		PVT_OTHER, pv_comp, 0,
1498 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT | PV_COMP_UID },
1499 	/* subject alternative name parameters for peer and local */
1500 	{{"tls_peer_san_email", sizeof("tls_peer_san_email")-1},
1501 		PVT_OTHER, pv_alt, 0,
1502 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_COMP_E },
1503 	{{"tls_my_san_email", sizeof("tls_my_san_email")-1},
1504 		PVT_OTHER, pv_alt, 0,
1505 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_COMP_E },
1506 	{{"tls_peer_san_hostname", sizeof("tls_peer_san_hostname")-1},
1507 		PVT_OTHER, pv_alt, 0,
1508 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_COMP_HOST },
1509 	{{"tls_my_san_hostname", sizeof("tls_my_san_hostname")-1},
1510 		PVT_OTHER, pv_alt, 0,
1511 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_COMP_HOST },
1512 	{{"tls_peer_san_uri", sizeof("tls_peer_san_uri")-1},
1513 		PVT_OTHER, pv_alt, 0,
1514 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_COMP_URI },
1515 	{{"tls_my_san_uri", sizeof("tls_my_san_uri")-1},
1516 		PVT_OTHER, pv_alt, 0,
1517 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_COMP_URI },
1518 	{{"tls_peer_san_ip", sizeof("tls_peer_san_ip")-1},
1519 		PVT_OTHER, pv_alt, 0,
1520 		0, 0, pv_init_iname, PV_CERT_PEER  | PV_COMP_IP },
1521 	{{"tls_my_san_ip", sizeof("tls_my_san_ip")-1},
1522 		PVT_OTHER, pv_alt, 0,
1523 		0, 0, pv_init_iname, PV_CERT_LOCAL | PV_COMP_IP },
1524 	/* peer certificate validation parameters */
1525 	{{"tls_peer_verified", sizeof("tls_peer_verified")-1},
1526 		PVT_OTHER, pv_check_cert, 0,
1527 		0, 0, pv_init_iname, PV_CERT_VERIFIED },
1528 	{{"tls_peer_revoked", sizeof("tls_peer_revoked")-1},
1529 		PVT_OTHER, pv_check_cert, 0,
1530 		0, 0, pv_init_iname, PV_CERT_REVOKED },
1531 	{{"tls_peer_expired", sizeof("tls_peer_expired")-1},
1532 		PVT_OTHER, pv_check_cert, 0,
1533 		0, 0, pv_init_iname, PV_CERT_EXPIRED },
1534 	{{"tls_peer_selfsigned", sizeof("tls_peer_selfsigned")-1},
1535 		PVT_OTHER, pv_check_cert, 0,
1536 		0, 0, pv_init_iname, PV_CERT_SELFSIGNED },
1537 	{{"tls_peer_notBefore", sizeof("tls_peer_notBefore")-1},
1538 		PVT_OTHER, pv_validity, 0,
1539 		0, 0, pv_init_iname, PV_CERT_NOTBEFORE },
1540 	{{"tls_peer_notAfter", sizeof("tls_peer_notAfter")-1},
1541 		PVT_OTHER, pv_validity, 0,
1542 		0, 0, pv_init_iname, PV_CERT_NOTAFTER },
1543 	/* peer certificate validation parameters */
1544 	{{"tls_peer_server_name", sizeof("tls_peer_server_name")-1},
1545 		PVT_OTHER, pv_tlsext_sn, 0,
1546 		0, 0, pv_init_iname, PV_TLSEXT_SNI },
1547 
1548 	{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
1549 
1550 };
1551