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
46521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh// SRTP cipher suite table. |internal_name| is used to construct a
47521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh// colon-separated profile strings which is needed by
48521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh// SSL_CTX_set_tlsext_use_srtp().
49f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstruct SrtpCipherMapEntry {
50f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  const char* internal_name;
51521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh  const int id;
52f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
53f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
54f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// This isn't elegant, but it's better than an external reference
55f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic SrtpCipherMapEntry SrtpCipherMap[] = {
56521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh    {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80},
57521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh    {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32},
58521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh    {nullptr, 0}};
59f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
60f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
61f7bb6e723bea160b11060c16d8a57f97eb57bb90pthatcher@webrtc.org#ifndef OPENSSL_IS_BORINGSSL
62456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh
633ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// Cipher name table. Maps internal OpenSSL cipher ids to the RFC name.
643ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.orgstruct SslCipherMapEntry {
653ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  uint32_t openssl_id;
663ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  const char* rfc_name;
673ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org};
683ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
693ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org#define DEFINE_CIPHER_ENTRY_SSL3(name)  {SSL3_CK_##name, "TLS_"#name}
703ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org#define DEFINE_CIPHER_ENTRY_TLS1(name)  {TLS1_CK_##name, "TLS_"#name}
713ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
723ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// There currently is no method available to get a RFC-compliant name for a
733ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// cipher suite from BoringSSL, so we need to define the mapping manually here.
743ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// This should go away once BoringSSL supports "SSL_CIPHER_standard_name"
753ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// (as available in OpenSSL if compiled with tracing enabled) or a similar
763ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// method.
773ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.orgstatic const SslCipherMapEntry kSslCipherMap[] = {
783ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // TLS v1.0 ciphersuites from RFC2246.
793ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_SSL3(RSA_RC4_128_SHA),
803ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {SSL3_CK_RSA_DES_192_CBC3_SHA,
813ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
823ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
833ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // AES ciphersuites from RFC3268.
843ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_RSA_WITH_AES_128_SHA,
853ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_RSA_WITH_AES_128_CBC_SHA"},
863ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
873ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"},
883ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_RSA_WITH_AES_256_SHA,
893ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_RSA_WITH_AES_256_CBC_SHA"},
903ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
913ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
923ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
933ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // ECC ciphersuites from RFC4492.
943ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_RC4_128_SHA),
953ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
963ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"},
973ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_128_CBC_SHA),
983ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_256_CBC_SHA),
993ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
1003ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_RC4_128_SHA),
1013ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
1023ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"},
1033ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_128_CBC_SHA),
1043ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_256_CBC_SHA),
1053ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
1063ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // TLS v1.2 ciphersuites.
1073ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_RSA_WITH_AES_128_SHA256,
1083ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_RSA_WITH_AES_128_CBC_SHA256"},
1093ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_RSA_WITH_AES_256_SHA256,
1103ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_RSA_WITH_AES_256_CBC_SHA256"},
1113ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
1123ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"},
1133ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
1143ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
1153ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
1163ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // TLS v1.2 GCM ciphersuites from RFC5288.
1173ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(RSA_WITH_AES_128_GCM_SHA256),
1183ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(RSA_WITH_AES_256_GCM_SHA384),
1193ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(DHE_RSA_WITH_AES_128_GCM_SHA256),
1203ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(DHE_RSA_WITH_AES_256_GCM_SHA384),
1213ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(DH_RSA_WITH_AES_128_GCM_SHA256),
1223ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(DH_RSA_WITH_AES_256_GCM_SHA384),
1233ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
1243ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // ECDH HMAC based ciphersuites from RFC5289.
1253ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256,
1263ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"},
1273ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384,
1283ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"},
1293ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
1303ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
1313ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
1323ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
1333ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
1343ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  // ECDH GCM based ciphersuites from RFC5289.
1353ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_128_GCM_SHA256),
1363ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_256_GCM_SHA384),
1373ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_128_GCM_SHA256),
1383ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_256_GCM_SHA384),
1393ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
1403ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  {0, NULL}
1413ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org};
142f7bb6e723bea160b11060c16d8a57f97eb57bb90pthatcher@webrtc.org#endif  // #ifndef OPENSSL_IS_BORINGSSL
1433ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
144456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#if defined(_MSC_VER)
145456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#pragma warning(push)
146456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#pragma warning(disable : 4309)
147456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#pragma warning(disable : 4310)
148456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#endif  // defined(_MSC_VER)
149456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh
1503ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// Default cipher used between OpenSSL/BoringSSL stream adapters.
1513ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org// This needs to be updated when the default of the SSL library changes.
152456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh// static_cast<uint16_t> causes build warnings on windows platform.
1536caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslCipher10 =
154456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA);
1556caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslEcCipher10 =
156456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
157831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#ifdef OPENSSL_IS_BORINGSSL
1586caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslCipher12 =
159456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256);
1606caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslEcCipher12 =
161456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256);
162831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch// Fallback cipher for DTLS 1.2 if hardware-accelerated AES-GCM is unavailable.
1633542013f587f0858fb24fa8e554ec3c01a323da8sprang// TODO(davidben): Switch to the standardized CHACHA20_POLY1305 variant when
1643542013f587f0858fb24fa8e554ec3c01a323da8sprang// available.
1656caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslCipher12NoAesGcm =
1663542013f587f0858fb24fa8e554ec3c01a323da8sprang    static_cast<uint16_t>(TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305_OLD);
1676caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslEcCipher12NoAesGcm =
1683542013f587f0858fb24fa8e554ec3c01a323da8sprang    static_cast<uint16_t>(TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305_OLD);
169831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#else  // !OPENSSL_IS_BORINGSSL
170831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch// OpenSSL sorts differently than BoringSSL, so the default cipher doesn't
171831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch// change between TLS 1.0 and TLS 1.2 with the current setup.
1726caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslCipher12 =
173456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA);
1746caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehstatic int kDefaultSslEcCipher12 =
175456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    static_cast<uint16_t>(TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA);
1763542013f587f0858fb24fa8e554ec3c01a323da8sprang#endif
1773ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
178456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#if defined(_MSC_VER)
179456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#pragma warning(pop)
180456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#endif  // defined(_MSC_VER)
181456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh
182f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//////////////////////////////////////////////////////////////////////
183f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// StreamBIO
184f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//////////////////////////////////////////////////////////////////////
185f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
186f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_write(BIO* h, const char* buf, int num);
187f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_read(BIO* h, char* buf, int size);
188f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_puts(BIO* h, const char* str);
189f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic long stream_ctrl(BIO* h, int cmd, long arg1, void* arg2);
190f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_new(BIO* h);
191f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_free(BIO* data);
192f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
19336d5c3cb447901ffff6a02a438e1d422cb806147davidben@webrtc.org// TODO(davidben): This should be const once BoringSSL is assumed.
19436d5c3cb447901ffff6a02a438e1d422cb806147davidben@webrtc.orgstatic BIO_METHOD methods_stream = {
195f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  BIO_TYPE_BIO,
196f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  "stream",
197f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream_write,
198f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream_read,
199f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream_puts,
200f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  0,
201f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream_ctrl,
202f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream_new,
203f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream_free,
204f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  NULL,
205f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
206f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
20736d5c3cb447901ffff6a02a438e1d422cb806147davidben@webrtc.orgstatic BIO_METHOD* BIO_s_stream() { return(&methods_stream); }
208f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
209f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic BIO* BIO_new_stream(StreamInterface* stream) {
210f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  BIO* ret = BIO_new(BIO_s_stream());
211f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (ret == NULL)
212f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return NULL;
213f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ret->ptr = stream;
214f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return ret;
215f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
216f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
217f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// bio methods return 1 (or at least non-zero) on success and 0 on failure.
218f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
219f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_new(BIO* b) {
220f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  b->shutdown = 0;
221f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  b->init = 1;
222f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  b->num = 0;  // 1 means end-of-stream
223f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  b->ptr = 0;
224f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return 1;
225f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
226f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
227f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_free(BIO* b) {
228f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (b == NULL)
229f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return 0;
230f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return 1;
231f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
232f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
233f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_read(BIO* b, char* out, int outl) {
234f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!out)
235f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return -1;
236f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
237f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  BIO_clear_retry_flags(b);
238f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  size_t read;
239f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int error;
240f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  StreamResult result = stream->Read(out, outl, &read, &error);
241f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (result == SR_SUCCESS) {
242d89b69aadeb9db67b7cc2de3300109d866c2a937henrike@webrtc.org    return checked_cast<int>(read);
243f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  } else if (result == SR_EOS) {
244f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    b->num = 1;
245f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  } else if (result == SR_BLOCK) {
246f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    BIO_set_retry_read(b);
247f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
248f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return -1;
249f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
250f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
251f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_write(BIO* b, const char* in, int inl) {
252f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!in)
253f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return -1;
254f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
255f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  BIO_clear_retry_flags(b);
256f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  size_t written;
257f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int error;
258f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  StreamResult result = stream->Write(in, inl, &written, &error);
259f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (result == SR_SUCCESS) {
260d89b69aadeb9db67b7cc2de3300109d866c2a937henrike@webrtc.org    return checked_cast<int>(written);
261f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  } else if (result == SR_BLOCK) {
262f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    BIO_set_retry_write(b);
263f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
264f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return -1;
265f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
266f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
267f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic int stream_puts(BIO* b, const char* str) {
268d89b69aadeb9db67b7cc2de3300109d866c2a937henrike@webrtc.org  return stream_write(b, str, checked_cast<int>(strlen(str)));
269f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
270f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
271f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstatic long stream_ctrl(BIO* b, int cmd, long num, void* ptr) {
27214abcc73227223def23a3eb06b47285c3a55a5b5henrike@webrtc.org  RTC_UNUSED(num);
27314abcc73227223def23a3eb06b47285c3a55a5b5henrike@webrtc.org  RTC_UNUSED(ptr);
274f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
275f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (cmd) {
276f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case BIO_CTRL_RESET:
277f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return 0;
278f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case BIO_CTRL_EOF:
279f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return b->num;
280f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case BIO_CTRL_WPENDING:
281f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case BIO_CTRL_PENDING:
282f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return 0;
283f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case BIO_CTRL_FLUSH:
284f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return 1;
285f4baca50bb98e1eeefea621365fac08cae2fe303Henrik Lundin    case BIO_CTRL_DGRAM_QUERY_MTU:
286f4baca50bb98e1eeefea621365fac08cae2fe303Henrik Lundin      // openssl defaults to mtu=256 unless we return something here.
287f4baca50bb98e1eeefea621365fac08cae2fe303Henrik Lundin      // The handshake doesn't actually need to send packets above 1k,
288f4baca50bb98e1eeefea621365fac08cae2fe303Henrik Lundin      // so this seems like a sensible value that should work in most cases.
289f4baca50bb98e1eeefea621365fac08cae2fe303Henrik Lundin      // Webrtc uses the same value for video packets.
290f4baca50bb98e1eeefea621365fac08cae2fe303Henrik Lundin      return 1200;
291f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    default:
292f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return 0;
293f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
294f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
295f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
296f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////
297f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// OpenSSLStreamAdapter
298f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/////////////////////////////////////////////////////////////////////////////
299f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
300f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgOpenSSLStreamAdapter::OpenSSLStreamAdapter(StreamInterface* stream)
301f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    : SSLStreamAdapter(stream),
302f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      state_(SSL_NONE),
303f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      role_(SSL_CLIENT),
304a7446d2a50167602b04f58c917f5075ad5e494dcGuo-wei Shieh      ssl_read_needs_write_(false),
305a7446d2a50167602b04f58c917f5075ad5e494dcGuo-wei Shieh      ssl_write_needs_read_(false),
306a7446d2a50167602b04f58c917f5075ad5e494dcGuo-wei Shieh      ssl_(NULL),
307a7446d2a50167602b04f58c917f5075ad5e494dcGuo-wei Shieh      ssl_ctx_(NULL),
308f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      custom_verification_succeeded_(false),
309831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      ssl_mode_(SSL_MODE_TLS),
310a7446d2a50167602b04f58c917f5075ad5e494dcGuo-wei Shieh      ssl_max_version_(SSL_PROTOCOL_TLS_12) {}
311f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
312f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgOpenSSLStreamAdapter::~OpenSSLStreamAdapter() {
313f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Cleanup();
314f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
315f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
316f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::SetIdentity(SSLIdentity* identity) {
317f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(!identity_);
318f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  identity_.reset(static_cast<OpenSSLIdentity*>(identity));
319f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
320f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
321f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::SetServerRole(SSLRole role) {
322f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  role_ = role;
323f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
324f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
325f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::GetPeerCertificate(SSLCertificate** cert) const {
326f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!peer_certificate_)
327f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
328f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
329f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  *cert = peer_certificate_->GetReference();
330f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
331f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
332f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
333f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string
334f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                    &digest_alg,
335f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                    const unsigned char*
336f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                    digest_val,
337f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                    size_t digest_len) {
338f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(!peer_certificate_);
339f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(peer_certificate_digest_algorithm_.size() == 0);
340f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(ssl_server_name_.empty());
341f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  size_t expected_len;
342f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
343f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!OpenSSLDigest::GetDigestSize(digest_alg, &expected_len)) {
344f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg;
345f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
346f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
347f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (expected_len != digest_len)
348f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
349f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
350f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  peer_certificate_digest_value_.SetData(digest_val, digest_len);
351f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  peer_certificate_digest_algorithm_ = digest_alg;
352f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
353f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
354f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
355f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
356521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shiehstd::string OpenSSLStreamAdapter::SslCipherSuiteToName(int cipher_suite) {
357456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#ifdef OPENSSL_IS_BORINGSSL
358521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh  const SSL_CIPHER* ssl_cipher = SSL_get_cipher_by_value(cipher_suite);
359456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  if (!ssl_cipher) {
360456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    return std::string();
361456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  }
362456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  char* cipher_name = SSL_CIPHER_get_rfc_name(ssl_cipher);
363456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  std::string rfc_name = std::string(cipher_name);
364456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  OPENSSL_free(cipher_name);
365456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  return rfc_name;
366456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh#else
3673ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  for (const SslCipherMapEntry* entry = kSslCipherMap; entry->rfc_name;
3683ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org       ++entry) {
369efb047d2dd57ad4fc2b2543dd294e73cc3670713guoweis    if (cipher_suite == static_cast<int>(entry->openssl_id)) {
3703ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org      return entry->rfc_name;
3713ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org    }
3723ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  }
373456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh  return std::string();
37427dc29b0df23eed5034f28d4d5f66ea0bb425d6cguoweis#endif
375456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh}
3763ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
377521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shiehbool OpenSSLStreamAdapter::GetSslCipherSuite(int* cipher_suite) {
3783ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  if (state_ != SSL_CONNECTED)
3793ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org    return false;
3803ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
3813ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  const SSL_CIPHER* current_cipher = SSL_get_current_cipher(ssl_);
3823ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  if (current_cipher == NULL) {
3833ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org    return false;
3843ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  }
3853ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
386521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh  *cipher_suite = static_cast<uint16_t>(SSL_CIPHER_get_id(current_cipher));
3873ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org  return true;
3883ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org}
3893ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
390f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Key Extractor interface
391f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
3920c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                                const uint8_t* context,
393f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                size_t context_len,
394f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                bool use_context,
3950c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                                uint8_t* result,
396f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                size_t result_len) {
397f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef HAVE_DTLS_SRTP
398f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int i;
399f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
4000c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  i = SSL_export_keying_material(ssl_, result, result_len, label.c_str(),
4010c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                 label.length(), const_cast<uint8_t*>(context),
402f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                 context_len, use_context);
403f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
404f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (i != 1)
405f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
406f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
407f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
408f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else
409f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return false;
410f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
411f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
412f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
413521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shiehbool OpenSSLStreamAdapter::SetDtlsSrtpCryptoSuites(
414521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh    const std::vector<int>& ciphers) {
415f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef HAVE_DTLS_SRTP
416f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  std::string internal_ciphers;
417f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
418f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (state_ != SSL_NONE)
419f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
420f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
421521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh  for (std::vector<int>::const_iterator cipher = ciphers.begin();
422f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org       cipher != ciphers.end(); ++cipher) {
423f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    bool found = false;
424521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh    for (SrtpCipherMapEntry* entry = SrtpCipherMap; entry->internal_name;
425f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org         ++entry) {
426521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh      if (*cipher == entry->id) {
427f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        found = true;
428f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        if (!internal_ciphers.empty())
429f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          internal_ciphers += ":";
430f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        internal_ciphers += entry->internal_name;
431f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        break;
432f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
433f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
434f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
435f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (!found) {
436f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_ERROR) << "Could not find cipher: " << *cipher;
437f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return false;
438f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
439f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
440f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
441f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (internal_ciphers.empty())
442f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
443f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
444f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  srtp_ciphers_ = internal_ciphers;
445f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
446f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else
447f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return false;
448f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
449f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
450f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
451521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shiehbool OpenSSLStreamAdapter::GetDtlsSrtpCryptoSuite(int* crypto_suite) {
452f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef HAVE_DTLS_SRTP
453f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(state_ == SSL_CONNECTED);
454f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (state_ != SSL_CONNECTED)
455f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
456f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
457c10eceab6ec2f6508979a4dc06049821a168e236henrike@webrtc.org  const SRTP_PROTECTION_PROFILE *srtp_profile =
458f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      SSL_get_selected_srtp_profile(ssl_);
459f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
460f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!srtp_profile)
461f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
462f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
463521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh  *crypto_suite = srtp_profile->id;
464521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh  ASSERT(!SrtpCryptoSuiteToName(*crypto_suite).empty());
465521ed7bf022c4e30574d7970c2be5be46567f4cdGuo-wei Shieh  return true;
466f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else
467f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return false;
468f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
469f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
470f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
471f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) {
472f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(server_name != NULL && server_name[0] != '\0');
473f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_server_name_ = server_name;
474f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return StartSSL();
475f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
476f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
477f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint OpenSSLStreamAdapter::StartSSLWithPeer() {
478f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(ssl_server_name_.empty());
479f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // It is permitted to specify peer_certificate_ only later.
480f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return StartSSL();
481f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
482f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
483f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::SetMode(SSLMode mode) {
484f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(state_ == SSL_NONE);
485f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_mode_ = mode;
486f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
487f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
488831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauchvoid OpenSSLStreamAdapter::SetMaxProtocolVersion(SSLProtocolVersion version) {
489831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  ASSERT(ssl_ctx_ == NULL);
490831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  ssl_max_version_ = version;
491831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch}
492831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch
493f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
494f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// StreamInterface Implementation
495f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org//
496f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
497f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgStreamResult OpenSSLStreamAdapter::Write(const void* data, size_t data_len,
498f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                         size_t* written, int* error) {
499f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Write(" << data_len << ")";
500f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
501f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (state_) {
502f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_NONE:
503f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // pass-through in clear text
504f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return StreamAdapterInterface::Write(data, data_len, written, error);
505f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
506f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_WAIT:
507f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_CONNECTING:
508f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_BLOCK;
509f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
510f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_CONNECTED:
511f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    break;
512f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
513f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_ERROR:
514f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_CLOSED:
515f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  default:
516f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (error)
517f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      *error = ssl_error_code_;
518f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_ERROR;
519f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
520f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
521f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // OpenSSL will return an error if we try to write zero bytes
522f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (data_len == 0) {
523f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (written)
524f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      *written = 0;
525f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_SUCCESS;
526f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
527f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
528f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_write_needs_read_ = false;
529f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
530d89b69aadeb9db67b7cc2de3300109d866c2a937henrike@webrtc.org  int code = SSL_write(ssl_, data, checked_cast<int>(data_len));
531f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int ssl_error = SSL_get_error(ssl_, code);
532f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (ssl_error) {
533f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_ERROR_NONE:
534f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << " -- success";
535f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
536f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (written)
537f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      *written = code;
538f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_SUCCESS;
539f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_ERROR_WANT_READ:
540f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << " -- error want read";
541f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ssl_write_needs_read_ = true;
542f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_BLOCK;
543f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_ERROR_WANT_WRITE:
544f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << " -- error want write";
545f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_BLOCK;
546f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
547f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  case SSL_ERROR_ZERO_RETURN:
548f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  default:
549f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    Error("SSL_write", (ssl_error ? ssl_error : -1), false);
550f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (error)
551f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      *error = ssl_error_code_;
552f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_ERROR;
553f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
554f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // not reached
555f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
556f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
557f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgStreamResult OpenSSLStreamAdapter::Read(void* data, size_t data_len,
558f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                        size_t* read, int* error) {
559f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Read(" << data_len << ")";
560f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (state_) {
561f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_NONE:
562f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      // pass-through in clear text
563f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return StreamAdapterInterface::Read(data, data_len, read, error);
564f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
565f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_WAIT:
566f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_CONNECTING:
567f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_BLOCK;
568f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
569f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_CONNECTED:
570f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      break;
571f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
572f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_CLOSED:
573f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_EOS;
574f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
575f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR:
576f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    default:
577f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (error)
578f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        *error = ssl_error_code_;
579f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_ERROR;
580f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
581f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
582f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Don't trust OpenSSL with zero byte reads
583f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (data_len == 0) {
584f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (read)
585f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      *read = 0;
586f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SR_SUCCESS;
587f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
588f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
589f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_read_needs_write_ = false;
590f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
591d89b69aadeb9db67b7cc2de3300109d866c2a937henrike@webrtc.org  int code = SSL_read(ssl_, data, checked_cast<int>(data_len));
592f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int ssl_error = SSL_get_error(ssl_, code);
593f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (ssl_error) {
594f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_NONE:
595f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- success";
596f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
597f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (read)
598f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        *read = code;
599f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
600f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (ssl_mode_ == SSL_MODE_DTLS) {
601f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        // Enforce atomic reads -- this is a short read
602f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        unsigned int pending = SSL_pending(ssl_);
603f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
604f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        if (pending) {
605f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          LOG(LS_INFO) << " -- short DTLS read. flushing";
606f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          FlushInput(pending);
607f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          if (error)
608f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org            *error = SSE_MSG_TRUNC;
609f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          return SR_ERROR;
610f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        }
611f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
612f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_SUCCESS;
613f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_WANT_READ:
614f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- error want read";
615f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_BLOCK;
616f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_WANT_WRITE:
617f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- error want write";
618f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ssl_read_needs_write_ = true;
619f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_BLOCK;
620f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_ZERO_RETURN:
621f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- remote side closed";
622f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_EOS;
623f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      break;
624f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    default:
625f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- error " << code;
626f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      Error("SSL_read", (ssl_error ? ssl_error : -1), false);
627f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (error)
628f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        *error = ssl_error_code_;
629f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SR_ERROR;
630f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
631f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // not reached
632f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
633f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
634f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::FlushInput(unsigned int left) {
635f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  unsigned char buf[2048];
636f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
637f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  while (left) {
638f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // This should always succeed
639f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    int toread = (sizeof(buf) < left) ? sizeof(buf) : left;
640f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    int code = SSL_read(ssl_, buf, toread);
641f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
642f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    int ssl_error = SSL_get_error(ssl_, code);
643f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(ssl_error == SSL_ERROR_NONE);
644f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
645f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (ssl_error != SSL_ERROR_NONE) {
646f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- error " << code;
647f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      Error("SSL_read", (ssl_error ? ssl_error : -1), false);
648f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return;
649f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
650f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
651f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << " -- flushed " << code << " bytes";
652f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    left -= code;
653f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
654f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
655f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
656f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::Close() {
657f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Cleanup();
658f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR);
659f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  StreamAdapterInterface::Close();
660f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
661f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
662f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgStreamState OpenSSLStreamAdapter::GetState() const {
663f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (state_) {
664f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_WAIT:
665f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_CONNECTING:
666f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SS_OPENING;
667f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_CONNECTED:
668f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SS_OPEN;
669f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    default:
670f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return SS_CLOSED;
671f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  };
672f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // not reached
673f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
674f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
675f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, int events,
676f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                   int err) {
677f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int events_to_signal = 0;
678f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int signal_error = 0;
679f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(stream == this->stream());
680f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if ((events & SE_OPEN)) {
681f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent SE_OPEN";
682f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (state_ != SSL_WAIT) {
683f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ASSERT(state_ == SSL_NONE);
684f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      events_to_signal |= SE_OPEN;
685f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    } else {
686f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      state_ = SSL_CONNECTING;
687f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (int err = BeginSSL()) {
688f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        Error("BeginSSL", err, true);
689f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        return;
690f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
691f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
692f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
693f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if ((events & (SE_READ|SE_WRITE))) {
694f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent"
695f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                 << ((events & SE_READ) ? " SE_READ" : "")
696f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                 << ((events & SE_WRITE) ? " SE_WRITE" : "");
697f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (state_ == SSL_NONE) {
698f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      events_to_signal |= events & (SE_READ|SE_WRITE);
699f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    } else if (state_ == SSL_CONNECTING) {
700f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (int err = ContinueSSL()) {
701f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        Error("ContinueSSL", err, true);
702f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        return;
703f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
704f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    } else if (state_ == SSL_CONNECTED) {
705f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (((events & SE_READ) && ssl_write_needs_read_) ||
706f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          (events & SE_WRITE)) {
707f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        LOG(LS_VERBOSE) << " -- onStreamWriteable";
708f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        events_to_signal |= SE_WRITE;
709f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
710f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (((events & SE_WRITE) && ssl_read_needs_write_) ||
711f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          (events & SE_READ)) {
712f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        LOG(LS_VERBOSE) << " -- onStreamReadable";
713f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        events_to_signal |= SE_READ;
714f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
715f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
716f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
717f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if ((events & SE_CLOSE)) {
718f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err << ")";
719f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    Cleanup();
720f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    events_to_signal |= SE_CLOSE;
721f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // SE_CLOSE is the only event that uses the final parameter to OnEvent().
722f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(signal_error == 0);
723f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    signal_error = err;
724f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
725f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (events_to_signal)
726f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error);
727f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
728f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
729f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint OpenSSLStreamAdapter::StartSSL() {
730f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(state_ == SSL_NONE);
731f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
732f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (StreamAdapterInterface::GetState() != SS_OPEN) {
733f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    state_ = SSL_WAIT;
734f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return 0;
735f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
736f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
737f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  state_ = SSL_CONNECTING;
738f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (int err = BeginSSL()) {
739f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    Error("BeginSSL", err, false);
740f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return err;
741f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
742f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
743f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return 0;
744f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
745f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
746f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint OpenSSLStreamAdapter::BeginSSL() {
747f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(state_ == SSL_CONNECTING);
748f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // The underlying stream has open. If we are in peer-to-peer mode
749f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // then a peer certificate must have been specified by now.
750f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(!ssl_server_name_.empty() ||
751f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org         !peer_certificate_digest_algorithm_.empty());
752f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_INFO) << "BeginSSL: "
753f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org               << (!ssl_server_name_.empty() ? ssl_server_name_ :
754f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                               "with peer");
755f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
756f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  BIO* bio = NULL;
757f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
758f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // First set up the context
759f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(ssl_ctx_ == NULL);
760f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_ctx_ = SetupSSLContext();
761f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!ssl_ctx_)
762f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return -1;
763f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
764f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bio = BIO_new_stream(static_cast<StreamInterface*>(stream()));
765f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!bio)
766f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return -1;
767f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
768f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_ = SSL_new(ssl_ctx_);
769f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!ssl_) {
770f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    BIO_free(bio);
771f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return -1;
772f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
773f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
774f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL_set_app_data(ssl_, this);
775f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
776f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL_set_bio(ssl_, bio, bio);  // the SSL object owns the bio now.
777a398020cba1279e4393fa25cf22a6260aa669766Joachim Bauch#ifndef OPENSSL_IS_BORINGSSL
7785ca688b3da35ea2a8da6e915c503b12d4d814bb2Joachim Bauch  if (ssl_mode_ == SSL_MODE_DTLS) {
7795ca688b3da35ea2a8da6e915c503b12d4d814bb2Joachim Bauch    // Enable read-ahead for DTLS so whole packets are read from internal BIO
780a398020cba1279e4393fa25cf22a6260aa669766Joachim Bauch    // before parsing. This is done internally by BoringSSL for DTLS.
7815ca688b3da35ea2a8da6e915c503b12d4d814bb2Joachim Bauch    SSL_set_read_ahead(ssl_, 1);
7825ca688b3da35ea2a8da6e915c503b12d4d814bb2Joachim Bauch  }
783a398020cba1279e4393fa25cf22a6260aa669766Joachim Bauch#endif
784f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
785f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
786f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org               SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
787f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
78811c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  // Specify an ECDH group for ECDHE ciphers, otherwise they cannot be
78911c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  // negotiated when acting as the server. Use NIST's P-256 which is commonly
79011c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  // supported.
79111c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
79211c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  if (ecdh == NULL)
79311c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org    return -1;
79411c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  SSL_set_options(ssl_, SSL_OP_SINGLE_ECDH_USE);
79511c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  SSL_set_tmp_ecdh(ssl_, ecdh);
79611c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org  EC_KEY_free(ecdh);
79711c6bde4741917aa3ec1615192ad8899b5a9542ejiayl@webrtc.org
798f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Do the connect
799f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return ContinueSSL();
800f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
801f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
802f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint OpenSSLStreamAdapter::ContinueSSL() {
803f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_VERBOSE) << "ContinueSSL";
804f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(state_ == SSL_CONNECTING);
805f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
806f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Clear the DTLS timer
807f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Thread::Current()->Clear(this, MSG_TIMEOUT);
808f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
809f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_);
810f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int ssl_error;
811f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  switch (ssl_error = SSL_get_error(ssl_, code)) {
812f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_NONE:
813f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- success";
814f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
815f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (!SSLPostConnectionCheck(ssl_, ssl_server_name_.c_str(), NULL,
816f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                  peer_certificate_digest_algorithm_)) {
817f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        LOG(LS_ERROR) << "TLS post connection check failed";
818f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        return -1;
819f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
820f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
821f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      state_ = SSL_CONNECTED;
822f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0);
823f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      break;
824f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
825f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_WANT_READ: {
826f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        LOG(LS_VERBOSE) << " -- error want read";
827f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        struct timeval timeout;
828f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        if (DTLSv1_get_timeout(ssl_, &timeout)) {
829f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000;
830f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
831f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          Thread::Current()->PostDelayed(delay, this, MSG_TIMEOUT, 0);
832f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        }
833f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
834f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      break;
835f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
836f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_WANT_WRITE:
837f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- error want write";
838f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      break;
839f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
840f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    case SSL_ERROR_ZERO_RETURN:
841f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    default:
842f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      LOG(LS_VERBOSE) << " -- error " << code;
843f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return (ssl_error != 0) ? ssl_error : -1;
844f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
845f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
846f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return 0;
847f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
848f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
849f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::Error(const char* context, int err, bool signal) {
850f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_WARNING) << "OpenSSLStreamAdapter::Error("
851f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                  << context << ", " << err << ")";
852f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  state_ = SSL_ERROR;
853f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ssl_error_code_ = err;
854f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Cleanup();
855f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (signal)
856f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err);
857f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
858f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
859f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::Cleanup() {
860f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_INFO) << "Cleanup";
861f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
862f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (state_ != SSL_ERROR) {
863f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    state_ = SSL_CLOSED;
864f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ssl_error_code_ = 0;
865f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
866f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
867f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (ssl_) {
868f1d751c7dede158bc9770e4d7c4cb07191ffdf3fjiayl@webrtc.org    int ret = SSL_shutdown(ssl_);
869f1d751c7dede158bc9770e4d7c4cb07191ffdf3fjiayl@webrtc.org    if (ret < 0) {
870f1d751c7dede158bc9770e4d7c4cb07191ffdf3fjiayl@webrtc.org      LOG(LS_WARNING) << "SSL_shutdown failed, error = "
871f1d751c7dede158bc9770e4d7c4cb07191ffdf3fjiayl@webrtc.org                      << SSL_get_error(ssl_, ret);
872f1d751c7dede158bc9770e4d7c4cb07191ffdf3fjiayl@webrtc.org    }
873f1d751c7dede158bc9770e4d7c4cb07191ffdf3fjiayl@webrtc.org
874f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    SSL_free(ssl_);
875f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ssl_ = NULL;
876f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
877f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (ssl_ctx_) {
878f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    SSL_CTX_free(ssl_ctx_);
879f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ssl_ctx_ = NULL;
880f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
881f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  identity_.reset();
882f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  peer_certificate_.reset();
883f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
884f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Clear the DTLS timer
885f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Thread::Current()->Clear(this, MSG_TIMEOUT);
886f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
887f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
888f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
889f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid OpenSSLStreamAdapter::OnMessage(Message* msg) {
890f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Process our own messages and then pass others to the superclass
891f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (MSG_TIMEOUT == msg->message_id) {
892f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_INFO) << "DTLS timeout expired";
893f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    DTLSv1_handle_timeout(ssl_);
894f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ContinueSSL();
895f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  } else {
896f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    StreamInterface::OnMessage(msg);
897f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
898f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
899f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
900f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
901f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL_CTX *ctx = NULL;
902f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
903831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#ifdef OPENSSL_IS_BORINGSSL
904f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
905831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        DTLS_method() : TLS_method());
906831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    // Version limiting for BoringSSL will be done below.
907831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#else
908831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  const SSL_METHOD* method;
909831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  switch (ssl_max_version_) {
910831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    case SSL_PROTOCOL_TLS_10:
911831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    case SSL_PROTOCOL_TLS_11:
912831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      // OpenSSL doesn't support setting min/max versions, so we always use
913831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      // (D)TLS 1.0 if a max. version below the max. available is requested.
914831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      if (ssl_mode_ == SSL_MODE_DTLS) {
915831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        if (role_ == SSL_CLIENT) {
916831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = DTLSv1_client_method();
917831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        } else {
918831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = DTLSv1_server_method();
919831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        }
920831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      } else {
921831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        if (role_ == SSL_CLIENT) {
922831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = TLSv1_client_method();
923831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        } else {
924831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = TLSv1_server_method();
925831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        }
926831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      }
927831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      break;
928831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    case SSL_PROTOCOL_TLS_12:
929831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    default:
930831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      if (ssl_mode_ == SSL_MODE_DTLS) {
931831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#if (OPENSSL_VERSION_NUMBER >= 0x10002000L)
932831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        // DTLS 1.2 only available starting from OpenSSL 1.0.2
933831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        if (role_ == SSL_CLIENT) {
934831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = DTLS_client_method();
935831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        } else {
936831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = DTLS_server_method();
937831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        }
938831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#else
939831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        if (role_ == SSL_CLIENT) {
940831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = DTLSv1_client_method();
941831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        } else {
942831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = DTLSv1_server_method();
943831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        }
944831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#endif
945831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      } else {
946831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
947831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        // New API only available starting from OpenSSL 1.1.0
948831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        if (role_ == SSL_CLIENT) {
949831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = TLS_client_method();
950831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        } else {
951831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = TLS_server_method();
952831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        }
953831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#else
954831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        if (role_ == SSL_CLIENT) {
955831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = SSLv23_client_method();
956831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        } else {
957831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          method = SSLv23_server_method();
958831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        }
959831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#endif
960831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      }
961831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      break;
962f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
963831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  ctx = SSL_CTX_new(method);
964831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#endif  // OPENSSL_IS_BORINGSSL
965831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch
966f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (ctx == NULL)
967f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return NULL;
968f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
969831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#ifdef OPENSSL_IS_BORINGSSL
970458ffd574bb14dfe61ad65d1b1fd09846e3b58cddavidben  SSL_CTX_set_min_proto_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
971831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      DTLS1_VERSION : TLS1_VERSION);
972831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  switch (ssl_max_version_) {
973831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    case SSL_PROTOCOL_TLS_10:
974458ffd574bb14dfe61ad65d1b1fd09846e3b58cddavidben      SSL_CTX_set_max_proto_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
975831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          DTLS1_VERSION : TLS1_VERSION);
976831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      break;
977831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    case SSL_PROTOCOL_TLS_11:
978458ffd574bb14dfe61ad65d1b1fd09846e3b58cddavidben      SSL_CTX_set_max_proto_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
979831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          DTLS1_VERSION : TLS1_1_VERSION);
980831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      break;
981831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    case SSL_PROTOCOL_TLS_12:
982831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch    default:
983458ffd574bb14dfe61ad65d1b1fd09846e3b58cddavidben      SSL_CTX_set_max_proto_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
984831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch          DTLS1_2_VERSION : TLS1_2_VERSION);
985831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      break;
986831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  }
987831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#endif
988831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch
989f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (identity_ && !identity_->ConfigureIdentity(ctx)) {
990f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    SSL_CTX_free(ctx);
991f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return NULL;
992f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
993f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
994a41ab9326c8f0f7eb738e5d51a239a2b9e276361tfarina#if !defined(NDEBUG)
995f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL_CTX_set_info_callback(ctx, OpenSSLAdapter::SSLInfoCallback);
996f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
997f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
998c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org  int mode = SSL_VERIFY_PEER;
999c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org  if (client_auth_enabled()) {
1000c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org    // Require a certificate from the client.
1001c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org    // Note: Normally this is always true in production, but it may be disabled
1002c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org    // for testing purposes (e.g. SSLAdapter unit tests).
1003c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org    mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1004c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org  }
1005c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org
1006c569a49a3dafdb5017961736c7715624dd059240tkchin@webrtc.org  SSL_CTX_set_verify(ctx, mode, SSLVerifyCallback);
1007f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL_CTX_set_verify_depth(ctx, 4);
1008831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  // Select list of available ciphers. Note that !SHA256 and !SHA384 only
1009831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  // remove HMAC-SHA256 and HMAC-SHA384 cipher suites, not GCM cipher suites
1010831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  // with SHA256 or SHA384 as the handshake hash.
1011831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  // This matches the list of SSLClientSocketOpenSSL in Chromium.
1012831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  SSL_CTX_set_cipher_list(ctx,
1013831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch      "DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK");
1014f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1015f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef HAVE_DTLS_SRTP
1016f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!srtp_ciphers_.empty()) {
1017f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) {
1018f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      SSL_CTX_free(ctx);
1019f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return NULL;
1020f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
1021f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
1022f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
1023f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1024f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return ctx;
1025f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
1026f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1027f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgint OpenSSLStreamAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
1028f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Get our SSL structure from the store
1029f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(
1030f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                        store,
1031f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                        SSL_get_ex_data_X509_STORE_CTX_idx()));
1032f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  OpenSSLStreamAdapter* stream =
1033f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));
1034f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1035f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (stream->peer_certificate_digest_algorithm_.empty()) {
1036f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return 0;
1037f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
1038f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  X509* cert = X509_STORE_CTX_get_current_cert(store);
10394e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  int depth = X509_STORE_CTX_get_error_depth(store);
10404e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org
10414e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  // For now We ignore the parent certificates and verify the leaf against
10424e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  // the digest.
10434e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  //
10444e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  // TODO(jiayl): Verify the chain is a proper chain and report the chain to
104507d09364b003e6738a02d9940aebab5d3814da6dtorbjorng  // |stream->peer_certificate_|.
10464e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  if (depth > 0) {
10474e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org    LOG(LS_INFO) << "Ignored chained certificate at depth " << depth;
10484e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org    return 1;
10494e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org  }
10504e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org
1051f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  unsigned char digest[EVP_MAX_MD_SIZE];
1052f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  size_t digest_length;
1053f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!OpenSSLCertificate::ComputeDigest(
1054f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org           cert,
1055f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org           stream->peer_certificate_digest_algorithm_,
1056f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org           digest, sizeof(digest),
1057f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org           &digest_length)) {
1058f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_WARNING) << "Failed to compute peer cert digest.";
1059f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return 0;
1060f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
10614e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org
1062f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Buffer computed_digest(digest, digest_length);
1063f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (computed_digest != stream->peer_certificate_digest_value_) {
1064f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_WARNING) << "Rejected peer certificate due to mismatched digest.";
1065f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return 0;
1066f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
1067f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Ignore any verification error if the digest matches, since there is no
1068f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // value in checking the validity of a self-signed cert issued by untrusted
1069f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // sources.
1070f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_INFO) << "Accepted peer certificate.";
10714e5f65a4c689ad739cdcd47c91ec0f3e520caca7henrike@webrtc.org
1072f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Record the peer's certificate.
1073f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  stream->peer_certificate_.reset(new OpenSSLCertificate(cert));
1074f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return 1;
1075f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
1076f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1077f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// This code is taken from the "Network Security with OpenSSL"
1078f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// sample in chapter 5
1079f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::SSLPostConnectionCheck(SSL* ssl,
1080f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                  const char* server_name,
1081f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                  const X509* peer_cert,
1082f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                  const std::string
1083f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                  &peer_digest) {
1084f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(server_name != NULL);
1085f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bool ok;
1086f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (server_name[0] != '\0') {  // traditional mode
1087f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ok = OpenSSLAdapter::VerifyServerName(ssl, server_name, ignore_bad_cert());
1088f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1089f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (ok) {
1090f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
1091f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org            custom_verification_succeeded_);
1092f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
1093f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  } else {  // peer-to-peer mode
1094f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT((peer_cert != NULL) || (!peer_digest.empty()));
1095f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // no server name validation
1096f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ok = true;
1097f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
1098f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1099f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!ok && ignore_bad_cert()) {
1100f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_ERROR) << "SSL_get_verify_result(ssl) = "
1101f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                  << SSL_get_verify_result(ssl);
1102f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_INFO) << "Other TLS post connection checks failed.";
1103f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ok = true;
1104f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
1105f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1106f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return ok;
1107f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
1108f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1109f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::HaveDtls() {
1110f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
1111f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
1112f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1113f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::HaveDtlsSrtp() {
1114f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef HAVE_DTLS_SRTP
1115f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
1116f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else
1117f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return false;
1118f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
1119f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
1120f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1121f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool OpenSSLStreamAdapter::HaveExporter() {
1122f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#ifdef HAVE_DTLS_SRTP
1123f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
1124f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else
1125f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return false;
1126f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
1127f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
1128f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
11296caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shiehint OpenSSLStreamAdapter::GetDefaultSslCipherForTest(SSLProtocolVersion version,
11306caafbe5b6b777b309a6eb90a02cf54d5106fb9bGuo-wei Shieh                                                     KeyType key_type) {
1131b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund  if (key_type == KT_RSA) {
1132b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund    switch (version) {
1133b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      case SSL_PROTOCOL_TLS_10:
1134b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      case SSL_PROTOCOL_TLS_11:
1135b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        return kDefaultSslCipher10;
1136b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      case SSL_PROTOCOL_TLS_12:
1137b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      default:
1138831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#ifdef OPENSSL_IS_BORINGSSL
1139b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        if (EVP_has_aes_hardware()) {
1140b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund          return kDefaultSslCipher12;
1141b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        } else {
1142b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund          return kDefaultSslCipher12NoAesGcm;
1143b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        }
1144b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund#else  // !OPENSSL_IS_BORINGSSL
1145831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch        return kDefaultSslCipher12;
1146b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund#endif
1147b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund    }
1148b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund  } else if (key_type == KT_ECDSA) {
1149b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund    switch (version) {
1150b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      case SSL_PROTOCOL_TLS_10:
1151b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      case SSL_PROTOCOL_TLS_11:
1152b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        return kDefaultSslEcCipher10;
1153b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      case SSL_PROTOCOL_TLS_12:
1154b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund      default:
1155b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund#ifdef OPENSSL_IS_BORINGSSL
1156b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        if (EVP_has_aes_hardware()) {
1157b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund          return kDefaultSslEcCipher12;
1158b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        } else {
1159b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund          return kDefaultSslEcCipher12NoAesGcm;
1160b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        }
1161831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#else  // !OPENSSL_IS_BORINGSSL
1162b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund        return kDefaultSslEcCipher12;
1163831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch#endif
1164b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund    }
1165b6d4ec418504fd947c6f96829c73180e9487e203Torbjorn Granlund  } else {
1166456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    RTC_NOTREACHED();
1167456696a9c1bbd586701dcca3e4b2695e419a10baGuo-wei Shieh    return kDefaultSslEcCipher12;
1168831c5585c7d2b4c4442e3c1255332f1c23b6a983Joachim Bauch  }
11693ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org}
11703ee4fe5a940128cbfe76c8609a56c69c2aeb0175pthatcher@webrtc.org
1171f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}  // namespace rtc
1172f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1173f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif  // HAVE_OPENSSL_SSL_H
1174