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