| | 222 | #if defined USE_OPENSSL && ! defined OPENSSL_NO_TLSEXT |
|---|
| | 223 | int network_ssl_servername_callback(SSL *ssl, int *al, server *srv) { |
|---|
| | 224 | const char *servername; |
|---|
| | 225 | connection *con = (connection *) SSL_get_app_data(ssl); |
|---|
| | 226 | |
|---|
| | 227 | buffer_copy_string(con->uri.scheme, "https"); |
|---|
| | 228 | |
|---|
| | 229 | if (NULL == (servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { |
|---|
| | 230 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
|---|
| | 231 | "failed to get TLS server name"); |
|---|
| | 232 | return SSL_TLSEXT_ERR_NOACK; |
|---|
| | 233 | } |
|---|
| | 234 | buffer_copy_string(con->sock->tlsext_server_name, servername); |
|---|
| | 235 | buffer_to_lower(con->sock->tlsext_server_name); |
|---|
| | 236 | |
|---|
| | 237 | config_patch_connection(srv, con, COMP_SERVER_SOCKET); |
|---|
| | 238 | config_patch_connection(srv, con, COMP_HTTP_SCHEME); |
|---|
| | 239 | config_patch_connection(srv, con, COMP_HTTP_HOST); |
|---|
| | 240 | |
|---|
| | 241 | if (NULL == con->conf.ssl_ctx) { |
|---|
| | 242 | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
|---|
| | 243 | "null SSL_CTX for TLS server name", con->sock->tlsext_server_name); |
|---|
| | 244 | return SSL_TLSEXT_ERR_ALERT_FATAL; |
|---|
| | 245 | } |
|---|
| | 246 | |
|---|
| | 247 | /* switch to new SSL_CTX in reaction to a client's server_name extension */ |
|---|
| | 248 | if (con->conf.ssl_ctx != SSL_set_SSL_CTX(ssl, con->conf.ssl_ctx)) { |
|---|
| | 249 | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
|---|
| | 250 | "failed to set SSL_CTX for TLS server name", con->sock->tlsext_server_name); |
|---|
| | 251 | return SSL_TLSEXT_ERR_ALERT_FATAL; |
|---|
| | 252 | } |
|---|
| | 253 | |
|---|
| | 254 | return SSL_TLSEXT_ERR_OK; |
|---|
| | 255 | } |
|---|
| | 256 | #endif |
|---|
| | 257 | |
|---|
| 471 | | if (srv->ssl_is_init == 0) { |
|---|
| 472 | | SSL_load_error_strings(); |
|---|
| 473 | | SSL_library_init(); |
|---|
| 474 | | srv->ssl_is_init = 1; |
|---|
| 475 | | |
|---|
| 476 | | if (0 == RAND_status()) { |
|---|
| 477 | | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
|---|
| 478 | | "not enough entropy in the pool"); |
|---|
| 479 | | return -1; |
|---|
| 480 | | } |
|---|
| 481 | | } |
|---|
| 482 | | |
|---|
| 483 | | if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) { |
|---|
| 484 | | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
|---|
| 485 | | ERR_error_string(ERR_get_error(), NULL)); |
|---|
| 486 | | return -1; |
|---|
| 487 | | } |
|---|
| 488 | | |
|---|
| 489 | | if (buffer_is_empty(s->ssl_pemfile)) { |
|---|
| | 507 | if (NULL == (srv_socket->ssl_ctx = s->ssl_ctx)) { |
|---|
| 493 | | |
|---|
| 494 | | if (!buffer_is_empty(s->ssl_ca_file)) { |
|---|
| 495 | | if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) { |
|---|
| 496 | | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
|---|
| 497 | | ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file); |
|---|
| 498 | | return -1; |
|---|
| 499 | | } |
|---|
| 500 | | } |
|---|
| 501 | | |
|---|
| 502 | | if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { |
|---|
| 503 | | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
|---|
| 504 | | ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); |
|---|
| 505 | | return -1; |
|---|
| 506 | | } |
|---|
| 507 | | |
|---|
| 508 | | if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { |
|---|
| 509 | | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
|---|
| 510 | | ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); |
|---|
| 511 | | return -1; |
|---|
| 512 | | } |
|---|
| 513 | | |
|---|
| 514 | | if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) { |
|---|
| 515 | | log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", |
|---|
| 516 | | "Private key does not match the certificate public key, reason:", |
|---|
| 517 | | ERR_error_string(ERR_get_error(), NULL), |
|---|
| 518 | | s->ssl_pemfile); |
|---|
| 519 | | return -1; |
|---|
| 520 | | } |
|---|
| 521 | | srv_socket->ssl_ctx = s->ssl_ctx; |
|---|
| | 589 | #ifdef USE_OPENSSL |
|---|
| | 590 | /* load SSL certificates */ |
|---|
| | 591 | for (i = 0; i < srv->config_context->used; i++) { |
|---|
| | 592 | data_config *dc = (data_config *)srv->config_context->data[i]; |
|---|
| | 593 | specific_config *s = srv->config_storage[i]; |
|---|
| | 594 | |
|---|
| | 595 | if (buffer_is_empty(s->ssl_pemfile)) continue; |
|---|
| | 596 | |
|---|
| | 597 | #ifdef OPENSSL_NO_TLSEXT |
|---|
| | 598 | if (COMP_HTTP_HOST == dc->comp) { |
|---|
| | 599 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
|---|
| | 600 | "can't use ssl.pemfile with $HTTP[\"host\"], openssl version does not support TLS extensions"); |
|---|
| | 601 | return -1; |
|---|
| | 602 | } |
|---|
| | 603 | #endif |
|---|
| | 604 | |
|---|
| | 605 | if (srv->ssl_is_init == 0) { |
|---|
| | 606 | SSL_load_error_strings(); |
|---|
| | 607 | SSL_library_init(); |
|---|
| | 608 | srv->ssl_is_init = 1; |
|---|
| | 609 | |
|---|
| | 610 | if (0 == RAND_status()) { |
|---|
| | 611 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
|---|
| | 612 | "not enough entropy in the pool"); |
|---|
| | 613 | return -1; |
|---|
| | 614 | } |
|---|
| | 615 | } |
|---|
| | 616 | |
|---|
| | 617 | if (NULL == (s->ssl_ctx = SSL_CTX_new(SSLv23_server_method()))) { |
|---|
| | 618 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
|---|
| | 619 | ERR_error_string(ERR_get_error(), NULL)); |
|---|
| | 620 | return -1; |
|---|
| | 621 | } |
|---|
| | 622 | |
|---|
| | 623 | if (!buffer_is_empty(s->ssl_ca_file)) { |
|---|
| | 624 | if (1 != SSL_CTX_load_verify_locations(s->ssl_ctx, s->ssl_ca_file->ptr, NULL)) { |
|---|
| | 625 | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
|---|
| | 626 | ERR_error_string(ERR_get_error(), NULL), s->ssl_ca_file); |
|---|
| | 627 | return -1; |
|---|
| | 628 | } |
|---|
| | 629 | } |
|---|
| | 630 | |
|---|
| | 631 | if (SSL_CTX_use_certificate_file(s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { |
|---|
| | 632 | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
|---|
| | 633 | ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); |
|---|
| | 634 | return -1; |
|---|
| | 635 | } |
|---|
| | 636 | |
|---|
| | 637 | if (SSL_CTX_use_PrivateKey_file (s->ssl_ctx, s->ssl_pemfile->ptr, SSL_FILETYPE_PEM) < 0) { |
|---|
| | 638 | log_error_write(srv, __FILE__, __LINE__, "ssb", "SSL:", |
|---|
| | 639 | ERR_error_string(ERR_get_error(), NULL), s->ssl_pemfile); |
|---|
| | 640 | return -1; |
|---|
| | 641 | } |
|---|
| | 642 | |
|---|
| | 643 | if (SSL_CTX_check_private_key(s->ssl_ctx) != 1) { |
|---|
| | 644 | log_error_write(srv, __FILE__, __LINE__, "sssb", "SSL:", |
|---|
| | 645 | "Private key does not match the certificate public key, reason:", |
|---|
| | 646 | ERR_error_string(ERR_get_error(), NULL), |
|---|
| | 647 | s->ssl_pemfile); |
|---|
| | 648 | return -1; |
|---|
| | 649 | } |
|---|
| | 650 | |
|---|
| | 651 | #ifndef OPENSSL_NO_TLSEXT |
|---|
| | 652 | if (!SSL_CTX_set_tlsext_servername_callback(s->ssl_ctx, network_ssl_servername_callback) || |
|---|
| | 653 | !SSL_CTX_set_tlsext_servername_arg(s->ssl_ctx, srv)) { |
|---|
| | 654 | log_error_write(srv, __FILE__, __LINE__, "ss", "SSL:", |
|---|
| | 655 | "failed to initialize TLS servername callback, openssl library does not support TLS servername extension"); |
|---|
| | 656 | return -1; |
|---|
| | 657 | } |
|---|
| | 658 | #endif |
|---|
| | 659 | } |
|---|
| | 660 | #endif |
|---|
| | 661 | |
|---|