| 416 | } |
| 417 | |
| 418 | static int SetSSLOptions(SSL_CTX* ctx, const std::string& ciphers, |
| 419 | int protocols, const VerifyOptions& verify) { |
| 420 | long ssloptions = SSL_OP_ALL // All known workarounds for bugs |
| 421 | | SSL_OP_NO_SSLv2 |
| 422 | #ifdef SSL_OP_NO_COMPRESSION |
| 423 | | SSL_OP_NO_COMPRESSION |
| 424 | #endif // SSL_OP_NO_COMPRESSION |
| 425 | | SSL_OP_CIPHER_SERVER_PREFERENCE |
| 426 | | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION; |
| 427 | |
| 428 | if (!(protocols & SSLv3)) { |
| 429 | ssloptions |= SSL_OP_NO_SSLv3; |
| 430 | } |
| 431 | if (!(protocols & TLSv1)) { |
| 432 | ssloptions |= SSL_OP_NO_TLSv1; |
| 433 | } |
| 434 | |
| 435 | #ifdef SSL_OP_NO_TLSv1_1 |
| 436 | if (!(protocols & TLSv1_1)) { |
| 437 | ssloptions |= SSL_OP_NO_TLSv1_1; |
| 438 | } |
| 439 | #endif // SSL_OP_NO_TLSv1_1 |
| 440 | |
| 441 | #ifdef SSL_OP_NO_TLSv1_2 |
| 442 | if (!(protocols & TLSv1_2)) { |
| 443 | ssloptions |= SSL_OP_NO_TLSv1_2; |
| 444 | } |
| 445 | #endif // SSL_OP_NO_TLSv1_2 |
| 446 | SSL_CTX_set_options(ctx, ssloptions); |
| 447 | |
| 448 | long sslmode = SSL_MODE_ENABLE_PARTIAL_WRITE |
| 449 | | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER; |
| 450 | SSL_CTX_set_mode(ctx, sslmode); |
| 451 | |
| 452 | if (!ciphers.empty() && |
| 453 | SSL_CTX_set_cipher_list(ctx, ciphers.c_str()) != 1) { |
| 454 | LOG(ERROR) << "Fail to set cipher list to " << ciphers |
| 455 | << ": " << SSLError(ERR_get_error()); |
| 456 | return -1; |
| 457 | } |
| 458 | |
| 459 | // TODO: Verify the CNAME in certificate matches the requesting host |
| 460 | if (verify.verify_depth > 0) { |
| 461 | if (verify.verify_mode == VerifyMode::VERIFY_FAIL_IF_NO_PEER_CERT) { |
| 462 | SSL_CTX_set_verify(ctx, (SSL_VERIFY_PEER |
| 463 | | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), NULL); |
| 464 | } else if (verify.verify_mode == VerifyMode::VERIFY_PEER) { |
| 465 | SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); |
| 466 | } else if (verify.verify_mode == VerifyMode::VERIFY_NONE) { |
| 467 | SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); |
| 468 | } else { |
| 469 | // for forward compatibility |
| 470 | SSL_CTX_set_verify(ctx, (SSL_VERIFY_PEER |
| 471 | | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), NULL); |
| 472 | } |
| 473 | SSL_CTX_set_verify_depth(ctx, verify.verify_depth); |
| 474 | std::string cafile = verify.ca_file_path; |
| 475 | if (cafile.empty()) { |
no test coverage detected