15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/spdy_ssl.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "openssl/err.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "openssl/ssl.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Each element consists of <the length of the string><string> . 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define NEXT_PROTO_STRING \ 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\x08spdy/4a2" \ 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\x06spdy/3" \ 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\x06spdy/2" \ 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\x08http/1.1" \ 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "\x08http/1.0" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SSL_CIPHER_LIST "!aNULL:!ADH:!eNull:!LOW:!EXP:RC4+RSA:MEDIUM:HIGH" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int ssl_set_npn_callback(SSL* s, 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const unsigned char** data, 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) unsigned int* len, 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void* arg) { 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) VLOG(1) << "SSL NPN callback: advertising protocols."; 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) *data = (const unsigned char*)NEXT_PROTO_STRING; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *len = strlen(NEXT_PROTO_STRING); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SSL_TLSEXT_ERR_OK; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitSSL(SSLState* state, 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string ssl_cert_name, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string ssl_key_name, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool use_npn, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int session_expiration_time, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool disable_ssl_compression) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_library_init(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintSslError(); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_load_error_strings(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintSslError(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state->ssl_method = SSLv23_method(); 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) state->ssl_ctx = SSL_CTX_new(state->ssl_method); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!state->ssl_ctx) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintSslError(); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "Unable to create SSL context"; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disable SSLv2 support. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_CTX_set_options(state->ssl_ctx, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_OP_NO_SSLv2 | SSL_OP_CIPHER_SERVER_PREFERENCE); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SSL_CTX_use_certificate_chain_file(state->ssl_ctx, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_cert_name.c_str()) <= 0) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintSslError(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "Unable to use cert.pem as SSL cert."; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (SSL_CTX_use_PrivateKey_file( 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) state->ssl_ctx, ssl_key_name.c_str(), SSL_FILETYPE_PEM) <= 0) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintSslError(); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "Unable to use key.pem as SSL key."; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SSL_CTX_check_private_key(state->ssl_ctx)) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintSslError(); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "The cert.pem and key.pem files don't match"; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (use_npn) { 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SSL_CTX_set_next_protos_advertised_cb( 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) state->ssl_ctx, ssl_set_npn_callback, NULL); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "SSL CTX default cipher list: " << SSL_CIPHER_LIST; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_CTX_set_cipher_list(state->ssl_ctx, SSL_CIPHER_LIST); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "SSL CTX session expiry: " << session_expiration_time 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " seconds"; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_CTX_set_timeout(state->ssl_ctx, session_expiration_time); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SSL_MODE_RELEASE_BUFFERS 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "SSL CTX: Setting Release Buffers mode."; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_CTX_set_mode(state->ssl_ctx, SSL_MODE_RELEASE_BUFFERS); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if !defined(OPENSSL_IS_BORINGSSL) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Proper methods to disable compression don't exist until 0.9.9+. For now 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we must manipulate the stack of compression methods directly. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (disable_ssl_compression) { 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) STACK_OF(SSL_COMP)* ssl_comp_methods = SSL_COMP_get_compression_methods(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_methods = sk_SSL_COMP_num(ssl_comp_methods); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_methods; i++) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<void>(sk_SSL_COMP_delete(ssl_comp_methods, i)); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSL* CreateSSLContext(SSL_CTX* ssl_ctx) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL* ssl = SSL_new(ssl_ctx); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSL_set_accept_state(ssl); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrintSslError(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ssl; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrintSslError() { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[128]; // this buffer must be at least 120 chars long. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error_num = ERR_get_error(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (error_num != 0) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ERR_error_string_n(error_num, buf, sizeof(buf)); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << buf; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_num = ERR_get_error(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 115