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
00027
00028
00029 #include <openssl/ssl.h>
00030 #include <openssl/x509v3.h>
00031 #include "../../globals.h"
00032 #include "../../tcp_server.h"
00033 #include "../../tcp_conn.h"
00034 #include "../../ut.h"
00035 #include "tls_select.h"
00036 #include "../../tls/tls_config.h"
00037
00038
00039 struct tcp_connection* get_cur_connection(struct sip_msg* msg)
00040 {
00041 struct tcp_connection* c;
00042
00043 if (msg->rcv.proto != PROTO_TLS) {
00044 LM_ERR("transport protocol is not TLS (bug in config)\n");
00045 return 0;
00046 }
00047
00048 c = tcpconn_get(msg->rcv.proto_reserved1, 0, 0, tcp_con_lifetime, 0);
00049 if (c && c->type != PROTO_TLS) {
00050 LM_ERR("connection found but is not TLS (bug in config)\n");
00051 tcpconn_put(c);
00052 return 0;
00053 }
00054 return c;
00055 }
00056
00057
00058 static inline SSL* get_ssl(struct tcp_connection* c)
00059 {
00060 if (!c || !c->extra_data) {
00061 LM_ERR("failed to extract SSL data from TLS connection\n");
00062 return 0;
00063 }
00064 return c->extra_data;
00065 }
00066
00067
00068 static inline int get_cert(X509** cert, struct tcp_connection** c,
00069 struct sip_msg* msg, int my)
00070 {
00071 SSL* ssl;
00072
00073 *cert = 0;
00074 *c = get_cur_connection(msg);
00075 if (!(*c)) {
00076 LM_INFO("TLS connection not found\n");
00077 return -1;
00078 }
00079 ssl = get_ssl(*c);
00080 if (!ssl) goto err;
00081 *cert = my ? SSL_get_certificate(ssl) : SSL_get_peer_certificate(ssl);
00082 if (!*cert) {
00083 LM_ERR("failed to get certificate from SSL structure\n");
00084 goto err;
00085 }
00086
00087 return 0;
00088 err:
00089 tcpconn_put(*c);
00090 return -1;
00091 }
00092
00093
00094 int tlsops_cipher(struct sip_msg *msg, pv_param_t *param,
00095 pv_value_t *res)
00096 {
00097 str cipher;
00098 static char buf[1024];
00099
00100 struct tcp_connection* c;
00101 SSL* ssl;
00102
00103 c = get_cur_connection(msg);
00104 if (!c) {
00105 LM_INFO("TLS connection not found in select_cipher\n");
00106 goto err;
00107 }
00108 ssl = get_ssl(c);
00109 if (!ssl) goto err;
00110
00111 cipher.s = (char*)SSL_CIPHER_get_name(SSL_get_current_cipher(ssl));
00112 cipher.len = cipher.s ? strlen(cipher.s) : 0;
00113 if (cipher.len >= 1024) {
00114 LM_ERR("cipher name too long\n");
00115 goto err;
00116 }
00117 memcpy(buf, cipher.s, cipher.len);
00118 res->rs.s = buf;
00119 res->rs.len = cipher.len;
00120 res->flags = PV_VAL_STR;
00121 tcpconn_put(c);
00122
00123 return 0;
00124 err:
00125 if (c) tcpconn_put(c);
00126 return pv_get_null(msg, param, res);
00127 }
00128
00129
00130 int tlsops_bits(struct sip_msg *msg, pv_param_t *param,
00131 pv_value_t *res)
00132 {
00133 str bits;
00134 int b;
00135 static char buf[1024];
00136
00137 struct tcp_connection* c;
00138 SSL* ssl;
00139
00140 c = get_cur_connection(msg);
00141 if (!c) {
00142 LM_INFO("TLS connection not found in select_bits\n");
00143 goto err;
00144 }
00145 ssl = get_ssl(c);
00146 if (!ssl) goto err;
00147
00148 b = SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl), 0);
00149 bits.s = int2str(b, &bits.len);
00150 if (bits.len >= 1024) {
00151 LM_ERR("bits string too long\n");
00152 goto err;
00153 }
00154 memcpy(buf, bits.s, bits.len);
00155 res->rs.s = buf;
00156 res->rs.len = bits.len;
00157 res->ri = b;
00158 res->flags = PV_VAL_STR | PV_VAL_INT;
00159 tcpconn_put(c);
00160
00161 return 0;
00162 err:
00163 if (c) tcpconn_put(c);
00164 return pv_get_null(msg, param, res);
00165 }
00166
00167
00168 int tlsops_version(struct sip_msg *msg, pv_param_t *param,
00169 pv_value_t *res)
00170 {
00171 str version;
00172 static char buf[1024];
00173
00174 struct tcp_connection* c;
00175 SSL* ssl;
00176
00177 c = get_cur_connection(msg);
00178 if (!c) {
00179 LM_INFO("TLS connection not found in select_version\n");
00180 goto err;
00181 }
00182 ssl = get_ssl(c);
00183 if (!ssl) goto err;
00184
00185 version.s = (char*)SSL_get_version(ssl);
00186 version.len = version.s ? strlen(version.s) : 0;
00187 if (version.len >= 1024) {
00188 LM_ERR("version string too long\n");
00189 goto err;
00190 }
00191 memcpy(buf, version.s, version.len);
00192
00193 res->rs.s = buf;
00194 res->rs.len = version.len;
00195 res->flags = PV_VAL_STR;
00196
00197 tcpconn_put(c);
00198
00199 return 0;
00200 err:
00201 if (c) tcpconn_put(c);
00202 return pv_get_null(msg, param, res);
00203 }
00204
00205
00206 int tlsops_desc(struct sip_msg *msg, pv_param_t *param,
00207 pv_value_t *res)
00208 {
00209 static char buf[128];
00210
00211 struct tcp_connection* c;
00212 SSL* ssl;
00213
00214 c = get_cur_connection(msg);
00215 if (!c) {
00216 LM_INFO("TLS connection not found in select_desc\n");
00217 goto err;
00218 }
00219 ssl = get_ssl(c);
00220 if (!ssl) goto err;
00221
00222 buf[0] = '\0';
00223 SSL_CIPHER_description(SSL_get_current_cipher(ssl), buf, 128);
00224 res->rs.s = buf;
00225 res->rs.len = strlen(buf);
00226 res->flags = PV_VAL_STR;
00227
00228 tcpconn_put(c);
00229
00230 return 0;
00231 err:
00232 if (c) tcpconn_put(c);
00233 return pv_get_null(msg, param, res);
00234 }
00235
00236
00237 int tlsops_cert_version(struct sip_msg *msg, pv_param_t *param,
00238 pv_value_t *res)
00239 {
00240 static char buf[INT2STR_MAX_LEN];
00241 X509* cert;
00242 struct tcp_connection* c;
00243 char* version;
00244 int my;
00245
00246 if (param->pvn.u.isname.name.n & CERT_PEER) {
00247 my = 0;
00248 } else if (param->pvn.u.isname.name.n & CERT_LOCAL) {
00249 my = 1;
00250 } else {
00251 LM_CRIT("bug in call to tlsops_cert_version\n");
00252 return pv_get_null(msg, param, res);
00253 }
00254
00255 if (get_cert(&cert, &c, msg, my) < 0) return -1;
00256 version = int2str(X509_get_version(cert), &res->rs.len);
00257 memcpy(buf, version, res->rs.len);
00258 res->rs.s = buf;
00259 res->flags = PV_VAL_STR;
00260 if (!my) X509_free(cert);
00261 tcpconn_put(c);
00262 return 0;
00263 }
00264
00265
00266
00267
00268
00269
00270 int tlsops_check_cert(struct sip_msg *msg, pv_param_t *param,
00271 pv_value_t *res)
00272 {
00273 static str succ = str_init("1");
00274 static str fail = str_init("0");
00275
00276 int err;
00277 struct tcp_connection* c;
00278 SSL* ssl;
00279 X509* cert = 0;
00280
00281 switch (param->pvn.u.isname.name.n) {
00282 case CERT_VERIFIED: err = X509_V_OK; break;
00283 case CERT_REVOKED: err = X509_V_ERR_CERT_REVOKED; break;
00284 case CERT_EXPIRED: err = X509_V_ERR_CERT_HAS_EXPIRED; break;
00285 case CERT_SELFSIGNED: err = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; break;
00286 default:
00287 LM_CRIT("unexpected parameter value \"%d\"\n",
00288 param->pvn.u.isname.name.n);
00289 return pv_get_null(msg, param, res);
00290 }
00291
00292 c = get_cur_connection(msg);
00293 if (!c) return -1;
00294
00295 ssl = get_ssl(c);
00296 if (!ssl) goto err;
00297
00298 if ((cert = SSL_get_peer_certificate(ssl)) && SSL_get_verify_result(ssl) == err) {
00299 res->rs.s = succ.s;
00300 res->rs.len = succ.len;
00301 res->ri = 1;
00302 } else {
00303 res->rs.s = fail.s;
00304 res->rs.len = fail.len;
00305 res->ri = 0;
00306 }
00307 res->flags = PV_VAL_STR | PV_VAL_INT;
00308
00309 if (cert) X509_free(cert);
00310 tcpconn_put(c);
00311
00312 return 0;
00313 err:
00314 if (cert) X509_free(cert);
00315 if (c) tcpconn_put(c);
00316 return pv_get_null(msg, param, res);
00317 }
00318
00319
00320 int tlsops_validity(struct sip_msg *msg, pv_param_t *param,
00321 pv_value_t *res)
00322 {
00323 static char buf[1024];
00324 X509* cert;
00325 struct tcp_connection* c;
00326 BUF_MEM* p;
00327 BIO* mem = 0;
00328 ASN1_TIME* date;
00329 int my = 0;
00330
00331 if (get_cert(&cert, &c, msg, my) < 0) return -1;
00332
00333 switch (param->pvn.u.isname.name.n) {
00334 case CERT_NOTBEFORE: date = X509_get_notBefore(cert); break;
00335 case CERT_NOTAFTER: date = X509_get_notAfter(cert); break;
00336 default:
00337 LM_CRIT("unexpected parameter value \"%d\"\n", param->pvn.u.isname.name.n);
00338 goto err;
00339 }
00340
00341 mem = BIO_new(BIO_s_mem());
00342 if (!mem) {
00343 LM_ERR("failed to create memory BIO\n");
00344 goto err;
00345 }
00346
00347 if (!ASN1_TIME_print(mem, date)) {
00348 LM_ERR("failed to print certificate date/time\n");
00349 goto err;
00350 }
00351
00352 BIO_get_mem_ptr(mem, &p);
00353 if (p->length >= 1024) {
00354 LM_ERR("Date/time too long\n");
00355 goto err;
00356 }
00357 memcpy(buf, p->data, p->length);
00358 res->rs.s = buf;
00359 res->rs.len = p->length;
00360 res->flags = PV_VAL_STR ;
00361
00362 BIO_free(mem);
00363 if (!my) X509_free(cert);
00364 tcpconn_put(c);
00365
00366 return 0;
00367 err:
00368 if (mem) BIO_free(mem);
00369 if (!my) X509_free(cert);
00370 tcpconn_put(c);
00371 return pv_get_null(msg, param, res);
00372 }
00373
00374
00375 int tlsops_sn(struct sip_msg *msg, pv_param_t *param,
00376 pv_value_t *res)
00377 {
00378 static char buf[INT2STR_MAX_LEN];
00379 X509* cert;
00380 struct tcp_connection* c;
00381 int my, serial;
00382 char* sn;
00383
00384 if (param->pvn.u.isname.name.n & CERT_PEER) {
00385 my = 0;
00386 } else if (param->pvn.u.isname.name.n & CERT_LOCAL) {
00387 my = 1;
00388 } else {
00389 LM_CRIT("could not determine certificate\n");
00390 return pv_get_null(msg, param, res);
00391 }
00392
00393 if (get_cert(&cert, &c, msg, my) < 0)
00394 return pv_get_null(msg, param, res);
00395
00396 serial = ASN1_INTEGER_get(X509_get_serialNumber(cert));
00397 sn = int2str( serial, &res->rs.len);
00398 memcpy(buf, sn, res->rs.len);
00399 res->rs.s = buf;
00400 res->ri = serial;
00401 res->flags = PV_VAL_STR | PV_VAL_INT;
00402
00403 if (!my) X509_free(cert);
00404 tcpconn_put(c);
00405 return 0;
00406 }
00407
00408 int tlsops_comp(struct sip_msg *msg, pv_param_t *param,
00409 pv_value_t *res)
00410 {
00411 static char buf[1024];
00412 X509* cert;
00413 struct tcp_connection* c;
00414 X509_NAME* name;
00415 X509_NAME_ENTRY* e;
00416 ASN1_STRING* asn1;
00417 int nid = NID_commonName, index, my = 0, issuer = 0, ind_local;
00418 char* elem;
00419 str text;
00420
00421 text.s = 0;
00422
00423 ind_local = param->pvn.u.isname.name.n;
00424
00425 LM_DBG("ind_local = %x", ind_local);
00426 if (ind_local & CERT_PEER) {
00427 my = 0;
00428 ind_local = ind_local ^ CERT_PEER;
00429 } else if (ind_local & CERT_LOCAL) {
00430 my = 1;
00431 ind_local = ind_local ^ CERT_LOCAL;
00432 } else {
00433 LM_CRIT("could not determine certificate\n");
00434 return pv_get_null(msg, param, res);
00435 }
00436
00437 if (ind_local & CERT_SUBJECT) {
00438 issuer = 0;
00439 ind_local = ind_local ^ CERT_SUBJECT;
00440 } else if (ind_local & CERT_ISSUER) {
00441 issuer = 1;
00442 ind_local = ind_local ^ CERT_ISSUER;
00443 } else {
00444 LM_CRIT("could not determine subject or issuer\n");
00445 return pv_get_null(msg, param, res);
00446 }
00447
00448 switch(ind_local) {
00449 case COMP_CN: nid = NID_commonName; break;
00450 case COMP_O: nid = NID_organizationName; break;
00451 case COMP_OU: nid = NID_organizationalUnitName; break;
00452 case COMP_C: nid = NID_countryName; break;
00453 case COMP_ST: nid = NID_stateOrProvinceName; break;
00454 case COMP_L: nid = NID_localityName; break;
00455 default: nid = NID_undef;
00456 }
00457
00458 if (get_cert(&cert, &c, msg, my) < 0) return -1;
00459
00460 name = issuer ? X509_get_issuer_name(cert) : X509_get_subject_name(cert);
00461 if (!name) {
00462 LM_ERR("cannot extract subject or issuer name from peer"
00463 " certificate\n");
00464 goto err;
00465 }
00466
00467 if (nid == NID_undef) {
00468 X509_NAME_oneline(name, buf, sizeof(buf));
00469 res->rs.s = buf;
00470 res->rs.len = strlen(buf);
00471 res->flags = PV_VAL_STR;
00472 } else {
00473 index = X509_NAME_get_index_by_NID(name, nid, -1);
00474 if (index == -1) {
00475 switch(ind_local) {
00476 case COMP_CN: elem = "CommonName"; break;
00477 case COMP_O: elem = "OrganizationName"; break;
00478 case COMP_OU: elem = "OrganizationalUnitUname"; break;
00479 case COMP_C: elem = "CountryName"; break;
00480 case COMP_ST: elem = "StateOrProvinceName"; break;
00481 case COMP_L: elem = "LocalityName"; break;
00482 default: elem = "Unknown"; break;
00483 }
00484 LM_DBG("element %s not found in "
00485 "certificate subject/issuer\n", elem);
00486 goto err;
00487 }
00488
00489 e = X509_NAME_get_entry(name, index);
00490 asn1 = X509_NAME_ENTRY_get_data(e);
00491 text.len = ASN1_STRING_to_UTF8((unsigned char**)(void*)&text.s, asn1);
00492 if (text.len < 0 || text.len >= 1024) {
00493 LM_ERR("failed to convert ASN1 string\n");
00494 goto err;
00495 }
00496 memcpy(buf, text.s, text.len);
00497 res->rs.s = buf;
00498 res->rs.len = text.len;
00499 res->flags = PV_VAL_STR;
00500
00501 OPENSSL_free(text.s);
00502 }
00503 if (!my) X509_free(cert);
00504 tcpconn_put(c);
00505 return 0;
00506
00507 err:
00508 if (text.s) OPENSSL_free(text.s);
00509 if (!my) X509_free(cert);
00510 tcpconn_put(c);
00511 return pv_get_null(msg, param, res);
00512 }
00513
00514 int tlsops_alt(struct sip_msg *msg, pv_param_t *param,
00515 pv_value_t *res)
00516 {
00517 static char buf[1024];
00518 int type = GEN_URI, my = 0, n, found = 0, ind_local;
00519 STACK_OF(GENERAL_NAME)* names = 0;
00520 GENERAL_NAME* nm;
00521 X509* cert;
00522 struct tcp_connection* c;
00523 str text;
00524 struct ip_addr ip;
00525
00526 ind_local = param->pvn.u.isname.name.n;
00527
00528 if (ind_local & CERT_PEER) {
00529 my = 0;
00530 ind_local = ind_local ^ CERT_PEER;
00531 } else if (ind_local & CERT_LOCAL) {
00532 my = 1;
00533 ind_local = ind_local ^ CERT_LOCAL;
00534 } else {
00535 LM_CRIT("could not determine certificate\n");
00536 return pv_get_null(msg, param, res);
00537 }
00538
00539 switch(ind_local) {
00540 case COMP_E: type = GEN_EMAIL; break;
00541 case COMP_HOST: type = GEN_DNS; break;
00542 case COMP_URI: type = GEN_URI; break;
00543 case COMP_IP: type = GEN_IPADD; break;
00544 default:
00545 LM_CRIT("ind_local=%d\n", ind_local);
00546 return pv_get_null(msg, param, res);
00547 }
00548
00549 if (get_cert(&cert, &c, msg, my) < 0) return -1;
00550
00551 names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
00552 if (!names) {
00553 LM_ERR("cannot get certificate alternative subject\n");
00554 goto err;
00555
00556 }
00557
00558 for (n = 0; n < sk_GENERAL_NAME_num(names); n++) {
00559 nm = sk_GENERAL_NAME_value(names, n);
00560 if (nm->type != type) continue;
00561 switch(type) {
00562 case GEN_EMAIL:
00563 case GEN_DNS:
00564 case GEN_URI:
00565 text.s = (char*)nm->d.ia5->data;
00566 text.len = nm->d.ia5->length;
00567 if (text.len >= 1024) {
00568 LM_ERR("alternative subject text too long\n");
00569 goto err;
00570 }
00571 memcpy(buf, text.s, text.len);
00572 res->rs.s = buf;
00573 res->rs.len = text.len;
00574 res->flags = PV_VAL_STR;
00575 found = 1;
00576 break;
00577
00578 case GEN_IPADD:
00579 ip.len = nm->d.iPAddress->length;
00580 ip.af = (ip.len == 16) ? AF_INET6 : AF_INET;
00581 memcpy(ip.u.addr, nm->d.iPAddress->data, ip.len);
00582 text.s = ip_addr2a(&ip);
00583 text.len = strlen(text.s);
00584 memcpy(buf, text.s, text.len);
00585 res->rs.s = buf;
00586 res->rs.len = text.len;
00587 res->flags = PV_VAL_STR;
00588 found = 1;
00589 break;
00590 }
00591 break;
00592 }
00593 if (!found) goto err;
00594
00595 if (names) sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
00596 if (!my) X509_free(cert);
00597 tcpconn_put(c);
00598 return 0;
00599 err:
00600 if (names) sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
00601 if (!my) X509_free(cert);
00602 tcpconn_put(c);
00603 return pv_get_null(msg, param, res);
00604 }
00605
00606
00607
00608 #ifdef OPENSSL_NO_TLSEXT
00609 int tlsops_tlsext(struct sip_msg *msg, pv_param_t *param,
00610 pv_value_t *res)
00611 {
00612 LM_ERR("TLS extension 'server name' pseudo variable is not available! "
00613 "please install openssl with TLS extension support and recompile "
00614 "openser\n");
00615 return pv_get_null(msg, param, res);
00616 }
00617 #else
00618 int tlsops_tlsext(struct sip_msg *msg, pv_param_t *param,
00619 pv_value_t *res)
00620 {
00621 static char buf[1024];
00622 struct tcp_connection* c;
00623 SSL* ssl;
00624
00625 c = get_cur_connection(msg);
00626 if (!c) {
00627 LM_INFO("TLS connection not found in select_desc\n");
00628 goto err;
00629 }
00630 ssl = get_ssl(c);
00631 if (!ssl) goto err;
00632 buf[0] = '\0';
00633
00634 switch (param->pvn.u.isname.name.n) {
00635 case TLSEXT_SNI:
00636 { const char *server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
00637 if (server_name) {
00638 LM_DBG("received server_name (TLS extension): '%s'\n",server_name);
00639 } else {
00640 LM_DBG("SSL_get_servername returned NULL\n");
00641 return pv_get_null(msg, param, res);
00642 }
00643
00644
00645
00646 if (strlen(server_name) > sizeof(buf)) {
00647 LM_ERR("server_name to big for buffer\n");
00648 buf[0] = '+';
00649 memcpy(buf+1, server_name+1+strlen(server_name)-sizeof(buf), sizeof(buf)-1);
00650 res->rs.len = sizeof(buf);
00651 } else {
00652 memcpy(buf, server_name, strlen(server_name));
00653 res->rs.len = strlen(server_name);
00654 }
00655 res->rs.s = buf;
00656 res->flags = PV_VAL_STR;
00657 }
00658 break;
00659
00660 default:
00661 LM_CRIT("unexpected parameter value \"%d\"\n",
00662 param->pvn.u.isname.name.n);
00663 tcpconn_put(c);
00664 return pv_get_null(msg, param, res);
00665 }
00666
00667 tcpconn_put(c);
00668 return 0;
00669 err:
00670 if (c) tcpconn_put(c);
00671 return pv_get_null(msg, param, res);
00672 }
00673 #endif