00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00034 #include <openssl/ssl.h>
00035 #include <openssl/x509v3.h>
00036 #include "../../globals.h"
00037 #include "../../tcp_server.h"
00038 #include "../../tcp_conn.h"
00039 #include "../../ut.h"
00040 #include "../../cfg/cfg.h"
00041 #include "tls_server.h"
00042 #include "tls_select.h"
00043 #include "tls_mod.h"
00044 #include "tls_init.h"
00045 #include "tls_cfg.h"
00046
00047 enum {
00048 CERT_LOCAL = 1,
00049 CERT_PEER,
00050 CERT_SUBJECT,
00051 CERT_ISSUER,
00052 CERT_VERIFIED,
00053 CERT_REVOKED,
00054 CERT_EXPIRED,
00055 CERT_SELFSIGNED,
00056 CERT_NOTBEFORE,
00057 CERT_NOTAFTER,
00058 COMP_CN,
00059 COMP_O,
00060 COMP_OU,
00061 COMP_C,
00062 COMP_ST,
00063 COMP_L,
00064 COMP_HOST,
00065 COMP_URI,
00066 COMP_E,
00067 COMP_IP,
00068 TLSEXT_SN
00069 };
00070
00071
00072 enum {
00073 PV_CERT_LOCAL = 1<<0,
00074 PV_CERT_PEER = 1<<1,
00075 PV_CERT_SUBJECT = 1<<2,
00076 PV_CERT_ISSUER = 1<<3,
00077
00078 PV_CERT_VERIFIED = 1<<4,
00079 PV_CERT_REVOKED = 1<<5,
00080 PV_CERT_EXPIRED = 1<<6,
00081 PV_CERT_SELFSIGNED = 1<<7,
00082 PV_CERT_NOTBEFORE = 1<<8,
00083 PV_CERT_NOTAFTER = 1<<9,
00084
00085 PV_COMP_CN = 1<<10,
00086 PV_COMP_O = 1<<11,
00087 PV_COMP_OU = 1<<12,
00088 PV_COMP_C = 1<<13,
00089 PV_COMP_ST = 1<<14,
00090 PV_COMP_L = 1<<15,
00091
00092 PV_COMP_HOST = 1<<16,
00093 PV_COMP_URI = 1<<17,
00094 PV_COMP_E = 1<<18,
00095 PV_COMP_IP = 1<<19,
00096
00097 PV_TLSEXT_SNI = 1<<20,
00098 };
00099
00100
00101
00102
00103
00104 struct tcp_connection* get_cur_connection(struct sip_msg* msg)
00105 {
00106 struct tcp_connection* c;
00107 if (msg->rcv.proto != PROTO_TLS) {
00108 ERR("Transport protocol is not TLS (bug in config)\n");
00109 return 0;
00110 }
00111
00112 c = tcpconn_get(msg->rcv.proto_reserved1, 0, 0, 0,
00113 cfg_get(tls, tls_cfg, con_lifetime));
00114 if (c && c->type != PROTO_TLS) {
00115 ERR("Connection found but is not TLS\n");
00116 tcpconn_put(c);
00117 return 0;
00118 }
00119 return c;
00120 }
00121
00122
00123 static SSL* get_ssl(struct tcp_connection* c)
00124 {
00125 struct tls_extra_data* extra;
00126
00127 if (!c || !c->extra_data) {
00128 ERR("Unable to extract SSL data from TLS connection\n");
00129 return 0;
00130 }
00131 extra = (struct tls_extra_data*)c->extra_data;
00132 return extra->ssl;
00133 }
00134
00135
00136 static int get_cert(X509** cert, struct tcp_connection** c, struct sip_msg* msg, int my)
00137 {
00138 SSL* ssl;
00139
00140 *cert = 0;
00141 *c = get_cur_connection(msg);
00142 if (!(*c)) {
00143 INFO("TLS connection not found\n");
00144 return -1;
00145 }
00146 ssl = get_ssl(*c);
00147 if (!ssl) goto err;
00148 *cert = my ? SSL_get_certificate(ssl) : SSL_get_peer_certificate(ssl);
00149 if (!*cert) {
00150 ERR("Unable to retrieve TLS certificate from SSL structure\n");
00151 goto err;
00152 }
00153
00154 return 0;
00155
00156 err:
00157 tcpconn_put(*c);
00158 return -1;
00159 }
00160
00161
00162 static int get_cipher(str* res, sip_msg_t* msg)
00163 {
00164 str cipher;
00165 static char buf[1024];
00166
00167 struct tcp_connection* c;
00168 SSL* ssl;
00169
00170 c = get_cur_connection(msg);
00171 if (!c) {
00172 INFO("TLS connection not found in select_cipher\n");
00173 goto err;
00174 }
00175 ssl = get_ssl(c);
00176 if (!ssl) goto err;
00177
00178 cipher.s = (char*)SSL_CIPHER_get_name(SSL_get_current_cipher(ssl));
00179 cipher.len = cipher.s ? strlen(cipher.s) : 0;
00180 if (cipher.len >= 1024) {
00181 ERR("Cipher name too long\n");
00182 goto err;
00183 }
00184 memcpy(buf, cipher.s, cipher.len);
00185 res->s = buf;
00186 res->len = cipher.len;
00187 tcpconn_put(c);
00188 return 0;
00189
00190 err:
00191 if (c) tcpconn_put(c);
00192 return -1;
00193 }
00194
00195 static int sel_cipher(str* res, select_t* s, sip_msg_t* msg)
00196 {
00197 return get_cipher(res, msg);
00198 }
00199
00200
00201 static int pv_cipher(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
00202 {
00203 if (get_cipher(&res->rs, msg) < 0) {
00204 return pv_get_null(msg, param, res);
00205 }
00206 res->flags = PV_VAL_STR;
00207 return 0;
00208 }
00209
00210
00211 static int get_bits(str* res, int* i, sip_msg_t* msg)
00212 {
00213 str bits;
00214 int b;
00215 static char buf[1024];
00216
00217 struct tcp_connection* c;
00218 SSL* ssl;
00219
00220 c = get_cur_connection(msg);
00221 if (!c) {
00222 INFO("TLS connection not found in select_bits\n");
00223 goto err;
00224 }
00225 ssl = get_ssl(c);
00226 if (!ssl) goto err;
00227
00228 b = SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl), 0);
00229 bits.s = int2str(b, &bits.len);
00230 if (bits.len >= 1024) {
00231 ERR("Bits string too long\n");
00232 goto err;
00233 }
00234 memcpy(buf, bits.s, bits.len);
00235 res->s = buf;
00236 res->len = bits.len;
00237 if (i) *i = b;
00238 tcpconn_put(c);
00239 return 0;
00240
00241 err:
00242 if (c) tcpconn_put(c);
00243 return -1;
00244 }
00245
00246
00247 static int sel_bits(str* res, select_t* s, sip_msg_t* msg)
00248 {
00249 return get_bits(res, NULL, msg);
00250 }
00251
00252 static int pv_bits(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
00253 {
00254 if (get_bits(&res->rs, &res->ri, msg) < 0) {
00255 return pv_get_null(msg, param, res);
00256 }
00257 res->flags = PV_VAL_STR | PV_VAL_INT;
00258 return 0;
00259 }
00260
00261
00262 static int get_version(str* res, sip_msg_t* msg)
00263 {
00264 str version;
00265 static char buf[1024];
00266
00267 struct tcp_connection* c;
00268 SSL* ssl;
00269
00270 c = get_cur_connection(msg);
00271 if (!c) {
00272 INFO("TLS connection not found in select_version\n");
00273 goto err;
00274 }
00275 ssl = get_ssl(c);
00276 if (!ssl) goto err;
00277
00278 version.s = (char*)SSL_get_version(ssl);
00279 version.len = version.s ? strlen(version.s) : 0;
00280 if (version.len >= 1024) {
00281 ERR("Version string too long\n");
00282 goto err;
00283 }
00284 memcpy(buf, version.s, version.len);
00285 res->s = buf;
00286 res->len = version.len;
00287 tcpconn_put(c);
00288 return 0;
00289
00290 err:
00291 if (c) tcpconn_put(c);
00292 return -1;
00293 }
00294
00295
00296 static int sel_version(str* res, select_t* s, sip_msg_t* msg)
00297 {
00298 return get_version(res, msg);
00299 }
00300
00301
00302 static int pv_version(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
00303 {
00304 if (get_version(&res->rs, msg) < 0) {
00305 return pv_get_null(msg, param, res);
00306 }
00307 res->flags = PV_VAL_STR;
00308 return 0;
00309 }
00310
00311
00312
00313 static int get_desc(str* res, sip_msg_t* msg)
00314 {
00315 static char buf[128];
00316
00317 struct tcp_connection* c;
00318 SSL* ssl;
00319
00320 c = get_cur_connection(msg);
00321 if (!c) {
00322 INFO("TLS connection not found in select_desc\n");
00323 goto err;
00324 }
00325 ssl = get_ssl(c);
00326 if (!ssl) goto err;
00327
00328 buf[0] = '\0';
00329 SSL_CIPHER_description(SSL_get_current_cipher(ssl), buf, 128);
00330 res->s = buf;
00331 res->len = strlen(buf);
00332 tcpconn_put(c);
00333 return 0;
00334
00335 err:
00336 if (c) tcpconn_put(c);
00337 return -1;
00338 }
00339
00340
00341 static int sel_desc(str* res, select_t* s, sip_msg_t* msg)
00342 {
00343 return get_desc(res, msg);
00344 }
00345
00346 static int pv_desc(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
00347 {
00348 if (get_desc(&res->rs, msg) < 0) {
00349 return pv_get_null(msg, param, res);
00350 }
00351 res->flags = PV_VAL_STR;
00352 return 0;
00353 }
00354
00355
00356
00357 static int get_cert_version(str* res, int local, sip_msg_t* msg)
00358 {
00359 static char buf[INT2STR_MAX_LEN];
00360 X509* cert;
00361 struct tcp_connection* c;
00362 char* version;
00363
00364 if (get_cert(&cert, &c, msg, local) < 0) return -1;
00365 version = int2str(X509_get_version(cert), &res->len);
00366 memcpy(buf, version, res->len);
00367 res->s = buf;
00368 if (!local) X509_free(cert);
00369 tcpconn_put(c);
00370 return 0;
00371 }
00372
00373 static int sel_cert_version(str* res, select_t* s, sip_msg_t* msg)
00374 {
00375 int local;
00376
00377 switch(s->params[s->n - 2].v.i) {
00378 case CERT_PEER: local = 0; break;
00379 case CERT_LOCAL: local = 1; break;
00380 default:
00381 BUG("Bug in call to sel_cert_version\n");
00382 return -1;
00383 }
00384
00385 return get_cert_version(res, local, msg);
00386 }
00387
00388 static int pv_cert_version(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
00389 {
00390 int local;
00391
00392 if (param->pvn.u.isname.name.n & PV_CERT_PEER) {
00393 local = 0;
00394 } else if (param->pvn.u.isname.name.n & PV_CERT_LOCAL) {
00395 local = 1;
00396 } else {
00397 BUG("bug in call to pv_cert_version\n");
00398 return pv_get_null(msg, param, res);
00399 }
00400
00401 if (get_cert_version(&res->rs, local, msg) < 0) {
00402 return pv_get_null(msg, param, res);
00403 }
00404 res->flags = PV_VAL_STR;
00405 return 0;
00406 }
00407
00408
00409
00410
00411
00412
00413
00414 static int check_cert(str* res, int* ires, int local, int err, sip_msg_t* msg)
00415 {
00416 static str succ = STR_STATIC_INIT("1");
00417 static str fail = STR_STATIC_INIT("0");
00418
00419 struct tcp_connection* c;
00420 SSL* ssl;
00421 X509* cert = 0;
00422
00423 c = get_cur_connection(msg);
00424 if (!c) return -1;
00425
00426 ssl = get_ssl(c);
00427 if (!ssl) goto error;
00428
00429 if (local) {
00430 DBG("Verification of local certificates not supported\n");
00431 goto error;
00432 } else {
00433 if ((cert = SSL_get_peer_certificate(ssl)) && SSL_get_verify_result(ssl) == err) {
00434 *res = succ;
00435 if (ires) *ires = 1;
00436 } else {
00437 *res = fail;
00438 if (ires) *ires = 0;
00439 }
00440 }
00441
00442 if (cert) X509_free(cert);
00443 tcpconn_put(c);
00444 return 0;
00445
00446 error:
00447 if (cert) X509_free(cert);
00448 if (c) tcpconn_put(c);
00449 return -1;
00450 }
00451
00452
00453 static int sel_check_cert(str* res, select_t* s, sip_msg_t* msg)
00454 {
00455 int local, err;
00456
00457 switch(s->params[s->n - 2].v.i) {
00458 case CERT_PEER: local = 0; break;
00459 case CERT_LOCAL: local = 1; break;
00460 default:
00461 BUG("Bug in call to sel_cert_version\n");
00462 return -1;
00463 }
00464
00465 switch (s->params[s->n - 1].v.i) {
00466 case CERT_VERIFIED: err = X509_V_OK; break;
00467 case CERT_REVOKED: err = X509_V_ERR_CERT_REVOKED; break;
00468 case CERT_EXPIRED: err = X509_V_ERR_CERT_HAS_EXPIRED; break;
00469 case CERT_SELFSIGNED: err = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; break;
00470 default:
00471 BUG("Unexpected parameter value \"%d\"\n", s->params[s->n - 1].v.i);
00472 return -1;
00473 }
00474
00475 return check_cert(res, NULL, local, err, msg);
00476 }
00477
00478 static int pv_check_cert(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
00479 {
00480 int err;
00481
00482 switch (param->pvn.u.isname.name.n) {
00483 case PV_CERT_VERIFIED: err = X509_V_OK; break;
00484 case PV_CERT_REVOKED: err = X509_V_ERR_CERT_REVOKED; break;
00485 case PV_CERT_EXPIRED: err = X509_V_ERR_CERT_HAS_EXPIRED; break;
00486 case PV_CERT_SELFSIGNED: err = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; break;
00487 default:
00488 BUG("unexpected parameter value \"%d\"\n", param->pvn.u.isname.name.n);
00489 return pv_get_null(msg, param, res);
00490 }
00491
00492
00493 if (check_cert(&res->rs, &res->ri, 0, err, msg) < 0) {
00494 return pv_get_null(msg, param, res);
00495 }
00496
00497 res->flags = PV_VAL_STR | PV_VAL_INT;
00498 return 0;
00499 }
00500
00501
00502
00503
00504 static int get_validity(str* res, int local, int bound, sip_msg_t* msg)
00505 {
00506 #define NOT_BEFORE 0
00507 #define NOT_AFTER 1
00508 static char buf[1024];
00509 X509* cert;
00510 struct tcp_connection* c;
00511 BUF_MEM* p;
00512 BIO* mem = 0;
00513 ASN1_TIME* date;
00514
00515 if (get_cert(&cert, &c, msg, local) < 0) return -1;
00516
00517 switch (bound) {
00518 case NOT_BEFORE: date = X509_get_notBefore(cert); break;
00519 case NOT_AFTER: date = X509_get_notAfter(cert); break;
00520 default:
00521 BUG("Unexpected parameter value \"%d\"\n", bound);
00522 goto err;
00523 }
00524
00525 mem = BIO_new(BIO_s_mem());
00526 if (!mem) {
00527 ERR("Error while creating memory BIO\n");
00528 goto err;
00529 }
00530
00531 if (!ASN1_TIME_print(mem, date)) {
00532 ERR("Error while printing certificate date/time\n");
00533 goto err;
00534 }
00535
00536 BIO_get_mem_ptr(mem, &p);
00537 if (p->length >= 1024) {
00538 ERR("Date/time too long\n");
00539 goto err;
00540 }
00541 memcpy(buf, p->data, p->length);
00542 res->s = buf;
00543 res->len = p->length;
00544
00545 BIO_free(mem);
00546 if (!local) X509_free(cert);
00547 tcpconn_put(c);
00548 return 0;
00549 err:
00550 if (mem) BIO_free(mem);
00551 if (!local) X509_free(cert);
00552 tcpconn_put(c);
00553 return -1;
00554 }
00555
00556 static int sel_validity(str* res, select_t* s, sip_msg_t* msg)
00557 {
00558 int local, bound;
00559
00560 switch(s->params[s->n - 2].v.i) {
00561 case CERT_PEER: local = 0; break;
00562 case CERT_LOCAL: local = 1; break;
00563 default:
00564 BUG("Could not determine certificate\n");
00565 return -1;
00566 }
00567
00568 switch (s->params[s->n - 1].v.i) {
00569 case CERT_NOTBEFORE: bound = NOT_BEFORE; break;
00570 case CERT_NOTAFTER: bound = NOT_AFTER; break;
00571 default:
00572 BUG("Unexpected parameter value \"%d\"\n", s->params[s->n - 1].v.i);
00573 return -1;
00574 }
00575
00576 return get_validity(res, local, bound, msg);
00577 }
00578
00579
00580 static int pv_validity(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
00581 {
00582 int bound;
00583
00584 switch (param->pvn.u.isname.name.n) {
00585 case PV_CERT_NOTBEFORE: bound = NOT_BEFORE; break;
00586 case PV_CERT_NOTAFTER: bound = NOT_AFTER; break;
00587 default:
00588 BUG("unexpected parameter value \"%d\"\n", param->pvn.u.isname.name.n);
00589 return pv_get_null(msg, param, res);
00590 }
00591
00592 if (get_validity(&res->rs, 0, bound, msg) < 0) {
00593 return pv_get_null(msg, param, res);
00594 }
00595
00596 res->flags = PV_VAL_STR;
00597 return 0;
00598 }
00599
00600
00601 static int get_sn(str* res, int* ires, int local, sip_msg_t* msg)
00602 {
00603 static char buf[INT2STR_MAX_LEN];
00604 X509* cert;
00605 struct tcp_connection* c;
00606 char* sn;
00607 int num;
00608
00609 if (get_cert(&cert, &c, msg, local) < 0) return -1;
00610
00611 num = ASN1_INTEGER_get(X509_get_serialNumber(cert));
00612 sn = int2str(num, &res->len);
00613 memcpy(buf, sn, res->len);
00614 res->s = buf;
00615 if (ires) *ires = num;
00616 if (!local) X509_free(cert);
00617 tcpconn_put(c);
00618 return 0;
00619 }
00620
00621 static int sel_sn(str* res, select_t* s, sip_msg_t* msg)
00622 {
00623 int local;
00624
00625 switch(s->params[s->n - 2].v.i) {
00626 case CERT_PEER: local = 0; break;
00627 case CERT_LOCAL: local = 1; break;
00628 default:
00629 BUG("Could not determine certificate\n");
00630 return -1;
00631 }
00632
00633 return get_sn(res, NULL, local, msg);
00634 }
00635
00636
00637 static int pv_sn(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
00638 {
00639 int local;
00640
00641 if (param->pvn.u.isname.name.n & PV_CERT_PEER) {
00642 local = 0;
00643 } else if (param->pvn.u.isname.name.n & PV_CERT_LOCAL) {
00644 local = 1;
00645 } else {
00646 BUG("could not determine certificate\n");
00647 return pv_get_null(msg, param, res);
00648 }
00649
00650 if (get_sn(&res->rs, &res->ri, local, msg) < 0) {
00651 return pv_get_null(msg, param, res);
00652 }
00653
00654 res->flags = PV_VAL_STR | PV_VAL_INT;
00655 return 0;
00656 }
00657
00658
00659
00660 static int get_comp(str* res, int local, int issuer, int nid, sip_msg_t* msg)
00661 {
00662 static char buf[1024];
00663 X509* cert;
00664 struct tcp_connection* c;
00665 X509_NAME* name;
00666 X509_NAME_ENTRY* e;
00667 ASN1_STRING* asn1;
00668 int index, text_len;
00669 char* elem;
00670 unsigned char* text_s;
00671
00672 text_s = 0;
00673
00674 if (get_cert(&cert, &c, msg, local) < 0) return -1;
00675
00676 name = issuer ? X509_get_issuer_name(cert) : X509_get_subject_name(cert);
00677 if (!name) {
00678 ERR("Cannot extract subject or issuer name from peer certificate\n");
00679 goto err;
00680 }
00681
00682 index = X509_NAME_get_index_by_NID(name, nid, -1);
00683 if (index == -1) {
00684 switch(nid) {
00685 case NID_commonName: elem = "CommonName"; break;
00686 case NID_organizationName: elem = "OrganizationName"; break;
00687 case NID_organizationalUnitName: elem = "OrganizationalUnitUname"; break;
00688 case NID_countryName: elem = "CountryName"; break;
00689 case NID_stateOrProvinceName: elem = "StateOrProvinceName"; break;
00690 case NID_localityName: elem = "LocalityName"; break;
00691 default: elem = "Unknown"; break;
00692 }
00693 DBG("Element %s not found in certificate subject/issuer\n", elem);
00694 goto err;
00695 }
00696
00697 e = X509_NAME_get_entry(name, index);
00698 asn1 = X509_NAME_ENTRY_get_data(e);
00699 text_len = ASN1_STRING_to_UTF8(&text_s, asn1);
00700 if (text_len < 0 || text_len >= 1024) {
00701 ERR("Error converting ASN1 string\n");
00702 goto err;
00703 }
00704 memcpy(buf, text_s, text_len);
00705 res->s = buf;
00706 res->len = text_len;
00707
00708 OPENSSL_free(text_s);
00709 if (!local) X509_free(cert);
00710 tcpconn_put(c);
00711 return 0;
00712
00713 err:
00714 if (text_s) OPENSSL_free(text_s);
00715 if (!local) X509_free(cert);
00716 tcpconn_put(c);
00717 return -1;
00718 }
00719
00720
00721 static int sel_comp(str* res, select_t* s, sip_msg_t* msg)
00722 {
00723 int i, local = 0, issuer = 0;
00724 int nid = NID_commonName;
00725
00726 for(i = 1; i <= s->n - 1; i++) {
00727 switch(s->params[i].v.i) {
00728 case CERT_LOCAL: local = 1; break;
00729 case CERT_PEER: local = 0; break;
00730 case CERT_SUBJECT: issuer = 0; break;
00731 case CERT_ISSUER: issuer = 1; break;
00732 case COMP_CN: nid = NID_commonName; break;
00733 case COMP_O: nid = NID_organizationName; break;
00734 case COMP_OU: nid = NID_organizationalUnitName; break;
00735 case COMP_C: nid = NID_countryName; break;
00736 case COMP_ST: nid = NID_stateOrProvinceName; break;
00737 case COMP_L: nid = NID_localityName; break;
00738 default:
00739 BUG("Bug in sel_comp: %d\n", s->params[s->n - 1].v.i);
00740 return -1;
00741 }
00742 }
00743
00744 return get_comp(res, local, issuer, nid, msg);
00745 }
00746
00747
00748 static int pv_comp(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
00749 {
00750 int ind_local, local = 0, issuer = 0, nid = NID_commonName;
00751
00752
00753 ind_local = param->pvn.u.isname.name.n;
00754 DBG("ind_local = %x", ind_local);
00755
00756 if (ind_local & PV_CERT_PEER) {
00757 local = 0;
00758 ind_local = ind_local ^ PV_CERT_PEER;
00759 } else if (ind_local & PV_CERT_LOCAL) {
00760 local = 1;
00761 ind_local = ind_local ^ PV_CERT_LOCAL;
00762 } else {
00763 BUG("could not determine certificate\n");
00764 return pv_get_null(msg, param, res);
00765 }
00766
00767 if (ind_local & PV_CERT_SUBJECT) {
00768 issuer = 0;
00769 ind_local = ind_local ^ PV_CERT_SUBJECT;
00770 } else if (ind_local & PV_CERT_ISSUER) {
00771 issuer = 1;
00772 ind_local = ind_local ^ PV_CERT_ISSUER;
00773 } else {
00774 BUG("could not determine subject or issuer\n");
00775 return pv_get_null(msg, param, res);
00776 }
00777
00778 switch(ind_local) {
00779 case PV_COMP_CN: nid = NID_commonName; break;
00780 case PV_COMP_O: nid = NID_organizationName; break;
00781 case PV_COMP_OU: nid = NID_organizationalUnitName; break;
00782 case PV_COMP_C: nid = NID_countryName; break;
00783 case PV_COMP_ST: nid = NID_stateOrProvinceName; break;
00784 case PV_COMP_L: nid = NID_localityName; break;
00785 default: nid = NID_undef;
00786 }
00787
00788 if (get_comp(&res->rs, local, issuer, nid, msg) < 0) {
00789 return pv_get_null(msg, param, res);
00790 }
00791
00792 res->flags = PV_VAL_STR;
00793 return 0;
00794 }
00795
00796
00797 static int get_alt(str* res, int local, int type, sip_msg_t* msg)
00798 {
00799 static char buf[1024];
00800 int n, found = 0;
00801 STACK_OF(GENERAL_NAME)* names = 0;
00802 GENERAL_NAME* nm;
00803 X509* cert;
00804 struct tcp_connection* c;
00805 str text;
00806 struct ip_addr ip;
00807
00808 if (get_cert(&cert, &c, msg, local) < 0) return -1;
00809
00810 names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
00811 if (!names) {
00812 DBG("Cannot get certificate alternative subject\n");
00813 goto err;
00814
00815 }
00816
00817 for (n = 0; n < sk_GENERAL_NAME_num(names); n++) {
00818 nm = sk_GENERAL_NAME_value(names, n);
00819 if (nm->type != type) continue;
00820 switch(type) {
00821 case GEN_EMAIL:
00822 case GEN_DNS:
00823 case GEN_URI:
00824 text.s = (char*)nm->d.ia5->data;
00825 text.len = nm->d.ia5->length;
00826 if (text.len >= 1024) {
00827 ERR("Alternative subject text too long\n");
00828 goto err;
00829 }
00830 memcpy(buf, text.s, text.len);
00831 res->s = buf;
00832 res->len = text.len;
00833 found = 1;
00834 break;
00835
00836 case GEN_IPADD:
00837 ip.len = nm->d.iPAddress->length;
00838 ip.af = (ip.len == 16) ? AF_INET6 : AF_INET;
00839 memcpy(ip.u.addr, nm->d.iPAddress->data, ip.len);
00840 text.s = ip_addr2a(&ip);
00841 text.len = strlen(text.s);
00842 memcpy(buf, text.s, text.len);
00843 res->s = buf;
00844 res->len = text.len;
00845 found = 1;
00846 break;
00847 }
00848 break;
00849 }
00850 if (!found) goto err;
00851
00852 if (names) sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
00853 if (!local) X509_free(cert);
00854 tcpconn_put(c);
00855 return 0;
00856 err:
00857 if (names) sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
00858 if (!local) X509_free(cert);
00859 tcpconn_put(c);
00860 return -1;
00861 }
00862
00863 static int sel_alt(str* res, select_t* s, sip_msg_t* msg)
00864 {
00865 int type = GEN_URI, local = 0, i;
00866
00867 for(i = 1; i <= s->n - 1; i++) {
00868 switch(s->params[i].v.i) {
00869 case CERT_LOCAL: local = 1; break;
00870 case CERT_PEER: local = 0; break;
00871 case COMP_E: type = GEN_EMAIL; break;
00872 case COMP_HOST: type = GEN_DNS; break;
00873 case COMP_URI: type = GEN_URI; break;
00874 case COMP_IP: type = GEN_IPADD; break;
00875 default:
00876 BUG("Bug in sel_alt: %d\n", s->params[s->n - 1].v.i);
00877 return -1;
00878 }
00879 }
00880
00881 return get_alt(res, local, type, msg);
00882 }
00883
00884
00885 static int pv_alt(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
00886 {
00887 int ind_local, local = 0, type = GEN_URI;
00888
00889 ind_local = param->pvn.u.isname.name.n;
00890
00891 if (ind_local & PV_CERT_PEER) {
00892 local = 0;
00893 ind_local = ind_local ^ PV_CERT_PEER;
00894 } else if (ind_local & PV_CERT_LOCAL) {
00895 local = 1;
00896 ind_local = ind_local ^ PV_CERT_LOCAL;
00897 } else {
00898 BUG("could not determine certificate\n");
00899 return pv_get_null(msg, param, res);
00900 }
00901
00902 switch(ind_local) {
00903 case PV_COMP_E: type = GEN_EMAIL; break;
00904 case PV_COMP_HOST: type = GEN_DNS; break;
00905 case PV_COMP_URI: type = GEN_URI; break;
00906 case PV_COMP_IP: type = GEN_IPADD; break;
00907 default:
00908 BUG("ind_local=%d\n", ind_local);
00909 return pv_get_null(msg, param, res);
00910 }
00911
00912 if (get_alt(&res->rs, local, type, msg) < 0) {
00913 return pv_get_null(msg, param, res);
00914 }
00915
00916 res->flags = PV_VAL_STR;
00917 return 0;
00918 }
00919
00920
00921 static int sel_tls(str* res, select_t* s, struct sip_msg* msg)
00922 {
00923 return sel_desc(res, s, msg);
00924 }
00925
00926
00927 static int sel_name(str* res, select_t* s, struct sip_msg* msg)
00928 {
00929 return sel_comp(res, s, msg);
00930 }
00931
00932
00933 static int sel_cert(str* res, select_t* s, struct sip_msg* msg)
00934 {
00935 return sel_comp(res, s, msg);
00936 }
00937
00938
00939 #ifdef OPENSSL_NO_TLSEXT
00940 static int get_tlsext_sn(str* res, sip_msg_t* msg)
00941 {
00942 ERR("TLS extension 'server name' is not available! "
00943 "please install openssl with TLS extension support and recompile "
00944 "the server\n");
00945 return -1;
00946 }
00947 #else
00948 static int get_tlsext_sn(str* res, sip_msg_t* msg)
00949 {
00950 static char buf[1024];
00951 struct tcp_connection* c;
00952 str server_name;
00953 SSL* ssl;
00954
00955 c = get_cur_connection(msg);
00956 if (!c) {
00957 INFO("TLS connection not found in select_desc\n");
00958 goto error;
00959 }
00960 ssl = get_ssl(c);
00961 if (!ssl) goto error;
00962
00963 buf[0] = '\0';
00964
00965 server_name.s = (char*)SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
00966 if (server_name.s) {
00967 server_name.len = strlen(server_name.s);
00968 DBG("received server_name (TLS extension): '%.*s'\n",
00969 STR_FMT(&server_name));
00970 } else {
00971 DBG("SSL_get_servername returned NULL\n");
00972 goto error;
00973 }
00974
00975
00976
00977
00978 if (server_name.len > sizeof(buf)) {
00979 ERR("server_name to big for buffer\n");
00980 buf[0] = '+';
00981 memcpy(buf + 1, server_name.s + 1 + server_name.len - sizeof(buf),
00982 sizeof(buf) - 1);
00983 res->len = sizeof(buf);
00984 } else {
00985 memcpy(buf, server_name.s, server_name.len);
00986 res->len = server_name.len;
00987 }
00988 res->s = buf;
00989
00990 tcpconn_put(c);
00991 return 0;
00992
00993 error:
00994 if (c) tcpconn_put(c);
00995 return -1;
00996 }
00997 #endif
00998
00999
01000 static int sel_tlsext_sn(str* res, select_t* s, sip_msg_t* msg)
01001 {
01002 return get_tlsext_sn(res, msg);
01003 }
01004
01005
01006 static int pv_tlsext_sn(sip_msg_t* msg, pv_param_t* param, pv_value_t* res)
01007 {
01008 if (param->pvn.u.isname.name.n != PV_TLSEXT_SNI) {
01009 BUG("unexpected parameter value \"%d\"\n",
01010 param->pvn.u.isname.name.n);
01011 return pv_get_null(msg, param, res);
01012 }
01013
01014 if (get_tlsext_sn(&res->rs, msg) < 0) {
01015 return pv_get_null(msg, param, res);
01016 }
01017
01018 res->flags = PV_VAL_STR;
01019 return 0;
01020 }
01021
01022
01023
01024
01025
01026 select_row_t tls_sel[] = {
01027
01028 { NULL, SEL_PARAM_STR, STR_STATIC_INIT("tls"), sel_tls, 0},
01029
01030 { sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("version"), sel_version, 0},
01031 { sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("desc"), sel_desc, 0},
01032 { sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("description"), sel_desc, 0},
01033 { sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("cipher"), sel_cipher, 0},
01034
01035 { sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("serverName"), sel_tlsext_sn, 0},
01036 { sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("server_name"), sel_tlsext_sn, 0},
01037
01038 { sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("peer"), sel_cert, DIVERSION | CERT_PEER},
01039 { sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("my"), sel_cert, DIVERSION | CERT_LOCAL},
01040 { sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("me"), sel_cert, DIVERSION | CERT_LOCAL},
01041 { sel_tls, SEL_PARAM_STR, STR_STATIC_INIT("myself"), sel_cert, DIVERSION | CERT_LOCAL},
01042
01043 { sel_cipher, SEL_PARAM_STR, STR_STATIC_INIT("bits"), sel_bits, 0},
01044
01045 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("subject"), sel_name, DIVERSION | CERT_SUBJECT},
01046 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("subj"), sel_name, DIVERSION | CERT_SUBJECT},
01047 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("issuer"), sel_name, DIVERSION | CERT_ISSUER},
01048
01049 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("verified"), sel_check_cert, DIVERSION | CERT_VERIFIED},
01050 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("revoked"), sel_check_cert, DIVERSION | CERT_REVOKED},
01051 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("expired"), sel_check_cert, DIVERSION | CERT_EXPIRED},
01052 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("self_signed"), sel_check_cert, DIVERSION | CERT_SELFSIGNED},
01053
01054 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("version"), sel_cert_version, 0},
01055
01056 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("sn"), sel_sn, 0},
01057 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("serialNumber"), sel_sn, 0},
01058 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("serial_number"), sel_sn, 0},
01059
01060 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("notBefore"), sel_validity, DIVERSION | CERT_NOTBEFORE},
01061 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("not_before"), sel_validity, DIVERSION | CERT_NOTBEFORE},
01062 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("notAfter"), sel_validity, DIVERSION | CERT_NOTAFTER},
01063 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("not_after"), sel_validity, DIVERSION | CERT_NOTAFTER},
01064
01065 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("email"), sel_alt, DIVERSION | COMP_E},
01066 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("emailAddress"), sel_alt, DIVERSION | COMP_E},
01067 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("email_address"), sel_alt, DIVERSION | COMP_E},
01068
01069 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("host"), sel_alt, DIVERSION | COMP_HOST},
01070 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("hostname"), sel_alt, DIVERSION | COMP_HOST},
01071 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("dns"), sel_alt, DIVERSION | COMP_HOST},
01072
01073 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("uri"), sel_alt, DIVERSION | COMP_URI},
01074 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("url"), sel_alt, DIVERSION | COMP_URI},
01075 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("urn"), sel_alt, DIVERSION | COMP_URI},
01076
01077 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("ip"), sel_alt, DIVERSION | COMP_IP},
01078 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("IPAddress"), sel_alt, DIVERSION | COMP_IP},
01079 { sel_cert, SEL_PARAM_STR, STR_STATIC_INIT("ip_address"), sel_alt, DIVERSION | COMP_IP},
01080
01081 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("cn"), sel_comp, DIVERSION | COMP_CN},
01082 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("commonName"), sel_comp, DIVERSION | COMP_CN},
01083 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("common_name"), sel_comp, DIVERSION | COMP_CN},
01084 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("name"), sel_comp, DIVERSION | COMP_CN},
01085
01086 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("l"), sel_comp, DIVERSION | COMP_L},
01087 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("localityName"), sel_comp, DIVERSION | COMP_L},
01088 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("locality_name"), sel_comp, DIVERSION | COMP_L},
01089 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("locality"), sel_comp, DIVERSION | COMP_L},
01090
01091 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("c"), sel_comp, DIVERSION | COMP_C},
01092 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("countryName"), sel_comp, DIVERSION | COMP_C},
01093 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("country_name"), sel_comp, DIVERSION | COMP_C},
01094 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("country"), sel_comp, DIVERSION | COMP_C},
01095
01096 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("st"), sel_comp, DIVERSION | COMP_ST},
01097 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("stateOrProvinceName"), sel_comp, DIVERSION | COMP_ST},
01098 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("state_or_province_name"), sel_comp, DIVERSION | COMP_ST},
01099 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("state"), sel_comp, DIVERSION | COMP_ST},
01100
01101 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("o"), sel_comp, DIVERSION | COMP_O},
01102 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("organizationName"), sel_comp, DIVERSION | COMP_O},
01103 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("organization_name"), sel_comp, DIVERSION | COMP_O},
01104 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("organization"), sel_comp, DIVERSION | COMP_O},
01105
01106 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("ou"), sel_comp, DIVERSION | COMP_OU},
01107 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("organizationalUnitName"), sel_comp, DIVERSION | COMP_OU},
01108 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("organizational_unit_name"), sel_comp, DIVERSION | COMP_OU},
01109 { sel_name, SEL_PARAM_STR, STR_STATIC_INIT("unit"), sel_comp, DIVERSION | COMP_OU},
01110
01111 { NULL, SEL_PARAM_INT, STR_NULL, NULL, 0}
01112 };
01113
01114
01115
01116
01117
01118 pv_export_t tls_pv[] = {
01119
01120 {{"tls_version", sizeof("tls_version")-1},
01121 PVT_OTHER, pv_version, 0,
01122 0, 0, 0, 0 },
01123 {{"tls_description", sizeof("tls_description")-1},
01124 PVT_OTHER, pv_desc, 0,
01125 0, 0, 0, 0 },
01126 {{"tls_cipher_info", sizeof("tls_cipher_info")-1},
01127 PVT_OTHER, pv_cipher, 0,
01128 0, 0, 0, 0 },
01129 {{"tls_cipher_bits", sizeof("tls_cipher_bits")-1},
01130 PVT_OTHER, pv_bits, 0,
01131 0, 0, 0, 0 },
01132
01133 {{"tls_peer_version", sizeof("tls_peer_version")-1},
01134 PVT_OTHER, pv_cert_version, 0,
01135 0, 0, pv_init_iname, PV_CERT_PEER },
01136 {{"tls_my_version", sizeof("tls_my_version")-1},
01137 PVT_OTHER, pv_cert_version, 0,
01138 0, 0, pv_init_iname, PV_CERT_LOCAL },
01139 {{"tls_peer_serial", sizeof("tls_peer_serial")-1},
01140 PVT_OTHER, pv_sn, 0,
01141 0, 0, pv_init_iname, PV_CERT_PEER },
01142 {{"tls_my_serial", sizeof("tls_my_serial")-1},
01143 PVT_OTHER, pv_sn,0,
01144 0, 0, pv_init_iname, PV_CERT_LOCAL },
01145
01146 {{"tls_peer_subject", sizeof("tls_peer_subject")-1},
01147 PVT_OTHER, pv_comp, 0,
01148 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_SUBJECT },
01149 {{"tls_peer_issuer", sizeof("tls_peer_issuer")-1},
01150 PVT_OTHER, pv_comp, 0,
01151 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_ISSUER },
01152 {{"tls_my_subject", sizeof("tls_my_subject")-1},
01153 PVT_OTHER, pv_comp, 0,
01154 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT },
01155 {{"tls_my_issuer", sizeof("tls_my_issuer")-1},
01156 PVT_OTHER, pv_comp, 0,
01157 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER },
01158 {{"tls_peer_subject_cn", sizeof("tls_peer_subject_cn")-1},
01159 PVT_OTHER, pv_comp, 0,
01160 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_SUBJECT | PV_COMP_CN },
01161 {{"tls_peer_issuer_cn", sizeof("tls_peer_issuer_cn")-1},
01162 PVT_OTHER, pv_comp, 0,
01163 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_ISSUER | PV_COMP_CN },
01164 {{"tls_my_subject_cn", sizeof("tls_my_subject_cn")-1},
01165 PVT_OTHER, pv_comp, 0,
01166 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT | PV_COMP_CN },
01167 {{"tls_my_issuer_cn", sizeof("tls_my_issuer_cn")-1},
01168 PVT_OTHER, pv_comp, 0,
01169 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER | PV_COMP_CN },
01170 {{"tls_peer_subject_locality", sizeof("tls_peer_subject_locality")-1},
01171 PVT_OTHER, pv_comp, 0,
01172 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_SUBJECT | PV_COMP_L },
01173 {{"tls_peer_issuer_locality", sizeof("tls_peer_issuer_locality")-1},
01174 PVT_OTHER, pv_comp, 0,
01175 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_ISSUER | PV_COMP_L },
01176 {{"tls_my_subject_locality", sizeof("tls_my_subject_locality")-1},
01177 PVT_OTHER, pv_comp, 0,
01178 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT | PV_COMP_L },
01179 {{"tls_my_issuer_locality", sizeof("tls_my_issuer_locality")-1},
01180 PVT_OTHER, pv_comp, 0,
01181 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER | PV_COMP_L },
01182 {{"tls_peer_subject_country", sizeof("tls_peer_subject_country")-1},
01183 PVT_OTHER, pv_comp, 0,
01184 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_SUBJECT | PV_COMP_C },
01185 {{"tls_peer_issuer_country", sizeof("tls_peer_issuer_country")-1},
01186 PVT_OTHER, pv_comp, 0,
01187 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_ISSUER | PV_COMP_C },
01188 {{"tls_my_subject_country", sizeof("tls_my_subject_country")-1},
01189 PVT_OTHER, pv_comp, 0,
01190 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT | PV_COMP_C },
01191 {{"tls_my_issuer_country", sizeof("tls_my_issuer_country")-1},
01192 PVT_OTHER, pv_comp, 0,
01193 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER | PV_COMP_C },
01194 {{"tls_peer_subject_state", sizeof("tls_peer_subject_state")-1},
01195 PVT_OTHER, pv_comp, 0,
01196 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_SUBJECT | PV_COMP_ST },
01197 {{"tls_peer_issuer_state", sizeof("tls_peer_issuer_state")-1},
01198 PVT_OTHER, pv_comp, 0,
01199 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_ISSUER | PV_COMP_ST },
01200 {{"tls_my_subject_state", sizeof("tls_my_subject_state")-1},
01201 PVT_OTHER, pv_comp, 0,
01202 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT | PV_COMP_ST },
01203 {{"tls_my_issuer_state", sizeof("tls_my_issuer_state")-1},
01204 PVT_OTHER, pv_comp, 0,
01205 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER | PV_COMP_ST },
01206 {{"tls_peer_subject_organization", sizeof("tls_peer_subject_organization")-1},
01207 PVT_OTHER, pv_comp, 0,
01208 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_SUBJECT | PV_COMP_O },
01209 {{"tls_peer_issuer_organization", sizeof("tls_peer_issuer_organization")-1},
01210 PVT_OTHER, pv_comp, 0,
01211 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_ISSUER | PV_COMP_O },
01212 {{"tls_my_subject_organization", sizeof("tls_my_subject_organization")-1},
01213 PVT_OTHER, pv_comp, 0,
01214 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT | PV_COMP_O },
01215 {{"tls_my_issuer_organization", sizeof("tls_my_issuer_organization")-1},
01216 PVT_OTHER, pv_comp, 0,
01217 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER | PV_COMP_O },
01218 {{"tls_peer_subject_unit", sizeof("tls_peer_subject_unit")-1},
01219 PVT_OTHER, pv_comp, 0,
01220 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_SUBJECT | PV_COMP_OU },
01221 {{"tls_peer_issuer_unit", sizeof("tls_peer_issuer_unit")-1},
01222 PVT_OTHER, pv_comp, 0,
01223 0, 0, pv_init_iname, PV_CERT_PEER | PV_CERT_ISSUER | PV_COMP_OU },
01224 {{"tls_my_subject_unit", sizeof("tls_my_subject_unit")-1},
01225 PVT_OTHER, pv_comp, 0,
01226 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_SUBJECT | PV_COMP_OU },
01227 {{"tls_my_issuer_unit", sizeof("tls_my_issuer_unit")-1},
01228 PVT_OTHER, pv_comp, 0,
01229 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_CERT_ISSUER | PV_COMP_OU },
01230
01231 {{"tls_peer_san_email", sizeof("tls_peer_san_email")-1},
01232 PVT_OTHER, pv_alt, 0,
01233 0, 0, pv_init_iname, PV_CERT_PEER | PV_COMP_E },
01234 {{"tls_my_san_email", sizeof("tls_my_san_email")-1},
01235 PVT_OTHER, pv_alt, 0,
01236 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_COMP_E },
01237 {{"tls_peer_san_hostname", sizeof("tls_peer_san_hostname")-1},
01238 PVT_OTHER, pv_alt, 0,
01239 0, 0, pv_init_iname, PV_CERT_PEER | PV_COMP_HOST },
01240 {{"tls_my_san_hostname", sizeof("tls_my_san_hostname")-1},
01241 PVT_OTHER, pv_alt, 0,
01242 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_COMP_HOST },
01243 {{"tls_peer_san_uri", sizeof("tls_peer_san_uri")-1},
01244 PVT_OTHER, pv_alt, 0,
01245 0, 0, pv_init_iname, PV_CERT_PEER | PV_COMP_URI },
01246 {{"tls_my_san_uri", sizeof("tls_my_san_uri")-1},
01247 PVT_OTHER, pv_alt, 0,
01248 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_COMP_URI },
01249 {{"tls_peer_san_ip", sizeof("tls_peer_san_ip")-1},
01250 PVT_OTHER, pv_alt, 0,
01251 0, 0, pv_init_iname, PV_CERT_PEER | PV_COMP_IP },
01252 {{"tls_my_san_ip", sizeof("tls_my_san_ip")-1},
01253 PVT_OTHER, pv_alt, 0,
01254 0, 0, pv_init_iname, PV_CERT_LOCAL | PV_COMP_IP },
01255
01256 {{"tls_peer_verified", sizeof("tls_peer_verified")-1},
01257 PVT_OTHER, pv_check_cert, 0,
01258 0, 0, pv_init_iname, PV_CERT_VERIFIED },
01259 {{"tls_peer_revoked", sizeof("tls_peer_revoked")-1},
01260 PVT_OTHER, pv_check_cert, 0,
01261 0, 0, pv_init_iname, PV_CERT_REVOKED },
01262 {{"tls_peer_expired", sizeof("tls_peer_expired")-1},
01263 PVT_OTHER, pv_check_cert, 0,
01264 0, 0, pv_init_iname, PV_CERT_EXPIRED },
01265 {{"tls_peer_selfsigned", sizeof("tls_peer_selfsigned")-1},
01266 PVT_OTHER, pv_check_cert, 0,
01267 0, 0, pv_init_iname, PV_CERT_SELFSIGNED },
01268 {{"tls_peer_notBefore", sizeof("tls_peer_notBefore")-1},
01269 PVT_OTHER, pv_validity, 0,
01270 0, 0, pv_init_iname, PV_CERT_NOTBEFORE },
01271 {{"tls_peer_notAfter", sizeof("tls_peer_notAfter")-1},
01272 PVT_OTHER, pv_validity, 0,
01273 0, 0, pv_init_iname, PV_CERT_NOTAFTER },
01274
01275 {{"tls_peer_server_name", sizeof("tls_peer_server_name")-1},
01276 PVT_OTHER, pv_tlsext_sn, 0,
01277 0, 0, pv_init_iname, PV_TLSEXT_SNI },
01278
01279 { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
01280
01281 };