Changeset 5472
- Timestamp:
- Oct 27, 2016 7:58:01 AM (8 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/include/pj/config.h
r5445 r5472 888 888 #ifndef PJ_SSL_SOCK_OSSL_CIPHERS 889 889 # define PJ_SSL_SOCK_OSSL_CIPHERS "HIGH:-COMPLEMENTOFDEFAULT" 890 #endif 891 892 893 /** 894 * Define the maximum number of curves supported by the secure socket. 895 * 896 * Default: 32 897 */ 898 #ifndef PJ_SSL_SOCK_MAX_CURVES 899 # define PJ_SSL_SOCK_MAX_CURVES 32 890 900 #endif 891 901 -
pjproject/trunk/pjlib/include/pj/ssl_sock.h
r5238 r5472 402 402 PJ_DECL(pj_ssl_cipher) pj_ssl_cipher_id(const char *cipher_name); 403 403 404 /** 405 * Elliptic curves enumeration. 406 */ 407 typedef enum pj_ssl_curve 408 { 409 PJ_TLS_UNKNOWN_CURVE = 0, 410 PJ_TLS_CURVE_SECT163K1 = 1, 411 PJ_TLS_CURVE_SECT163R1 = 2, 412 PJ_TLS_CURVE_SECT163R2 = 3, 413 PJ_TLS_CURVE_SECT193R1 = 4, 414 PJ_TLS_CURVE_SECT193R2 = 5, 415 PJ_TLS_CURVE_SECT233K1 = 6, 416 PJ_TLS_CURVE_SECT233R1 = 7, 417 PJ_TLS_CURVE_SECT239K1 = 8, 418 PJ_TLS_CURVE_SECT283K1 = 9, 419 PJ_TLS_CURVE_SECT283R1 = 10, 420 PJ_TLS_CURVE_SECT409K1 = 11, 421 PJ_TLS_CURVE_SECT409R1 = 12, 422 PJ_TLS_CURVE_SECT571K1 = 13, 423 PJ_TLS_CURVE_SECT571R1 = 14, 424 PJ_TLS_CURVE_SECP160K1 = 15, 425 PJ_TLS_CURVE_SECP160R1 = 16, 426 PJ_TLS_CURVE_SECP160R2 = 17, 427 PJ_TLS_CURVE_SECP192K1 = 18, 428 PJ_TLS_CURVE_SECP192R1 = 19, 429 PJ_TLS_CURVE_SECP224K1 = 20, 430 PJ_TLS_CURVE_SECP224R1 = 21, 431 PJ_TLS_CURVE_SECP256K1 = 22, 432 PJ_TLS_CURVE_SECP256R1 = 23, 433 PJ_TLS_CURVE_SECP384R1 = 24, 434 PJ_TLS_CURVE_SECP521R1 = 25, 435 PJ_TLS_CURVE_BRAINPOOLP256R1 = 26, 436 PJ_TLS_CURVE_BRAINPOOLP384R1 = 27, 437 PJ_TLS_CURVE_BRAINPOOLP512R1 = 28, 438 PJ_TLS_CURVE_ARBITRARY_EXPLICIT_PRIME_CURVES = 0XFF01, 439 PJ_TLS_CURVE_ARBITRARY_EXPLICIT_CHAR2_CURVES = 0XFF02 440 } pj_ssl_curve; 441 442 /** 443 * Get curve list supported by SSL/TLS backend. 444 * 445 * @param curves The curves buffer to receive curve list. 446 * @param curves_num Maximum number of curves to be received. 447 * 448 * @return PJ_SUCCESS when successful. 449 */ 450 PJ_DECL(pj_status_t) pj_ssl_curve_get_availables(pj_ssl_curve curves[], 451 unsigned *curve_num); 452 453 /** 454 * Check if the specified curve is supported by SSL/TLS backend. 455 * 456 * @param curve The curve. 457 * 458 * @return PJ_TRUE when supported. 459 */ 460 PJ_DECL(pj_bool_t) pj_ssl_curve_is_supported(pj_ssl_curve curve); 461 462 463 /** 464 * Get curve name string. 465 * 466 * @param curve The curve. 467 * 468 * @return The curve name or NULL if curve is not recognized/ 469 * supported. 470 */ 471 PJ_DECL(const char*) pj_ssl_curve_name(pj_ssl_curve curve); 472 473 /** 474 * Get curve ID from curve name string. Note that on different backends 475 * (e.g. OpenSSL or Symbian implementation), curve names may not be 476 * equivalent for the same curve ID. 477 * 478 * @param curve_name The curve name string. 479 * 480 * @return The curve ID or PJ_TLS_UNKNOWN_CURVE if the curve 481 * name string is not recognized/supported. 482 */ 483 PJ_DECL(pj_ssl_curve) pj_ssl_curve_id(const char *curve_name); 484 485 /* 486 * Entropy enumeration 487 */ 488 typedef enum pj_ssl_entropy 489 { 490 PJ_SSL_ENTROPY_NONE = 0, 491 PJ_SSL_ENTROPY_EGD = 1, 492 PJ_SSL_ENTROPY_RANDOM = 2, 493 PJ_SSL_ENTROPY_URANDOM = 3, 494 PJ_SSL_ENTROPY_FILE = 4, 495 PJ_SSL_ENTROPY_UNKNOWN = 0x0F 496 } pj_ssl_entropy_t; 404 497 405 498 /** … … 771 864 772 865 /** 866 * Number of curves contained in the specified curve preference. 867 * If this is set to zero, then default curve list of the backend 868 * will be used. 869 * 870 * Default: 0 (zero). 871 */ 872 unsigned curves_num; 873 874 /** 875 * Curves and order preference. The #pj_ssl_curve_get_availables() 876 * can be used to check the available curves supported by backend. 877 */ 878 pj_ssl_curve *curves; 879 880 /** 881 * The supported signature algorithms. Set the sigalgs string 882 * using this form: 883 * "<DIGEST>+<ALGORITHM>:<DIGEST>+<ALGORITHM>" 884 * Digests are: "RSA", "DSA" or "ECDSA" 885 * Algorithms are: "MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512" 886 * Example: "ECDSA+SHA256:RSA+SHA256" 887 */ 888 pj_str_t sigalgs; 889 890 /** 891 * Reseed random number generator. 892 * For type #PJ_SSL_ENTROPY_FILE, parameter \a entropy_path 893 * must be set to a file. 894 * For type #PJ_SSL_ENTROPY_EGD, parameter \a entropy_path 895 * must be set to a socket. 896 * 897 * Default value is PJ_SSL_ENTROPY_NONE. 898 */ 899 pj_ssl_entropy_t entropy_type; 900 901 /** 902 * When using a file/socket for entropy #PJ_SSL_ENTROPY_EGD or 903 * #PJ_SSL_ENTROPY_FILE, \a entropy_path must contain the path 904 * to entropy socket/file. 905 * 906 * Default value is an empty string. 907 */ 908 pj_str_t entropy_path; 909 910 /** 773 911 * Security negotiation timeout. If this is set to zero (both sec and 774 912 * msec), the negotiation doesn't have a timeout. -
pjproject/trunk/pjlib/src/pj/ssl_sock_common.c
r5214 r5472 68 68 } 69 69 70 if (src->curves_num > 0) { 71 unsigned i; 72 dst->curves = (pj_ssl_curve *)pj_pool_calloc(pool, src->curves_num, 73 sizeof(pj_ssl_curve)); 74 for (i = 0; i < src->curves_num; ++i) 75 dst->curves[i] = src->curves[i]; 76 } 77 70 78 if (src->server_name.slen) { 71 79 /* Server name must be null-terminated */ 72 80 pj_strdup_with_null(pool, &dst->server_name, &src->server_name); 81 } 82 83 if (src->sigalgs.slen) { 84 /* Sigalgs name must be null-terminated */ 85 pj_strdup_with_null(pool, &dst->sigalgs, &src->sigalgs); 86 } 87 88 if (src->entropy_path.slen) { 89 /* Path name must be null-terminated */ 90 pj_strdup_with_null(pool, &dst->entropy_path, &src->entropy_path); 73 91 } 74 92 } -
pjproject/trunk/pjlib/src/pj/ssl_sock_ossl.c
r5459 r5472 50 50 #include <openssl/err.h> 51 51 #include <openssl/x509v3.h> 52 52 #include <openssl/rand.h> 53 #include <openssl/engine.h> 54 55 #if !defined(OPENSSL_NO_EC) 56 extern int tls1_ec_nid2curve_id(int nid); 57 extern int tls1_ec_curve_id2nid(int curve_id); 58 #endif 53 59 54 60 #ifdef _MSC_VER … … 300 306 } openssl_ciphers[PJ_SSL_SOCK_MAX_CIPHERS]; 301 307 308 /* OpenSSL available curves */ 309 static unsigned openssl_curves_num; 310 static struct openssl_curves_t { 311 pj_ssl_curve id; 312 const char *name; 313 } openssl_curves[PJ_SSL_SOCK_MAX_CURVES]; 314 302 315 /* OpenSSL application data index */ 303 316 static int sslsock_idx; … … 329 342 330 343 /* Init available ciphers */ 331 if (openssl_cipher_num == 0 ) {344 if (openssl_cipher_num == 0 || openssl_curves_num == 0) { 332 345 SSL_METHOD *meth = NULL; 333 346 SSL_CTX *ctx; … … 335 348 STACK_OF(SSL_CIPHER) *sk_cipher; 336 349 unsigned i, n; 350 int nid; 351 const char *cname; 337 352 338 353 meth = (SSL_METHOD*)SSLv23_server_method(); … … 353 368 354 369 ssl = SSL_new(ctx); 370 355 371 sk_cipher = SSL_get_ciphers(ssl); 356 372 … … 366 382 openssl_ciphers[i].name = SSL_CIPHER_get_name(c); 367 383 } 384 openssl_cipher_num = n; 385 386 ssl->session = SSL_SESSION_new(); 387 388 #if !defined(OPENSSL_NO_EC) 389 openssl_curves_num = SSL_get_shared_curve(ssl,-1); 390 if (openssl_curves_num > PJ_ARRAY_SIZE(openssl_curves)) 391 openssl_curves_num = PJ_ARRAY_SIZE(openssl_curves); 392 393 for (i = 0; i < openssl_curves_num; i++) { 394 nid = SSL_get_shared_curve(ssl, i); 395 396 if (nid & TLSEXT_nid_unknown) { 397 cname = "curve unknown"; 398 nid &= 0xFFFF; 399 } else { 400 cname = EC_curve_nid2nist(nid); 401 if (!cname) 402 cname = OBJ_nid2sn(nid); 403 } 404 405 openssl_curves[i].id = tls1_ec_nid2curve_id(nid); 406 openssl_curves[i].name = cname; 407 } 408 #else 409 openssl_curves_num = 0; 410 #endif 368 411 369 412 SSL_free(ssl); 370 413 SSL_CTX_free(ctx); 371 372 openssl_cipher_num = n;373 414 } 374 415 … … 376 417 sslsock_idx = SSL_get_ex_new_index(0, "SSL socket", NULL, NULL, NULL); 377 418 378 return PJ_SUCCESS;419 return status; 379 420 } 380 421 … … 499 540 /* Setting SSL sock cipher list */ 500 541 static pj_status_t set_cipher_list(pj_ssl_sock_t *ssock); 501 542 /* Setting SSL sock curves list */ 543 static pj_status_t set_curves_list(pj_ssl_sock_t *ssock); 544 /* Setting sigalgs list */ 545 static pj_status_t set_sigalgs(pj_ssl_sock_t *ssock); 546 /* Setting entropy for rng */ 547 static void set_entropy(pj_ssl_sock_t *ssock); 502 548 503 549 /* Create and initialize new SSL context and instance */ … … 523 569 /* Make sure OpenSSL library has been initialized */ 524 570 init_openssl(); 571 572 set_entropy(ssock); 525 573 526 574 if (ssock->param.proto == PJ_SSL_SOCK_PROTO_DEFAULT) … … 776 824 return status; 777 825 826 /* Set curve list */ 827 status = set_curves_list(ssock); 828 if (status != PJ_SUCCESS) 829 return status; 830 831 /* Set sigalg list */ 832 status = set_sigalgs(ssock); 833 if (status != PJ_SUCCESS) 834 return status; 835 778 836 /* Setup SSL BIOs */ 779 837 ssock->ossl_rbio = BIO_new(BIO_s_mem()); … … 940 998 } 941 999 1000 static pj_status_t set_curves_list(pj_ssl_sock_t *ssock) 1001 { 1002 #if !defined(OPENSSL_NO_EC) 1003 int ret; 1004 int curves[PJ_SSL_SOCK_MAX_CURVES]; 1005 int cnt; 1006 1007 if (ssock->param.curves_num == 0) 1008 return PJ_SUCCESS; 1009 1010 for (cnt = 0; cnt < ssock->param.curves_num; cnt++) { 1011 curves[cnt] = tls1_ec_curve_id2nid(ssock->param.curves[cnt]); 1012 } 1013 1014 if( ssock->ossl_ssl->server ) { 1015 ret = SSL_set1_curves(ssock->ossl_ssl, curves, 1016 ssock->param.curves_num); 1017 if (ret < 1) 1018 return GET_SSL_STATUS(ssock); 1019 } else { 1020 ret = SSL_CTX_set1_curves(ssock->ossl_ctx, curves, 1021 ssock->param.curves_num); 1022 if (ret < 1) 1023 return GET_SSL_STATUS(ssock); 1024 } 1025 1026 return PJ_SUCCESS; 1027 #else 1028 return PJ_ENOTSUP; 1029 #endif 1030 } 1031 1032 static pj_status_t set_sigalgs(pj_ssl_sock_t *ssock) 1033 { 1034 int ret; 1035 1036 if (ssock->param.sigalgs.ptr && ssock->param.sigalgs.slen) { 1037 if (ssock->is_server) { 1038 ret = SSL_set1_client_sigalgs_list(ssock->ossl_ssl, 1039 ssock->param.sigalgs.ptr); 1040 } else { 1041 ret = SSL_set1_sigalgs_list(ssock->ossl_ssl, 1042 ssock->param.sigalgs.ptr); 1043 } 1044 1045 if (ret < 1) 1046 return GET_SSL_STATUS(ssock); 1047 } 1048 1049 return PJ_SUCCESS; 1050 } 1051 1052 static void set_entropy(pj_ssl_sock_t *ssock) 1053 { 1054 int ret; 1055 1056 switch (ssock->param.entropy_type) { 1057 #ifndef OPENSSL_NO_EGD 1058 case PJ_SSL_ENTROPY_EGD: 1059 ret = RAND_egd(ssock->param.entropy_path.ptr); 1060 break; 1061 #endif 1062 case PJ_SSL_ENTROPY_RANDOM: 1063 ret = RAND_load_file("/dev/random",255); 1064 break; 1065 case PJ_SSL_ENTROPY_URANDOM: 1066 ret = RAND_load_file("/dev/urandom",255); 1067 break; 1068 case PJ_SSL_ENTROPY_FILE: 1069 ret = RAND_load_file(ssock->param.entropy_path.ptr,255); 1070 break; 1071 case PJ_SSL_ENTROPY_NONE: 1072 default: 1073 return; 1074 break; 1075 } 1076 1077 if (ret < 0) { 1078 PJ_LOG(3, (ssock->pool->obj_name, "SSL failed to reseed with " 1079 "entropy type %d", 1080 ssock->param.entropy_type)); 1081 } 1082 } 942 1083 943 1084 /* Parse OpenSSL ASN1_TIME to pj_time_val and GMT info */ … … 2232 2373 } 2233 2374 2375 /* Get available curves. */ 2376 PJ_DEF(pj_status_t) pj_ssl_curve_get_availables(pj_ssl_curve curves[], 2377 unsigned *curve_num) 2378 { 2379 unsigned i; 2380 2381 PJ_ASSERT_RETURN(curves && curve_num, PJ_EINVAL); 2382 2383 if (openssl_curves_num == 0) { 2384 init_openssl(); 2385 shutdown_openssl(); 2386 } 2387 2388 if (openssl_curves_num == 0) { 2389 *curve_num = 0; 2390 return PJ_ENOTFOUND; 2391 } 2392 2393 *curve_num = PJ_MIN(*curve_num, openssl_curves_num); 2394 2395 for (i = 0; i < *curve_num; ++i) 2396 curves[i] = openssl_curves[i].id; 2397 2398 return PJ_SUCCESS; 2399 } 2400 2401 /* Get curve name string. */ 2402 PJ_DEF(const char*) pj_ssl_curve_name(pj_ssl_curve curve) 2403 { 2404 unsigned i; 2405 2406 if (openssl_curves_num == 0) { 2407 init_openssl(); 2408 shutdown_openssl(); 2409 } 2410 2411 for (i = 0; i < openssl_curves_num; ++i) { 2412 if (curve == openssl_curves[i].id) 2413 return openssl_curves[i].name; 2414 } 2415 2416 return NULL; 2417 } 2418 2419 /* Get curve ID from curve name string. */ 2420 PJ_DEF(pj_ssl_curve) pj_ssl_curve_id(const char *curve_name) 2421 { 2422 unsigned i; 2423 2424 if (openssl_curves_num == 0) { 2425 init_openssl(); 2426 shutdown_openssl(); 2427 } 2428 2429 for (i = 0; i < openssl_curves_num; ++i) { 2430 if (!pj_ansi_stricmp(openssl_curves[i].name, curve_name)) 2431 return openssl_curves[i].id; 2432 } 2433 2434 return PJ_TLS_UNKNOWN_CURVE; 2435 } 2436 2437 /* Check if the specified curve is supported by SSL/TLS backend. */ 2438 PJ_DEF(pj_bool_t) pj_ssl_curve_is_supported(pj_ssl_curve curve) 2439 { 2440 unsigned i; 2441 2442 if (openssl_curves_num == 0) { 2443 init_openssl(); 2444 shutdown_openssl(); 2445 } 2446 2447 for (i = 0; i < openssl_curves_num; ++i) { 2448 if (curve == openssl_curves[i].id) 2449 return PJ_TRUE; 2450 } 2451 2452 return PJ_FALSE; 2453 } 2234 2454 2235 2455 /* -
pjproject/trunk/pjsip/include/pjsip/sip_transport_tls.h
r5089 r5472 142 142 143 143 /** 144 * Number of curves contained in the specified curve preference. 145 * If this is set to zero, then default curve list of the backend 146 * will be used. 147 * 148 * Default: 0 (zero). 149 */ 150 unsigned curves_num; 151 152 /** 153 * Curves and order preference. The #pj_ssl_curve_get_availables() 154 * can be used to check the available curves supported by backend. 155 */ 156 pj_ssl_curve *curves; 157 158 /** 159 * The supported signature algorithms. Set the sigalgs string 160 * using this form: 161 * "<DIGEST>+<ALGORITHM>:<DIGEST>+<ALGORITHM>" 162 * Digests are: "RSA", "DSA" or "ECDSA" 163 * Algorithms are: "MD5", "SHA1", "SHA224", "SHA256", "SHA384", "SHA512" 164 * Example: "ECDSA+SHA256:RSA+SHA256" 165 */ 166 pj_str_t sigalgs; 167 168 /** 169 * Reseed random number generator. 170 * For type #PJ_SSL_ENTROPY_FILE, parameter \a entropy_path 171 * must be set to a file. 172 * For type #PJ_SSL_ENTROPY_EGD, parameter \a entropy_path 173 * must be set to a socket. 174 * 175 * Default value is PJ_SSL_ENTROPY_NONE. 176 */ 177 pj_ssl_entropy_t entropy_type; 178 179 /** 180 * When using a file/socket for entropy #PJ_SSL_ENTROPY_EGD or 181 * #PJ_SSL_ENTROPY_FILE, \a entropy_path must contain the path 182 * to entropy socket/file. 183 * 184 * Default value is an empty string. 185 */ 186 pj_str_t entropy_path; 187 188 /** 144 189 * Specifies TLS transport behavior on the server TLS certificate 145 190 * verification result: … … 293 338 pj_strdup_with_null(pool, &dst->privkey_file, &src->privkey_file); 294 339 pj_strdup_with_null(pool, &dst->password, &src->password); 340 pj_strdup_with_null(pool, &dst->sigalgs, &src->sigalgs); 341 pj_strdup_with_null(pool, &dst->entropy_path, &src->entropy_path); 295 342 if (src->ciphers_num) { 296 343 unsigned i; … … 299 346 for (i=0; i<src->ciphers_num; ++i) 300 347 dst->ciphers[i] = src->ciphers[i]; 348 } 349 350 if (src->curves_num) { 351 unsigned i; 352 dst->curves = (pj_ssl_curve*) pj_pool_calloc(pool, src->curves_num, 353 sizeof(pj_ssl_curve)); 354 for (i=0; i<src->curves_num; ++i) 355 dst->curves[i] = src->curves[i]; 301 356 } 302 357 } -
pjproject/trunk/pjsip/src/pjsip/sip_transport_tls.c
r5386 r5472 392 392 ssock_param.ciphers_num = listener->tls_setting.ciphers_num; 393 393 ssock_param.ciphers = listener->tls_setting.ciphers; 394 ssock_param.curves_num = listener->tls_setting.curves_num; 395 ssock_param.curves = listener->tls_setting.curves; 396 ssock_param.sigalgs = listener->tls_setting.sigalgs; 397 ssock_param.entropy_type = listener->tls_setting.entropy_type; 398 ssock_param.entropy_path = listener->tls_setting.entropy_path; 394 399 ssock_param.reuse_addr = listener->tls_setting.reuse_addr; 395 400 ssock_param.qos_type = listener->tls_setting.qos_type; … … 1071 1076 ssock_param.ciphers_num = listener->tls_setting.ciphers_num; 1072 1077 ssock_param.ciphers = listener->tls_setting.ciphers; 1078 ssock_param.curves_num = listener->tls_setting.curves_num; 1079 ssock_param.curves = listener->tls_setting.curves; 1080 ssock_param.sigalgs = listener->tls_setting.sigalgs; 1081 ssock_param.entropy_type = listener->tls_setting.entropy_type; 1082 ssock_param.entropy_path = listener->tls_setting.entropy_path; 1073 1083 ssock_param.qos_type = listener->tls_setting.qos_type; 1074 1084 ssock_param.qos_ignore_error = listener->tls_setting.qos_ignore_error;
Note: See TracChangeset
for help on using the changeset viewer.