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