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