webrtc_m130/rtc_base/ssl_stream_adapter.h

283 lines
12 KiB
C
Raw Normal View History

/*
* Copyright 2004 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef RTC_BASE_SSL_STREAM_ADAPTER_H_
#define RTC_BASE_SSL_STREAM_ADAPTER_H_
#include <stddef.h>
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "absl/memory/memory.h"
#include "rtc_base/deprecation.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/ssl_identity.h"
#include "rtc_base/stream.h"
#include "rtc_base/third_party/sigslot/sigslot.h"
namespace rtc {
// Constants for SSL profile.
const int TLS_NULL_WITH_NULL_NULL = 0;
Reland "Reland "Replace the usage of MetricsObserverInterface by RTC_HISTOGRAM_*."" This is a reland of 1a2cc0acba6a66f89249455d8e5775849b56f755 Original change's description: > Reland "Replace the usage of MetricsObserverInterface by RTC_HISTOGRAM_*." > > This is a reland of 870bca1f418a1abf445169a638a61f9a649d557f > > Original change's description: > > Replace the usage of MetricsObserverInterface by RTC_HISTOGRAM_*. > > > > We now use RTC_HISTOGRAM_* macros in system_wrappers/include/metrics.h > > to report the metrics in pc/ and p2p/ that are currently been reported > > using MetricsObserverInterface. > > > > TBR=tommi@webrtc.org > > > > Bug: webrtc:9409 > > Change-Id: I47c9975402293c72250203fa1ec19eb1668766f6 > > Reviewed-on: https://webrtc-review.googlesource.com/83782 > > Commit-Queue: Qingsi Wang <qingsi@google.com> > > Reviewed-by: Harald Alvestrand <hta@webrtc.org> > > Reviewed-by: Taylor (left Google) <deadbeef@webrtc.org> > > Reviewed-by: Steve Anton <steveanton@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#23914} > > TBR=steveanton@webrtc.org,hta@webrtc.org,tommi@webrtc.org > > Bug: webrtc:9409 > Change-Id: I37fc95ced60dea25aa9b4f5ad44bdf7174c8bd5c > Reviewed-on: https://webrtc-review.googlesource.com/88060 > Reviewed-by: Qingsi Wang <qingsi@webrtc.org> > Commit-Queue: Qingsi Wang <qingsi@google.com> > Cr-Commit-Position: refs/heads/master@{#23919} TBR=steveanton@webrtc.org,tommi@webrtc.org Bug: webrtc:9409 Change-Id: Ib55f0b6c9bcb9d9585924a4dfac5cf643ff4d76b Reviewed-on: https://webrtc-review.googlesource.com/88343 Commit-Queue: Qingsi Wang <qingsi@google.com> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23957}
2018-07-12 12:54:53 -07:00
const int SSL_CIPHER_SUITE_MAX_VALUE = 0xFFFF;
// Constants for SRTP profiles.
const int SRTP_INVALID_CRYPTO_SUITE = 0;
#ifndef SRTP_AES128_CM_SHA1_80
const int SRTP_AES128_CM_SHA1_80 = 0x0001;
#endif
#ifndef SRTP_AES128_CM_SHA1_32
const int SRTP_AES128_CM_SHA1_32 = 0x0002;
#endif
#ifndef SRTP_AEAD_AES_128_GCM
const int SRTP_AEAD_AES_128_GCM = 0x0007;
#endif
#ifndef SRTP_AEAD_AES_256_GCM
const int SRTP_AEAD_AES_256_GCM = 0x0008;
#endif
Reland "Reland "Replace the usage of MetricsObserverInterface by RTC_HISTOGRAM_*."" This is a reland of 1a2cc0acba6a66f89249455d8e5775849b56f755 Original change's description: > Reland "Replace the usage of MetricsObserverInterface by RTC_HISTOGRAM_*." > > This is a reland of 870bca1f418a1abf445169a638a61f9a649d557f > > Original change's description: > > Replace the usage of MetricsObserverInterface by RTC_HISTOGRAM_*. > > > > We now use RTC_HISTOGRAM_* macros in system_wrappers/include/metrics.h > > to report the metrics in pc/ and p2p/ that are currently been reported > > using MetricsObserverInterface. > > > > TBR=tommi@webrtc.org > > > > Bug: webrtc:9409 > > Change-Id: I47c9975402293c72250203fa1ec19eb1668766f6 > > Reviewed-on: https://webrtc-review.googlesource.com/83782 > > Commit-Queue: Qingsi Wang <qingsi@google.com> > > Reviewed-by: Harald Alvestrand <hta@webrtc.org> > > Reviewed-by: Taylor (left Google) <deadbeef@webrtc.org> > > Reviewed-by: Steve Anton <steveanton@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#23914} > > TBR=steveanton@webrtc.org,hta@webrtc.org,tommi@webrtc.org > > Bug: webrtc:9409 > Change-Id: I37fc95ced60dea25aa9b4f5ad44bdf7174c8bd5c > Reviewed-on: https://webrtc-review.googlesource.com/88060 > Reviewed-by: Qingsi Wang <qingsi@webrtc.org> > Commit-Queue: Qingsi Wang <qingsi@google.com> > Cr-Commit-Position: refs/heads/master@{#23919} TBR=steveanton@webrtc.org,tommi@webrtc.org Bug: webrtc:9409 Change-Id: Ib55f0b6c9bcb9d9585924a4dfac5cf643ff4d76b Reviewed-on: https://webrtc-review.googlesource.com/88343 Commit-Queue: Qingsi Wang <qingsi@google.com> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23957}
2018-07-12 12:54:53 -07:00
const int SRTP_CRYPTO_SUITE_MAX_VALUE = 0xFFFF;
// Names of SRTP profiles listed above.
// 128-bit AES with 80-bit SHA-1 HMAC.
extern const char CS_AES_CM_128_HMAC_SHA1_80[];
// 128-bit AES with 32-bit SHA-1 HMAC.
extern const char CS_AES_CM_128_HMAC_SHA1_32[];
// 128-bit AES GCM with 16 byte AEAD auth tag.
extern const char CS_AEAD_AES_128_GCM[];
// 256-bit AES GCM with 16 byte AEAD auth tag.
extern const char CS_AEAD_AES_256_GCM[];
// Given the DTLS-SRTP protection profile ID, as defined in
// https://tools.ietf.org/html/rfc4568#section-6.2 , return the SRTP profile
// name, as defined in https://tools.ietf.org/html/rfc5764#section-4.1.2.
std::string SrtpCryptoSuiteToName(int crypto_suite);
// The reverse of above conversion.
int SrtpCryptoSuiteFromName(const std::string& crypto_suite);
// Get key length and salt length for given crypto suite. Returns true for
// valid suites, otherwise false.
bool GetSrtpKeyAndSaltLengths(int crypto_suite,
int* key_length,
int* salt_length);
// Returns true if the given crypto suite id uses a GCM cipher.
bool IsGcmCryptoSuite(int crypto_suite);
// Returns true if the given crypto suite name uses a GCM cipher.
bool IsGcmCryptoSuiteName(const std::string& crypto_suite);
// SSLStreamAdapter : A StreamInterfaceAdapter that does SSL/TLS.
// After SSL has been started, the stream will only open on successful
// SSL verification of certificates, and the communication is
// encrypted of course.
//
// This class was written with SSLAdapter as a starting point. It
// offers a similar interface, with two differences: there is no
// support for a restartable SSL connection, and this class has a
// peer-to-peer mode.
//
// The SSL library requires initialization and cleanup. Static method
// for doing this are in SSLAdapter. They should possibly be moved out
// to a neutral class.
enum SSLRole { SSL_CLIENT, SSL_SERVER };
enum SSLMode { SSL_MODE_TLS, SSL_MODE_DTLS };
Make a switch to disable DTLS 1.0, TLS 1.0 and TLS 1.1 downgrade in WebRTC. This reverts commit af1f8655b2cb69af382396ea642eb0a2bf04bb4d Landing the change with default set to "enabled" (DTLS 1.0 will continue to work by default), so that flipping the default can be a separate CL. Original change's description: > Revert "Disable DTLS 1.0, TLS 1.0 and TLS 1.1 downgrade in WebRTC." > > This reverts commit 7276b974b78ea4f409d8738b1b6f1515f7a8968e. > > Reason for revert: Changing to a later Chrome release. > > Original change's description: > > Disable DTLS 1.0, TLS 1.0 and TLS 1.1 downgrade in WebRTC. > > > > This change disables DTLS 1.0, TLS 1.0 and TLS 1.1 in WebRTC by default. This > > is part of a larger effort at Google to remove old TLS protocols: > > https://security.googleblog.com/2018/10/modernizing-transport-security.html > > > > For the M74 timeline I have added a disabled by default field trial > > WebRTC-LegacyTlsProtocols which can be enabled to support these cipher suites > > as consumers move away from these legacy cipher protocols but it will be off > > in Chrome. > > > > This is compliant with the webrtc-security-arch specification which states: > > > > All Implementations MUST implement DTLS 1.2 with the > > TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 cipher suite and the P-256 > > curve [FIPS186]. Earlier drafts of this specification required DTLS > > 1.0 with the cipher suite TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, and > > at the time of this writing some implementations do not support DTLS > > 1.2; endpoints which support only DTLS 1.2 might encounter > > interoperability issues. The DTLS-SRTP protection profile > > SRTP_AES128_CM_HMAC_SHA1_80 MUST be supported for SRTP. > > Implementations MUST favor cipher suites which support (Perfect > > Forward Secrecy) PFS over non-PFS cipher suites and SHOULD favor AEAD > > over non-AEAD cipher suites. > > > > Bug: webrtc:10261 > > Change-Id: I847c567592911cc437f095376ad67585b4355fc0 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/125141 > > Commit-Queue: Benjamin Wright <benwright@webrtc.org> > > Reviewed-by: David Benjamin <davidben@webrtc.org> > > Reviewed-by: Qingsi Wang <qingsi@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#27006} > > TBR=steveanton@webrtc.org,davidben@webrtc.org,qingsi@webrtc.org,benwright@webrtc.org > > # Not skipping CQ checks because original CL landed > 1 day ago. > > Bug: webrtc:10261 > Change-Id: I34727e65c069e1fb2ad71838828ad0a22b5fe811 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/130367 > Commit-Queue: Benjamin Wright <benwright@webrtc.org> > Reviewed-by: Benjamin Wright <benwright@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#27403} Bug: webrtc:10261 Change-Id: I28c6819d37665976e396df280b4abf48fb91d533 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/169851 Commit-Queue: Harald Alvestrand <hta@webrtc.org> Reviewed-by: Benjamin Wright <benwright@webrtc.org> Reviewed-by: Qingsi Wang <qingsi@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/master@{#30733}
2020-03-09 19:39:36 +01:00
// Note: TLS_10, TLS_11, and DTLS_10 will all be ignored, and only
// DTLS1_2 will be accepted, if the trial flag
// WebRTC-LegacyTlsProtocols/Disabled/ is passed in. Support for these
// protocol versions will be completely removed in M84 or later.
// TODO(https://bugs.webrtc.org/10261).
enum SSLProtocolVersion {
SSL_PROTOCOL_NOT_GIVEN = -1,
SSL_PROTOCOL_TLS_10 = 0,
SSL_PROTOCOL_TLS_11,
SSL_PROTOCOL_TLS_12,
SSL_PROTOCOL_DTLS_10 = SSL_PROTOCOL_TLS_11,
SSL_PROTOCOL_DTLS_12 = SSL_PROTOCOL_TLS_12,
};
enum class SSLPeerCertificateDigestError {
NONE,
UNKNOWN_ALGORITHM,
INVALID_LENGTH,
VERIFICATION_FAILED,
};
// Errors for Read -- in the high range so no conflict with OpenSSL.
enum { SSE_MSG_TRUNC = 0xff0001 };
// Used to send back UMA histogram value. Logged when Dtls handshake fails.
enum class SSLHandshakeError { UNKNOWN, INCOMPATIBLE_CIPHERSUITE, MAX_VALUE };
class SSLStreamAdapter : public StreamAdapterInterface {
public:
// Instantiate an SSLStreamAdapter wrapping the given stream,
// (using the selected implementation for the platform).
// Caller is responsible for freeing the returned object.
static std::unique_ptr<SSLStreamAdapter> Create(
std::unique_ptr<StreamInterface> stream);
explicit SSLStreamAdapter(std::unique_ptr<StreamInterface> stream);
~SSLStreamAdapter() override;
// Specify our SSL identity: key and certificate. SSLStream takes ownership
// of the SSLIdentity object and will free it when appropriate. Should be
// called no more than once on a given SSLStream instance.
virtual void SetIdentity(std::unique_ptr<SSLIdentity> identity) = 0;
virtual SSLIdentity* GetIdentityForTesting() const = 0;
// Call this to indicate that we are to play the server role (or client role,
// if the default argument is replaced by SSL_CLIENT).
// The default argument is for backward compatibility.
// TODO(ekr@rtfm.com): rename this SetRole to reflect its new function
virtual void SetServerRole(SSLRole role = SSL_SERVER) = 0;
// Do DTLS or TLS.
virtual void SetMode(SSLMode mode) = 0;
// Set maximum supported protocol version. The highest version supported by
// both ends will be used for the connection, i.e. if one party supports
// DTLS 1.0 and the other DTLS 1.2, DTLS 1.0 will be used.
// If requested version is not supported by underlying crypto library, the
// next lower will be used.
virtual void SetMaxProtocolVersion(SSLProtocolVersion version) = 0;
// Set the initial retransmission timeout for DTLS messages. When the timeout
// expires, the message gets retransmitted and the timeout is exponentially
// increased.
// This should only be called before StartSSL().
virtual void SetInitialRetransmissionTimeout(int timeout_ms) = 0;
// StartSSL starts negotiation with a peer, whose certificate is verified
// using the certificate digest. Generally, SetIdentity() and possibly
// SetServerRole() should have been called before this.
// SetPeerCertificateDigest() must also be called. It may be called after
// StartSSLWithPeer() but must be called before the underlying stream opens.
//
// Use of the stream prior to calling StartSSL will pass data in clear text.
// Calling StartSSL causes SSL negotiation to begin as soon as possible: right
// away if the underlying wrapped stream is already opened, or else as soon as
// it opens.
//
// StartSSL returns a negative error code on failure. Returning 0 means
// success so far, but negotiation is probably not complete and will continue
// asynchronously. In that case, the exposed stream will open after
// successful negotiation and verification, or an SE_CLOSE event will be
// raised if negotiation fails.
virtual int StartSSL() = 0;
// Specify the digest of the certificate that our peer is expected to use.
// Only this certificate will be accepted during SSL verification. The
// certificate is assumed to have been obtained through some other secure
// channel (such as the signaling channel). This must specify the terminal
// certificate, not just a CA. SSLStream makes a copy of the digest value.
//
// Returns true if successful.
// |error| is optional and provides more information about the failure.
virtual bool SetPeerCertificateDigest(
const std::string& digest_alg,
const unsigned char* digest_val,
size_t digest_len,
SSLPeerCertificateDigestError* error = nullptr) = 0;
// Retrieves the peer's certificate chain including leaf certificate, if a
// connection has been established.
virtual std::unique_ptr<SSLCertChain> GetPeerSSLCertChain() const = 0;
// Retrieves the IANA registration id of the cipher suite used for the
// connection (e.g. 0x2F for "TLS_RSA_WITH_AES_128_CBC_SHA").
virtual bool GetSslCipherSuite(int* cipher_suite);
// Retrieves the enum value for SSL version.
// Will return -1 until the version has been negotiated.
virtual SSLProtocolVersion GetSslVersion() const = 0;
// Retrieves the 2-byte version from the TLS protocol.
// Will return false until the version has been negotiated.
virtual bool GetSslVersionBytes(int* version) const = 0;
// Key Exporter interface from RFC 5705
// Arguments are:
// label -- the exporter label.
// part of the RFC defining each exporter
// usage (IN)
// context/context_len -- a context to bind to for this connection;
// optional, can be null, 0 (IN)
// use_context -- whether to use the context value
// (needed to distinguish no context from
// zero-length ones).
// result -- where to put the computed value
// result_len -- the length of the computed value
virtual bool ExportKeyingMaterial(const std::string& label,
const uint8_t* context,
size_t context_len,
bool use_context,
uint8_t* result,
size_t result_len);
// DTLS-SRTP interface
virtual bool SetDtlsSrtpCryptoSuites(const std::vector<int>& crypto_suites);
virtual bool GetDtlsSrtpCryptoSuite(int* crypto_suite);
// Returns true if a TLS connection has been established.
// The only difference between this and "GetState() == SE_OPEN" is that if
// the peer certificate digest hasn't been verified, the state will still be
// SS_OPENING but IsTlsConnected should return true.
virtual bool IsTlsConnected() = 0;
// Capabilities testing.
// Used to have "DTLS supported", "DTLS-SRTP supported" etc. methods, but now
// that's assumed.
static bool IsBoringSsl();
// Returns true iff the supplied cipher is deemed to be strong.
// TODO(torbjorng): Consider removing the KeyType argument.
static bool IsAcceptableCipher(int cipher, KeyType key_type);
static bool IsAcceptableCipher(const std::string& cipher, KeyType key_type);
// TODO(guoweis): Move this away from a static class method. Currently this is
// introduced such that any caller could depend on sslstreamadapter.h without
// depending on specific SSL implementation.
static std::string SslCipherSuiteToName(int cipher_suite);
////////////////////////////////////////////////////////////////////////////
// Testing only member functions
////////////////////////////////////////////////////////////////////////////
// Use our timeutils.h source of timing in BoringSSL, allowing us to test
// using a fake clock.
static void EnableTimeCallbackForTesting();
// Deprecated. Do not use this API outside of testing.
// Do not set this to false outside of testing.
void SetClientAuthEnabledForTesting(bool enabled) {
client_auth_enabled_ = enabled;
}
// Deprecated. Do not use this API outside of testing.
// Returns true by default, else false if explicitly set to disable client
// authentication.
bool GetClientAuthEnabled() const { return client_auth_enabled_; }
sigslot::signal1<SSLHandshakeError> SignalSSLHandshakeError;
private:
// If true (default), the client is required to provide a certificate during
// handshake. If no certificate is given, handshake fails. This applies to
// server mode only.
bool client_auth_enabled_ = true;
};
} // namespace rtc
#endif // RTC_BASE_SSL_STREAM_ADAPTER_H_