- add sources.
[platform/framework/web/crosswalk.git] / src / net / tools / flip_server / spdy_ssl.cc
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 #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   // TODO(joth): Remove const_cast when the openssl 1.0.0 upgrade is complete.
40   // (See http://codereview.chromium.org/9254031).
41   state->ssl_ctx = SSL_CTX_new(const_cast<SSL_METHOD*>(state->ssl_method));
42   if (!state->ssl_ctx) {
43     PrintSslError();
44     LOG(FATAL) << "Unable to create SSL context";
45   }
46   // Disable SSLv2 support.
47   SSL_CTX_set_options(state->ssl_ctx,
48                       SSL_OP_NO_SSLv2 | SSL_OP_CIPHER_SERVER_PREFERENCE);
49   if (SSL_CTX_use_certificate_chain_file(state->ssl_ctx,
50                                          ssl_cert_name.c_str()) <= 0) {
51     PrintSslError();
52     LOG(FATAL) << "Unable to use cert.pem as SSL cert.";
53   }
54   if (SSL_CTX_use_PrivateKey_file(state->ssl_ctx,
55                                   ssl_key_name.c_str(),
56                                   SSL_FILETYPE_PEM) <= 0) {
57     PrintSslError();
58     LOG(FATAL) << "Unable to use key.pem as SSL key.";
59   }
60   if (!SSL_CTX_check_private_key(state->ssl_ctx)) {
61     PrintSslError();
62     LOG(FATAL) << "The cert.pem and key.pem files don't match";
63   }
64   if (use_npn) {
65     SSL_CTX_set_next_protos_advertised_cb(state->ssl_ctx,
66                                           ssl_set_npn_callback, NULL);
67   }
68   VLOG(1) << "SSL CTX default cipher list: " << SSL_CIPHER_LIST;
69   SSL_CTX_set_cipher_list(state->ssl_ctx, SSL_CIPHER_LIST);
70
71   VLOG(1) << "SSL CTX session expiry: " << session_expiration_time
72           << " seconds";
73   SSL_CTX_set_timeout(state->ssl_ctx, session_expiration_time);
74
75 #ifdef SSL_MODE_RELEASE_BUFFERS
76   VLOG(1) << "SSL CTX: Setting Release Buffers mode.";
77   SSL_CTX_set_mode(state->ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
78 #endif
79
80   // Proper methods to disable compression don't exist until 0.9.9+. For now
81   // we must manipulate the stack of compression methods directly.
82   if (disable_ssl_compression) {
83     STACK_OF(SSL_COMP) *ssl_comp_methods = SSL_COMP_get_compression_methods();
84     int num_methods = sk_SSL_COMP_num(ssl_comp_methods);
85     int i;
86     for (i = 0; i < num_methods; i++) {
87       static_cast<void>(sk_SSL_COMP_delete(ssl_comp_methods, i));
88     }
89   }
90 }
91
92 SSL* CreateSSLContext(SSL_CTX* ssl_ctx) {
93   SSL* ssl = SSL_new(ssl_ctx);
94   SSL_set_accept_state(ssl);
95   PrintSslError();
96   return ssl;
97 }
98
99 void PrintSslError() {
100   char buf[128];  // this buffer must be at least 120 chars long.
101   int error_num = ERR_get_error();
102   while (error_num != 0) {
103     ERR_error_string_n(error_num, buf, sizeof(buf));
104     LOG(ERROR) << buf;
105     error_num = ERR_get_error();
106   }
107 }
108
109 }  // namespace net
110