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