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_OPENSSLSTREAMADAPTER_H__
     12 #define WEBRTC_BASE_OPENSSLSTREAMADAPTER_H__
     13 
     14 #include <string>
     15 #include <vector>
     16 
     17 #include "webrtc/base/buffer.h"
     18 #include "webrtc/base/sslstreamadapter.h"
     19 #include "webrtc/base/opensslidentity.h"
     20 
     21 typedef struct ssl_st SSL;
     22 typedef struct ssl_ctx_st SSL_CTX;
     23 typedef struct x509_store_ctx_st X509_STORE_CTX;
     24 
     25 namespace rtc {
     26 
     27 // This class was written with OpenSSLAdapter (a socket adapter) as a
     28 // starting point. It has similar structure and functionality, with
     29 // the peer-to-peer mode added.
     30 //
     31 // Static methods to initialize and deinit the SSL library are in
     32 // OpenSSLAdapter. This class also uses
     33 // OpenSSLAdapter::custom_verify_callback_ (a static field). These
     34 // should probably be moved out to a neutral class.
     35 //
     36 // In a few cases I have factored out some OpenSSLAdapter code into
     37 // static methods so it can be reused from this class. Eventually that
     38 // code should probably be moved to a common support
     39 // class. Unfortunately there remain a few duplicated sections of
     40 // code. I have not done more restructuring because I did not want to
     41 // affect existing code that uses OpenSSLAdapter.
     42 //
     43 // This class does not support the SSL connection restart feature
     44 // present in OpenSSLAdapter. I am not entirely sure how the feature
     45 // is useful and I am not convinced that it works properly.
     46 //
     47 // This implementation is careful to disallow data exchange after an
     48 // SSL error, and it has an explicit SSL_CLOSED state. It should not
     49 // be possible to send any data in clear after one of the StartSSL
     50 // methods has been called.
     51 
     52 // Look in sslstreamadapter.h for documentation of the methods.
     53 
     54 class OpenSSLIdentity;
     55 
     56 ///////////////////////////////////////////////////////////////////////////////
     57 
     58 class OpenSSLStreamAdapter : public SSLStreamAdapter {
     59  public:
     60   explicit OpenSSLStreamAdapter(StreamInterface* stream);
     61   virtual ~OpenSSLStreamAdapter();
     62 
     63   virtual void SetIdentity(SSLIdentity* identity);
     64 
     65   // Default argument is for compatibility
     66   virtual void SetServerRole(SSLRole role = SSL_SERVER);
     67   virtual bool SetPeerCertificateDigest(const std::string& digest_alg,
     68                                         const unsigned char* digest_val,
     69                                         size_t digest_len);
     70 
     71   virtual bool GetPeerCertificate(SSLCertificate** cert) const;
     72 
     73   virtual int StartSSLWithServer(const char* server_name);
     74   virtual int StartSSLWithPeer();
     75   virtual void SetMode(SSLMode mode);
     76 
     77   virtual StreamResult Read(void* data, size_t data_len,
     78                             size_t* read, int* error);
     79   virtual StreamResult Write(const void* data, size_t data_len,
     80                              size_t* written, int* error);
     81   virtual void Close();
     82   virtual StreamState GetState() const;
     83 
     84   // Key Extractor interface
     85   virtual bool ExportKeyingMaterial(const std::string& label,
     86                                     const uint8* context,
     87                                     size_t context_len,
     88                                     bool use_context,
     89                                     uint8* result,
     90                                     size_t result_len);
     91 
     92 
     93   // DTLS-SRTP interface
     94   virtual bool SetDtlsSrtpCiphers(const std::vector<std::string>& ciphers);
     95   virtual bool GetDtlsSrtpCipher(std::string* cipher);
     96 
     97   // Capabilities interfaces
     98   static bool HaveDtls();
     99   static bool HaveDtlsSrtp();
    100   static bool HaveExporter();
    101 
    102  protected:
    103   virtual void OnEvent(StreamInterface* stream, int events, int err);
    104 
    105  private:
    106   enum SSLState {
    107     // Before calling one of the StartSSL methods, data flows
    108     // in clear text.
    109     SSL_NONE,
    110     SSL_WAIT,  // waiting for the stream to open to start SSL negotiation
    111     SSL_CONNECTING,  // SSL negotiation in progress
    112     SSL_CONNECTED,  // SSL stream successfully established
    113     SSL_ERROR,  // some SSL error occurred, stream is closed
    114     SSL_CLOSED  // Clean close
    115   };
    116 
    117   enum { MSG_TIMEOUT = MSG_MAX+1};
    118 
    119   // The following three methods return 0 on success and a negative
    120   // error code on failure. The error code may be from OpenSSL or -1
    121   // on some other error cases, so it can't really be interpreted
    122   // unfortunately.
    123 
    124   // Go from state SSL_NONE to either SSL_CONNECTING or SSL_WAIT,
    125   // depending on whether the underlying stream is already open or
    126   // not.
    127   int StartSSL();
    128   // Prepare SSL library, state is SSL_CONNECTING.
    129   int BeginSSL();
    130   // Perform SSL negotiation steps.
    131   int ContinueSSL();
    132 
    133   // Error handler helper. signal is given as true for errors in
    134   // asynchronous contexts (when an error method was not returned
    135   // through some other method), and in that case an SE_CLOSE event is
    136   // raised on the stream with the specified error.
    137   // A 0 error means a graceful close, otherwise there is not really enough
    138   // context to interpret the error code.
    139   void Error(const char* context, int err, bool signal);
    140   void Cleanup();
    141 
    142   // Override MessageHandler
    143   virtual void OnMessage(Message* msg);
    144 
    145   // Flush the input buffers by reading left bytes (for DTLS)
    146   void FlushInput(unsigned int left);
    147 
    148   // SSL library configuration
    149   SSL_CTX* SetupSSLContext();
    150   // SSL verification check
    151   bool SSLPostConnectionCheck(SSL* ssl, const char* server_name,
    152                               const X509* peer_cert,
    153                               const std::string& peer_digest);
    154   // SSL certification verification error handler, called back from
    155   // the openssl library. Returns an int interpreted as a boolean in
    156   // the C style: zero means verification failure, non-zero means
    157   // passed.
    158   static int SSLVerifyCallback(int ok, X509_STORE_CTX* store);
    159 
    160   SSLState state_;
    161   SSLRole role_;
    162   int ssl_error_code_;  // valid when state_ == SSL_ERROR or SSL_CLOSED
    163   // Whether the SSL negotiation is blocked on needing to read or
    164   // write to the wrapped stream.
    165   bool ssl_read_needs_write_;
    166   bool ssl_write_needs_read_;
    167 
    168   SSL* ssl_;
    169   SSL_CTX* ssl_ctx_;
    170 
    171   // Our key and certificate, mostly useful in peer-to-peer mode.
    172   scoped_ptr<OpenSSLIdentity> identity_;
    173   // in traditional mode, the server name that the server's certificate
    174   // must specify. Empty in peer-to-peer mode.
    175   std::string ssl_server_name_;
    176   // The certificate that the peer must present or did present. Initially
    177   // null in traditional mode, until the connection is established.
    178   scoped_ptr<OpenSSLCertificate> peer_certificate_;
    179   // In peer-to-peer mode, the digest of the certificate that
    180   // the peer must present.
    181   Buffer peer_certificate_digest_value_;
    182   std::string peer_certificate_digest_algorithm_;
    183 
    184   // OpenSSLAdapter::custom_verify_callback_ result
    185   bool custom_verification_succeeded_;
    186 
    187   // The DtlsSrtp ciphers
    188   std::string srtp_ciphers_;
    189 
    190   // Do DTLS or not
    191   SSLMode ssl_mode_;
    192 };
    193 
    194 /////////////////////////////////////////////////////////////////////////////
    195 
    196 }  // namespace rtc
    197 
    198 #endif  // WEBRTC_BASE_OPENSSLSTREAMADAPTER_H__
    199