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