| | 64 | |
| | 65 | #if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT |
| | 66 | int network_ssl_servername_callback(SSL *ssl, int *al, server *srv) { |
| | 67 | const char *servername; |
| | 68 | connection *con = (connection *) SSL_get_app_data(ssl); |
| | 69 | |
| | 70 | if (NULL == (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { |
| | 71 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
| | 72 | "failed to get TLS server name"); |
| | 73 | return SSL_TLSEXT_ERR_NOACK; |
| | 74 | } |
| | 75 | buffer_copy_string(con->tlsext_server_name, servername); |
| | 76 | buffer_to_lower(con->tlsext_server_name); |
| | 77 | |
| | 78 | config_patch_connection(srv, con, COMP_SERVER_SOCKET); |
| | 79 | config_patch_connection(srv, con, COMP_HTTP_HOST); |
| | 80 | |
| | 81 | if (NULL == con->conf.ssl_ctx) { |
| | 82 | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
| | 83 | "null SSL_CTX for TLS server name", con->tlsext_server_name); |
| | 84 | return SSL_TLSEXT_ERR_ALERT_FATAL; |
| | 85 | } |
| | 86 | |
| | 87 | /* switch to new SSL_CTX in reaction to a client's server_name extension */ |
| | 88 | if (con->conf.ssl_ctx != SSL_set_SSL_CTX(ssl, con->conf.ssl_ctx)) { |
| | 89 | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
| | 90 | "failed to set SSL_CTX for TLS server name", con->tlsext_server_name); |
| | 91 | return SSL_TLSEXT_ERR_ALERT_FATAL; |
| | 92 | } |
| | 93 | |
| | 94 | return SSL_TLSEXT_ERR_OK; |
| | 95 | } |
| | 96 | #endif |
| 315 | | if (srv->ssl_is_init == 0) { |
| 316 | | SSL_load_error_strings(); |
| 317 | | SSL_library_init(); |
| 318 | | srv->ssl_is_init = 1; |
| 319 | | |
| 320 | | if (0 == RAND_status()) { |
| 321 | | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
| 322 | | "not enough entropy in the pool"); |
| 323 | | return -1; |
| 324 | | } |
| 325 | | } |
| 326 | | |
| 327 | | if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) { |
| 328 | | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
| 329 | | ERR_error_string(ERR_get_error(), NULL)); |
| 330 | | return -1; |
| 331 | | } |
| 332 | | |
| 333 | | if (!s->ssl_use_sslv2) { |
| 334 | | /* disable SSLv2 */ |
| 335 | | if (SSL_OP_NO_SSLv2 != SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2)) { |
| 336 | | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
| 337 | | ERR_error_string(ERR_get_error(), NULL)); |
| 338 | | return -1; |
| 339 | | } |
| 340 | | } |
| 341 | | |
| 342 | | if (!buffer_is_empty(s->ssl_cipher_list)) { |
| 343 | | /* Disable support for low encryption ciphers */ |
| 344 | | if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) { |
| 345 | | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
| 346 | | ERR_error_string(ERR_get_error(), NULL)); |
| 347 | | return -1; |
| 348 | | } |
| 349 | | } |
| 350 | | |
| 351 | | if (buffer_is_empty(s->ssl_pemfile)) { |
| | 348 | if (NULL == (srv_socket->ssl_ctx = s->ssl_ctx)) { |
| 355 | | |
| 356 | | if (!buffer_is_empty(s->ssl_ca_file)) { |
| 357 | | if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) { |
| 358 | | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
| 359 | | ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file); |
| 360 | | return -1; |
| 361 | | } |
| 362 | | } |
| 363 | | |
| 364 | | if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { |
| 365 | | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
| 366 | | ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); |
| 367 | | return -1; |
| 368 | | } |
| 369 | | |
| 370 | | if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { |
| 371 | | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
| 372 | | ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); |
| 373 | | return -1; |
| 374 | | } |
| 375 | | |
| 376 | | if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) { |
| 377 | | log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", |
| 378 | | "Private key does not match the certificate public key, reason:", |
| 379 | | ERR_error_string(ERR_get_error(), NULL), |
| 380 | | s->ssl_pemfile); |
| 381 | | return -1; |
| 382 | | } |
| 383 | | SSL_CTX_set_default_read_ahead(s->ssl_ctx, 1); |
| 384 | | SSL_CTX_set_mode(s->ssl_ctx, SSL_CTX_get_mode(s->ssl_ctx) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); |
| 385 | | |
| 386 | | srv_socket->ssl_ctx = s->ssl_ctx; |
| | 458 | |
| | 459 | #ifdef USE_OPENSSL |
| | 460 | /* load SSL certificates */ |
| | 461 | for (i = 0; i < srv->config_context->used; i++) { |
| | 462 | data_config *dc = (data_config *)srv->config_context->data[i]; |
| | 463 | specific_config *s = srv->config_storage[i]; |
| | 464 | |
| | 465 | if (buffer_is_empty(s->ssl_pemfile)) continue; |
| | 466 | |
| | 467 | #ifdef OPENSSL_NO_TLSEXT |
| | 468 | if (COMP_HTTP_HOST == dc->comp) { |
| | 469 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
| | 470 | "can't use ssl.pemfile with $HTTP[\"host\"], openssl version does not support TLS extensions"); |
| | 471 | return -1; |
| | 472 | } |
| | 473 | #endif |
| | 474 | |
| | 475 | if (srv->ssl_is_init == 0) { |
| | 476 | SSL_load_error_strings(); |
| | 477 | SSL_library_init(); |
| | 478 | srv->ssl_is_init = 1; |
| | 479 | |
| | 480 | if (0 == RAND_status()) { |
| | 481 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
| | 482 | "not enough entropy in the pool"); |
| | 483 | return -1; |
| | 484 | } |
| | 485 | } |
| | 486 | |
| | 487 | if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) { |
| | 488 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
| | 489 | ERR_error_string(ERR_get_error(), NULL)); |
| | 490 | return -1; |
| | 491 | } |
| | 492 | |
| | 493 | if (!s->ssl_use_sslv2) { |
| | 494 | /* disable SSLv2 */ |
| | 495 | if (SSL_OP_NO_SSLv2 != SSL_CTX_set_options(s->ssl_ctx, SSL_OP_NO_SSLv2)) { |
| | 496 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
| | 497 | ERR_error_string(ERR_get_error(), NULL)); |
| | 498 | return -1; |
| | 499 | } |
| | 500 | } |
| | 501 | |
| | 502 | if (!buffer_is_empty(s->ssl_cipher_list)) { |
| | 503 | /* Disable support for low encryption ciphers */ |
| | 504 | if (SSL_CTX_set_cipher_list(s->ssl_ctx, s->ssl_cipher_list->ptr) != 1) { |
| | 505 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
| | 506 | ERR_error_string(ERR_get_error(), NULL)); |
| | 507 | return -1; |
| | 508 | } |
| | 509 | } |
| | 510 | |
| | 511 | if (!buffer_is_empty(s->ssl_ca_file)) { |
| | 512 | if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) { |
| | 513 | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
| | 514 | ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file); |
| | 515 | return -1; |
| | 516 | } |
| | 517 | } |
| | 518 | |
| | 519 | if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { |
| | 520 | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
| | 521 | ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); |
| | 522 | return -1; |
| | 523 | } |
| | 524 | |
| | 525 | if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { |
| | 526 | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
| | 527 | ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); |
| | 528 | return -1; |
| | 529 | } |
| | 530 | |
| | 531 | if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) { |
| | 532 | log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", |
| | 533 | "Private key does not match the certificate public key, reason:", |
| | 534 | ERR_error_string(ERR_get_error(), NULL), |
| | 535 | s->ssl_pemfile); |
| | 536 | return -1; |
| | 537 | } |
| | 538 | SSL_CTX_set_default_read_ahead(s->ssl_ctx, 1); |
| | 539 | SSL_CTX_set_mode(s->ssl_ctx, SSL_CTX_get_mode(s->ssl_ctx) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); |
| | 540 | |
| | 541 | #ifndef OPENSSL_NO_TLSEXT |
| | 542 | if (!SSL_CTX_set_tlsext_servername_callback(s->ssl_ctx, network_ssl_servername_callback) || |
| | 543 | !SSL_CTX_set_tlsext_servername_arg(s->ssl_ctx, srv)) { |
| | 544 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
| | 545 | "failed to initialize TLS servername callback, openssl library does not support TLS servername extension"); |
| | 546 | return -1; |
| | 547 | } |
| | 548 | #endif |
| | 549 | } |
| | 550 | #endif |