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 // SSLStreamAdapter : A StreamInterfaceAdapter that does SSL/TLS.
     23 // After SSL has been started, the stream will only open on successful
     24 // SSL verification of certificates, and the communication is
     25 // encrypted of course.
     26 //
     27 // This class was written with SSLAdapter as a starting point. It
     28 // offers a similar interface, with two differences: there is no
     29 // support for a restartable SSL connection, and this class has a
     30 // peer-to-peer mode.
     31 //
     32 // The SSL library requires initialization and cleanup. Static method
     33 // for doing this are in SSLAdapter. They should possibly be moved out
     34 // to a neutral class.
     35 
     36 
     37 enum SSLRole { SSL_CLIENT, SSL_SERVER };
     38 enum SSLMode { SSL_MODE_TLS, SSL_MODE_DTLS };
     39 
     40 // Errors for Read -- in the high range so no conflict with OpenSSL.
     41 enum { SSE_MSG_TRUNC = 0xff0001 };
     42 
     43 class SSLStreamAdapter : public StreamAdapterInterface {
     44  public:
     45   // Instantiate an SSLStreamAdapter wrapping the given stream,
     46   // (using the selected implementation for the platform).
     47   // Caller is responsible for freeing the returned object.
     48   static SSLStreamAdapter* Create(StreamInterface* stream);
     49 
     50   explicit SSLStreamAdapter(StreamInterface* stream)
     51       : StreamAdapterInterface(stream), ignore_bad_cert_(false),
     52         client_auth_enabled_(true) { }
     53 
     54   void set_ignore_bad_cert(bool ignore) { ignore_bad_cert_ = ignore; }
     55   bool ignore_bad_cert() const { return ignore_bad_cert_; }
     56 
     57   void set_client_auth_enabled(bool enabled) { client_auth_enabled_ = enabled; }
     58   bool client_auth_enabled() const { return client_auth_enabled_; }
     59 
     60   // Specify our SSL identity: key and certificate. Mostly this is
     61   // only used in the peer-to-peer mode (unless we actually want to
     62   // provide a client certificate to a server).
     63   // SSLStream takes ownership of the SSLIdentity object and will
     64   // free it when appropriate. Should be called no more than once on a
     65   // given SSLStream instance.
     66   virtual void SetIdentity(SSLIdentity* identity) = 0;
     67 
     68   // Call this to indicate that we are to play the server's role in
     69   // the peer-to-peer mode.
     70   // The default argument is for backward compatibility
     71   // TODO(ekr (at) rtfm.com): rename this SetRole to reflect its new function
     72   virtual void SetServerRole(SSLRole role = SSL_SERVER) = 0;
     73 
     74   // Do DTLS or TLS
     75   virtual void SetMode(SSLMode mode) = 0;
     76 
     77   // The mode of operation is selected by calling either
     78   // StartSSLWithServer or StartSSLWithPeer.
     79   // Use of the stream prior to calling either of these functions will
     80   // pass data in clear text.
     81   // Calling one of these functions causes SSL negotiation to begin as
     82   // soon as possible: right away if the underlying wrapped stream is
     83   // already opened, or else as soon as it opens.
     84   //
     85   // These functions return a negative error code on failure.
     86   // Returning 0 means success so far, but negotiation is probably not
     87   // complete and will continue asynchronously.  In that case, the
     88   // exposed stream will open after successful negotiation and
     89   // verification, or an SE_CLOSE event will be raised if negotiation
     90   // fails.
     91 
     92   // StartSSLWithServer starts SSL negotiation with a server in
     93   // traditional mode. server_name specifies the expected server name
     94   // which the server's certificate needs to specify.
     95   virtual int StartSSLWithServer(const char* server_name) = 0;
     96 
     97   // StartSSLWithPeer starts negotiation in the special peer-to-peer
     98   // mode.
     99   // Generally, SetIdentity() and possibly SetServerRole() should have
    100   // been called before this.
    101   // SetPeerCertificate() or SetPeerCertificateDigest() must also be called.
    102   // It may be called after StartSSLWithPeer() but must be called before the
    103   // underlying stream opens.
    104   virtual int StartSSLWithPeer() = 0;
    105 
    106   // Specify the digest of the certificate that our peer is expected to use in
    107   // peer-to-peer mode. Only this certificate will be accepted during
    108   // SSL verification. The certificate is assumed to have been
    109   // obtained through some other secure channel (such as the XMPP
    110   // channel). Unlike SetPeerCertificate(), this must specify the
    111   // terminal certificate, not just a CA.
    112   // SSLStream makes a copy of the digest value.
    113   virtual bool SetPeerCertificateDigest(const std::string& digest_alg,
    114                                         const unsigned char* digest_val,
    115                                         size_t digest_len) = 0;
    116 
    117   // Retrieves the peer's X.509 certificate, if a connection has been
    118   // established. It returns the transmitted over SSL, including the entire
    119   // chain. The returned certificate is owned by the caller.
    120   virtual bool GetPeerCertificate(SSLCertificate** cert) const = 0;
    121 
    122   // Key Exporter interface from RFC 5705
    123   // Arguments are:
    124   // label               -- the exporter label.
    125   //                        part of the RFC defining each exporter
    126   //                        usage (IN)
    127   // context/context_len -- a context to bind to for this connection;
    128   //                        optional, can be NULL, 0 (IN)
    129   // use_context         -- whether to use the context value
    130   //                        (needed to distinguish no context from
    131   //                        zero-length ones).
    132   // result              -- where to put the computed value
    133   // result_len          -- the length of the computed value
    134   virtual bool ExportKeyingMaterial(const std::string& label,
    135                                     const uint8* context,
    136                                     size_t context_len,
    137                                     bool use_context,
    138                                     uint8* result,
    139                                     size_t result_len) {
    140     return false;  // Default is unsupported
    141   }
    142 
    143 
    144   // DTLS-SRTP interface
    145   virtual bool SetDtlsSrtpCiphers(const std::vector<std::string>& ciphers) {
    146     return false;
    147   }
    148 
    149   virtual bool GetDtlsSrtpCipher(std::string* cipher) {
    150     return false;
    151   }
    152 
    153   // Capabilities testing
    154   static bool HaveDtls();
    155   static bool HaveDtlsSrtp();
    156   static bool HaveExporter();
    157 
    158  private:
    159   // If true, the server certificate need not match the configured
    160   // server_name, and in fact missing certificate authority and other
    161   // verification errors are ignored.
    162   bool ignore_bad_cert_;
    163 
    164   // If true (default), the client is required to provide a certificate during
    165   // handshake. If no certificate is given, handshake fails. This applies to
    166   // server mode only.
    167   bool client_auth_enabled_;
    168 };
    169 
    170 }  // namespace rtc
    171 
    172 #endif  // WEBRTC_BASE_SSLSTREAMADAPTER_H_
    173