Home | History | Annotate | Download | only in base
      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 
     81   explicit SSLStreamAdapter(StreamInterface* stream)
     82       : StreamAdapterInterface(stream), ignore_bad_cert_(false),
     83         client_auth_enabled_(true) { }
     84 
     85   void set_ignore_bad_cert(bool ignore) { ignore_bad_cert_ = ignore; }
     86   bool ignore_bad_cert() const { return ignore_bad_cert_; }
     87 
     88   void set_client_auth_enabled(bool enabled) { client_auth_enabled_ = 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 (at) 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