opensslstreamadapter.cc revision 0c4e06b4c6107a1b94f764e279e4fb4161e905b0
1f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/*
2f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *
4f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
5f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
6f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
7f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
8f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */
10f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
11f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if HAVE_CONFIG_H
12f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "config.h"
13f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif  // HAVE_CONFIG_H
14f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
15f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if HAVE_OPENSSL_SSL_H
16f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
17f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/opensslstreamadapter.h"
18f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
19f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <openssl/bio.h>
20f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <openssl/crypto.h>
21f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <openssl/err.h>
22f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <openssl/rand.h>
233ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org#include <openssl/tls1.h>
24f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <openssl/x509v3.h>
25f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
26f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <vector>
27f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
28f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/common.h"
29f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/logging.h"
30d89b69aadeb9db67b7cc2de3300109d866c2a937henrike@webrtc.org#include "webrtc/base/safe_conversions.h"
31f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/stream.h"
32f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/openssl.h"
33f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/openssladapter.h"
34f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/openssldigest.h"
35f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/opensslidentity.h"
36f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/stringutils.h"
37f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/thread.h"
38f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
39f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgnamespace rtc {
40f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
41f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if (OPENSSL_VERSION_NUMBER >= 0x10001000L)
42f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define HAVE_DTLS_SRTP
43f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
44f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
45f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef HAVE_DTLS_SRTP
46f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// SRTP cipher suite table
47f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstruct SrtpCipherMapEntry {
48f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  const char* external_name;
49f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  const char* internal_name;
50f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
51f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
52f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// This isn't elegant, but it's better than an external reference
53f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic SrtpCipherMapEntry SrtpCipherMap[] = {
54456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    {CS_AES_CM_128_HMAC_SHA1_80, "SRTP_AES128_CM_SHA1_80"},
55456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    {CS_AES_CM_128_HMAC_SHA1_32, "SRTP_AES128_CM_SHA1_32"},
56456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    {NULL, NULL}};
57f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
58f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
59f7bb6e723bea160b11060c16d8a57f97eb57bb90pthatcher@webrtc.org#ifndef OPENSSL_IS_BORINGSSL
60456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh
613ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// Cipher name table. Maps internal OpenSSL cipher ids to the RFC name.
623ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.orgstruct SslCipherMapEntry {
633ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  uint32_t openssl_id;
643ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  const char* rfc_name;
653ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org};
663ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
673ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org#define DEFINE_CIPHER_ENTRY_SSL3(name)  {SSL3_CK_##name, "TLS_"#name}
683ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org#define DEFINE_CIPHER_ENTRY_TLS1(name)  {TLS1_CK_##name, "TLS_"#name}
693ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
703ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// There currently is no method available to get a RFC-compliant name for a
713ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// cipher suite from BoringSSL, so we need to define the mapping manually here.
723ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// This should go away once BoringSSL supports "SSL_CIPHER_standard_name"
733ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// (as available in OpenSSL if compiled with tracing enabled) or a similar
743ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// method.
753ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.orgstatic const SslCipherMapEntry kSslCipherMap[] = {
763ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // TLS v1.0 ciphersuites from RFC2246.
773ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_SSL3(RSA_RC4_128_SHA),
783ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {SSL3_CK_RSA_DES_192_CBC3_SHA,
793ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
803ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
813ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // AES ciphersuites from RFC3268.
823ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_RSA_WITH_AES_128_SHA,
833ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_RSA_WITH_AES_128_CBC_SHA"},
843ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
853ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"},
863ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_RSA_WITH_AES_256_SHA,
873ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_RSA_WITH_AES_256_CBC_SHA"},
883ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
893ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
903ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
913ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // ECC ciphersuites from RFC4492.
923ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_RC4_128_SHA),
933ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
943ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"},
953ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_128_CBC_SHA),
963ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_256_CBC_SHA),
973ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
983ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_RC4_128_SHA),
993ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
1003ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"},
1013ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_128_CBC_SHA),
1023ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_256_CBC_SHA),
1033ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
1043ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // TLS v1.2 ciphersuites.
1053ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_RSA_WITH_AES_128_SHA256,
1063ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_RSA_WITH_AES_128_CBC_SHA256"},
1073ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_RSA_WITH_AES_256_SHA256,
1083ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_RSA_WITH_AES_256_CBC_SHA256"},
1093ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
1103ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"},
1113ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
1123ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
1133ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
1143ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // TLS v1.2 GCM ciphersuites from RFC5288.
1153ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(RSA_WITH_AES_128_GCM_SHA256),
1163ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(RSA_WITH_AES_256_GCM_SHA384),
1173ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(DHE_RSA_WITH_AES_128_GCM_SHA256),
1183ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(DHE_RSA_WITH_AES_256_GCM_SHA384),
1193ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(DH_RSA_WITH_AES_128_GCM_SHA256),
1203ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(DH_RSA_WITH_AES_256_GCM_SHA384),
1213ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
1223ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // ECDH HMAC based ciphersuites from RFC5289.
1233ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256,
1243ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"},
1253ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384,
1263ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"},
1273ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
1283ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
1293ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
1303ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
1313ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
1323ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // ECDH GCM based ciphersuites from RFC5289.
1333ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_128_GCM_SHA256),
1343ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_256_GCM_SHA384),
1353ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_128_GCM_SHA256),
1363ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_256_GCM_SHA384),
1373ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
1383ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {0, NULL}
1393ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org};
140f7bb6e723bea160b11060c16d8a57f97eb57bb90pthatcher@webrtc.org#endif  // #ifndef OPENSSL_IS_BORINGSSL
1413ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
142456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#if defined(_MSC_VER)
143456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#pragma warning(push)
144456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#pragma warning(disable : 4309)
145456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#pragma warning(disable : 4310)
146456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#endif  // defined(_MSC_VER)
147456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh
1483ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// Default cipher used between OpenSSL/BoringSSL stream adapters.
1493ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// This needs to be updated when the default of the SSL library changes.
150456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh// static_cast<uint16_t> causes build warnings on windows platform.
1516caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslCipher10 =
152456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA);
1536caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslEcCipher10 =
154456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
155831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#ifdef OPENSSL_IS_BORINGSSL
1566caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslCipher12 =
157456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256);
1586caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslEcCipher12 =
159456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256);
160831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch// Fallback cipher for DTLS 1.2 if hardware-accelerated AES-GCM is unavailable.
1616caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslCipher12NoAesGcm =
162456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305);
1636caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslEcCipher12NoAesGcm =
164456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305);
165831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#else  // !OPENSSL_IS_BORINGSSL
166831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch// OpenSSL sorts differently than BoringSSL, so the default cipher doesn't
167831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch// change between TLS 1.0 and TLS 1.2 with the current setup.
1686caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslCipher12 =
169456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA);
1706caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslEcCipher12 =
171456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
172831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#endif
1733ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
174456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#if defined(_MSC_VER)
175456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#pragma warning(pop)
176456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#endif  // defined(_MSC_VER)
177456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh
178f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//////////////////////////////////////////////////////////////////////
179f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// StreamBIO
180f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//////////////////////////////////////////////////////////////////////
181f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
182f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_write(BIO* h, const char* buf, int num);
183f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_read(BIO* h, char* buf, int size);
184f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_puts(BIO* h, const char* str);
185f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic long stream_ctrl(BIO* h, int cmd, long arg1, void* arg2);
186f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_new(BIO* h);
187f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_free(BIO* data);
188f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
18936d5c3cb447901ffff6a02a438e1d422cb806147davidben@webrtc.org// TODO(davidben): This should be const once BoringSSL is assumed.
19036d5c3cb447901ffff6a02a438e1d422cb806147davidben@webrtc.orgstatic BIO_METHOD methods_stream = {
191f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  BIO_TYPE_BIO,
192f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  "stream",
193f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream_write,
194f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream_read,
195f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream_puts,
196f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  0,
197f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream_ctrl,
198f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream_new,
199f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream_free,
200f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  NULL,
201f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
202f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
20336d5c3cb447901ffff6a02a438e1d422cb806147davidben@webrtc.orgstatic BIO_METHOD* BIO_s_stream() { return(&methods_stream); }
204f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
205f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic BIO* BIO_new_stream(StreamInterface* stream) {
206f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  BIO* ret = BIO_new(BIO_s_stream());
207f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (ret == NULL)
208f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return NULL;
209f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ret->ptr = stream;
210f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return ret;
211f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
212f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
213f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// bio methods return 1 (or at least non-zero) on success and 0 on failure.
214f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
215f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_new(BIO* b) {
216f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  b->shutdown = 0;
217f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  b->init = 1;
218f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  b->num = 0;  // 1 means end-of-stream
219f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  b->ptr = 0;
220f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return 1;
221f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
222f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
223f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_free(BIO* b) {
224f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (b == NULL)
225f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return 0;
226f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return 1;
227f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
228f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
229f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_read(BIO* b, char* out, int outl) {
230f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!out)
231f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return -1;
232f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
233f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  BIO_clear_retry_flags(b);
234f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  size_t read;
235f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int error;
236f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  StreamResult result = stream->Read(out, outl, &read, &error);
237f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (result == SR_SUCCESS) {
238d89b69aadeb9db67b7cc2de3300109d866c2a937henrike@webrtc.org    return checked_cast<int>(read);
239f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  } else if (result == SR_EOS) {
240f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    b->num = 1;
241f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  } else if (result == SR_BLOCK) {
242f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    BIO_set_retry_read(b);
243f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
244f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return -1;
245f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
246f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
247f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_write(BIO* b, const char* in, int inl) {
248f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!in)
249f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return -1;
250f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
251f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  BIO_clear_retry_flags(b);
252f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  size_t written;
253f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int error;
254f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  StreamResult result = stream->Write(in, inl, &written, &error);
255f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (result == SR_SUCCESS) {
256d89b69aadeb9db67b7cc2de3300109d866c2a937henrike@webrtc.org    return checked_cast<int>(written);
257f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  } else if (result == SR_BLOCK) {
258f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    BIO_set_retry_write(b);
259f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
260f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return -1;
261f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
262f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
263f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_puts(BIO* b, const char* str) {
264d89b69aadeb9db67b7cc2de3300109d866c2a937henrike@webrtc.org  return stream_write(b, str, checked_cast<int>(strlen(str)));
265f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
266f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
267f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic long stream_ctrl(BIO* b, int cmd, long num, void* ptr) {
26814abcc73227223def23a3eb06b47285c3a55a5b5henrike@webrtc.org  RTC_UNUSED(num);
26914abcc73227223def23a3eb06b47285c3a55a5b5henrike@webrtc.org  RTC_UNUSED(ptr);
270f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
271f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (cmd) {
272f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case BIO_CTRL_RESET:
273f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return 0;
274f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case BIO_CTRL_EOF:
275f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return b->num;
276f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case BIO_CTRL_WPENDING:
277f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case BIO_CTRL_PENDING:
278f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return 0;
279f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case BIO_CTRL_FLUSH:
280f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return 1;
281f4baca50bb98e1eeefea621365fac08cae2fe303Henrik Lundin    case BIO_CTRL_DGRAM_QUERY_MTU:
282f4baca50bb98e1eeefea621365fac08cae2fe303Henrik Lundin      // openssl defaults to mtu=256 unless we return something here.
283f4baca50bb98e1eeefea621365fac08cae2fe303Henrik Lundin      // The handshake doesn't actually need to send packets above 1k,
284f4baca50bb98e1eeefea621365fac08cae2fe303Henrik Lundin      // so this seems like a sensible value that should work in most cases.
285f4baca50bb98e1eeefea621365fac08cae2fe303Henrik Lundin      // Webrtc uses the same value for video packets.
286f4baca50bb98e1eeefea621365fac08cae2fe303Henrik Lundin      return 1200;
287f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    default:
288f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return 0;
289f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
290f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
291f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
292f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////
293f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// OpenSSLStreamAdapter
294f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////
295f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
296f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgOpenSSLStreamAdapter::OpenSSLStreamAdapter(StreamInterface* stream)
297f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    : SSLStreamAdapter(stream),
298f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      state_(SSL_NONE),
299f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      role_(SSL_CLIENT),
300f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ssl_read_needs_write_(false), ssl_write_needs_read_(false),
301f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ssl_(NULL), ssl_ctx_(NULL),
302f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      custom_verification_succeeded_(false),
303831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      ssl_mode_(SSL_MODE_TLS),
304831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      ssl_max_version_(SSL_PROTOCOL_TLS_11) {
305f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
306f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
307f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgOpenSSLStreamAdapter::~OpenSSLStreamAdapter() {
308f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Cleanup();
309f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
310f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
311f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::SetIdentity(SSLIdentity* identity) {
312f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(!identity_);
313f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  identity_.reset(static_cast<OpenSSLIdentity*>(identity));
314f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
315f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
316f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::SetServerRole(SSLRole role) {
317f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  role_ = role;
318f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
319f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
320f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::GetPeerCertificate(SSLCertificate** cert) const {
321f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!peer_certificate_)
322f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
323f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
324f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  *cert = peer_certificate_->GetReference();
325f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
326f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
327f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
328f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string
329f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                    &digest_alg,
330f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                    const unsigned char*
331f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                    digest_val,
332f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                    size_t digest_len) {
333f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(!peer_certificate_);
334f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(peer_certificate_digest_algorithm_.size() == 0);
335f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(ssl_server_name_.empty());
336f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  size_t expected_len;
337f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
338f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!OpenSSLDigest::GetDigestSize(digest_alg, &expected_len)) {
339f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg;
340f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
341f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
342f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (expected_len != digest_len)
343f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
344f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
345f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  peer_certificate_digest_value_.SetData(digest_val, digest_len);
346f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  peer_certificate_digest_algorithm_ = digest_alg;
347f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
348f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
349f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
350f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
3516caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstd::string OpenSSLStreamAdapter::GetSslCipherSuiteName(int cipher) {
352456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#ifdef OPENSSL_IS_BORINGSSL
353456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  const SSL_CIPHER* ssl_cipher = SSL_get_cipher_by_value(cipher);
354456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  if (!ssl_cipher) {
355456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    return std::string();
356456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  }
357456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  char* cipher_name = SSL_CIPHER_get_rfc_name(ssl_cipher);
358456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  std::string rfc_name = std::string(cipher_name);
359456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  OPENSSL_free(cipher_name);
360456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  return rfc_name;
361456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#else
3623ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  for (const SslCipherMapEntry* entry = kSslCipherMap; entry->rfc_name;
3633ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org       ++entry) {
36442b4faa28afed9e9358c97aae85f0ef742afa196Guo-wei Shieh    if (cipher == entry->openssl_id) {
3653ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      return entry->rfc_name;
3663ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org    }
3673ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  }
368456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  return std::string();
36927dc29b0df23eed5034f28d4d5f66ea0bb425d6cguoweis#endif
370456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh}
3713ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
3726caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehbool OpenSSLStreamAdapter::GetSslCipherSuite(int* cipher) {
3733ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  if (state_ != SSL_CONNECTED)
3743ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org    return false;
3753ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
3763ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  const SSL_CIPHER* current_cipher = SSL_get_current_cipher(ssl_);
3773ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  if (current_cipher == NULL) {
3783ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org    return false;
3793ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  }
3803ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
381456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  *cipher = static_cast<uint16_t>(SSL_CIPHER_get_id(current_cipher));
3823ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  return true;
3833ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org}
3843ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
385f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Key Extractor interface
386f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
3870c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                                const uint8_t* context,
388f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                size_t context_len,
389f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                bool use_context,
3900c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                                uint8_t* result,
391f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                size_t result_len) {
392f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef HAVE_DTLS_SRTP
393f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int i;
394f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
3950c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  i = SSL_export_keying_material(ssl_, result, result_len, label.c_str(),
3960c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                 label.length(), const_cast<uint8_t*>(context),
397f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                 context_len, use_context);
398f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
399f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (i != 1)
400f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
401f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
402f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
403f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else
404f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return false;
405f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
406f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
407f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
408f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::SetDtlsSrtpCiphers(
409f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const std::vector<std::string>& ciphers) {
410f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef HAVE_DTLS_SRTP
411f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  std::string internal_ciphers;
412f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
413f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (state_ != SSL_NONE)
414f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
415f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
416f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  for (std::vector<std::string>::const_iterator cipher = ciphers.begin();
417f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org       cipher != ciphers.end(); ++cipher) {
418f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    bool found = false;
419f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    for (SrtpCipherMapEntry *entry = SrtpCipherMap; entry->internal_name;
420f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org         ++entry) {
421f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (*cipher == entry->external_name) {
422f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        found = true;
423f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        if (!internal_ciphers.empty())
424f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          internal_ciphers += ":";
425f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        internal_ciphers += entry->internal_name;
426f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        break;
427f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
428f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
429f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
430f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (!found) {
431f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_ERROR) << "Could not find cipher: " << *cipher;
432f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return false;
433f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
434f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
435f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
436f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (internal_ciphers.empty())
437f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
438f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
439f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  srtp_ciphers_ = internal_ciphers;
440f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
441f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else
442f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return false;
443f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
444f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
445f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
446f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::GetDtlsSrtpCipher(std::string* cipher) {
447f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef HAVE_DTLS_SRTP
448f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(state_ == SSL_CONNECTED);
449f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (state_ != SSL_CONNECTED)
450f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
451f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
452c10eceab6ec2f6508979a4dc06049821a168e236henrike@webrtc.org  const SRTP_PROTECTION_PROFILE *srtp_profile =
453f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      SSL_get_selected_srtp_profile(ssl_);
454f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
455f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!srtp_profile)
456f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
457f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
458f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  for (SrtpCipherMapEntry *entry = SrtpCipherMap;
459f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org       entry->internal_name; ++entry) {
460f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (!strcmp(entry->internal_name, srtp_profile->name)) {
461f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      *cipher = entry->external_name;
462f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return true;
463f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
464f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
465f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
466f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(false);  // This should never happen
467f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
468f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return false;
469f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else
470f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return false;
471f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
472f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
473f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
474f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) {
475f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(server_name != NULL && server_name[0] != '\0');
476f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_server_name_ = server_name;
477f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return StartSSL();
478f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
479f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
480f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint OpenSSLStreamAdapter::StartSSLWithPeer() {
481f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(ssl_server_name_.empty());
482f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // It is permitted to specify peer_certificate_ only later.
483f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return StartSSL();
484f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
485f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
486f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::SetMode(SSLMode mode) {
487f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(state_ == SSL_NONE);
488f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_mode_ = mode;
489f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
490f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
491831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauchvoid OpenSSLStreamAdapter::SetMaxProtocolVersion(SSLProtocolVersion version) {
492831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  ASSERT(ssl_ctx_ == NULL);
493831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  ssl_max_version_ = version;
494831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch}
495831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch
496f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
497f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// StreamInterface Implementation
498f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
499f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
500f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgStreamResult OpenSSLStreamAdapter::Write(const void* data, size_t data_len,
501f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                         size_t* written, int* error) {
502f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Write(" << data_len << ")";
503f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
504f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (state_) {
505f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_NONE:
506f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // pass-through in clear text
507f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return StreamAdapterInterface::Write(data, data_len, written, error);
508f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
509f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_WAIT:
510f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_CONNECTING:
511f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_BLOCK;
512f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
513f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_CONNECTED:
514f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    break;
515f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
516f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_ERROR:
517f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_CLOSED:
518f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  default:
519f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (error)
520f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      *error = ssl_error_code_;
521f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_ERROR;
522f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
523f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
524f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // OpenSSL will return an error if we try to write zero bytes
525f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (data_len == 0) {
526f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (written)
527f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      *written = 0;
528f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_SUCCESS;
529f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
530f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
531f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_write_needs_read_ = false;
532f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
533d89b69aadeb9db67b7cc2de3300109d866c2a937henrike@webrtc.org  int code = SSL_write(ssl_, data, checked_cast<int>(data_len));
534f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int ssl_error = SSL_get_error(ssl_, code);
535f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (ssl_error) {
536f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_ERROR_NONE:
537f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << " -- success";
538f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
539f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (written)
540f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      *written = code;
541f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_SUCCESS;
542f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_ERROR_WANT_READ:
543f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << " -- error want read";
544f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ssl_write_needs_read_ = true;
545f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_BLOCK;
546f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_ERROR_WANT_WRITE:
547f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << " -- error want write";
548f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_BLOCK;
549f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
550f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_ERROR_ZERO_RETURN:
551f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  default:
552f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    Error("SSL_write", (ssl_error ? ssl_error : -1), false);
553f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (error)
554f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      *error = ssl_error_code_;
555f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_ERROR;
556f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
557f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // not reached
558f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
559f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
560f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgStreamResult OpenSSLStreamAdapter::Read(void* data, size_t data_len,
561f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                        size_t* read, int* error) {
562f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Read(" << data_len << ")";
563f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (state_) {
564f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_NONE:
565f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      // pass-through in clear text
566f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return StreamAdapterInterface::Read(data, data_len, read, error);
567f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
568f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_WAIT:
569f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_CONNECTING:
570f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_BLOCK;
571f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
572f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_CONNECTED:
573f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      break;
574f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
575f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_CLOSED:
576f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_EOS;
577f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
578f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR:
579f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    default:
580f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (error)
581f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        *error = ssl_error_code_;
582f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_ERROR;
583f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
584f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
585f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Don't trust OpenSSL with zero byte reads
586f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (data_len == 0) {
587f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (read)
588f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      *read = 0;
589f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_SUCCESS;
590f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
591f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
592f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_read_needs_write_ = false;
593f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
594d89b69aadeb9db67b7cc2de3300109d866c2a937henrike@webrtc.org  int code = SSL_read(ssl_, data, checked_cast<int>(data_len));
595f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int ssl_error = SSL_get_error(ssl_, code);
596f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (ssl_error) {
597f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_NONE:
598f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- success";
599f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
600f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (read)
601f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        *read = code;
602f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
603f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (ssl_mode_ == SSL_MODE_DTLS) {
604f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        // Enforce atomic reads -- this is a short read
605f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        unsigned int pending = SSL_pending(ssl_);
606f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
607f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        if (pending) {
608f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          LOG(LS_INFO) << " -- short DTLS read. flushing";
609f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          FlushInput(pending);
610f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          if (error)
611f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org            *error = SSE_MSG_TRUNC;
612f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          return SR_ERROR;
613f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        }
614f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
615f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_SUCCESS;
616f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_WANT_READ:
617f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- error want read";
618f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_BLOCK;
619f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_WANT_WRITE:
620f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- error want write";
621f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ssl_read_needs_write_ = true;
622f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_BLOCK;
623f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_ZERO_RETURN:
624f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- remote side closed";
625f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_EOS;
626f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      break;
627f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    default:
628f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- error " << code;
629f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      Error("SSL_read", (ssl_error ? ssl_error : -1), false);
630f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (error)
631f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        *error = ssl_error_code_;
632f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_ERROR;
633f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
634f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // not reached
635f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
636f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
637f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::FlushInput(unsigned int left) {
638f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  unsigned char buf[2048];
639f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
640f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  while (left) {
641f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // This should always succeed
642f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    int toread = (sizeof(buf) < left) ? sizeof(buf) : left;
643f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    int code = SSL_read(ssl_, buf, toread);
644f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
645f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    int ssl_error = SSL_get_error(ssl_, code);
646f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(ssl_error == SSL_ERROR_NONE);
647f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
648f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (ssl_error != SSL_ERROR_NONE) {
649f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- error " << code;
650f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      Error("SSL_read", (ssl_error ? ssl_error : -1), false);
651f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return;
652f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
653f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
654f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << " -- flushed " << code << " bytes";
655f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    left -= code;
656f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
657f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
658f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
659f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::Close() {
660f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Cleanup();
661f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR);
662f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  StreamAdapterInterface::Close();
663f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
664f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
665f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgStreamState OpenSSLStreamAdapter::GetState() const {
666f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (state_) {
667f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_WAIT:
668f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_CONNECTING:
669f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SS_OPENING;
670f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_CONNECTED:
671f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SS_OPEN;
672f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    default:
673f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SS_CLOSED;
674f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  };
675f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // not reached
676f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
677f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
678f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, int events,
679f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                   int err) {
680f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int events_to_signal = 0;
681f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int signal_error = 0;
682f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(stream == this->stream());
683f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if ((events & SE_OPEN)) {
684f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent SE_OPEN";
685f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (state_ != SSL_WAIT) {
686f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ASSERT(state_ == SSL_NONE);
687f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      events_to_signal |= SE_OPEN;
688f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    } else {
689f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      state_ = SSL_CONNECTING;
690f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (int err = BeginSSL()) {
691f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        Error("BeginSSL", err, true);
692f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        return;
693f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
694f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
695f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
696f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if ((events & (SE_READ|SE_WRITE))) {
697f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent"
698f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                 << ((events & SE_READ) ? " SE_READ" : "")
699f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                 << ((events & SE_WRITE) ? " SE_WRITE" : "");
700f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (state_ == SSL_NONE) {
701f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      events_to_signal |= events & (SE_READ|SE_WRITE);
702f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    } else if (state_ == SSL_CONNECTING) {
703f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (int err = ContinueSSL()) {
704f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        Error("ContinueSSL", err, true);
705f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        return;
706f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
707f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    } else if (state_ == SSL_CONNECTED) {
708f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (((events & SE_READ) && ssl_write_needs_read_) ||
709f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          (events & SE_WRITE)) {
710f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        LOG(LS_VERBOSE) << " -- onStreamWriteable";
711f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        events_to_signal |= SE_WRITE;
712f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
713f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (((events & SE_WRITE) && ssl_read_needs_write_) ||
714f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          (events & SE_READ)) {
715f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        LOG(LS_VERBOSE) << " -- onStreamReadable";
716f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        events_to_signal |= SE_READ;
717f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
718f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
719f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
720f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if ((events & SE_CLOSE)) {
721f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err << ")";
722f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    Cleanup();
723f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    events_to_signal |= SE_CLOSE;
724f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // SE_CLOSE is the only event that uses the final parameter to OnEvent().
725f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(signal_error == 0);
726f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    signal_error = err;
727f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
728f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (events_to_signal)
729f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error);
730f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
731f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
732f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint OpenSSLStreamAdapter::StartSSL() {
733f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(state_ == SSL_NONE);
734f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
735f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (StreamAdapterInterface::GetState() != SS_OPEN) {
736f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    state_ = SSL_WAIT;
737f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return 0;
738f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
739f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
740f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  state_ = SSL_CONNECTING;
741f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (int err = BeginSSL()) {
742f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    Error("BeginSSL", err, false);
743f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return err;
744f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
745f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
746f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return 0;
747f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
748f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
749f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint OpenSSLStreamAdapter::BeginSSL() {
750f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(state_ == SSL_CONNECTING);
751f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // The underlying stream has open. If we are in peer-to-peer mode
752f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // then a peer certificate must have been specified by now.
753f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(!ssl_server_name_.empty() ||
754f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org         !peer_certificate_digest_algorithm_.empty());
755f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_INFO) << "BeginSSL: "
756f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org               << (!ssl_server_name_.empty() ? ssl_server_name_ :
757f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                               "with peer");
758f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
759f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  BIO* bio = NULL;
760f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
761f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // First set up the context
762f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(ssl_ctx_ == NULL);
763f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_ctx_ = SetupSSLContext();
764f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!ssl_ctx_)
765f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return -1;
766f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
767f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bio = BIO_new_stream(static_cast<StreamInterface*>(stream()));
768f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!bio)
769f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return -1;
770f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
771f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_ = SSL_new(ssl_ctx_);
772f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!ssl_) {
773f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    BIO_free(bio);
774f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return -1;
775f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
776f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
777f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL_set_app_data(ssl_, this);
778f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
779f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL_set_bio(ssl_, bio, bio);  // the SSL object owns the bio now.
780a398020cba1279e4393fa25cf22a6260aa669766Joachim Bauch#ifndef OPENSSL_IS_BORINGSSL
7815ca688b3da35ea2a8da6e915c503b12d4d814bb2Joachim Bauch  if (ssl_mode_ == SSL_MODE_DTLS) {
7825ca688b3da35ea2a8da6e915c503b12d4d814bb2Joachim Bauch    // Enable read-ahead for DTLS so whole packets are read from internal BIO
783a398020cba1279e4393fa25cf22a6260aa669766Joachim Bauch    // before parsing. This is done internally by BoringSSL for DTLS.
7845ca688b3da35ea2a8da6e915c503b12d4d814bb2Joachim Bauch    SSL_set_read_ahead(ssl_, 1);
7855ca688b3da35ea2a8da6e915c503b12d4d814bb2Joachim Bauch  }
786a398020cba1279e4393fa25cf22a6260aa669766Joachim Bauch#endif
787f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
788f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
789f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org               SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
790f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
79111c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  // Specify an ECDH group for ECDHE ciphers, otherwise they cannot be
79211c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  // negotiated when acting as the server. Use NIST's P-256 which is commonly
79311c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  // supported.
79411c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
79511c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  if (ecdh == NULL)
79611c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org    return -1;
79711c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  SSL_set_options(ssl_, SSL_OP_SINGLE_ECDH_USE);
79811c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  SSL_set_tmp_ecdh(ssl_, ecdh);
79911c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  EC_KEY_free(ecdh);
80011c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org
801f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Do the connect
802f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return ContinueSSL();
803f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
804f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
805f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint OpenSSLStreamAdapter::ContinueSSL() {
806f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_VERBOSE) << "ContinueSSL";
807f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(state_ == SSL_CONNECTING);
808f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
809f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Clear the DTLS timer
810f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Thread::Current()->Clear(this, MSG_TIMEOUT);
811f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
812f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_);
813f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int ssl_error;
814f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (ssl_error = SSL_get_error(ssl_, code)) {
815f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_NONE:
816f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- success";
817f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
818f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (!SSLPostConnectionCheck(ssl_, ssl_server_name_.c_str(), NULL,
819f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                  peer_certificate_digest_algorithm_)) {
820f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        LOG(LS_ERROR) << "TLS post connection check failed";
821f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        return -1;
822f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
823f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
824f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      state_ = SSL_CONNECTED;
825f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0);
826f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      break;
827f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
828f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_WANT_READ: {
829f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        LOG(LS_VERBOSE) << " -- error want read";
830f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        struct timeval timeout;
831f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        if (DTLSv1_get_timeout(ssl_, &timeout)) {
832f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000;
833f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
834f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          Thread::Current()->PostDelayed(delay, this, MSG_TIMEOUT, 0);
835f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        }
836f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
837f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      break;
838f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
839f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_WANT_WRITE:
840f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- error want write";
841f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      break;
842f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
843f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_ZERO_RETURN:
844f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    default:
845f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- error " << code;
846f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return (ssl_error != 0) ? ssl_error : -1;
847f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
848f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
849f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return 0;
850f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
851f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
852f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::Error(const char* context, int err, bool signal) {
853f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_WARNING) << "OpenSSLStreamAdapter::Error("
854f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                  << context << ", " << err << ")";
855f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  state_ = SSL_ERROR;
856f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_error_code_ = err;
857f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Cleanup();
858f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (signal)
859f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err);
860f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
861f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
862f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::Cleanup() {
863f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_INFO) << "Cleanup";
864f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
865f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (state_ != SSL_ERROR) {
866f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    state_ = SSL_CLOSED;
867f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ssl_error_code_ = 0;
868f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
869f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
870f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (ssl_) {
871f1d751c7dede158bc9770e4d7c4cb07191ffdf3fjiayl@webrtc.org    int ret = SSL_shutdown(ssl_);
872f1d751c7dede158bc9770e4d7c4cb07191ffdf3fjiayl@webrtc.org    if (ret < 0) {
873f1d751c7dede158bc9770e4d7c4cb07191ffdf3fjiayl@webrtc.org      LOG(LS_WARNING) << "SSL_shutdown failed, error = "
874f1d751c7dede158bc9770e4d7c4cb07191ffdf3fjiayl@webrtc.org                      << SSL_get_error(ssl_, ret);
875f1d751c7dede158bc9770e4d7c4cb07191ffdf3fjiayl@webrtc.org    }
876f1d751c7dede158bc9770e4d7c4cb07191ffdf3fjiayl@webrtc.org
877f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    SSL_free(ssl_);
878f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ssl_ = NULL;
879f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
880f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (ssl_ctx_) {
881f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    SSL_CTX_free(ssl_ctx_);
882f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ssl_ctx_ = NULL;
883f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
884f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  identity_.reset();
885f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  peer_certificate_.reset();
886f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
887f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Clear the DTLS timer
888f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Thread::Current()->Clear(this, MSG_TIMEOUT);
889f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
890f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
891f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
892f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::OnMessage(Message* msg) {
893f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Process our own messages and then pass others to the superclass
894f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (MSG_TIMEOUT == msg->message_id) {
895f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_INFO) << "DTLS timeout expired";
896f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    DTLSv1_handle_timeout(ssl_);
897f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ContinueSSL();
898f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  } else {
899f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    StreamInterface::OnMessage(msg);
900f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
901f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
902f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
903f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
904f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL_CTX *ctx = NULL;
905f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
906831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#ifdef OPENSSL_IS_BORINGSSL
907f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
908831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        DTLS_method() : TLS_method());
909831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    // Version limiting for BoringSSL will be done below.
910831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#else
911831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  const SSL_METHOD* method;
912831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  switch (ssl_max_version_) {
913831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    case SSL_PROTOCOL_TLS_10:
914831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    case SSL_PROTOCOL_TLS_11:
915831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      // OpenSSL doesn't support setting min/max versions, so we always use
916831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      // (D)TLS 1.0 if a max. version below the max. available is requested.
917831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      if (ssl_mode_ == SSL_MODE_DTLS) {
918831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        if (role_ == SSL_CLIENT) {
919831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = DTLSv1_client_method();
920831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        } else {
921831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = DTLSv1_server_method();
922831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        }
923831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      } else {
924831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        if (role_ == SSL_CLIENT) {
925831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = TLSv1_client_method();
926831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        } else {
927831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = TLSv1_server_method();
928831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        }
929831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      }
930831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      break;
931831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    case SSL_PROTOCOL_TLS_12:
932831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    default:
933831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      if (ssl_mode_ == SSL_MODE_DTLS) {
934831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#if (OPENSSL_VERSION_NUMBER >= 0x10002000L)
935831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        // DTLS 1.2 only available starting from OpenSSL 1.0.2
936831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        if (role_ == SSL_CLIENT) {
937831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = DTLS_client_method();
938831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        } else {
939831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = DTLS_server_method();
940831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        }
941831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#else
942831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        if (role_ == SSL_CLIENT) {
943831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = DTLSv1_client_method();
944831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        } else {
945831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = DTLSv1_server_method();
946831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        }
947831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#endif
948831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      } else {
949831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
950831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        // New API only available starting from OpenSSL 1.1.0
951831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        if (role_ == SSL_CLIENT) {
952831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = TLS_client_method();
953831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        } else {
954831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = TLS_server_method();
955831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        }
956831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#else
957831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        if (role_ == SSL_CLIENT) {
958831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = SSLv23_client_method();
959831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        } else {
960831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = SSLv23_server_method();
961831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        }
962831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#endif
963831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      }
964831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      break;
965f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
966831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  ctx = SSL_CTX_new(method);
967831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#endif  // OPENSSL_IS_BORINGSSL
968831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch
969f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (ctx == NULL)
970f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return NULL;
971f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
972831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#ifdef OPENSSL_IS_BORINGSSL
973831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  SSL_CTX_set_min_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
974831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      DTLS1_VERSION : TLS1_VERSION);
975831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  switch (ssl_max_version_) {
976831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    case SSL_PROTOCOL_TLS_10:
977831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      SSL_CTX_set_max_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
978831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          DTLS1_VERSION : TLS1_VERSION);
979831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      break;
980831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    case SSL_PROTOCOL_TLS_11:
981831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      SSL_CTX_set_max_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
982831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          DTLS1_VERSION : TLS1_1_VERSION);
983831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      break;
984831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    case SSL_PROTOCOL_TLS_12:
985831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    default:
986831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      SSL_CTX_set_max_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
987831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          DTLS1_2_VERSION : TLS1_2_VERSION);
988831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      break;
989831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  }
990831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#endif
991831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch
992f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (identity_ && !identity_->ConfigureIdentity(ctx)) {
993f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    SSL_CTX_free(ctx);
994f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return NULL;
995f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
996f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
997f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef _DEBUG
998f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL_CTX_set_info_callback(ctx, OpenSSLAdapter::SSLInfoCallback);
999f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
1000f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1001c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org  int mode = SSL_VERIFY_PEER;
1002c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org  if (client_auth_enabled()) {
1003c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org    // Require a certificate from the client.
1004c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org    // Note: Normally this is always true in production, but it may be disabled
1005c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org    // for testing purposes (e.g. SSLAdapter unit tests).
1006c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org    mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1007c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org  }
1008c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org
1009c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org  SSL_CTX_set_verify(ctx, mode, SSLVerifyCallback);
1010f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL_CTX_set_verify_depth(ctx, 4);
1011831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  // Select list of available ciphers. Note that !SHA256 and !SHA384 only
1012831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  // remove HMAC-SHA256 and HMAC-SHA384 cipher suites, not GCM cipher suites
1013831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  // with SHA256 or SHA384 as the handshake hash.
1014831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  // This matches the list of SSLClientSocketOpenSSL in Chromium.
1015831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  SSL_CTX_set_cipher_list(ctx,
1016831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      "DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK");
1017f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1018f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef HAVE_DTLS_SRTP
1019f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!srtp_ciphers_.empty()) {
1020f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) {
1021f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      SSL_CTX_free(ctx);
1022f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return NULL;
1023f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
1024f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
1025f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
1026f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1027f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return ctx;
1028f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
1029f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1030f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint OpenSSLStreamAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
1031f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Get our SSL structure from the store
1032f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(
1033f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                        store,
1034f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                        SSL_get_ex_data_X509_STORE_CTX_idx()));
1035f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  OpenSSLStreamAdapter* stream =
1036f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));
1037f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1038f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (stream->peer_certificate_digest_algorithm_.empty()) {
1039f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return 0;
1040f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
1041f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  X509* cert = X509_STORE_CTX_get_current_cert(store);
10424e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  int depth = X509_STORE_CTX_get_error_depth(store);
10434e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org
10444e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  // For now We ignore the parent certificates and verify the leaf against
10454e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  // the digest.
10464e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  //
10474e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  // TODO(jiayl): Verify the chain is a proper chain and report the chain to
104807d09364b003e6738a02d9940aebab5d3814da6dtorbjorng  // |stream->peer_certificate_|.
10494e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  if (depth > 0) {
10504e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org    LOG(LS_INFO) << "Ignored chained certificate at depth " << depth;
10514e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org    return 1;
10524e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  }
10534e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org
1054f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  unsigned char digest[EVP_MAX_MD_SIZE];
1055f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  size_t digest_length;
1056f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!OpenSSLCertificate::ComputeDigest(
1057f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org           cert,
1058f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org           stream->peer_certificate_digest_algorithm_,
1059f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org           digest, sizeof(digest),
1060f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org           &digest_length)) {
1061f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_WARNING) << "Failed to compute peer cert digest.";
1062f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return 0;
1063f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
10644e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org
1065f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Buffer computed_digest(digest, digest_length);
1066f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (computed_digest != stream->peer_certificate_digest_value_) {
1067f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_WARNING) << "Rejected peer certificate due to mismatched digest.";
1068f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return 0;
1069f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
1070f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Ignore any verification error if the digest matches, since there is no
1071f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // value in checking the validity of a self-signed cert issued by untrusted
1072f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // sources.
1073f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_INFO) << "Accepted peer certificate.";
10744e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org
1075f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Record the peer's certificate.
1076f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream->peer_certificate_.reset(new OpenSSLCertificate(cert));
1077f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return 1;
1078f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
1079f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1080f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// This code is taken from the "Network Security with OpenSSL"
1081f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// sample in chapter 5
1082f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::SSLPostConnectionCheck(SSL* ssl,
1083f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                  const char* server_name,
1084f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                  const X509* peer_cert,
1085f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                  const std::string
1086f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                  &peer_digest) {
1087f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(server_name != NULL);
1088f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bool ok;
1089f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (server_name[0] != '\0') {  // traditional mode
1090f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ok = OpenSSLAdapter::VerifyServerName(ssl, server_name, ignore_bad_cert());
1091f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1092f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (ok) {
1093f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
1094f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org            custom_verification_succeeded_);
1095f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
1096f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  } else {  // peer-to-peer mode
1097f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT((peer_cert != NULL) || (!peer_digest.empty()));
1098f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // no server name validation
1099f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ok = true;
1100f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
1101f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1102f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!ok && ignore_bad_cert()) {
1103f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_ERROR) << "SSL_get_verify_result(ssl) = "
1104f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                  << SSL_get_verify_result(ssl);
1105f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_INFO) << "Other TLS post connection checks failed.";
1106f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ok = true;
1107f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
1108f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1109f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return ok;
1110f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
1111f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1112f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::HaveDtls() {
1113f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
1114f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
1115f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1116f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::HaveDtlsSrtp() {
1117f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef HAVE_DTLS_SRTP
1118f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
1119f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else
1120f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return false;
1121f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
1122f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
1123f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1124f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::HaveExporter() {
1125f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef HAVE_DTLS_SRTP
1126f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
1127f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else
1128f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return false;
1129f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
1130f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
1131f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
11326caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehint OpenSSLStreamAdapter::GetDefaultSslCipherForTest(SSLProtocolVersion version,
11336caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shieh                                                     KeyType key_type) {
1134b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund  if (key_type == KT_RSA) {
1135b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund    switch (version) {
1136b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      case SSL_PROTOCOL_TLS_10:
1137b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      case SSL_PROTOCOL_TLS_11:
1138b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        return kDefaultSslCipher10;
1139b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      case SSL_PROTOCOL_TLS_12:
1140b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      default:
1141831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#ifdef OPENSSL_IS_BORINGSSL
1142b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        if (EVP_has_aes_hardware()) {
1143b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund          return kDefaultSslCipher12;
1144b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        } else {
1145b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund          return kDefaultSslCipher12NoAesGcm;
1146b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        }
1147b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund#else  // !OPENSSL_IS_BORINGSSL
1148831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        return kDefaultSslCipher12;
1149b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund#endif
1150b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund    }
1151b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund  } else if (key_type == KT_ECDSA) {
1152b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund    switch (version) {
1153b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      case SSL_PROTOCOL_TLS_10:
1154b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      case SSL_PROTOCOL_TLS_11:
1155b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        return kDefaultSslEcCipher10;
1156b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      case SSL_PROTOCOL_TLS_12:
1157b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      default:
1158b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund#ifdef OPENSSL_IS_BORINGSSL
1159b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        if (EVP_has_aes_hardware()) {
1160b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund          return kDefaultSslEcCipher12;
1161b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        } else {
1162b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund          return kDefaultSslEcCipher12NoAesGcm;
1163b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        }
1164831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#else  // !OPENSSL_IS_BORINGSSL
1165b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        return kDefaultSslEcCipher12;
1166831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#endif
1167b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund    }
1168b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund  } else {
1169456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    RTC_NOTREACHED();
1170456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    return kDefaultSslEcCipher12;
1171831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  }
11723ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org}
11733ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
1174f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}  // namespace rtc
1175f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1176f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif  // HAVE_OPENSSL_SSL_H
1177