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