Home | History | Annotate | Download | only in flip_server
      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 
     11 namespace 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 
     16 int 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 
     26 void 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 
     90 SSL* 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 
     97 void 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