1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2009 The Chromium Authors. All rights reserved. 2dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Use of this source code is governed by a BSD-style license that can be 3dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// found in the LICENSE file. 4dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "net/tools/flip_server/spdy_ssl.h" 6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 7dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/logging.h" 8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "openssl/err.h" 9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "openssl/ssl.h" 10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace net { 12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#define NEXT_PROTO_STRING "\x06spdy/2\x08http/1.1\x08http/1.0" 14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#define SSL_CIPHER_LIST "!aNULL:!ADH:!eNull:!LOW:!EXP:RC4+RSA:MEDIUM:HIGH" 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenint ssl_set_npn_callback(SSL *s, 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const unsigned char **data, 18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen unsigned int *len, 19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen void *arg) { 20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << "SSL NPN callback: advertising protocols."; 21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen *data = (const unsigned char *) NEXT_PROTO_STRING; 22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen *len = strlen(NEXT_PROTO_STRING); 23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return SSL_TLSEXT_ERR_OK; 24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid InitSSL(SSLState* state, 27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string ssl_cert_name, 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string ssl_key_name, 29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool use_npn, 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int session_expiration_time, 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool disable_ssl_compression) { 32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSL_library_init(); 33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PrintSslError(); 34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSL_load_error_strings(); 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PrintSslError(); 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 38dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen state->ssl_method = SSLv23_method(); 39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen state->ssl_ctx = SSL_CTX_new(state->ssl_method); 40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!state->ssl_ctx) { 41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PrintSslError(); 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(FATAL) << "Unable to create SSL context"; 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Disable SSLv2 support. 45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSL_CTX_set_options(state->ssl_ctx, 46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSL_OP_NO_SSLv2 | SSL_OP_CIPHER_SERVER_PREFERENCE); 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (SSL_CTX_use_certificate_chain_file(state->ssl_ctx, 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ssl_cert_name.c_str()) <= 0) { 49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PrintSslError(); 50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(FATAL) << "Unable to use cert.pem as SSL cert."; 51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (SSL_CTX_use_PrivateKey_file(state->ssl_ctx, 53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ssl_key_name.c_str(), 54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSL_FILETYPE_PEM) <= 0) { 55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PrintSslError(); 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(FATAL) << "Unable to use key.pem as SSL key."; 57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!SSL_CTX_check_private_key(state->ssl_ctx)) { 59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PrintSslError(); 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(FATAL) << "The cert.pem and key.pem files don't match"; 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (use_npn) { 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSL_CTX_set_next_protos_advertised_cb(state->ssl_ctx, 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ssl_set_npn_callback, NULL); 65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << "SSL CTX default cipher list: " << SSL_CIPHER_LIST; 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSL_CTX_set_cipher_list(state->ssl_ctx, SSL_CIPHER_LIST); 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << "SSL CTX session expiry: " << session_expiration_time 70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen << " seconds"; 71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSL_CTX_set_timeout(state->ssl_ctx, session_expiration_time); 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#ifdef SSL_MODE_RELEASE_BUFFERS 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen VLOG(1) << "SSL CTX: Setting Release Buffers mode."; 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSL_CTX_set_mode(state->ssl_ctx, SSL_MODE_RELEASE_BUFFERS); 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Proper methods to disable compression don't exist until 0.9.9+. For now 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // we must manipulate the stack of compression methods directly. 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (disable_ssl_compression) { 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen STACK_OF(SSL_COMP) *ssl_comp_methods = SSL_COMP_get_compression_methods(); 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int num_methods = sk_SSL_COMP_num(ssl_comp_methods); 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int i; 84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (i = 0; i < num_methods; i++) { 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen static_cast<void>(sk_SSL_COMP_delete(ssl_comp_methods, i)); 86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 90dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenSSL* CreateSSLContext(SSL_CTX* ssl_ctx) { 91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSL* ssl = SSL_new(ssl_ctx); 92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen SSL_set_accept_state(ssl); 93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen PrintSslError(); 94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return ssl; 95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid PrintSslError() { 98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen char buf[128]; // this buffer must be at least 120 chars long. 99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen int error_num = ERR_get_error(); 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen while (error_num != 0) { 101dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ERR_error_string_n(error_num, buf, sizeof(buf)); 102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen LOG(ERROR) << buf; 103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen error_num = ERR_get_error(); 104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} // namespace net 108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 109