15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  Use of this source code is governed by a BSD-style license
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  that can be found in the LICENSE file in the root of the source
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  tree. An additional intellectual property rights grant can be found
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  in the file PATENTS.  All contributing project authors may
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *  be found in the AUTHORS file in the root of the source tree.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef WEBRTC_BASE_OPENSSLSTREAMADAPTER_H__
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define WEBRTC_BASE_OPENSSLSTREAMADAPTER_H__
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <string>
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <vector>
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "webrtc/base/buffer.h"
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "webrtc/base/sslstreamadapter.h"
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "webrtc/base/opensslidentity.h"
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef struct ssl_st SSL;
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef struct ssl_ctx_st SSL_CTX;
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef struct x509_store_ctx_st X509_STORE_CTX;
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace rtc {
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// This class was written with OpenSSLAdapter (a socket adapter) as a
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// starting point. It has similar structure and functionality, with
2993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)// the peer-to-peer mode added.
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)//
3106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)// Static methods to initialize and deinit the SSL library are in
3209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// OpenSSLAdapter. This class also uses
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// OpenSSLAdapter::custom_verify_callback_ (a static field). These
3409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// should probably be moved out to a neutral class.
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)//
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// In a few cases I have factored out some OpenSSLAdapter code into
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// static methods so it can be reused from this class. Eventually that
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)// code should probably be moved to a common support
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// class. Unfortunately there remain a few duplicated sections of
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// code. I have not done more restructuring because I did not want to
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// affect existing code that uses OpenSSLAdapter.
427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch//
431e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)// This class does not support the SSL connection restart feature
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// present in OpenSSLAdapter. I am not entirely sure how the feature
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// is useful and I am not convinced that it works properly.
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)//
4709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// This implementation is careful to disallow data exchange after an
4809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// SSL error, and it has an explicit SSL_CLOSED state. It should not
4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// be possible to send any data in clear after one of the StartSSL
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// methods has been called.
5109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
5209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)// Look in sslstreamadapter.h for documentation of the methods.
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class OpenSSLIdentity;
5509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
5609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)class OpenSSLStreamAdapter : public SSLStreamAdapter {
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) public:
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  explicit OpenSSLStreamAdapter(StreamInterface* stream);
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual ~OpenSSLStreamAdapter();
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual void SetIdentity(SSLIdentity* identity);
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // Default argument is for compatibility
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual void SetServerRole(SSLRole role = SSL_SERVER);
677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch  virtual bool SetPeerCertificateDigest(const std::string& digest_alg,
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                        const unsigned char* digest_val,
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                        size_t digest_len);
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual bool GetPeerCertificate(SSLCertificate** cert) const;
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual int StartSSLWithServer(const char* server_name);
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual int StartSSLWithPeer();
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual void SetMode(SSLMode mode);
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual StreamResult Read(void* data, size_t data_len,
78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                            size_t* read, int* error);
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual StreamResult Write(const void* data, size_t data_len,
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                             size_t* written, int* error);
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual void Close();
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual StreamState GetState() const;
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // Key Extractor interface
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual bool ExportKeyingMaterial(const std::string& label,
861e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)                                    const uint8* context,
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                    size_t context_len,
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                    bool use_context,
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                    uint8* result,
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                                    size_t result_len);
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // DTLS-SRTP interface
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual bool SetDtlsSrtpCiphers(const std::vector<std::string>& ciphers);
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  virtual bool GetDtlsSrtpCipher(std::string* cipher);
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // Capabilities interfaces
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static bool HaveDtls();
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static bool HaveDtlsSrtp();
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  static bool HaveExporter();
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) protected:
10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)  virtual void OnEvent(StreamInterface* stream, int events, int err);
10409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) private:
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  enum SSLState {
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Before calling one of the StartSSL methods, data flows
1081e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    // in clear text.
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SSL_NONE,
11009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    SSL_WAIT,  // waiting for the stream to open to start SSL negotiation
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SSL_CONNECTING,  // SSL negotiation in progress
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SSL_CONNECTED,  // SSL stream successfully established
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SSL_ERROR,  // some SSL error occurred, stream is closed
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    SSL_CLOSED  // Clean close
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  };
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  enum { MSG_TIMEOUT = MSG_MAX+1};
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
119926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)  // The following three methods return 0 on success and a negative
120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)  // error code on failure. The error code may be from OpenSSL or -1
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // on some other error cases, so it can't really be interpreted
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // unfortunately.
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // Go from state SSL_NONE to either SSL_CONNECTING or SSL_WAIT,
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  // 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