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