147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/* 247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * 447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Use of this source code is governed by a BSD-style license 547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * in the file PATENTS. All contributing project authors may 847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */ 1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifndef WEBRTC_BASE_SSLSTREAMADAPTER_H_ 1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WEBRTC_BASE_SSLSTREAMADAPTER_H_ 1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <string> 1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <vector> 1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/stream.h" 1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/sslidentity.h" 1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc { 2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// SSLStreamAdapter : A StreamInterfaceAdapter that does SSL/TLS. 2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// After SSL has been started, the stream will only open on successful 2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// SSL verification of certificates, and the communication is 2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// encrypted of course. 2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// This class was written with SSLAdapter as a starting point. It 2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// offers a similar interface, with two differences: there is no 2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// support for a restartable SSL connection, and this class has a 3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// peer-to-peer mode. 3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// 3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// The SSL library requires initialization and cleanup. Static method 3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// for doing this are in SSLAdapter. They should possibly be moved out 3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// to a neutral class. 3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgenum SSLRole { SSL_CLIENT, SSL_SERVER }; 3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgenum SSLMode { SSL_MODE_TLS, SSL_MODE_DTLS }; 3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Errors for Read -- in the high range so no conflict with OpenSSL. 4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgenum { SSE_MSG_TRUNC = 0xff0001 }; 4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass SSLStreamAdapter : public StreamAdapterInterface { 4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Instantiate an SSLStreamAdapter wrapping the given stream, 4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // (using the selected implementation for the platform). 4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Caller is responsible for freeing the returned object. 4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static SSLStreamAdapter* Create(StreamInterface* stream); 4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org explicit SSLStreamAdapter(StreamInterface* stream) 514f81cfbdcc099ef101e726a7b1fa8bfc30a23d49tkchin@webrtc.org : StreamAdapterInterface(stream), ignore_bad_cert_(false), 524f81cfbdcc099ef101e726a7b1fa8bfc30a23d49tkchin@webrtc.org client_auth_enabled_(true) { } 5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void set_ignore_bad_cert(bool ignore) { ignore_bad_cert_ = ignore; } 5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool ignore_bad_cert() const { return ignore_bad_cert_; } 5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 574f81cfbdcc099ef101e726a7b1fa8bfc30a23d49tkchin@webrtc.org void set_client_auth_enabled(bool enabled) { client_auth_enabled_ = enabled; } 584f81cfbdcc099ef101e726a7b1fa8bfc30a23d49tkchin@webrtc.org bool client_auth_enabled() const { return client_auth_enabled_; } 594f81cfbdcc099ef101e726a7b1fa8bfc30a23d49tkchin@webrtc.org 6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Specify our SSL identity: key and certificate. Mostly this is 6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // only used in the peer-to-peer mode (unless we actually want to 6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // provide a client certificate to a server). 6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // SSLStream takes ownership of the SSLIdentity object and will 6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // free it when appropriate. Should be called no more than once on a 6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // given SSLStream instance. 6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual void SetIdentity(SSLIdentity* identity) = 0; 6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Call this to indicate that we are to play the server's role in 6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // the peer-to-peer mode. 7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // The default argument is for backward compatibility 7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // TODO(ekr@rtfm.com): rename this SetRole to reflect its new function 7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual void SetServerRole(SSLRole role = SSL_SERVER) = 0; 7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Do DTLS or TLS 7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual void SetMode(SSLMode mode) = 0; 7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // The mode of operation is selected by calling either 7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // StartSSLWithServer or StartSSLWithPeer. 7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Use of the stream prior to calling either of these functions will 8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // pass data in clear text. 8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Calling one of these functions causes SSL negotiation to begin as 8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // soon as possible: right away if the underlying wrapped stream is 8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // already opened, or else as soon as it opens. 8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // 8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // These functions return a negative error code on failure. 8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Returning 0 means success so far, but negotiation is probably not 8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // complete and will continue asynchronously. In that case, the 8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // exposed stream will open after successful negotiation and 8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // verification, or an SE_CLOSE event will be raised if negotiation 9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // fails. 9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // StartSSLWithServer starts SSL negotiation with a server in 9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // traditional mode. server_name specifies the expected server name 9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // which the server's certificate needs to specify. 9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual int StartSSLWithServer(const char* server_name) = 0; 9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // StartSSLWithPeer starts negotiation in the special peer-to-peer 9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // mode. 9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Generally, SetIdentity() and possibly SetServerRole() should have 10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // been called before this. 10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // SetPeerCertificate() or SetPeerCertificateDigest() must also be called. 10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // It may be called after StartSSLWithPeer() but must be called before the 10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // underlying stream opens. 10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual int StartSSLWithPeer() = 0; 10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Specify the digest of the certificate that our peer is expected to use in 10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // peer-to-peer mode. Only this certificate will be accepted during 10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // SSL verification. The certificate is assumed to have been 10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // obtained through some other secure channel (such as the XMPP 11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // channel). Unlike SetPeerCertificate(), this must specify the 11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // terminal certificate, not just a CA. 11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // SSLStream makes a copy of the digest value. 11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual bool SetPeerCertificateDigest(const std::string& digest_alg, 11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const unsigned char* digest_val, 11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t digest_len) = 0; 11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Retrieves the peer's X.509 certificate, if a connection has been 11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // established. It returns the transmitted over SSL, including the entire 11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // chain. The returned certificate is owned by the caller. 12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual bool GetPeerCertificate(SSLCertificate** cert) const = 0; 12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Key Exporter interface from RFC 5705 12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Arguments are: 12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // label -- the exporter label. 12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // part of the RFC defining each exporter 12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // usage (IN) 12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // context/context_len -- a context to bind to for this connection; 12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // optional, can be NULL, 0 (IN) 12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // use_context -- whether to use the context value 13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // (needed to distinguish no context from 13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // zero-length ones). 13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // result -- where to put the computed value 13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // result_len -- the length of the computed value 13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual bool ExportKeyingMaterial(const std::string& label, 13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const uint8* context, 13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t context_len, 13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool use_context, 13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org uint8* result, 13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org size_t result_len) { 14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; // Default is unsupported 14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // DTLS-SRTP interface 14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual bool SetDtlsSrtpCiphers(const std::vector<std::string>& ciphers) { 14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual bool GetDtlsSrtpCipher(std::string* cipher) { 15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return false; 15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Capabilities testing 15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static bool HaveDtls(); 15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static bool HaveDtlsSrtp(); 15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static bool HaveExporter(); 15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1584f81cfbdcc099ef101e726a7b1fa8bfc30a23d49tkchin@webrtc.org private: 15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // If true, the server certificate need not match the configured 16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // server_name, and in fact missing certificate authority and other 16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // verification errors are ignored. 16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool ignore_bad_cert_; 1634f81cfbdcc099ef101e726a7b1fa8bfc30a23d49tkchin@webrtc.org 1644f81cfbdcc099ef101e726a7b1fa8bfc30a23d49tkchin@webrtc.org // If true (default), the client is required to provide a certificate during 1654f81cfbdcc099ef101e726a7b1fa8bfc30a23d49tkchin@webrtc.org // handshake. If no certificate is given, handshake fails. This applies to 1664f81cfbdcc099ef101e726a7b1fa8bfc30a23d49tkchin@webrtc.org // server mode only. 1674f81cfbdcc099ef101e726a7b1fa8bfc30a23d49tkchin@webrtc.org bool client_auth_enabled_; 16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // namespace rtc 17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // WEBRTC_BASE_SSLSTREAMADAPTER_H_ 173