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 11 #ifndef RTC_BASE_SSL_STREAM_ADAPTER_H_ 12 #define RTC_BASE_SSL_STREAM_ADAPTER_H_ 13 14 #include <stddef.h> 15 #include <stdint.h> 16 17 #include <memory> 18 #include <string> 19 #include <vector> 20 21 #include "absl/memory/memory.h" 22 #include "absl/strings/string_view.h" 23 #include "rtc_base/ssl_certificate.h" 24 #include "rtc_base/ssl_identity.h" 25 #include "rtc_base/stream.h" 26 #include "rtc_base/third_party/sigslot/sigslot.h" 27 28 namespace rtc { 29 30 // Constants for SSL profile. 31 constexpr int kTlsNullWithNullNull = 0; 32 constexpr int kSslCipherSuiteMaxValue = 0xFFFF; 33 34 // Constants for SRTP profiles. 35 constexpr int kSrtpInvalidCryptoSuite = 0; 36 constexpr int kSrtpAes128CmSha1_80 = 0x0001; 37 constexpr int kSrtpAes128CmSha1_32 = 0x0002; 38 constexpr int kSrtpAeadAes128Gcm = 0x0007; 39 constexpr int kSrtpAeadAes256Gcm = 0x0008; 40 constexpr int kSrtpCryptoSuiteMaxValue = 0xFFFF; 41 42 // Names of SRTP profiles listed above. 43 // 128-bit AES with 80-bit SHA-1 HMAC. 44 extern const char kCsAesCm128HmacSha1_80[]; 45 // 128-bit AES with 32-bit SHA-1 HMAC. 46 extern const char kCsAesCm128HmacSha1_32[]; 47 // 128-bit AES GCM with 16 byte AEAD auth tag. 48 extern const char kCsAeadAes128Gcm[]; 49 // 256-bit AES GCM with 16 byte AEAD auth tag. 50 extern const char kCsAeadAes256Gcm[]; 51 52 // Given the DTLS-SRTP protection profile ID, as defined in 53 // https://tools.ietf.org/html/rfc4568#section-6.2 , return the SRTP profile 54 // name, as defined in https://tools.ietf.org/html/rfc5764#section-4.1.2. 55 std::string SrtpCryptoSuiteToName(int crypto_suite); 56 57 // The reverse of above conversion. 58 int SrtpCryptoSuiteFromName(absl::string_view crypto_suite); 59 60 // Get key length and salt length for given crypto suite. Returns true for 61 // valid suites, otherwise false. 62 bool GetSrtpKeyAndSaltLengths(int crypto_suite, 63 int* key_length, 64 int* salt_length); 65 66 // Returns true if the given crypto suite id uses a GCM cipher. 67 bool IsGcmCryptoSuite(int crypto_suite); 68 69 // Returns true if the given crypto suite name uses a GCM cipher. 70 bool IsGcmCryptoSuiteName(absl::string_view crypto_suite); 71 72 // SSLStreamAdapter : A StreamInterfaceAdapter that does SSL/TLS. 73 // After SSL has been started, the stream will only open on successful 74 // SSL verification of certificates, and the communication is 75 // encrypted of course. 76 // 77 // This class was written with SSLAdapter as a starting point. It 78 // offers a similar interface, with two differences: there is no 79 // support for a restartable SSL connection, and this class has a 80 // peer-to-peer mode. 81 // 82 // The SSL library requires initialization and cleanup. Static method 83 // for doing this are in SSLAdapter. They should possibly be moved out 84 // to a neutral class. 85 86 enum SSLRole { SSL_CLIENT, SSL_SERVER }; 87 enum SSLMode { SSL_MODE_TLS, SSL_MODE_DTLS }; 88 89 // Note: TLS_10, TLS_11, and DTLS_10 will all be ignored, and only DTLS1_2 will 90 // be accepted unless the trial flag WebRTC-LegacyTlsProtocols/Enabled/ is 91 // passed in or an explicit override is used. Support for the legacy protocol 92 // versions will be completely removed in the future. 93 // See https://bugs.webrtc.org/10261. 94 enum SSLProtocolVersion { 95 SSL_PROTOCOL_NOT_GIVEN = -1, 96 SSL_PROTOCOL_TLS_10 = 0, 97 SSL_PROTOCOL_TLS_11, 98 SSL_PROTOCOL_TLS_12, 99 SSL_PROTOCOL_DTLS_10 = SSL_PROTOCOL_TLS_11, 100 SSL_PROTOCOL_DTLS_12 = SSL_PROTOCOL_TLS_12, 101 }; 102 enum class SSLPeerCertificateDigestError { 103 NONE, 104 UNKNOWN_ALGORITHM, 105 INVALID_LENGTH, 106 VERIFICATION_FAILED, 107 }; 108 109 // Errors for Read -- in the high range so no conflict with OpenSSL. 110 enum { SSE_MSG_TRUNC = 0xff0001 }; 111 112 // Used to send back UMA histogram value. Logged when Dtls handshake fails. 113 enum class SSLHandshakeError { UNKNOWN, INCOMPATIBLE_CIPHERSUITE, MAX_VALUE }; 114 115 class SSLStreamAdapter : public StreamInterface, public sigslot::has_slots<> { 116 public: 117 // Instantiate an SSLStreamAdapter wrapping the given stream, 118 // (using the selected implementation for the platform). 119 // Caller is responsible for freeing the returned object. 120 static std::unique_ptr<SSLStreamAdapter> Create( 121 std::unique_ptr<StreamInterface> stream); 122 123 SSLStreamAdapter() = default; 124 ~SSLStreamAdapter() override = default; 125 126 // Specify our SSL identity: key and certificate. SSLStream takes ownership 127 // of the SSLIdentity object and will free it when appropriate. Should be 128 // called no more than once on a given SSLStream instance. 129 virtual void SetIdentity(std::unique_ptr<SSLIdentity> identity) = 0; 130 virtual SSLIdentity* GetIdentityForTesting() const = 0; 131 132 // Call this to indicate that we are to play the server role (or client role, 133 // if the default argument is replaced by SSL_CLIENT). 134 // The default argument is for backward compatibility. 135 // TODO([email protected]): rename this SetRole to reflect its new function 136 virtual void SetServerRole(SSLRole role = SSL_SERVER) = 0; 137 138 // Do DTLS or TLS. 139 virtual void SetMode(SSLMode mode) = 0; 140 141 // Set maximum supported protocol version. The highest version supported by 142 // both ends will be used for the connection, i.e. if one party supports 143 // DTLS 1.0 and the other DTLS 1.2, DTLS 1.0 will be used. 144 // If requested version is not supported by underlying crypto library, the 145 // next lower will be used. 146 virtual void SetMaxProtocolVersion(SSLProtocolVersion version) = 0; 147 148 // Set the initial retransmission timeout for DTLS messages. When the timeout 149 // expires, the message gets retransmitted and the timeout is exponentially 150 // increased. 151 // This should only be called before StartSSL(). 152 virtual void SetInitialRetransmissionTimeout(int timeout_ms) = 0; 153 154 // StartSSL starts negotiation with a peer, whose certificate is verified 155 // using the certificate digest. Generally, SetIdentity() and possibly 156 // SetServerRole() should have been called before this. 157 // SetPeerCertificateDigest() must also be called. It may be called after 158 // StartSSLWithPeer() but must be called before the underlying stream opens. 159 // 160 // Use of the stream prior to calling StartSSL will pass data in clear text. 161 // Calling StartSSL causes SSL negotiation to begin as soon as possible: right 162 // away if the underlying wrapped stream is already opened, or else as soon as 163 // it opens. 164 // 165 // StartSSL returns a negative error code on failure. Returning 0 means 166 // success so far, but negotiation is probably not complete and will continue 167 // asynchronously. In that case, the exposed stream will open after 168 // successful negotiation and verification, or an SE_CLOSE event will be 169 // raised if negotiation fails. 170 virtual int StartSSL() = 0; 171 172 // Specify the digest of the certificate that our peer is expected to use. 173 // Only this certificate will be accepted during SSL verification. The 174 // certificate is assumed to have been obtained through some other secure 175 // channel (such as the signaling channel). This must specify the terminal 176 // certificate, not just a CA. SSLStream makes a copy of the digest value. 177 // 178 // Returns true if successful. 179 // `error` is optional and provides more information about the failure. 180 virtual bool SetPeerCertificateDigest( 181 absl::string_view digest_alg, 182 const unsigned char* digest_val, 183 size_t digest_len, 184 SSLPeerCertificateDigestError* error = nullptr) = 0; 185 186 // Retrieves the peer's certificate chain including leaf certificate, if a 187 // connection has been established. 188 virtual std::unique_ptr<SSLCertChain> GetPeerSSLCertChain() const = 0; 189 190 // Retrieves the IANA registration id of the cipher suite used for the 191 // connection (e.g. 0x2F for "TLS_RSA_WITH_AES_128_CBC_SHA"). 192 virtual bool GetSslCipherSuite(int* cipher_suite); 193 194 // Retrieves the enum value for SSL version. 195 // Will return -1 until the version has been negotiated. 196 virtual SSLProtocolVersion GetSslVersion() const = 0; 197 // Retrieves the 2-byte version from the TLS protocol. 198 // Will return false until the version has been negotiated. 199 virtual bool GetSslVersionBytes(int* version) const = 0; 200 201 // Key Exporter interface from RFC 5705 202 // Arguments are: 203 // label -- the exporter label. 204 // part of the RFC defining each exporter 205 // usage (IN) 206 // context/context_len -- a context to bind to for this connection; 207 // optional, can be null, 0 (IN) 208 // use_context -- whether to use the context value 209 // (needed to distinguish no context from 210 // zero-length ones). 211 // result -- where to put the computed value 212 // result_len -- the length of the computed value 213 virtual bool ExportKeyingMaterial(absl::string_view label, 214 const uint8_t* context, 215 size_t context_len, 216 bool use_context, 217 uint8_t* result, 218 size_t result_len); 219 220 // DTLS-SRTP interface 221 virtual bool SetDtlsSrtpCryptoSuites(const std::vector<int>& crypto_suites); 222 virtual bool GetDtlsSrtpCryptoSuite(int* crypto_suite); 223 224 // Returns true if a TLS connection has been established. 225 // The only difference between this and "GetState() == SE_OPEN" is that if 226 // the peer certificate digest hasn't been verified, the state will still be 227 // SS_OPENING but IsTlsConnected should return true. 228 virtual bool IsTlsConnected() = 0; 229 230 // Capabilities testing. 231 // Used to have "DTLS supported", "DTLS-SRTP supported" etc. methods, but now 232 // that's assumed. 233 static bool IsBoringSsl(); 234 235 // Returns true iff the supplied cipher is deemed to be strong. 236 // TODO(torbjorng): Consider removing the KeyType argument. 237 static bool IsAcceptableCipher(int cipher, KeyType key_type); 238 static bool IsAcceptableCipher(absl::string_view cipher, KeyType key_type); 239 240 // TODO(guoweis): Move this away from a static class method. Currently this is 241 // introduced such that any caller could depend on sslstreamadapter.h without 242 // depending on specific SSL implementation. 243 static std::string SslCipherSuiteToName(int cipher_suite); 244 245 //////////////////////////////////////////////////////////////////////////// 246 // Testing only member functions 247 //////////////////////////////////////////////////////////////////////////// 248 249 // Use our timeutils.h source of timing in BoringSSL, allowing us to test 250 // using a fake clock. 251 static void EnableTimeCallbackForTesting(); 252 253 // Deprecated. Do not use this API outside of testing. 254 // Do not set this to false outside of testing. SetClientAuthEnabledForTesting(bool enabled)255 void SetClientAuthEnabledForTesting(bool enabled) { 256 client_auth_enabled_ = enabled; 257 } 258 259 // Deprecated. Do not use this API outside of testing. 260 // Returns true by default, else false if explicitly set to disable client 261 // authentication. GetClientAuthEnabled()262 bool GetClientAuthEnabled() const { return client_auth_enabled_; } 263 264 sigslot::signal1<SSLHandshakeError> SignalSSLHandshakeError; 265 266 private: 267 // If true (default), the client is required to provide a certificate during 268 // handshake. If no certificate is given, handshake fails. This applies to 269 // server mode only. 270 bool client_auth_enabled_ = true; 271 }; 272 273 } // namespace rtc 274 275 #endif // RTC_BASE_SSL_STREAM_ADAPTER_H_ 276