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_SSLSTREAMADAPTER_H_ 12 #define WEBRTC_BASE_SSLSTREAMADAPTER_H_ 13 14 #include <string> 15 #include <vector> 16 17 #include "webrtc/base/stream.h" 18 #include "webrtc/base/sslidentity.h" 19 20 namespace rtc { 21 22 // SSLStreamAdapter : A StreamInterfaceAdapter that does SSL/TLS. 23 // After SSL has been started, the stream will only open on successful 24 // SSL verification of certificates, and the communication is 25 // encrypted of course. 26 // 27 // This class was written with SSLAdapter as a starting point. It 28 // offers a similar interface, with two differences: there is no 29 // support for a restartable SSL connection, and this class has a 30 // peer-to-peer mode. 31 // 32 // The SSL library requires initialization and cleanup. Static method 33 // for doing this are in SSLAdapter. They should possibly be moved out 34 // to a neutral class. 35 36 37 enum SSLRole { SSL_CLIENT, SSL_SERVER }; 38 enum SSLMode { SSL_MODE_TLS, SSL_MODE_DTLS }; 39 40 // Errors for Read -- in the high range so no conflict with OpenSSL. 41 enum { SSE_MSG_TRUNC = 0xff0001 }; 42 43 class SSLStreamAdapter : public StreamAdapterInterface { 44 public: 45 // Instantiate an SSLStreamAdapter wrapping the given stream, 46 // (using the selected implementation for the platform). 47 // Caller is responsible for freeing the returned object. 48 static SSLStreamAdapter* Create(StreamInterface* stream); 49 50 explicit SSLStreamAdapter(StreamInterface* stream) 51 : StreamAdapterInterface(stream), ignore_bad_cert_(false), 52 client_auth_enabled_(true) { } 53 54 void set_ignore_bad_cert(bool ignore) { ignore_bad_cert_ = ignore; } 55 bool ignore_bad_cert() const { return ignore_bad_cert_; } 56 57 void set_client_auth_enabled(bool enabled) { client_auth_enabled_ = enabled; } 58 bool client_auth_enabled() const { return client_auth_enabled_; } 59 60 // Specify our SSL identity: key and certificate. Mostly this is 61 // only used in the peer-to-peer mode (unless we actually want to 62 // provide a client certificate to a server). 63 // SSLStream takes ownership of the SSLIdentity object and will 64 // free it when appropriate. Should be called no more than once on a 65 // given SSLStream instance. 66 virtual void SetIdentity(SSLIdentity* identity) = 0; 67 68 // Call this to indicate that we are to play the server's role in 69 // the peer-to-peer mode. 70 // The default argument is for backward compatibility 71 // TODO(ekr (at) rtfm.com): rename this SetRole to reflect its new function 72 virtual void SetServerRole(SSLRole role = SSL_SERVER) = 0; 73 74 // Do DTLS or TLS 75 virtual void SetMode(SSLMode mode) = 0; 76 77 // The mode of operation is selected by calling either 78 // StartSSLWithServer or StartSSLWithPeer. 79 // Use of the stream prior to calling either of these functions will 80 // pass data in clear text. 81 // Calling one of these functions causes SSL negotiation to begin as 82 // soon as possible: right away if the underlying wrapped stream is 83 // already opened, or else as soon as it opens. 84 // 85 // These functions return a negative error code on failure. 86 // Returning 0 means success so far, but negotiation is probably not 87 // complete and will continue asynchronously. In that case, the 88 // exposed stream will open after successful negotiation and 89 // verification, or an SE_CLOSE event will be raised if negotiation 90 // fails. 91 92 // StartSSLWithServer starts SSL negotiation with a server in 93 // traditional mode. server_name specifies the expected server name 94 // which the server's certificate needs to specify. 95 virtual int StartSSLWithServer(const char* server_name) = 0; 96 97 // StartSSLWithPeer starts negotiation in the special peer-to-peer 98 // mode. 99 // Generally, SetIdentity() and possibly SetServerRole() should have 100 // been called before this. 101 // SetPeerCertificate() or SetPeerCertificateDigest() must also be called. 102 // It may be called after StartSSLWithPeer() but must be called before the 103 // underlying stream opens. 104 virtual int StartSSLWithPeer() = 0; 105 106 // Specify the digest of the certificate that our peer is expected to use in 107 // peer-to-peer mode. Only this certificate will be accepted during 108 // SSL verification. The certificate is assumed to have been 109 // obtained through some other secure channel (such as the XMPP 110 // channel). Unlike SetPeerCertificate(), this must specify the 111 // terminal certificate, not just a CA. 112 // SSLStream makes a copy of the digest value. 113 virtual bool SetPeerCertificateDigest(const std::string& digest_alg, 114 const unsigned char* digest_val, 115 size_t digest_len) = 0; 116 117 // Retrieves the peer's X.509 certificate, if a connection has been 118 // established. It returns the transmitted over SSL, including the entire 119 // chain. The returned certificate is owned by the caller. 120 virtual bool GetPeerCertificate(SSLCertificate** cert) const = 0; 121 122 // Key Exporter interface from RFC 5705 123 // Arguments are: 124 // label -- the exporter label. 125 // part of the RFC defining each exporter 126 // usage (IN) 127 // context/context_len -- a context to bind to for this connection; 128 // optional, can be NULL, 0 (IN) 129 // use_context -- whether to use the context value 130 // (needed to distinguish no context from 131 // zero-length ones). 132 // result -- where to put the computed value 133 // result_len -- the length of the computed value 134 virtual bool ExportKeyingMaterial(const std::string& label, 135 const uint8* context, 136 size_t context_len, 137 bool use_context, 138 uint8* result, 139 size_t result_len) { 140 return false; // Default is unsupported 141 } 142 143 144 // DTLS-SRTP interface 145 virtual bool SetDtlsSrtpCiphers(const std::vector<std::string>& ciphers) { 146 return false; 147 } 148 149 virtual bool GetDtlsSrtpCipher(std::string* cipher) { 150 return false; 151 } 152 153 // Capabilities testing 154 static bool HaveDtls(); 155 static bool HaveDtlsSrtp(); 156 static bool HaveExporter(); 157 158 private: 159 // If true, the server certificate need not match the configured 160 // server_name, and in fact missing certificate authority and other 161 // verification errors are ignored. 162 bool ignore_bad_cert_; 163 164 // If true (default), the client is required to provide a certificate during 165 // handshake. If no certificate is given, handshake fails. This applies to 166 // server mode only. 167 bool client_auth_enabled_; 168 }; 169 170 } // namespace rtc 171 172 #endif // WEBRTC_BASE_SSLSTREAMADAPTER_H_ 173