Changeset 3106 for pjproject/trunk/pjlib/src/pj/ssl_sock_ossl.c
- Timestamp:
- Feb 24, 2010 5:43:34 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/src/pj/ssl_sock_ossl.c
r3020 r3106 46 46 #include <openssl/ssl.h> 47 47 #include <openssl/err.h> 48 #include <openssl/x509v3.h> 48 49 49 50 … … 153 154 pj_ioqueue_op_key_t handshake_op_key; 154 155 pj_timer_entry timer; 156 pj_status_t verify_status; 155 157 156 158 pj_sock_t sock; … … 208 210 #define PJ_SSL_ERRNO_SPACE_SIZE PJ_ERRNO_SPACE_SIZE 209 211 212 #define STATUS_FROM_SSL_ERR(err, status) { \ 213 status = ERR_GET_LIB(err)*300 + ERR_GET_REASON(err);\ 214 pj_assert(status < PJ_SSL_ERRNO_SPACE_SIZE);\ 215 if (status) status += PJ_SSL_ERRNO_START;\ 216 } 217 210 218 #define GET_SSL_STATUS(status) { \ 211 219 unsigned long e = ERR_get_error();\ 212 status = ERR_GET_LIB(e)*300 + ERR_GET_REASON(e);\ 213 pj_assert(status < PJ_SSL_ERRNO_SPACE_SIZE);\ 214 if (status) status += PJ_SSL_ERRNO_START;\ 220 STATUS_FROM_SSL_ERR(e, status);\ 215 221 } 216 222 … … 236 242 { 237 243 const char *tmp = NULL; 238 tmp = ERR_reason_error_string(ssl_err); 244 245 if (ssl_err >= 300) 246 tmp = ERR_reason_error_string(ssl_err); 247 else 248 tmp = X509_verify_cert_error_string(ssl_err); 239 249 240 250 if (tmp) { … … 263 273 static pj_ssl_cipher openssl_ciphers[100]; 264 274 static unsigned openssl_cipher_num; 275 276 /* OpenSSL application data index */ 277 static int sslsock_idx; 265 278 266 279 … … 330 343 } 331 344 345 /* Create OpenSSL application data index for SSL socket */ 346 sslsock_idx = SSL_get_ex_new_index(0, "SSL socket", NULL, NULL, NULL); 347 332 348 return PJ_SUCCESS; 333 349 } … … 356 372 357 373 358 /* Create and initialize new SSL context */ 359 static pj_status_t create_ssl_ctx(pj_ssl_sock_t *ssock, SSL_CTX **p_ctx) 374 /* SSL password callback. */ 375 static int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) 376 { 377 pj_ssl_sock_t *ssock; 378 SSL *ossl_ssl; 379 int err; 380 381 /* Get SSL instance */ 382 ossl_ssl = X509_STORE_CTX_get_ex_data(x509_ctx, 383 SSL_get_ex_data_X509_STORE_CTX_idx()); 384 pj_assert(ossl_ssl); 385 386 /* Get SSL socket instance */ 387 ssock = SSL_get_ex_data(ossl_ssl, sslsock_idx); 388 pj_assert(ssock); 389 390 /* Store verification status */ 391 err = X509_STORE_CTX_get_error(x509_ctx); 392 switch (err) { 393 case X509_V_OK: 394 break; 395 396 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 397 ssock->verify_status |= PJ_SSL_CERT_EISSUER_NOT_FOUND; 398 break; 399 400 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 401 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 402 case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: 403 case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: 404 ssock->verify_status |= PJ_SSL_CERT_EINVALID_FORMAT; 405 break; 406 407 case X509_V_ERR_CERT_NOT_YET_VALID: 408 case X509_V_ERR_CERT_HAS_EXPIRED: 409 ssock->verify_status |= PJ_SSL_CERT_EVALIDITY_PERIOD; 410 break; 411 412 case X509_V_ERR_UNABLE_TO_GET_CRL: 413 case X509_V_ERR_CRL_NOT_YET_VALID: 414 case X509_V_ERR_CRL_HAS_EXPIRED: 415 case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: 416 case X509_V_ERR_CRL_SIGNATURE_FAILURE: 417 case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: 418 case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: 419 ssock->verify_status |= PJ_SSL_CERT_ECRL_FAILURE; 420 break; 421 422 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 423 case X509_V_ERR_CERT_UNTRUSTED: 424 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: 425 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: 426 ssock->verify_status |= PJ_SSL_CERT_EUNTRUSTED; 427 break; 428 429 case X509_V_ERR_CERT_SIGNATURE_FAILURE: 430 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: 431 case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: 432 case X509_V_ERR_AKID_SKID_MISMATCH: 433 case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: 434 case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: 435 ssock->verify_status |= PJ_SSL_CERT_EISSUER_MISMATCH; 436 break; 437 438 case X509_V_ERR_CERT_REVOKED: 439 ssock->verify_status |= PJ_SSL_CERT_EREVOKED; 440 break; 441 442 case X509_V_ERR_INVALID_PURPOSE: 443 case X509_V_ERR_CERT_REJECTED: 444 case X509_V_ERR_INVALID_CA: 445 ssock->verify_status |= PJ_SSL_CERT_EINVALID_PURPOSE; 446 break; 447 448 case X509_V_ERR_CERT_CHAIN_TOO_LONG: /* not really used */ 449 case X509_V_ERR_PATH_LENGTH_EXCEEDED: 450 ssock->verify_status |= PJ_SSL_CERT_ECHAIN_TOO_LONG; 451 break; 452 453 /* Unknown errors */ 454 case X509_V_ERR_OUT_OF_MEM: 455 default: 456 ssock->verify_status |= PJ_SSL_CERT_EUNKNOWN; 457 break; 458 } 459 460 /* When verification is not requested just return ok here, however 461 * application can still get the verification status. 462 */ 463 if (PJ_FALSE == ssock->param.verify_peer) 464 preverify_ok = 1; 465 466 return preverify_ok; 467 } 468 469 /* Setting SSL sock cipher list */ 470 static pj_status_t set_cipher_list(pj_ssl_sock_t *ssock); 471 472 473 /* Create and initialize new SSL context and instance */ 474 static pj_status_t create_ssl(pj_ssl_sock_t *ssock) 360 475 { 361 476 SSL_METHOD *ssl_method; … … 365 480 pj_status_t status; 366 481 367 pj_assert(ssock && p_ctx);482 pj_assert(ssock); 368 483 369 484 cert = ssock->cert; … … 394 509 } 395 510 396 /* Create SSL context for the listener*/511 /* Create SSL context */ 397 512 ctx = SSL_CTX_new(ssl_method); 398 513 if (ctx == NULL) { … … 456 571 } 457 572 573 /* Create SSL instance */ 574 ssock->ossl_ctx = ctx; 575 ssock->ossl_ssl = SSL_new(ssock->ossl_ctx); 576 if (ssock->ossl_ssl == NULL) { 577 GET_SSL_STATUS(status); 578 return status; 579 } 580 581 /* Set SSL sock as application data of SSL instance */ 582 SSL_set_ex_data(ssock->ossl_ssl, sslsock_idx, ssock); 458 583 459 584 /* SSL verification options */ 460 if (ssock->param.verify_peer) { 461 mode = SSL_VERIFY_PEER; 462 } else { 463 mode = SSL_VERIFY_NONE; 464 } 465 585 mode = SSL_VERIFY_PEER; 466 586 if (ssock->is_server && ssock->param.require_client_cert) 467 mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_PEER; 468 469 SSL_CTX_set_verify(ctx, mode, NULL); 470 471 *p_ctx = ctx; 587 mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; 588 589 SSL_set_verify(ssock->ossl_ssl, mode, &verify_cb); 590 591 /* Set cipher list */ 592 status = set_cipher_list(ssock); 593 if (status != PJ_SUCCESS) 594 return status; 595 596 /* Setup SSL BIOs */ 597 ssock->ossl_rbio = BIO_new(BIO_s_mem()); 598 ssock->ossl_wbio = BIO_new(BIO_s_mem()); 599 BIO_set_close(ssock->ossl_rbio, BIO_CLOSE); 600 BIO_set_close(ssock->ossl_wbio, BIO_CLOSE); 601 SSL_set_bio(ssock->ossl_ssl, ssock->ossl_rbio, ssock->ossl_wbio); 472 602 473 603 return PJ_SUCCESS; … … 475 605 476 606 477 /* Destroy SSL context */ 478 static void destroy_ssl_ctx(SSL_CTX *ctx) 479 { 480 SSL_CTX_free(ctx); 607 /* Destroy SSL context and instance */ 608 static void destroy_ssl(pj_ssl_sock_t *ssock) 609 { 610 /* Destroy SSL instance */ 611 if (ssock->ossl_ssl) { 612 SSL_shutdown(ssock->ossl_ssl); 613 SSL_free(ssock->ossl_ssl); /* this will also close BIOs */ 614 ssock->ossl_ssl = NULL; 615 } 616 617 /* Destroy SSL context */ 618 if (ssock->ossl_ctx) { 619 SSL_CTX_free(ssock->ossl_ctx); 620 ssock->ossl_ctx = NULL; 621 } 481 622 482 623 /* Potentially shutdown OpenSSL library if this is the last … … 492 633 ssock->ssl_state = SSL_STATE_NULL; 493 634 494 if (ssock->ossl_ssl) { 495 SSL_shutdown(ssock->ossl_ssl); 496 SSL_free(ssock->ossl_ssl); /* this will also close BIOs */ 497 ssock->ossl_ssl = NULL; 498 } 499 if (ssock->ossl_ctx) { 500 destroy_ssl_ctx(ssock->ossl_ctx); 501 ssock->ossl_ctx = NULL; 502 } 635 destroy_ssl(ssock); 636 503 637 if (ssock->asock) { 504 638 pj_activesock_close(ssock->asock); … … 640 774 641 775 642 /* Get certificate info from OpenSSL X509 */ 776 /* Get Common Name field string from a general name string */ 777 static void get_cn_from_gen_name(const pj_str_t *gen_name, pj_str_t *cn) 778 { 779 pj_str_t CN_sign = {"/CN=", 4}; 780 char *p, *q; 781 782 pj_bzero(cn, sizeof(cn)); 783 784 p = pj_strstr(gen_name, &CN_sign); 785 if (!p) 786 return; 787 788 p += 4; /* shift pointer to value part */ 789 pj_strset(cn, p, gen_name->slen - (p - gen_name->ptr)); 790 q = pj_strchr(cn, '/'); 791 if (q) 792 cn->slen = q - p; 793 } 794 795 796 /* Get certificate info from OpenSSL X509, in case the certificate info 797 * hal already populated, this function will check if the contents need 798 * to be updated by inspecting the issuer and the serial number. 799 */ 643 800 static void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci, X509 *x) 644 801 { 645 pj_ssl_cert_info info; 646 char buf1[256]; 647 char buf2[256]; 648 649 pj_assert(pool && ci); 650 651 if (!x) { 652 pj_bzero(ci, sizeof(pj_ssl_cert_info)); 802 pj_bool_t update_needed; 803 char buf[512]; 804 pj_uint8_t serial_no[64] = {0}; /* should be >= sizeof(ci->serial_no) */ 805 pj_uint8_t *p; 806 unsigned len; 807 GENERAL_NAMES *names = NULL; 808 809 pj_assert(pool && ci && x); 810 811 /* Get issuer */ 812 X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof(buf)); 813 814 /* Get serial no */ 815 p = (pj_uint8_t*) M_ASN1_STRING_data(X509_get_serialNumber(x)); 816 len = M_ASN1_STRING_length(X509_get_serialNumber(x)); 817 if (len > sizeof(ci->serial_no)) 818 len = sizeof(ci->serial_no); 819 pj_memcpy(serial_no + sizeof(ci->serial_no) - len, p, len); 820 821 /* Check if the contents need to be updated. */ 822 update_needed = pj_strcmp2(&ci->issuer.info, buf) || 823 pj_memcmp(ci->serial_no, serial_no, sizeof(ci->serial_no)); 824 if (!update_needed) 653 825 return; 654 } 655 656 pj_bzero(&info, sizeof(info)); 657 658 /* Populate cert info */ 659 info.subject = pj_str(X509_NAME_oneline(X509_get_subject_name(x),buf1, 660 sizeof(buf1))); 661 info.issuer = pj_str(X509_NAME_oneline(X509_get_issuer_name(x), buf2, 662 sizeof(buf2))); 663 info.version = X509_get_version(x) + 1; 664 parse_ossl_asn1_time(&info.validity_start, &info.validity_use_gmt, 826 827 /* Update cert info */ 828 829 pj_bzero(ci, sizeof(pj_ssl_cert_info)); 830 831 /* Version */ 832 ci->version = X509_get_version(x) + 1; 833 834 /* Issuer */ 835 pj_strdup2(pool, &ci->issuer.info, buf); 836 get_cn_from_gen_name(&ci->issuer.info, &ci->issuer.cn); 837 838 /* Serial number */ 839 pj_memcpy(ci->serial_no, serial_no, sizeof(ci->serial_no)); 840 841 /* Subject */ 842 pj_strdup2(pool, &ci->subject.info, 843 X509_NAME_oneline(X509_get_subject_name(x), 844 buf, sizeof(buf))); 845 get_cn_from_gen_name(&ci->subject.info, &ci->subject.cn); 846 847 /* Validity */ 848 parse_ossl_asn1_time(&ci->validity.start, &ci->validity.gmt, 665 849 X509_get_notBefore(x)); 666 parse_ossl_asn1_time(& info.validity_end, &info.validity_use_gmt,850 parse_ossl_asn1_time(&ci->validity.end, &ci->validity.gmt, 667 851 X509_get_notAfter(x)); 668 852 669 /* Update certificate info */ 670 if (pj_strcmp(&ci->subject, &info.subject)) 671 pj_strdup(pool, &ci->subject, &info.subject); 672 if (pj_strcmp(&ci->issuer, &info.issuer)) 673 pj_strdup(pool, &ci->issuer, &info.issuer); 674 ci->version = info.version; 675 ci->validity_start = info.validity_start; 676 ci->validity_end = info.validity_end; 677 ci->validity_use_gmt = info.validity_use_gmt; 853 /* Subject Alternative Name extension */ 854 if (ci->version >= 3) { 855 names = (GENERAL_NAMES*) X509_get_ext_d2i(x, NID_subject_alt_name, 856 NULL, NULL); 857 } 858 if (names) { 859 unsigned i, cnt; 860 861 cnt = sk_GENERAL_NAME_num(names); 862 ci->subj_alt_name.entry = pj_pool_calloc(pool, cnt, 863 sizeof(*ci->subj_alt_name.entry)); 864 865 for (i = 0; i < cnt; ++i) { 866 unsigned char *p = 0; 867 pj_ssl_cert_name_type type = PJ_SSL_CERT_NAME_UNKNOWN; 868 const GENERAL_NAME *name; 869 870 name = sk_GENERAL_NAME_value(names, i); 871 872 switch (name->type) { 873 case GEN_EMAIL: 874 len = ASN1_STRING_to_UTF8(&p, name->d.ia5); 875 type = PJ_SSL_CERT_NAME_RFC822; 876 break; 877 case GEN_DNS: 878 len = ASN1_STRING_to_UTF8(&p, name->d.ia5); 879 type = PJ_SSL_CERT_NAME_DNS; 880 break; 881 case GEN_URI: 882 len = ASN1_STRING_to_UTF8(&p, name->d.ia5); 883 type = PJ_SSL_CERT_NAME_URI; 884 break; 885 case GEN_IPADD: 886 p = ASN1_STRING_data(name->d.ip); 887 len = ASN1_STRING_length(name->d.ip); 888 type = PJ_SSL_CERT_NAME_IP; 889 break; 890 default: 891 break; 892 } 893 894 if (p && len && type != PJ_SSL_CERT_NAME_UNKNOWN) { 895 ci->subj_alt_name.entry[ci->subj_alt_name.cnt].type = type; 896 if (type == PJ_SSL_CERT_NAME_IP) { 897 int af = pj_AF_INET(); 898 if (len == sizeof(pj_in6_addr)) af = pj_AF_INET6(); 899 pj_inet_ntop2(af, p, buf, sizeof(buf)); 900 pj_strdup2(pool, 901 &ci->subj_alt_name.entry[ci->subj_alt_name.cnt].name, 902 buf); 903 } else { 904 pj_strdup2(pool, 905 &ci->subj_alt_name.entry[ci->subj_alt_name.cnt].name, 906 (char*)p); 907 OPENSSL_free(p); 908 } 909 ci->subj_alt_name.cnt++; 910 } 911 } 912 } 678 913 } 679 914 … … 690 925 /* Active local certificate */ 691 926 x = SSL_get_certificate(ssock->ossl_ssl); 692 get_cert_info(ssock->pool, &ssock->local_cert_info, x); 693 /* Don't free local's X509! */ 927 if (x) { 928 get_cert_info(ssock->pool, &ssock->local_cert_info, x); 929 /* Don't free local's X509! */ 930 } else { 931 pj_bzero(&ssock->local_cert_info, sizeof(pj_ssl_cert_info)); 932 } 694 933 695 934 /* Active remote certificate */ 696 935 x = SSL_get_peer_certificate(ssock->ossl_ssl); 697 get_cert_info(ssock->pool, &ssock->remote_cert_info, x); 698 /* Free peer's X509 */ 699 X509_free(x); 936 if (x) { 937 get_cert_info(ssock->pool, &ssock->remote_cert_info, x); 938 /* Free peer's X509 */ 939 X509_free(x); 940 } else { 941 pj_bzero(&ssock->remote_cert_info, sizeof(pj_ssl_cert_info)); 942 } 700 943 } 701 944 … … 1232 1475 1233 1476 /* Create SSL context */ 1234 status = create_ssl _ctx(ssock, &ssock->ossl_ctx);1477 status = create_ssl(ssock); 1235 1478 if (status != PJ_SUCCESS) 1236 1479 goto on_return; 1237 1238 /* Create SSL instance */1239 ssock->ossl_ssl = SSL_new(ssock->ossl_ctx);1240 if (ssock->ossl_ssl == NULL) {1241 GET_SSL_STATUS(status);1242 goto on_return;1243 }1244 1245 /* Set cipher list */1246 status = set_cipher_list(ssock);1247 if (status != PJ_SUCCESS)1248 goto on_return;1249 1250 /* Setup SSL BIOs */1251 ssock->ossl_rbio = BIO_new(BIO_s_mem());1252 ssock->ossl_wbio = BIO_new(BIO_s_mem());1253 BIO_set_close(ssock->ossl_rbio, BIO_CLOSE);1254 BIO_set_close(ssock->ossl_wbio, BIO_CLOSE);1255 SSL_set_bio(ssock->ossl_ssl, ssock->ossl_rbio, ssock->ossl_wbio);1256 1480 1257 1481 /* Prepare read buffer */ … … 1352 1576 1353 1577 /* Create SSL context */ 1354 status = create_ssl _ctx(ssock, &ssock->ossl_ctx);1578 status = create_ssl(ssock); 1355 1579 if (status != PJ_SUCCESS) 1356 1580 goto on_return; 1357 1358 /* Create SSL instance */1359 ssock->ossl_ssl = SSL_new(ssock->ossl_ctx);1360 if (ssock->ossl_ssl == NULL) {1361 GET_SSL_STATUS(status);1362 goto on_return;1363 }1364 1365 /* Set cipher list */1366 status = set_cipher_list(ssock);1367 if (status != PJ_SUCCESS)1368 goto on_return;1369 1370 /* Setup SSL BIOs */1371 ssock->ossl_rbio = BIO_new(BIO_s_mem());1372 ssock->ossl_wbio = BIO_new(BIO_s_mem());1373 BIO_set_close(ssock->ossl_rbio, BIO_CLOSE);1374 BIO_set_close(ssock->ossl_wbio, BIO_CLOSE);1375 SSL_set_bio(ssock->ossl_ssl, ssock->ossl_rbio, ssock->ossl_wbio);1376 1581 1377 1582 /* Prepare read buffer */ … … 1652 1857 1653 1858 if (info->established) { 1859 const SSL_CIPHER *cipher; 1860 1654 1861 /* Current cipher */ 1655 const SSL_CIPHER *cipher;1656 1657 1862 cipher = SSL_get_current_cipher(ssock->ossl_ssl); 1658 1863 info->cipher = (cipher->id & 0x00FFFFFF); … … 1662 1867 1663 1868 /* Certificates info */ 1664 info->local_cert_info = ssock->local_cert_info; 1665 info->remote_cert_info = ssock->remote_cert_info; 1869 info->local_cert_info = &ssock->local_cert_info; 1870 info->remote_cert_info = &ssock->remote_cert_info; 1871 1872 /* Verification status */ 1873 info->verify_status = ssock->verify_status; 1666 1874 } 1667 1875
Note: See TracChangeset
for help on using the changeset viewer.