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