| 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 |