blob: 8a3044d1a39f347797e018bf7e94f268f4a80137 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000011#if HAVE_OPENSSL_SSL_H
12
13#include "webrtc/base/opensslstreamadapter.h"
14
15#include <openssl/bio.h>
16#include <openssl/crypto.h>
17#include <openssl/err.h>
18#include <openssl/rand.h>
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +000019#include <openssl/tls1.h>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000020#include <openssl/x509v3.h>
21
22#include <vector>
23
24#include "webrtc/base/common.h"
25#include "webrtc/base/logging.h"
Tommid44c0772016-03-11 17:12:32 -080026#include "webrtc/base/safe_conversions.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000027#include "webrtc/base/stream.h"
28#include "webrtc/base/openssl.h"
29#include "webrtc/base/openssladapter.h"
30#include "webrtc/base/openssldigest.h"
31#include "webrtc/base/opensslidentity.h"
32#include "webrtc/base/stringutils.h"
33#include "webrtc/base/thread.h"
34
35namespace rtc {
36
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +010037#if (OPENSSL_VERSION_NUMBER >= 0x10001000L)
38#define HAVE_DTLS_SRTP
39#endif
40
41#ifdef HAVE_DTLS_SRTP
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -080042// SRTP cipher suite table. |internal_name| is used to construct a
43// colon-separated profile strings which is needed by
44// SSL_CTX_set_tlsext_use_srtp().
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000045struct SrtpCipherMapEntry {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000046 const char* internal_name;
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -080047 const int id;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000048};
49
50// This isn't elegant, but it's better than an external reference
51static SrtpCipherMapEntry SrtpCipherMap[] = {
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -080052 {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80},
53 {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32},
54 {nullptr, 0}};
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +010055#endif
56
57#ifndef OPENSSL_IS_BORINGSSL
58
59// Cipher name table. Maps internal OpenSSL cipher ids to the RFC name.
60struct SslCipherMapEntry {
61 uint32_t openssl_id;
62 const char* rfc_name;
63};
64
65#define DEFINE_CIPHER_ENTRY_SSL3(name) {SSL3_CK_##name, "TLS_"#name}
66#define DEFINE_CIPHER_ENTRY_TLS1(name) {TLS1_CK_##name, "TLS_"#name}
67
68// There currently is no method available to get a RFC-compliant name for a
69// cipher suite from BoringSSL, so we need to define the mapping manually here.
70// This should go away once BoringSSL supports "SSL_CIPHER_standard_name"
71// (as available in OpenSSL if compiled with tracing enabled) or a similar
72// method.
73static const SslCipherMapEntry kSslCipherMap[] = {
74 // TLS v1.0 ciphersuites from RFC2246.
75 DEFINE_CIPHER_ENTRY_SSL3(RSA_RC4_128_SHA),
76 {SSL3_CK_RSA_DES_192_CBC3_SHA,
77 "TLS_RSA_WITH_3DES_EDE_CBC_SHA"},
78
79 // AES ciphersuites from RFC3268.
80 {TLS1_CK_RSA_WITH_AES_128_SHA,
81 "TLS_RSA_WITH_AES_128_CBC_SHA"},
82 {TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
83 "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"},
84 {TLS1_CK_RSA_WITH_AES_256_SHA,
85 "TLS_RSA_WITH_AES_256_CBC_SHA"},
86 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
87 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"},
88
89 // ECC ciphersuites from RFC4492.
90 DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_RC4_128_SHA),
91 {TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
92 "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"},
93 DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_128_CBC_SHA),
94 DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_256_CBC_SHA),
95
96 DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_RC4_128_SHA),
97 {TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
98 "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"},
99 DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_128_CBC_SHA),
100 DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_256_CBC_SHA),
101
102 // TLS v1.2 ciphersuites.
103 {TLS1_CK_RSA_WITH_AES_128_SHA256,
104 "TLS_RSA_WITH_AES_128_CBC_SHA256"},
105 {TLS1_CK_RSA_WITH_AES_256_SHA256,
106 "TLS_RSA_WITH_AES_256_CBC_SHA256"},
107 {TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
108 "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"},
109 {TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
110 "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"},
111
112 // TLS v1.2 GCM ciphersuites from RFC5288.
113 DEFINE_CIPHER_ENTRY_TLS1(RSA_WITH_AES_128_GCM_SHA256),
114 DEFINE_CIPHER_ENTRY_TLS1(RSA_WITH_AES_256_GCM_SHA384),
115 DEFINE_CIPHER_ENTRY_TLS1(DHE_RSA_WITH_AES_128_GCM_SHA256),
116 DEFINE_CIPHER_ENTRY_TLS1(DHE_RSA_WITH_AES_256_GCM_SHA384),
117 DEFINE_CIPHER_ENTRY_TLS1(DH_RSA_WITH_AES_128_GCM_SHA256),
118 DEFINE_CIPHER_ENTRY_TLS1(DH_RSA_WITH_AES_256_GCM_SHA384),
119
120 // ECDH HMAC based ciphersuites from RFC5289.
121 {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256,
122 "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"},
123 {TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384,
124 "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"},
125 {TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
126 "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"},
127 {TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
128 "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"},
129
130 // ECDH GCM based ciphersuites from RFC5289.
131 DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_128_GCM_SHA256),
132 DEFINE_CIPHER_ENTRY_TLS1(ECDHE_ECDSA_WITH_AES_256_GCM_SHA384),
133 DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_128_GCM_SHA256),
134 DEFINE_CIPHER_ENTRY_TLS1(ECDHE_RSA_WITH_AES_256_GCM_SHA384),
135
136 {0, NULL}
137};
138#endif // #ifndef OPENSSL_IS_BORINGSSL
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000139
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700140#if defined(_MSC_VER)
141#pragma warning(push)
142#pragma warning(disable : 4309)
143#pragma warning(disable : 4310)
144#endif // defined(_MSC_VER)
145
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700146#if defined(_MSC_VER)
147#pragma warning(pop)
148#endif // defined(_MSC_VER)
149
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000150//////////////////////////////////////////////////////////////////////
151// StreamBIO
152//////////////////////////////////////////////////////////////////////
153
154static int stream_write(BIO* h, const char* buf, int num);
155static int stream_read(BIO* h, char* buf, int size);
156static int stream_puts(BIO* h, const char* str);
157static long stream_ctrl(BIO* h, int cmd, long arg1, void* arg2);
158static int stream_new(BIO* h);
159static int stream_free(BIO* data);
160
davidben@webrtc.org36d5c3c2015-01-22 23:06:17 +0000161// TODO(davidben): This should be const once BoringSSL is assumed.
162static BIO_METHOD methods_stream = {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000163 BIO_TYPE_BIO,
164 "stream",
165 stream_write,
166 stream_read,
167 stream_puts,
168 0,
169 stream_ctrl,
170 stream_new,
171 stream_free,
172 NULL,
173};
174
davidben@webrtc.org36d5c3c2015-01-22 23:06:17 +0000175static BIO_METHOD* BIO_s_stream() { return(&methods_stream); }
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000176
177static BIO* BIO_new_stream(StreamInterface* stream) {
178 BIO* ret = BIO_new(BIO_s_stream());
179 if (ret == NULL)
180 return NULL;
181 ret->ptr = stream;
182 return ret;
183}
184
185// bio methods return 1 (or at least non-zero) on success and 0 on failure.
186
187static int stream_new(BIO* b) {
188 b->shutdown = 0;
189 b->init = 1;
190 b->num = 0; // 1 means end-of-stream
191 b->ptr = 0;
192 return 1;
193}
194
195static int stream_free(BIO* b) {
196 if (b == NULL)
197 return 0;
198 return 1;
199}
200
201static int stream_read(BIO* b, char* out, int outl) {
202 if (!out)
203 return -1;
204 StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
205 BIO_clear_retry_flags(b);
206 size_t read;
207 int error;
208 StreamResult result = stream->Read(out, outl, &read, &error);
209 if (result == SR_SUCCESS) {
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000210 return checked_cast<int>(read);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000211 } else if (result == SR_EOS) {
212 b->num = 1;
213 } else if (result == SR_BLOCK) {
214 BIO_set_retry_read(b);
215 }
216 return -1;
217}
218
219static int stream_write(BIO* b, const char* in, int inl) {
220 if (!in)
221 return -1;
222 StreamInterface* stream = static_cast<StreamInterface*>(b->ptr);
223 BIO_clear_retry_flags(b);
224 size_t written;
225 int error;
226 StreamResult result = stream->Write(in, inl, &written, &error);
227 if (result == SR_SUCCESS) {
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000228 return checked_cast<int>(written);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000229 } else if (result == SR_BLOCK) {
230 BIO_set_retry_write(b);
231 }
232 return -1;
233}
234
235static int stream_puts(BIO* b, const char* str) {
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000236 return stream_write(b, str, checked_cast<int>(strlen(str)));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000237}
238
239static long stream_ctrl(BIO* b, int cmd, long num, void* ptr) {
henrike@webrtc.org14abcc72014-05-16 16:54:44 +0000240 RTC_UNUSED(num);
241 RTC_UNUSED(ptr);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000242
243 switch (cmd) {
244 case BIO_CTRL_RESET:
245 return 0;
246 case BIO_CTRL_EOF:
247 return b->num;
248 case BIO_CTRL_WPENDING:
249 case BIO_CTRL_PENDING:
250 return 0;
251 case BIO_CTRL_FLUSH:
252 return 1;
Henrik Lundinf4baca52015-06-10 09:45:58 +0200253 case BIO_CTRL_DGRAM_QUERY_MTU:
254 // openssl defaults to mtu=256 unless we return something here.
255 // The handshake doesn't actually need to send packets above 1k,
256 // so this seems like a sensible value that should work in most cases.
257 // Webrtc uses the same value for video packets.
258 return 1200;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000259 default:
260 return 0;
261 }
262}
263
264/////////////////////////////////////////////////////////////////////////////
265// OpenSSLStreamAdapter
266/////////////////////////////////////////////////////////////////////////////
267
268OpenSSLStreamAdapter::OpenSSLStreamAdapter(StreamInterface* stream)
269 : SSLStreamAdapter(stream),
270 state_(SSL_NONE),
271 role_(SSL_CLIENT),
Guo-wei Shieha7446d22016-01-11 15:27:03 -0800272 ssl_read_needs_write_(false),
273 ssl_write_needs_read_(false),
274 ssl_(NULL),
275 ssl_ctx_(NULL),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000276 custom_verification_succeeded_(false),
Joachim Bauch831c5582015-05-20 12:48:41 +0200277 ssl_mode_(SSL_MODE_TLS),
Guo-wei Shieha7446d22016-01-11 15:27:03 -0800278 ssl_max_version_(SSL_PROTOCOL_TLS_12) {}
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000279
280OpenSSLStreamAdapter::~OpenSSLStreamAdapter() {
281 Cleanup();
282}
283
284void OpenSSLStreamAdapter::SetIdentity(SSLIdentity* identity) {
285 ASSERT(!identity_);
286 identity_.reset(static_cast<OpenSSLIdentity*>(identity));
287}
288
289void OpenSSLStreamAdapter::SetServerRole(SSLRole role) {
290 role_ = role;
291}
292
293bool OpenSSLStreamAdapter::GetPeerCertificate(SSLCertificate** cert) const {
294 if (!peer_certificate_)
295 return false;
296
297 *cert = peer_certificate_->GetReference();
298 return true;
299}
300
301bool OpenSSLStreamAdapter::SetPeerCertificateDigest(const std::string
302 &digest_alg,
303 const unsigned char*
304 digest_val,
305 size_t digest_len) {
306 ASSERT(!peer_certificate_);
307 ASSERT(peer_certificate_digest_algorithm_.size() == 0);
308 ASSERT(ssl_server_name_.empty());
309 size_t expected_len;
310
311 if (!OpenSSLDigest::GetDigestSize(digest_alg, &expected_len)) {
312 LOG(LS_WARNING) << "Unknown digest algorithm: " << digest_alg;
313 return false;
314 }
315 if (expected_len != digest_len)
316 return false;
317
318 peer_certificate_digest_value_.SetData(digest_val, digest_len);
319 peer_certificate_digest_algorithm_ = digest_alg;
320
321 return true;
322}
323
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800324std::string OpenSSLStreamAdapter::SslCipherSuiteToName(int cipher_suite) {
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +0100325#ifdef OPENSSL_IS_BORINGSSL
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800326 const SSL_CIPHER* ssl_cipher = SSL_get_cipher_by_value(cipher_suite);
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700327 if (!ssl_cipher) {
328 return std::string();
329 }
330 char* cipher_name = SSL_CIPHER_get_rfc_name(ssl_cipher);
331 std::string rfc_name = std::string(cipher_name);
332 OPENSSL_free(cipher_name);
333 return rfc_name;
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +0100334#else
335 for (const SslCipherMapEntry* entry = kSslCipherMap; entry->rfc_name;
336 ++entry) {
337 if (cipher_suite == static_cast<int>(entry->openssl_id)) {
338 return entry->rfc_name;
339 }
340 }
341 return std::string();
342#endif
Guo-wei Shieh456696a2015-09-30 21:48:54 -0700343}
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000344
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800345bool OpenSSLStreamAdapter::GetSslCipherSuite(int* cipher_suite) {
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000346 if (state_ != SSL_CONNECTED)
347 return false;
348
349 const SSL_CIPHER* current_cipher = SSL_get_current_cipher(ssl_);
350 if (current_cipher == NULL) {
351 return false;
352 }
353
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800354 *cipher_suite = static_cast<uint16_t>(SSL_CIPHER_get_id(current_cipher));
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +0000355 return true;
356}
357
torbjorng43166b82016-03-11 00:06:47 -0800358int OpenSSLStreamAdapter::GetSslVersion() const {
359 if (state_ != SSL_CONNECTED)
360 return -1;
361
362 int ssl_version = SSL_version(ssl_);
363 if (ssl_mode_ == SSL_MODE_DTLS) {
364 if (ssl_version == DTLS1_VERSION)
365 return SSL_PROTOCOL_DTLS_10;
366 else if (ssl_version == DTLS1_2_VERSION)
367 return SSL_PROTOCOL_DTLS_12;
368 } else {
369 if (ssl_version == TLS1_VERSION)
370 return SSL_PROTOCOL_TLS_10;
371 else if (ssl_version == TLS1_1_VERSION)
372 return SSL_PROTOCOL_TLS_11;
373 else if (ssl_version == TLS1_2_VERSION)
374 return SSL_PROTOCOL_TLS_12;
375 }
376
377 return -1;
378}
379
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000380// Key Extractor interface
381bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200382 const uint8_t* context,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000383 size_t context_len,
384 bool use_context,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200385 uint8_t* result,
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000386 size_t result_len) {
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +0100387#ifdef HAVE_DTLS_SRTP
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000388 int i;
389
Peter Boström0c4e06b2015-10-07 12:23:21 +0200390 i = SSL_export_keying_material(ssl_, result, result_len, label.c_str(),
391 label.length(), const_cast<uint8_t*>(context),
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000392 context_len, use_context);
393
394 if (i != 1)
395 return false;
396
397 return true;
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +0100398#else
399 return false;
400#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000401}
402
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800403bool OpenSSLStreamAdapter::SetDtlsSrtpCryptoSuites(
404 const std::vector<int>& ciphers) {
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +0100405#ifdef HAVE_DTLS_SRTP
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000406 std::string internal_ciphers;
407
408 if (state_ != SSL_NONE)
409 return false;
410
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800411 for (std::vector<int>::const_iterator cipher = ciphers.begin();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000412 cipher != ciphers.end(); ++cipher) {
413 bool found = false;
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800414 for (SrtpCipherMapEntry* entry = SrtpCipherMap; entry->internal_name;
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000415 ++entry) {
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800416 if (*cipher == entry->id) {
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000417 found = true;
418 if (!internal_ciphers.empty())
419 internal_ciphers += ":";
420 internal_ciphers += entry->internal_name;
421 break;
422 }
423 }
424
425 if (!found) {
426 LOG(LS_ERROR) << "Could not find cipher: " << *cipher;
427 return false;
428 }
429 }
430
431 if (internal_ciphers.empty())
432 return false;
433
434 srtp_ciphers_ = internal_ciphers;
435 return true;
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +0100436#else
437 return false;
438#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000439}
440
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800441bool OpenSSLStreamAdapter::GetDtlsSrtpCryptoSuite(int* crypto_suite) {
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +0100442#ifdef HAVE_DTLS_SRTP
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000443 ASSERT(state_ == SSL_CONNECTED);
444 if (state_ != SSL_CONNECTED)
445 return false;
446
henrike@webrtc.orgc10ecea2015-01-07 17:59:28 +0000447 const SRTP_PROTECTION_PROFILE *srtp_profile =
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000448 SSL_get_selected_srtp_profile(ssl_);
449
450 if (!srtp_profile)
451 return false;
452
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800453 *crypto_suite = srtp_profile->id;
454 ASSERT(!SrtpCryptoSuiteToName(*crypto_suite).empty());
455 return true;
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +0100456#else
457 return false;
458#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000459}
460
461int OpenSSLStreamAdapter::StartSSLWithServer(const char* server_name) {
462 ASSERT(server_name != NULL && server_name[0] != '\0');
463 ssl_server_name_ = server_name;
464 return StartSSL();
465}
466
467int OpenSSLStreamAdapter::StartSSLWithPeer() {
468 ASSERT(ssl_server_name_.empty());
469 // It is permitted to specify peer_certificate_ only later.
470 return StartSSL();
471}
472
473void OpenSSLStreamAdapter::SetMode(SSLMode mode) {
474 ASSERT(state_ == SSL_NONE);
475 ssl_mode_ = mode;
476}
477
Joachim Bauch831c5582015-05-20 12:48:41 +0200478void OpenSSLStreamAdapter::SetMaxProtocolVersion(SSLProtocolVersion version) {
479 ASSERT(ssl_ctx_ == NULL);
480 ssl_max_version_ = version;
481}
482
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000483//
484// StreamInterface Implementation
485//
486
487StreamResult OpenSSLStreamAdapter::Write(const void* data, size_t data_len,
488 size_t* written, int* error) {
489 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Write(" << data_len << ")";
490
491 switch (state_) {
492 case SSL_NONE:
493 // pass-through in clear text
494 return StreamAdapterInterface::Write(data, data_len, written, error);
495
496 case SSL_WAIT:
497 case SSL_CONNECTING:
498 return SR_BLOCK;
499
500 case SSL_CONNECTED:
501 break;
502
503 case SSL_ERROR:
504 case SSL_CLOSED:
505 default:
506 if (error)
507 *error = ssl_error_code_;
508 return SR_ERROR;
509 }
510
511 // OpenSSL will return an error if we try to write zero bytes
512 if (data_len == 0) {
513 if (written)
514 *written = 0;
515 return SR_SUCCESS;
516 }
517
518 ssl_write_needs_read_ = false;
519
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000520 int code = SSL_write(ssl_, data, checked_cast<int>(data_len));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000521 int ssl_error = SSL_get_error(ssl_, code);
522 switch (ssl_error) {
523 case SSL_ERROR_NONE:
524 LOG(LS_VERBOSE) << " -- success";
525 ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
526 if (written)
527 *written = code;
528 return SR_SUCCESS;
529 case SSL_ERROR_WANT_READ:
530 LOG(LS_VERBOSE) << " -- error want read";
531 ssl_write_needs_read_ = true;
532 return SR_BLOCK;
533 case SSL_ERROR_WANT_WRITE:
534 LOG(LS_VERBOSE) << " -- error want write";
535 return SR_BLOCK;
536
537 case SSL_ERROR_ZERO_RETURN:
538 default:
539 Error("SSL_write", (ssl_error ? ssl_error : -1), false);
540 if (error)
541 *error = ssl_error_code_;
542 return SR_ERROR;
543 }
544 // not reached
545}
546
547StreamResult OpenSSLStreamAdapter::Read(void* data, size_t data_len,
548 size_t* read, int* error) {
549 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::Read(" << data_len << ")";
550 switch (state_) {
551 case SSL_NONE:
552 // pass-through in clear text
553 return StreamAdapterInterface::Read(data, data_len, read, error);
554
555 case SSL_WAIT:
556 case SSL_CONNECTING:
557 return SR_BLOCK;
558
559 case SSL_CONNECTED:
560 break;
561
562 case SSL_CLOSED:
563 return SR_EOS;
564
565 case SSL_ERROR:
566 default:
567 if (error)
568 *error = ssl_error_code_;
569 return SR_ERROR;
570 }
571
572 // Don't trust OpenSSL with zero byte reads
573 if (data_len == 0) {
574 if (read)
575 *read = 0;
576 return SR_SUCCESS;
577 }
578
579 ssl_read_needs_write_ = false;
580
henrike@webrtc.orgd89b69a2014-11-06 17:23:09 +0000581 int code = SSL_read(ssl_, data, checked_cast<int>(data_len));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000582 int ssl_error = SSL_get_error(ssl_, code);
583 switch (ssl_error) {
584 case SSL_ERROR_NONE:
585 LOG(LS_VERBOSE) << " -- success";
586 ASSERT(0 < code && static_cast<unsigned>(code) <= data_len);
587 if (read)
588 *read = code;
589
590 if (ssl_mode_ == SSL_MODE_DTLS) {
591 // Enforce atomic reads -- this is a short read
592 unsigned int pending = SSL_pending(ssl_);
593
594 if (pending) {
595 LOG(LS_INFO) << " -- short DTLS read. flushing";
596 FlushInput(pending);
597 if (error)
598 *error = SSE_MSG_TRUNC;
599 return SR_ERROR;
600 }
601 }
602 return SR_SUCCESS;
603 case SSL_ERROR_WANT_READ:
604 LOG(LS_VERBOSE) << " -- error want read";
605 return SR_BLOCK;
606 case SSL_ERROR_WANT_WRITE:
607 LOG(LS_VERBOSE) << " -- error want write";
608 ssl_read_needs_write_ = true;
609 return SR_BLOCK;
610 case SSL_ERROR_ZERO_RETURN:
611 LOG(LS_VERBOSE) << " -- remote side closed";
guoweis4cc9f982016-02-24 11:10:06 -0800612 // When we're closed at SSL layer, also close the stream level which
613 // performs necessary clean up. Otherwise, a new incoming packet after
614 // this could overflow the stream buffer.
615 this->stream()->Close();
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000616 return SR_EOS;
617 break;
618 default:
619 LOG(LS_VERBOSE) << " -- error " << code;
620 Error("SSL_read", (ssl_error ? ssl_error : -1), false);
621 if (error)
622 *error = ssl_error_code_;
623 return SR_ERROR;
624 }
625 // not reached
626}
627
628void OpenSSLStreamAdapter::FlushInput(unsigned int left) {
629 unsigned char buf[2048];
630
631 while (left) {
632 // This should always succeed
633 int toread = (sizeof(buf) < left) ? sizeof(buf) : left;
634 int code = SSL_read(ssl_, buf, toread);
635
636 int ssl_error = SSL_get_error(ssl_, code);
637 ASSERT(ssl_error == SSL_ERROR_NONE);
638
639 if (ssl_error != SSL_ERROR_NONE) {
640 LOG(LS_VERBOSE) << " -- error " << code;
641 Error("SSL_read", (ssl_error ? ssl_error : -1), false);
642 return;
643 }
644
645 LOG(LS_VERBOSE) << " -- flushed " << code << " bytes";
646 left -= code;
647 }
648}
649
650void OpenSSLStreamAdapter::Close() {
651 Cleanup();
652 ASSERT(state_ == SSL_CLOSED || state_ == SSL_ERROR);
653 StreamAdapterInterface::Close();
654}
655
656StreamState OpenSSLStreamAdapter::GetState() const {
657 switch (state_) {
658 case SSL_WAIT:
659 case SSL_CONNECTING:
660 return SS_OPENING;
661 case SSL_CONNECTED:
662 return SS_OPEN;
663 default:
664 return SS_CLOSED;
665 };
666 // not reached
667}
668
669void OpenSSLStreamAdapter::OnEvent(StreamInterface* stream, int events,
670 int err) {
671 int events_to_signal = 0;
672 int signal_error = 0;
673 ASSERT(stream == this->stream());
674 if ((events & SE_OPEN)) {
675 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent SE_OPEN";
676 if (state_ != SSL_WAIT) {
677 ASSERT(state_ == SSL_NONE);
678 events_to_signal |= SE_OPEN;
679 } else {
680 state_ = SSL_CONNECTING;
681 if (int err = BeginSSL()) {
682 Error("BeginSSL", err, true);
683 return;
684 }
685 }
686 }
687 if ((events & (SE_READ|SE_WRITE))) {
688 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent"
689 << ((events & SE_READ) ? " SE_READ" : "")
690 << ((events & SE_WRITE) ? " SE_WRITE" : "");
691 if (state_ == SSL_NONE) {
692 events_to_signal |= events & (SE_READ|SE_WRITE);
693 } else if (state_ == SSL_CONNECTING) {
694 if (int err = ContinueSSL()) {
695 Error("ContinueSSL", err, true);
696 return;
697 }
698 } else if (state_ == SSL_CONNECTED) {
699 if (((events & SE_READ) && ssl_write_needs_read_) ||
700 (events & SE_WRITE)) {
701 LOG(LS_VERBOSE) << " -- onStreamWriteable";
702 events_to_signal |= SE_WRITE;
703 }
704 if (((events & SE_WRITE) && ssl_read_needs_write_) ||
705 (events & SE_READ)) {
706 LOG(LS_VERBOSE) << " -- onStreamReadable";
707 events_to_signal |= SE_READ;
708 }
709 }
710 }
711 if ((events & SE_CLOSE)) {
712 LOG(LS_VERBOSE) << "OpenSSLStreamAdapter::OnEvent(SE_CLOSE, " << err << ")";
713 Cleanup();
714 events_to_signal |= SE_CLOSE;
715 // SE_CLOSE is the only event that uses the final parameter to OnEvent().
716 ASSERT(signal_error == 0);
717 signal_error = err;
718 }
719 if (events_to_signal)
720 StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error);
721}
722
723int OpenSSLStreamAdapter::StartSSL() {
724 ASSERT(state_ == SSL_NONE);
725
726 if (StreamAdapterInterface::GetState() != SS_OPEN) {
727 state_ = SSL_WAIT;
728 return 0;
729 }
730
731 state_ = SSL_CONNECTING;
732 if (int err = BeginSSL()) {
733 Error("BeginSSL", err, false);
734 return err;
735 }
736
737 return 0;
738}
739
740int OpenSSLStreamAdapter::BeginSSL() {
741 ASSERT(state_ == SSL_CONNECTING);
742 // The underlying stream has open. If we are in peer-to-peer mode
743 // then a peer certificate must have been specified by now.
744 ASSERT(!ssl_server_name_.empty() ||
745 !peer_certificate_digest_algorithm_.empty());
746 LOG(LS_INFO) << "BeginSSL: "
747 << (!ssl_server_name_.empty() ? ssl_server_name_ :
748 "with peer");
749
750 BIO* bio = NULL;
751
752 // First set up the context
753 ASSERT(ssl_ctx_ == NULL);
754 ssl_ctx_ = SetupSSLContext();
755 if (!ssl_ctx_)
756 return -1;
757
758 bio = BIO_new_stream(static_cast<StreamInterface*>(stream()));
759 if (!bio)
760 return -1;
761
762 ssl_ = SSL_new(ssl_ctx_);
763 if (!ssl_) {
764 BIO_free(bio);
765 return -1;
766 }
767
768 SSL_set_app_data(ssl_, this);
769
770 SSL_set_bio(ssl_, bio, bio); // the SSL object owns the bio now.
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +0100771#ifndef OPENSSL_IS_BORINGSSL
772 if (ssl_mode_ == SSL_MODE_DTLS) {
773 // Enable read-ahead for DTLS so whole packets are read from internal BIO
774 // before parsing. This is done internally by BoringSSL for DTLS.
775 SSL_set_read_ahead(ssl_, 1);
776 }
777#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000778
779 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
780 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
781
David Benjamin60d5f3f2016-03-24 13:28:25 -0400782#if !defined(OPENSSL_IS_BORINGSSL)
783 // Specify an ECDH group for ECDHE ciphers, otherwise OpenSSL cannot
784 // negotiate them when acting as the server. Use NIST's P-256 which is
785 // commonly supported. BoringSSL doesn't need explicit configuration and has
786 // a reasonable default set.
jiayl@webrtc.org11c6bde2014-08-28 16:14:38 +0000787 EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
788 if (ecdh == NULL)
789 return -1;
790 SSL_set_options(ssl_, SSL_OP_SINGLE_ECDH_USE);
791 SSL_set_tmp_ecdh(ssl_, ecdh);
792 EC_KEY_free(ecdh);
David Benjamin60d5f3f2016-03-24 13:28:25 -0400793#endif
jiayl@webrtc.org11c6bde2014-08-28 16:14:38 +0000794
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000795 // Do the connect
796 return ContinueSSL();
797}
798
799int OpenSSLStreamAdapter::ContinueSSL() {
800 LOG(LS_VERBOSE) << "ContinueSSL";
801 ASSERT(state_ == SSL_CONNECTING);
802
803 // Clear the DTLS timer
804 Thread::Current()->Clear(this, MSG_TIMEOUT);
805
806 int code = (role_ == SSL_CLIENT) ? SSL_connect(ssl_) : SSL_accept(ssl_);
807 int ssl_error;
808 switch (ssl_error = SSL_get_error(ssl_, code)) {
809 case SSL_ERROR_NONE:
810 LOG(LS_VERBOSE) << " -- success";
811
812 if (!SSLPostConnectionCheck(ssl_, ssl_server_name_.c_str(), NULL,
813 peer_certificate_digest_algorithm_)) {
814 LOG(LS_ERROR) << "TLS post connection check failed";
815 return -1;
816 }
817
818 state_ = SSL_CONNECTED;
819 StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0);
820 break;
821
822 case SSL_ERROR_WANT_READ: {
823 LOG(LS_VERBOSE) << " -- error want read";
824 struct timeval timeout;
825 if (DTLSv1_get_timeout(ssl_, &timeout)) {
826 int delay = timeout.tv_sec * 1000 + timeout.tv_usec/1000;
827
828 Thread::Current()->PostDelayed(delay, this, MSG_TIMEOUT, 0);
829 }
830 }
831 break;
832
833 case SSL_ERROR_WANT_WRITE:
834 LOG(LS_VERBOSE) << " -- error want write";
835 break;
836
837 case SSL_ERROR_ZERO_RETURN:
838 default:
839 LOG(LS_VERBOSE) << " -- error " << code;
840 return (ssl_error != 0) ? ssl_error : -1;
841 }
842
843 return 0;
844}
845
846void OpenSSLStreamAdapter::Error(const char* context, int err, bool signal) {
847 LOG(LS_WARNING) << "OpenSSLStreamAdapter::Error("
848 << context << ", " << err << ")";
849 state_ = SSL_ERROR;
850 ssl_error_code_ = err;
851 Cleanup();
852 if (signal)
853 StreamAdapterInterface::OnEvent(stream(), SE_CLOSE, err);
854}
855
856void OpenSSLStreamAdapter::Cleanup() {
857 LOG(LS_INFO) << "Cleanup";
858
859 if (state_ != SSL_ERROR) {
860 state_ = SSL_CLOSED;
861 ssl_error_code_ = 0;
862 }
863
864 if (ssl_) {
jiayl@webrtc.orgf1d751c2014-09-25 16:38:46 +0000865 int ret = SSL_shutdown(ssl_);
866 if (ret < 0) {
867 LOG(LS_WARNING) << "SSL_shutdown failed, error = "
868 << SSL_get_error(ssl_, ret);
869 }
870
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000871 SSL_free(ssl_);
872 ssl_ = NULL;
873 }
874 if (ssl_ctx_) {
875 SSL_CTX_free(ssl_ctx_);
876 ssl_ctx_ = NULL;
877 }
878 identity_.reset();
879 peer_certificate_.reset();
880
881 // Clear the DTLS timer
882 Thread::Current()->Clear(this, MSG_TIMEOUT);
883}
884
885
886void OpenSSLStreamAdapter::OnMessage(Message* msg) {
887 // Process our own messages and then pass others to the superclass
888 if (MSG_TIMEOUT == msg->message_id) {
889 LOG(LS_INFO) << "DTLS timeout expired";
890 DTLSv1_handle_timeout(ssl_);
891 ContinueSSL();
892 } else {
893 StreamInterface::OnMessage(msg);
894 }
895}
896
897SSL_CTX* OpenSSLStreamAdapter::SetupSSLContext() {
898 SSL_CTX *ctx = NULL;
899
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +0100900#ifdef OPENSSL_IS_BORINGSSL
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000901 ctx = SSL_CTX_new(ssl_mode_ == SSL_MODE_DTLS ?
Joachim Bauch831c5582015-05-20 12:48:41 +0200902 DTLS_method() : TLS_method());
903 // Version limiting for BoringSSL will be done below.
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +0100904#else
905 const SSL_METHOD* method;
906 switch (ssl_max_version_) {
907 case SSL_PROTOCOL_TLS_10:
908 case SSL_PROTOCOL_TLS_11:
909 // OpenSSL doesn't support setting min/max versions, so we always use
910 // (D)TLS 1.0 if a max. version below the max. available is requested.
911 if (ssl_mode_ == SSL_MODE_DTLS) {
912 if (role_ == SSL_CLIENT) {
913 method = DTLSv1_client_method();
914 } else {
915 method = DTLSv1_server_method();
916 }
917 } else {
918 if (role_ == SSL_CLIENT) {
919 method = TLSv1_client_method();
920 } else {
921 method = TLSv1_server_method();
922 }
923 }
924 break;
925 case SSL_PROTOCOL_TLS_12:
926 default:
927 if (ssl_mode_ == SSL_MODE_DTLS) {
928#if (OPENSSL_VERSION_NUMBER >= 0x10002000L)
929 // DTLS 1.2 only available starting from OpenSSL 1.0.2
930 if (role_ == SSL_CLIENT) {
931 method = DTLS_client_method();
932 } else {
933 method = DTLS_server_method();
934 }
935#else
936 if (role_ == SSL_CLIENT) {
937 method = DTLSv1_client_method();
938 } else {
939 method = DTLSv1_server_method();
940 }
941#endif
942 } else {
943#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
944 // New API only available starting from OpenSSL 1.1.0
945 if (role_ == SSL_CLIENT) {
946 method = TLS_client_method();
947 } else {
948 method = TLS_server_method();
949 }
950#else
951 if (role_ == SSL_CLIENT) {
952 method = SSLv23_client_method();
953 } else {
954 method = SSLv23_server_method();
955 }
956#endif
957 }
958 break;
959 }
960 ctx = SSL_CTX_new(method);
961#endif // OPENSSL_IS_BORINGSSL
Joachim Bauch831c5582015-05-20 12:48:41 +0200962
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000963 if (ctx == NULL)
964 return NULL;
965
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +0100966#ifdef OPENSSL_IS_BORINGSSL
Joachim Bauch831c5582015-05-20 12:48:41 +0200967 SSL_CTX_set_min_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
968 DTLS1_VERSION : TLS1_VERSION);
969 switch (ssl_max_version_) {
970 case SSL_PROTOCOL_TLS_10:
971 SSL_CTX_set_max_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
972 DTLS1_VERSION : TLS1_VERSION);
973 break;
974 case SSL_PROTOCOL_TLS_11:
975 SSL_CTX_set_max_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
976 DTLS1_VERSION : TLS1_1_VERSION);
977 break;
978 case SSL_PROTOCOL_TLS_12:
979 default:
980 SSL_CTX_set_max_version(ctx, ssl_mode_ == SSL_MODE_DTLS ?
981 DTLS1_2_VERSION : TLS1_2_VERSION);
982 break;
983 }
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +0100984#endif
Joachim Bauch831c5582015-05-20 12:48:41 +0200985
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000986 if (identity_ && !identity_->ConfigureIdentity(ctx)) {
987 SSL_CTX_free(ctx);
988 return NULL;
989 }
990
tfarinaa41ab932015-10-30 16:08:48 -0700991#if !defined(NDEBUG)
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000992 SSL_CTX_set_info_callback(ctx, OpenSSLAdapter::SSLInfoCallback);
993#endif
994
tkchin@webrtc.orgc569a492014-09-23 05:56:44 +0000995 int mode = SSL_VERIFY_PEER;
996 if (client_auth_enabled()) {
997 // Require a certificate from the client.
998 // Note: Normally this is always true in production, but it may be disabled
999 // for testing purposes (e.g. SSLAdapter unit tests).
1000 mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1001 }
1002
1003 SSL_CTX_set_verify(ctx, mode, SSLVerifyCallback);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001004 SSL_CTX_set_verify_depth(ctx, 4);
Joachim Bauch831c5582015-05-20 12:48:41 +02001005 // Select list of available ciphers. Note that !SHA256 and !SHA384 only
1006 // remove HMAC-SHA256 and HMAC-SHA384 cipher suites, not GCM cipher suites
1007 // with SHA256 or SHA384 as the handshake hash.
1008 // This matches the list of SSLClientSocketOpenSSL in Chromium.
1009 SSL_CTX_set_cipher_list(ctx,
1010 "DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK");
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001011
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +01001012#ifdef HAVE_DTLS_SRTP
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001013 if (!srtp_ciphers_.empty()) {
1014 if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) {
1015 SSL_CTX_free(ctx);
1016 return NULL;
1017 }
1018 }
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +01001019#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001020
1021 return ctx;
1022}
1023
1024int OpenSSLStreamAdapter::SSLVerifyCallback(int ok, X509_STORE_CTX* store) {
1025 // Get our SSL structure from the store
1026 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(
1027 store,
1028 SSL_get_ex_data_X509_STORE_CTX_idx()));
1029 OpenSSLStreamAdapter* stream =
1030 reinterpret_cast<OpenSSLStreamAdapter*>(SSL_get_app_data(ssl));
1031
1032 if (stream->peer_certificate_digest_algorithm_.empty()) {
1033 return 0;
1034 }
1035 X509* cert = X509_STORE_CTX_get_current_cert(store);
henrike@webrtc.org4e5f65a2014-06-05 20:40:11 +00001036 int depth = X509_STORE_CTX_get_error_depth(store);
1037
1038 // For now We ignore the parent certificates and verify the leaf against
1039 // the digest.
1040 //
1041 // TODO(jiayl): Verify the chain is a proper chain and report the chain to
torbjorng07d09362015-09-22 11:58:04 -07001042 // |stream->peer_certificate_|.
henrike@webrtc.org4e5f65a2014-06-05 20:40:11 +00001043 if (depth > 0) {
1044 LOG(LS_INFO) << "Ignored chained certificate at depth " << depth;
1045 return 1;
1046 }
1047
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001048 unsigned char digest[EVP_MAX_MD_SIZE];
1049 size_t digest_length;
1050 if (!OpenSSLCertificate::ComputeDigest(
1051 cert,
1052 stream->peer_certificate_digest_algorithm_,
1053 digest, sizeof(digest),
1054 &digest_length)) {
1055 LOG(LS_WARNING) << "Failed to compute peer cert digest.";
1056 return 0;
1057 }
henrike@webrtc.org4e5f65a2014-06-05 20:40:11 +00001058
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001059 Buffer computed_digest(digest, digest_length);
1060 if (computed_digest != stream->peer_certificate_digest_value_) {
1061 LOG(LS_WARNING) << "Rejected peer certificate due to mismatched digest.";
1062 return 0;
1063 }
1064 // Ignore any verification error if the digest matches, since there is no
1065 // value in checking the validity of a self-signed cert issued by untrusted
1066 // sources.
1067 LOG(LS_INFO) << "Accepted peer certificate.";
henrike@webrtc.org4e5f65a2014-06-05 20:40:11 +00001068
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001069 // Record the peer's certificate.
1070 stream->peer_certificate_.reset(new OpenSSLCertificate(cert));
1071 return 1;
1072}
1073
1074// This code is taken from the "Network Security with OpenSSL"
1075// sample in chapter 5
1076bool OpenSSLStreamAdapter::SSLPostConnectionCheck(SSL* ssl,
1077 const char* server_name,
1078 const X509* peer_cert,
1079 const std::string
1080 &peer_digest) {
1081 ASSERT(server_name != NULL);
1082 bool ok;
1083 if (server_name[0] != '\0') { // traditional mode
1084 ok = OpenSSLAdapter::VerifyServerName(ssl, server_name, ignore_bad_cert());
1085
1086 if (ok) {
1087 ok = (SSL_get_verify_result(ssl) == X509_V_OK ||
1088 custom_verification_succeeded_);
1089 }
1090 } else { // peer-to-peer mode
1091 ASSERT((peer_cert != NULL) || (!peer_digest.empty()));
1092 // no server name validation
1093 ok = true;
1094 }
1095
1096 if (!ok && ignore_bad_cert()) {
1097 LOG(LS_ERROR) << "SSL_get_verify_result(ssl) = "
1098 << SSL_get_verify_result(ssl);
1099 LOG(LS_INFO) << "Other TLS post connection checks failed.";
1100 ok = true;
1101 }
1102
1103 return ok;
1104}
1105
1106bool OpenSSLStreamAdapter::HaveDtls() {
1107 return true;
1108}
1109
1110bool OpenSSLStreamAdapter::HaveDtlsSrtp() {
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +01001111#ifdef HAVE_DTLS_SRTP
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001112 return true;
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +01001113#else
1114 return false;
1115#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001116}
1117
1118bool OpenSSLStreamAdapter::HaveExporter() {
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +01001119#ifdef HAVE_DTLS_SRTP
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001120 return true;
Torbjorn Granlund9adc91d2016-03-24 14:05:06 +01001121#else
1122 return false;
1123#endif
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001124}
1125
torbjorng43166b82016-03-11 00:06:47 -08001126#define CDEF(X) \
1127 { static_cast<uint16_t>(TLS1_CK_##X & 0xffff), "TLS_" #X }
1128
1129struct cipher_list {
1130 uint16_t cipher;
1131 const char* cipher_str;
1132};
1133
1134// TODO(torbjorng): Perhaps add more cipher suites to these lists.
1135static const cipher_list OK_RSA_ciphers[] = {
1136 CDEF(ECDHE_RSA_WITH_AES_128_CBC_SHA),
1137 CDEF(ECDHE_RSA_WITH_AES_256_CBC_SHA),
1138 CDEF(ECDHE_RSA_WITH_AES_128_GCM_SHA256),
1139#ifdef TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA256
1140 CDEF(ECDHE_RSA_WITH_AES_256_GCM_SHA256),
1141#endif
1142 CDEF(ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256),
1143};
1144
1145static const cipher_list OK_ECDSA_ciphers[] = {
1146 CDEF(ECDHE_ECDSA_WITH_AES_128_CBC_SHA),
1147 CDEF(ECDHE_ECDSA_WITH_AES_256_CBC_SHA),
1148 CDEF(ECDHE_ECDSA_WITH_AES_128_GCM_SHA256),
1149#ifdef TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA256
1150 CDEF(ECDHE_ECDSA_WITH_AES_256_GCM_SHA256),
1151#endif
1152 CDEF(ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256),
1153};
1154#undef CDEF
1155
1156bool OpenSSLStreamAdapter::IsAcceptableCipher(int cipher, KeyType key_type) {
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001157 if (key_type == KT_RSA) {
torbjorng43166b82016-03-11 00:06:47 -08001158 for (const cipher_list& c : OK_RSA_ciphers) {
1159 if (cipher == c.cipher)
1160 return true;
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +02001161 }
Joachim Bauch831c5582015-05-20 12:48:41 +02001162 }
torbjorng43166b82016-03-11 00:06:47 -08001163
1164 if (key_type == KT_ECDSA) {
1165 for (const cipher_list& c : OK_ECDSA_ciphers) {
1166 if (cipher == c.cipher)
1167 return true;
1168 }
1169 }
1170
1171 return false;
1172}
1173
1174bool OpenSSLStreamAdapter::IsAcceptableCipher(const std::string& cipher,
1175 KeyType key_type) {
1176 if (key_type == KT_RSA) {
1177 for (const cipher_list& c : OK_RSA_ciphers) {
1178 if (cipher == c.cipher_str)
1179 return true;
1180 }
1181 }
1182
1183 if (key_type == KT_ECDSA) {
1184 for (const cipher_list& c : OK_ECDSA_ciphers) {
1185 if (cipher == c.cipher_str)
1186 return true;
1187 }
1188 }
1189
1190 return false;
pthatcher@webrtc.org3ee4fe52015-02-11 22:34:36 +00001191}
1192
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001193} // namespace rtc
1194
1195#endif // HAVE_OPENSSL_SSL_H