| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 1 | /* | 
|  | 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 |  | 
| Steve Anton | 10542f2 | 2019-01-11 17:11:00 | [diff] [blame] | 11 | #include "rtc_base/ssl_stream_adapter.h" | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 12 |  | 
| Harald Alvestrand | 53c424e | 2024-08-01 06:31:02 | [diff] [blame] | 13 | #include <cstddef> | 
|  | 14 | #include <cstdint> | 
|  | 15 | #include <memory> | 
| Jonas Oreland | 50544d8 | 2025-05-07 08:44:59 | [diff] [blame] | 16 | #include <optional> | 
|  | 17 | #include <set> | 
| Harald Alvestrand | 53c424e | 2024-08-01 06:31:02 | [diff] [blame] | 18 | #include <string> | 
|  | 19 | #include <utility> | 
| Jonas Oreland | 50544d8 | 2025-05-07 08:44:59 | [diff] [blame] | 20 | #include <vector> | 
| Harald Alvestrand | 53c424e | 2024-08-01 06:31:02 | [diff] [blame] | 21 |  | 
|  | 22 | #include "absl/functional/any_invocable.h" | 
| Ali Tofigh | 7fa9057 | 2022-03-17 14:47:49 | [diff] [blame] | 23 | #include "absl/strings/string_view.h" | 
| Philipp Hancke | 4060745 | 2024-11-26 18:50:26 | [diff] [blame] | 24 | #include "api/array_view.h" | 
| Evan Shrubsole | daf96cf | 2025-03-31 12:34:02 | [diff] [blame] | 25 | #include "api/field_trials_view.h" | 
| Steve Anton | 10542f2 | 2019-01-11 17:11:00 | [diff] [blame] | 26 | #include "rtc_base/openssl_stream_adapter.h" | 
| Harald Alvestrand | 53c424e | 2024-08-01 06:31:02 | [diff] [blame] | 27 | #include "rtc_base/ssl_identity.h" | 
|  | 28 | #include "rtc_base/stream.h" | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 29 |  | 
| Evan Shrubsole | eb835d0 | 2025-03-12 09:41:06 | [diff] [blame] | 30 | namespace webrtc { | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 31 |  | 
| Philipp Hancke | db519e7 | 2024-06-25 16:26:45 | [diff] [blame] | 32 | // Deprecated, prefer SrtpCryptoSuiteToName. | 
| Björn Terelius | e71fa4e | 2024-06-25 09:55:12 | [diff] [blame] | 33 | const char kCsAesCm128HmacSha1_80[] = "AES_CM_128_HMAC_SHA1_80"; | 
|  | 34 | const char kCsAesCm128HmacSha1_32[] = "AES_CM_128_HMAC_SHA1_32"; | 
|  | 35 | const char kCsAeadAes128Gcm[] = "AEAD_AES_128_GCM"; | 
|  | 36 | const char kCsAeadAes256Gcm[] = "AEAD_AES_256_GCM"; | 
|  | 37 |  | 
| Guo-wei Shieh | 521ed7b | 2015-11-19 03:41:53 | [diff] [blame] | 38 | std::string SrtpCryptoSuiteToName(int crypto_suite) { | 
| jbauch | cb56065 | 2016-08-04 12:20:32 | [diff] [blame] | 39 | switch (crypto_suite) { | 
| Björn Terelius | e71fa4e | 2024-06-25 09:55:12 | [diff] [blame] | 40 | case kSrtpAes128CmSha1_80: | 
| Philipp Hancke | db519e7 | 2024-06-25 16:26:45 | [diff] [blame] | 41 | return "AES_CM_128_HMAC_SHA1_80"; | 
|  | 42 | case kSrtpAes128CmSha1_32: | 
|  | 43 | return "AES_CM_128_HMAC_SHA1_32"; | 
| Mirko Bonadei | 7750d80 | 2021-07-26 15:27:42 | [diff] [blame] | 44 | case kSrtpAeadAes128Gcm: | 
| Philipp Hancke | db519e7 | 2024-06-25 16:26:45 | [diff] [blame] | 45 | return "AEAD_AES_128_GCM"; | 
| Mirko Bonadei | 7750d80 | 2021-07-26 15:27:42 | [diff] [blame] | 46 | case kSrtpAeadAes256Gcm: | 
| Philipp Hancke | db519e7 | 2024-06-25 16:26:45 | [diff] [blame] | 47 | return "AEAD_AES_256_GCM"; | 
| Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 48 | default: | 
|  | 49 | return std::string(); | 
| jbauch | cb56065 | 2016-08-04 12:20:32 | [diff] [blame] | 50 | } | 
| Guo-wei Shieh | 521ed7b | 2015-11-19 03:41:53 | [diff] [blame] | 51 | } | 
|  | 52 |  | 
| Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 53 | bool GetSrtpKeyAndSaltLengths(int crypto_suite, | 
|  | 54 | int* key_length, | 
|  | 55 | int* salt_length) { | 
| jbauch | cb56065 | 2016-08-04 12:20:32 | [diff] [blame] | 56 | switch (crypto_suite) { | 
| Mirko Bonadei | 7750d80 | 2021-07-26 15:27:42 | [diff] [blame] | 57 | case kSrtpAes128CmSha1_32: | 
|  | 58 | case kSrtpAes128CmSha1_80: | 
| Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 59 | // SRTP_AES128_CM_HMAC_SHA1_32 and SRTP_AES128_CM_HMAC_SHA1_80 are defined | 
|  | 60 | // in RFC 5764 to use a 128 bits key and 112 bits salt for the cipher. | 
|  | 61 | *key_length = 16; | 
|  | 62 | *salt_length = 14; | 
|  | 63 | break; | 
| Mirko Bonadei | 7750d80 | 2021-07-26 15:27:42 | [diff] [blame] | 64 | case kSrtpAeadAes128Gcm: | 
|  | 65 | // kSrtpAeadAes128Gcm is defined in RFC 7714 to use a 128 bits key and | 
| Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 66 | // a 96 bits salt for the cipher. | 
|  | 67 | *key_length = 16; | 
|  | 68 | *salt_length = 12; | 
|  | 69 | break; | 
| Mirko Bonadei | 7750d80 | 2021-07-26 15:27:42 | [diff] [blame] | 70 | case kSrtpAeadAes256Gcm: | 
|  | 71 | // kSrtpAeadAes256Gcm is defined in RFC 7714 to use a 256 bits key and | 
| Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 72 | // a 96 bits salt for the cipher. | 
|  | 73 | *key_length = 32; | 
|  | 74 | *salt_length = 12; | 
|  | 75 | break; | 
|  | 76 | default: | 
|  | 77 | return false; | 
| jbauch | cb56065 | 2016-08-04 12:20:32 | [diff] [blame] | 78 | } | 
|  | 79 | return true; | 
|  | 80 | } | 
|  | 81 |  | 
|  | 82 | bool IsGcmCryptoSuite(int crypto_suite) { | 
| Mirko Bonadei | 7750d80 | 2021-07-26 15:27:42 | [diff] [blame] | 83 | return (crypto_suite == kSrtpAeadAes256Gcm || | 
|  | 84 | crypto_suite == kSrtpAeadAes128Gcm); | 
| jbauch | cb56065 | 2016-08-04 12:20:32 | [diff] [blame] | 85 | } | 
|  | 86 |  | 
| Harald Alvestrand | 8515d5a | 2020-03-20 21:51:32 | [diff] [blame] | 87 | std::unique_ptr<SSLStreamAdapter> SSLStreamAdapter::Create( | 
| Evan Shrubsole | eb835d0 | 2025-03-12 09:41:06 | [diff] [blame] | 88 | std::unique_ptr<StreamInterface> stream, | 
| Evan Shrubsole | 318cc33 | 2025-05-09 10:38:33 | [diff] [blame] | 89 | absl::AnyInvocable<void(SSLHandshakeError)> handshake_error, | 
| Evan Shrubsole | eb835d0 | 2025-03-12 09:41:06 | [diff] [blame] | 90 | const FieldTrialsView* field_trials) { | 
| Evan Shrubsole | daf96cf | 2025-03-31 12:34:02 | [diff] [blame] | 91 | return std::make_unique<OpenSSLStreamAdapter>( | 
| Jonas Oreland | 12574a3 | 2024-12-19 14:15:50 | [diff] [blame] | 92 | std::move(stream), std::move(handshake_error), field_trials); | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 93 | } | 
|  | 94 |  | 
| Taylor Brandstetter | 4f0dfbd | 2016-06-16 00:15:23 | [diff] [blame] | 95 | bool SSLStreamAdapter::IsBoringSsl() { | 
| Evan Shrubsole | daf96cf | 2025-03-31 12:34:02 | [diff] [blame] | 96 | return OpenSSLStreamAdapter::IsBoringSsl(); | 
| Taylor Brandstetter | 4f0dfbd | 2016-06-16 00:15:23 | [diff] [blame] | 97 | } | 
| Evan Shrubsole | 8f7678f | 2025-04-01 14:23:55 | [diff] [blame] | 98 | bool SSLStreamAdapter::IsAcceptableCipher(int cipher, KeyType key_type) { | 
| Evan Shrubsole | daf96cf | 2025-03-31 12:34:02 | [diff] [blame] | 99 | return OpenSSLStreamAdapter::IsAcceptableCipher(cipher, key_type); | 
| Guo-wei Shieh | 456696a | 2015-10-01 04:48:54 | [diff] [blame] | 100 | } | 
| Ali Tofigh | 7fa9057 | 2022-03-17 14:47:49 | [diff] [blame] | 101 | bool SSLStreamAdapter::IsAcceptableCipher(absl::string_view cipher, | 
| Evan Shrubsole | 8f7678f | 2025-04-01 14:23:55 | [diff] [blame] | 102 | KeyType key_type) { | 
| Evan Shrubsole | daf96cf | 2025-03-31 12:34:02 | [diff] [blame] | 103 | return OpenSSLStreamAdapter::IsAcceptableCipher(cipher, key_type); | 
| torbjorng | 43166b8 | 2016-03-11 08:06:47 | [diff] [blame] | 104 | } | 
| Benjamin Wright | b19b497 | 2018-10-25 17:46:49 | [diff] [blame] | 105 |  | 
| Jonas Oreland | 50544d8 | 2025-05-07 08:44:59 | [diff] [blame] | 106 | std::optional<std::string> | 
|  | 107 | SSLStreamAdapter::GetEphemeralKeyExchangeCipherGroupName(uint16_t group_id) { | 
|  | 108 | #if defined(OPENSSL_IS_BORINGSSL) | 
|  | 109 | auto val = SSL_get_group_name(group_id); | 
|  | 110 | if (val != nullptr) { | 
|  | 111 | return std::string(val); | 
|  | 112 | } | 
|  | 113 | #endif | 
|  | 114 | return std::nullopt; | 
|  | 115 | } | 
|  | 116 |  | 
|  | 117 | std::set<uint16_t> | 
|  | 118 | SSLStreamAdapter::GetSupportedEphemeralKeyExchangeCipherGroups() { | 
|  | 119 | return { | 
|  | 120 | // It would be nice if BoringSSL had a function like this! | 
|  | 121 | #ifdef SSL_GROUP_SECP224R1 | 
|  | 122 | SSL_GROUP_SECP224R1, | 
|  | 123 | #endif | 
|  | 124 | #ifdef SSL_GROUP_SECP256R1 | 
|  | 125 | SSL_GROUP_SECP256R1, | 
|  | 126 | #endif | 
|  | 127 | #ifdef SSL_GROUP_SECP384R1 | 
|  | 128 | SSL_GROUP_SECP384R1, | 
|  | 129 | #endif | 
|  | 130 | #ifdef SSL_GROUP_SECP521R1 | 
|  | 131 | SSL_GROUP_SECP521R1, | 
|  | 132 | #endif | 
|  | 133 | #ifdef SSL_GROUP_X25519 | 
|  | 134 | SSL_GROUP_X25519, | 
|  | 135 | #endif | 
|  | 136 | #ifdef SSL_GROUP_X25519_MLKEM768 | 
|  | 137 | SSL_GROUP_X25519_MLKEM768, | 
|  | 138 | #endif | 
|  | 139 | }; | 
|  | 140 | } | 
|  | 141 |  | 
|  | 142 | std::vector<uint16_t> | 
|  | 143 | SSLStreamAdapter::GetDefaultEphemeralKeyExchangeCipherGroups( | 
|  | 144 | const FieldTrialsView* field_trials) { | 
|  | 145 | // It would be nice if BoringSSL had a function like this! | 
|  | 146 | // from boringssl/src/ssl/extensions.cc kDefaultGroups. | 
|  | 147 | if (field_trials && field_trials->IsEnabled("WebRTC-EnableDtlsPqc")) { | 
|  | 148 | return { | 
|  | 149 | #ifdef SSL_GROUP_X25519_MLKEM768 | 
|  | 150 | SSL_GROUP_X25519_MLKEM768, | 
|  | 151 | #endif | 
|  | 152 | #ifdef SSL_GROUP_X25519 | 
|  | 153 | SSL_GROUP_X25519, | 
|  | 154 | #endif | 
|  | 155 | #ifdef SSL_GROUP_SECP256R1 | 
|  | 156 | SSL_GROUP_SECP256R1, | 
|  | 157 | #endif | 
|  | 158 | #ifdef SSL_GROUP_SECP384R1 | 
|  | 159 | SSL_GROUP_SECP384R1, | 
|  | 160 | #endif | 
|  | 161 | }; | 
|  | 162 | } | 
|  | 163 | return { | 
|  | 164 | #ifdef SSL_GROUP_X25519 | 
|  | 165 | SSL_GROUP_X25519, | 
|  | 166 | #endif | 
|  | 167 | #ifdef SSL_GROUP_SECP256R1 | 
|  | 168 | SSL_GROUP_SECP256R1, | 
|  | 169 | #endif | 
|  | 170 | #ifdef SSL_GROUP_SECP384R1 | 
|  | 171 | SSL_GROUP_SECP384R1, | 
|  | 172 | #endif | 
|  | 173 | }; | 
|  | 174 | } | 
|  | 175 |  | 
| Philipp Hancke | 4060745 | 2024-11-26 18:50:26 | [diff] [blame] | 176 | // Default shim for backward compat. | 
|  | 177 | bool SSLStreamAdapter::SetPeerCertificateDigest( | 
|  | 178 | absl::string_view digest_alg, | 
|  | 179 | const unsigned char* digest_val, | 
|  | 180 | size_t digest_len, | 
|  | 181 | SSLPeerCertificateDigestError* error) { | 
|  | 182 | unsigned char* nonconst_val = const_cast<unsigned char*>(digest_val); | 
|  | 183 | SSLPeerCertificateDigestError ret = SetPeerCertificateDigest( | 
| Evan Shrubsole | f0a4647 | 2025-04-17 07:33:36 | [diff] [blame] | 184 | digest_alg, ArrayView<uint8_t>(nonconst_val, digest_len)); | 
| Philipp Hancke | 4060745 | 2024-11-26 18:50:26 | [diff] [blame] | 185 | if (error) | 
|  | 186 | *error = ret; | 
|  | 187 | return ret == SSLPeerCertificateDigestError::NONE; | 
|  | 188 | } | 
|  | 189 |  | 
| Benjamin Wright | b19b497 | 2018-10-25 17:46:49 | [diff] [blame] | 190 | /////////////////////////////////////////////////////////////////////////////// | 
|  | 191 | // Test only settings | 
|  | 192 | /////////////////////////////////////////////////////////////////////////////// | 
|  | 193 |  | 
|  | 194 | void SSLStreamAdapter::EnableTimeCallbackForTesting() { | 
| Evan Shrubsole | daf96cf | 2025-03-31 12:34:02 | [diff] [blame] | 195 | OpenSSLStreamAdapter::EnableTimeCallbackForTesting(); | 
| deadbeef | 6cf94a0 | 2016-11-29 01:38:34 | [diff] [blame] | 196 | } | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 197 |  | 
| Jonas Oreland | ac40185 | 2024-12-18 08:18:21 | [diff] [blame] | 198 | SSLProtocolVersion SSLStreamAdapter::GetMaxSupportedDTLSProtocolVersion() { | 
| Evan Shrubsole | daf96cf | 2025-03-31 12:34:02 | [diff] [blame] | 199 | return OpenSSLStreamAdapter::GetMaxSupportedDTLSProtocolVersion(); | 
| Jonas Oreland | ac40185 | 2024-12-18 08:18:21 | [diff] [blame] | 200 | } | 
|  | 201 |  | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 | [diff] [blame] | 202 | /////////////////////////////////////////////////////////////////////////////// | 
|  | 203 |  | 
| Evan Shrubsole | eb835d0 | 2025-03-12 09:41:06 | [diff] [blame] | 204 | }  // namespace webrtc |