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