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 x509_store_ctx_st X509_STORE_CTX; 24 25namespace 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 54class OpenSSLIdentity; 55 56/////////////////////////////////////////////////////////////////////////////// 57 58class 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