• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 WEBRTC_BASE_SSLSTREAMADAPTER_H_
12 #define WEBRTC_BASE_SSLSTREAMADAPTER_H_
13 
14 #include <string>
15 #include <vector>
16 
17 #include "webrtc/base/stream.h"
18 #include "webrtc/base/sslidentity.h"
19 
20 namespace rtc {
21 
22 // Constants for SSL profile.
23 const int TLS_NULL_WITH_NULL_NULL = 0;
24 
25 // Constants for SRTP profiles.
26 const int SRTP_INVALID_CRYPTO_SUITE = 0;
27 const int SRTP_AES128_CM_SHA1_80 = 0x0001;
28 const int SRTP_AES128_CM_SHA1_32 = 0x0002;
29 
30 // Cipher suite to use for SRTP. Typically a 80-bit HMAC will be used, except
31 // in applications (voice) where the additional bandwidth may be significant.
32 // A 80-bit HMAC is always used for SRTCP.
33 // 128-bit AES with 80-bit SHA-1 HMAC.
34 extern const char CS_AES_CM_128_HMAC_SHA1_80[];
35 // 128-bit AES with 32-bit SHA-1 HMAC.
36 extern const char CS_AES_CM_128_HMAC_SHA1_32[];
37 
38 // Given the DTLS-SRTP protection profile ID, as defined in
39 // https://tools.ietf.org/html/rfc4568#section-6.2 , return the SRTP profile
40 // name, as defined in https://tools.ietf.org/html/rfc5764#section-4.1.2.
41 std::string SrtpCryptoSuiteToName(int crypto_suite);
42 
43 // The reverse of above conversion.
44 int SrtpCryptoSuiteFromName(const std::string& crypto_suite);
45 
46 // SSLStreamAdapter : A StreamInterfaceAdapter that does SSL/TLS.
47 // After SSL has been started, the stream will only open on successful
48 // SSL verification of certificates, and the communication is
49 // encrypted of course.
50 //
51 // This class was written with SSLAdapter as a starting point. It
52 // offers a similar interface, with two differences: there is no
53 // support for a restartable SSL connection, and this class has a
54 // peer-to-peer mode.
55 //
56 // The SSL library requires initialization and cleanup. Static method
57 // for doing this are in SSLAdapter. They should possibly be moved out
58 // to a neutral class.
59 
60 
61 enum SSLRole { SSL_CLIENT, SSL_SERVER };
62 enum SSLMode { SSL_MODE_TLS, SSL_MODE_DTLS };
63 enum SSLProtocolVersion {
64   SSL_PROTOCOL_TLS_10,
65   SSL_PROTOCOL_TLS_11,
66   SSL_PROTOCOL_TLS_12,
67   SSL_PROTOCOL_DTLS_10 = SSL_PROTOCOL_TLS_11,
68   SSL_PROTOCOL_DTLS_12 = SSL_PROTOCOL_TLS_12,
69 };
70 
71 // Errors for Read -- in the high range so no conflict with OpenSSL.
72 enum { SSE_MSG_TRUNC = 0xff0001 };
73 
74 class SSLStreamAdapter : public StreamAdapterInterface {
75  public:
76   // Instantiate an SSLStreamAdapter wrapping the given stream,
77   // (using the selected implementation for the platform).
78   // Caller is responsible for freeing the returned object.
79   static SSLStreamAdapter* Create(StreamInterface* stream);
80 
SSLStreamAdapter(StreamInterface * stream)81   explicit SSLStreamAdapter(StreamInterface* stream)
82       : StreamAdapterInterface(stream), ignore_bad_cert_(false),
83         client_auth_enabled_(true) { }
84 
set_ignore_bad_cert(bool ignore)85   void set_ignore_bad_cert(bool ignore) { ignore_bad_cert_ = ignore; }
ignore_bad_cert()86   bool ignore_bad_cert() const { return ignore_bad_cert_; }
87 
set_client_auth_enabled(bool enabled)88   void set_client_auth_enabled(bool enabled) { client_auth_enabled_ = enabled; }
client_auth_enabled()89   bool client_auth_enabled() const { return client_auth_enabled_; }
90 
91   // Specify our SSL identity: key and certificate. Mostly this is
92   // only used in the peer-to-peer mode (unless we actually want to
93   // provide a client certificate to a server).
94   // SSLStream takes ownership of the SSLIdentity object and will
95   // free it when appropriate. Should be called no more than once on a
96   // given SSLStream instance.
97   virtual void SetIdentity(SSLIdentity* identity) = 0;
98 
99   // Call this to indicate that we are to play the server's role in
100   // the peer-to-peer mode.
101   // The default argument is for backward compatibility
102   // TODO(ekr@rtfm.com): rename this SetRole to reflect its new function
103   virtual void SetServerRole(SSLRole role = SSL_SERVER) = 0;
104 
105   // Do DTLS or TLS
106   virtual void SetMode(SSLMode mode) = 0;
107 
108   // Set maximum supported protocol version. The highest version supported by
109   // both ends will be used for the connection, i.e. if one party supports
110   // DTLS 1.0 and the other DTLS 1.2, DTLS 1.0 will be used.
111   // If requested version is not supported by underlying crypto library, the
112   // next lower will be used.
113   virtual void SetMaxProtocolVersion(SSLProtocolVersion version) = 0;
114 
115   // The mode of operation is selected by calling either
116   // StartSSLWithServer or StartSSLWithPeer.
117   // Use of the stream prior to calling either of these functions will
118   // pass data in clear text.
119   // Calling one of these functions causes SSL negotiation to begin as
120   // soon as possible: right away if the underlying wrapped stream is
121   // already opened, or else as soon as it opens.
122   //
123   // These functions return a negative error code on failure.
124   // Returning 0 means success so far, but negotiation is probably not
125   // complete and will continue asynchronously.  In that case, the
126   // exposed stream will open after successful negotiation and
127   // verification, or an SE_CLOSE event will be raised if negotiation
128   // fails.
129 
130   // StartSSLWithServer starts SSL negotiation with a server in
131   // traditional mode. server_name specifies the expected server name
132   // which the server's certificate needs to specify.
133   virtual int StartSSLWithServer(const char* server_name) = 0;
134 
135   // StartSSLWithPeer starts negotiation in the special peer-to-peer
136   // mode.
137   // Generally, SetIdentity() and possibly SetServerRole() should have
138   // been called before this.
139   // SetPeerCertificate() or SetPeerCertificateDigest() must also be called.
140   // It may be called after StartSSLWithPeer() but must be called before the
141   // underlying stream opens.
142   virtual int StartSSLWithPeer() = 0;
143 
144   // Specify the digest of the certificate that our peer is expected to use in
145   // peer-to-peer mode. Only this certificate will be accepted during
146   // SSL verification. The certificate is assumed to have been
147   // obtained through some other secure channel (such as the XMPP
148   // channel). Unlike SetPeerCertificate(), this must specify the
149   // terminal certificate, not just a CA.
150   // SSLStream makes a copy of the digest value.
151   virtual bool SetPeerCertificateDigest(const std::string& digest_alg,
152                                         const unsigned char* digest_val,
153                                         size_t digest_len) = 0;
154 
155   // Retrieves the peer's X.509 certificate, if a connection has been
156   // established. It returns the transmitted over SSL, including the entire
157   // chain. The returned certificate is owned by the caller.
158   virtual bool GetPeerCertificate(SSLCertificate** cert) const = 0;
159 
160   // Retrieves the IANA registration id of the cipher suite used for the
161   // connection (e.g. 0x2F for "TLS_RSA_WITH_AES_128_CBC_SHA").
162   virtual bool GetSslCipherSuite(int* cipher_suite);
163 
164   // Key Exporter interface from RFC 5705
165   // Arguments are:
166   // label               -- the exporter label.
167   //                        part of the RFC defining each exporter
168   //                        usage (IN)
169   // context/context_len -- a context to bind to for this connection;
170   //                        optional, can be NULL, 0 (IN)
171   // use_context         -- whether to use the context value
172   //                        (needed to distinguish no context from
173   //                        zero-length ones).
174   // result              -- where to put the computed value
175   // result_len          -- the length of the computed value
176   virtual bool ExportKeyingMaterial(const std::string& label,
177                                     const uint8_t* context,
178                                     size_t context_len,
179                                     bool use_context,
180                                     uint8_t* result,
181                                     size_t result_len);
182 
183   // DTLS-SRTP interface
184   virtual bool SetDtlsSrtpCryptoSuites(const std::vector<int>& crypto_suites);
185   virtual bool GetDtlsSrtpCryptoSuite(int* crypto_suite);
186 
187   // Capabilities testing
188   static bool HaveDtls();
189   static bool HaveDtlsSrtp();
190   static bool HaveExporter();
191 
192   // Returns the default Ssl cipher used between streams of this class
193   // for the given protocol version. This is used by the unit tests.
194   // TODO(guoweis): Move this away from a static class method.
195   static int GetDefaultSslCipherForTest(SSLProtocolVersion version,
196                                         KeyType key_type);
197 
198   // TODO(guoweis): Move this away from a static class method. Currently this is
199   // introduced such that any caller could depend on sslstreamadapter.h without
200   // depending on specific SSL implementation.
201   static std::string SslCipherSuiteToName(int cipher_suite);
202 
203  private:
204   // If true, the server certificate need not match the configured
205   // server_name, and in fact missing certificate authority and other
206   // verification errors are ignored.
207   bool ignore_bad_cert_;
208 
209   // If true (default), the client is required to provide a certificate during
210   // handshake. If no certificate is given, handshake fails. This applies to
211   // server mode only.
212   bool client_auth_enabled_;
213 };
214 
215 }  // namespace rtc
216 
217 #endif  // WEBRTC_BASE_SSLSTREAMADAPTER_H_
218