OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #if HAVE_OPENSSL_SSL_H | |
12 | |
13 #include "webrtc/base/opensslstreamadapter.h" | 11 #include "webrtc/base/opensslstreamadapter.h" |
14 | 12 |
15 #include <openssl/bio.h> | 13 #include <openssl/bio.h> |
16 #include <openssl/crypto.h> | 14 #include <openssl/crypto.h> |
17 #include <openssl/err.h> | 15 #include <openssl/err.h> |
18 #include <openssl/rand.h> | 16 #include <openssl/rand.h> |
19 #include <openssl/tls1.h> | 17 #include <openssl/tls1.h> |
20 #include <openssl/x509v3.h> | 18 #include <openssl/x509v3.h> |
21 #ifndef OPENSSL_IS_BORINGSSL | 19 #ifndef OPENSSL_IS_BORINGSSL |
22 #include <openssl/dtls1.h> | 20 #include <openssl/dtls1.h> |
(...skipping 15 matching lines...) Expand all Loading... |
38 #include "webrtc/base/stringutils.h" | 36 #include "webrtc/base/stringutils.h" |
39 #include "webrtc/base/timeutils.h" | 37 #include "webrtc/base/timeutils.h" |
40 #include "webrtc/base/thread.h" | 38 #include "webrtc/base/thread.h" |
41 | 39 |
42 namespace { | 40 namespace { |
43 bool g_use_time_callback_for_testing = false; | 41 bool g_use_time_callback_for_testing = false; |
44 } | 42 } |
45 | 43 |
46 namespace rtc { | 44 namespace rtc { |
47 | 45 |
48 #if (OPENSSL_VERSION_NUMBER >= 0x10001000L) | 46 #if (OPENSSL_VERSION_NUMBER < 0x10001000L) |
49 #define HAVE_DTLS_SRTP | 47 #error "webrtc requires at least OpenSSL version 1.0.1, to support DTLS-SRTP" |
50 #endif | 48 #endif |
51 | 49 |
52 #ifdef HAVE_DTLS_SRTP | |
53 // SRTP cipher suite table. |internal_name| is used to construct a | 50 // SRTP cipher suite table. |internal_name| is used to construct a |
54 // colon-separated profile strings which is needed by | 51 // colon-separated profile strings which is needed by |
55 // SSL_CTX_set_tlsext_use_srtp(). | 52 // SSL_CTX_set_tlsext_use_srtp(). |
56 struct SrtpCipherMapEntry { | 53 struct SrtpCipherMapEntry { |
57 const char* internal_name; | 54 const char* internal_name; |
58 const int id; | 55 const int id; |
59 }; | 56 }; |
60 | 57 |
61 // This isn't elegant, but it's better than an external reference | 58 // This isn't elegant, but it's better than an external reference |
62 static SrtpCipherMapEntry SrtpCipherMap[] = { | 59 static SrtpCipherMapEntry SrtpCipherMap[] = { |
63 {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80}, | 60 {"SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80}, |
64 {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32}, | 61 {"SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32}, |
65 {"SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM}, | 62 {"SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM}, |
66 {"SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM}, | 63 {"SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM}, |
67 {nullptr, 0}}; | 64 {nullptr, 0}}; |
68 #endif | |
69 | 65 |
70 #ifdef OPENSSL_IS_BORINGSSL | 66 #ifdef OPENSSL_IS_BORINGSSL |
71 // Not used in production code. Actual time should be relative to Jan 1, 1970. | 67 // Not used in production code. Actual time should be relative to Jan 1, 1970. |
72 static void TimeCallbackForTesting(const SSL* ssl, struct timeval* out_clock) { | 68 static void TimeCallbackForTesting(const SSL* ssl, struct timeval* out_clock) { |
73 int64_t time = TimeNanos(); | 69 int64_t time = TimeNanos(); |
74 out_clock->tv_sec = time / kNumNanosecsPerSec; | 70 out_clock->tv_sec = time / kNumNanosecsPerSec; |
75 out_clock->tv_usec = (time % kNumNanosecsPerSec) / kNumNanosecsPerMicrosec; | 71 out_clock->tv_usec = (time % kNumNanosecsPerSec) / kNumNanosecsPerMicrosec; |
76 } | 72 } |
77 #else // #ifdef OPENSSL_IS_BORINGSSL | 73 #else // #ifdef OPENSSL_IS_BORINGSSL |
78 | 74 |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 return -1; | 421 return -1; |
426 } | 422 } |
427 | 423 |
428 // Key Extractor interface | 424 // Key Extractor interface |
429 bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label, | 425 bool OpenSSLStreamAdapter::ExportKeyingMaterial(const std::string& label, |
430 const uint8_t* context, | 426 const uint8_t* context, |
431 size_t context_len, | 427 size_t context_len, |
432 bool use_context, | 428 bool use_context, |
433 uint8_t* result, | 429 uint8_t* result, |
434 size_t result_len) { | 430 size_t result_len) { |
435 #ifdef HAVE_DTLS_SRTP | |
436 int i; | 431 int i; |
437 | 432 |
438 i = SSL_export_keying_material(ssl_, result, result_len, label.c_str(), | 433 i = SSL_export_keying_material(ssl_, result, result_len, label.c_str(), |
439 label.length(), const_cast<uint8_t*>(context), | 434 label.length(), const_cast<uint8_t*>(context), |
440 context_len, use_context); | 435 context_len, use_context); |
441 | 436 |
442 if (i != 1) | 437 if (i != 1) |
443 return false; | 438 return false; |
444 | 439 |
445 return true; | 440 return true; |
446 #else | |
447 return false; | |
448 #endif | |
449 } | 441 } |
450 | 442 |
451 bool OpenSSLStreamAdapter::SetDtlsSrtpCryptoSuites( | 443 bool OpenSSLStreamAdapter::SetDtlsSrtpCryptoSuites( |
452 const std::vector<int>& ciphers) { | 444 const std::vector<int>& ciphers) { |
453 #ifdef HAVE_DTLS_SRTP | |
454 std::string internal_ciphers; | 445 std::string internal_ciphers; |
455 | 446 |
456 if (state_ != SSL_NONE) | 447 if (state_ != SSL_NONE) |
457 return false; | 448 return false; |
458 | 449 |
459 for (std::vector<int>::const_iterator cipher = ciphers.begin(); | 450 for (std::vector<int>::const_iterator cipher = ciphers.begin(); |
460 cipher != ciphers.end(); ++cipher) { | 451 cipher != ciphers.end(); ++cipher) { |
461 bool found = false; | 452 bool found = false; |
462 for (SrtpCipherMapEntry* entry = SrtpCipherMap; entry->internal_name; | 453 for (SrtpCipherMapEntry* entry = SrtpCipherMap; entry->internal_name; |
463 ++entry) { | 454 ++entry) { |
(...skipping 10 matching lines...) Expand all Loading... |
474 LOG(LS_ERROR) << "Could not find cipher: " << *cipher; | 465 LOG(LS_ERROR) << "Could not find cipher: " << *cipher; |
475 return false; | 466 return false; |
476 } | 467 } |
477 } | 468 } |
478 | 469 |
479 if (internal_ciphers.empty()) | 470 if (internal_ciphers.empty()) |
480 return false; | 471 return false; |
481 | 472 |
482 srtp_ciphers_ = internal_ciphers; | 473 srtp_ciphers_ = internal_ciphers; |
483 return true; | 474 return true; |
484 #else | |
485 return false; | |
486 #endif | |
487 } | 475 } |
488 | 476 |
489 bool OpenSSLStreamAdapter::GetDtlsSrtpCryptoSuite(int* crypto_suite) { | 477 bool OpenSSLStreamAdapter::GetDtlsSrtpCryptoSuite(int* crypto_suite) { |
490 #ifdef HAVE_DTLS_SRTP | |
491 RTC_DCHECK(state_ == SSL_CONNECTED); | 478 RTC_DCHECK(state_ == SSL_CONNECTED); |
492 if (state_ != SSL_CONNECTED) | 479 if (state_ != SSL_CONNECTED) |
493 return false; | 480 return false; |
494 | 481 |
495 const SRTP_PROTECTION_PROFILE *srtp_profile = | 482 const SRTP_PROTECTION_PROFILE *srtp_profile = |
496 SSL_get_selected_srtp_profile(ssl_); | 483 SSL_get_selected_srtp_profile(ssl_); |
497 | 484 |
498 if (!srtp_profile) | 485 if (!srtp_profile) |
499 return false; | 486 return false; |
500 | 487 |
501 *crypto_suite = srtp_profile->id; | 488 *crypto_suite = srtp_profile->id; |
502 RTC_DCHECK(!SrtpCryptoSuiteToName(*crypto_suite).empty()); | 489 RTC_DCHECK(!SrtpCryptoSuiteToName(*crypto_suite).empty()); |
503 return true; | 490 return true; |
504 #else | |
505 return false; | |
506 #endif | |
507 } | 491 } |
508 | 492 |
509 bool OpenSSLStreamAdapter::IsTlsConnected() { | 493 bool OpenSSLStreamAdapter::IsTlsConnected() { |
510 return state_ == SSL_CONNECTED; | 494 return state_ == SSL_CONNECTED; |
511 } | 495 } |
512 | 496 |
513 int OpenSSLStreamAdapter::StartSSL() { | 497 int OpenSSLStreamAdapter::StartSSL() { |
514 if (state_ != SSL_NONE) { | 498 if (state_ != SSL_NONE) { |
515 // Don't allow StartSSL to be called twice. | 499 // Don't allow StartSSL to be called twice. |
516 return -1; | 500 return -1; |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1089 | 1073 |
1090 SSL_CTX_set_verify(ctx, mode, SSLVerifyCallback); | 1074 SSL_CTX_set_verify(ctx, mode, SSLVerifyCallback); |
1091 SSL_CTX_set_verify_depth(ctx, 4); | 1075 SSL_CTX_set_verify_depth(ctx, 4); |
1092 // Select list of available ciphers. Note that !SHA256 and !SHA384 only | 1076 // Select list of available ciphers. Note that !SHA256 and !SHA384 only |
1093 // remove HMAC-SHA256 and HMAC-SHA384 cipher suites, not GCM cipher suites | 1077 // remove HMAC-SHA256 and HMAC-SHA384 cipher suites, not GCM cipher suites |
1094 // with SHA256 or SHA384 as the handshake hash. | 1078 // with SHA256 or SHA384 as the handshake hash. |
1095 // This matches the list of SSLClientSocketOpenSSL in Chromium. | 1079 // This matches the list of SSLClientSocketOpenSSL in Chromium. |
1096 SSL_CTX_set_cipher_list(ctx, | 1080 SSL_CTX_set_cipher_list(ctx, |
1097 "DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK"); | 1081 "DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK"); |
1098 | 1082 |
1099 #ifdef HAVE_DTLS_SRTP | |
1100 if (!srtp_ciphers_.empty()) { | 1083 if (!srtp_ciphers_.empty()) { |
1101 if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) { | 1084 if (SSL_CTX_set_tlsext_use_srtp(ctx, srtp_ciphers_.c_str())) { |
1102 SSL_CTX_free(ctx); | 1085 SSL_CTX_free(ctx); |
1103 return NULL; | 1086 return NULL; |
1104 } | 1087 } |
1105 } | 1088 } |
1106 #endif | |
1107 | 1089 |
1108 return ctx; | 1090 return ctx; |
1109 } | 1091 } |
1110 | 1092 |
1111 bool OpenSSLStreamAdapter::VerifyPeerCertificate() { | 1093 bool OpenSSLStreamAdapter::VerifyPeerCertificate() { |
1112 if (!has_peer_certificate_digest() || !peer_certificate_) { | 1094 if (!has_peer_certificate_digest() || !peer_certificate_) { |
1113 LOG(LS_WARNING) << "Missing digest or peer certificate."; | 1095 LOG(LS_WARNING) << "Missing digest or peer certificate."; |
1114 return false; | 1096 return false; |
1115 } | 1097 } |
1116 | 1098 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 // If the peer certificate digest isn't known yet, we'll wait to verify | 1144 // If the peer certificate digest isn't known yet, we'll wait to verify |
1163 // until it's known, and for now just return a success status. | 1145 // until it's known, and for now just return a success status. |
1164 if (stream->peer_certificate_digest_algorithm_.empty()) { | 1146 if (stream->peer_certificate_digest_algorithm_.empty()) { |
1165 LOG(LS_INFO) << "Waiting to verify certificate until digest is known."; | 1147 LOG(LS_INFO) << "Waiting to verify certificate until digest is known."; |
1166 return 1; | 1148 return 1; |
1167 } | 1149 } |
1168 | 1150 |
1169 return stream->VerifyPeerCertificate(); | 1151 return stream->VerifyPeerCertificate(); |
1170 } | 1152 } |
1171 | 1153 |
1172 bool OpenSSLStreamAdapter::HaveDtls() { | |
1173 return true; | |
1174 } | |
1175 | |
1176 bool OpenSSLStreamAdapter::HaveDtlsSrtp() { | |
1177 #ifdef HAVE_DTLS_SRTP | |
1178 return true; | |
1179 #else | |
1180 return false; | |
1181 #endif | |
1182 } | |
1183 | |
1184 bool OpenSSLStreamAdapter::HaveExporter() { | |
1185 #ifdef HAVE_DTLS_SRTP | |
1186 return true; | |
1187 #else | |
1188 return false; | |
1189 #endif | |
1190 } | |
1191 | |
1192 bool OpenSSLStreamAdapter::IsBoringSsl() { | 1154 bool OpenSSLStreamAdapter::IsBoringSsl() { |
1193 #ifdef OPENSSL_IS_BORINGSSL | 1155 #ifdef OPENSSL_IS_BORINGSSL |
1194 return true; | 1156 return true; |
1195 #else | 1157 #else |
1196 return false; | 1158 return false; |
1197 #endif | 1159 #endif |
1198 } | 1160 } |
1199 | 1161 |
1200 #define CDEF(X) \ | 1162 #define CDEF(X) \ |
1201 { static_cast<uint16_t>(TLS1_CK_##X & 0xffff), "TLS_" #X } | 1163 { static_cast<uint16_t>(TLS1_CK_##X & 0xffff), "TLS_" #X } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1266 } | 1228 } |
1267 | 1229 |
1268 return false; | 1230 return false; |
1269 } | 1231 } |
1270 | 1232 |
1271 void OpenSSLStreamAdapter::enable_time_callback_for_testing() { | 1233 void OpenSSLStreamAdapter::enable_time_callback_for_testing() { |
1272 g_use_time_callback_for_testing = true; | 1234 g_use_time_callback_for_testing = true; |
1273 } | 1235 } |
1274 | 1236 |
1275 } // namespace rtc | 1237 } // namespace rtc |
1276 | |
1277 #endif // HAVE_OPENSSL_SSL_H | |
OLD | NEW |