Home | History | Annotate | Download | only in flip_server
      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