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