Changeset 5472 for pjproject/trunk/pjlib/src/pj/ssl_sock_ossl.c
- Timestamp:
- Oct 27, 2016 7:58:01 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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 /*
Note: See TracChangeset
for help on using the changeset viewer.