Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer containing the fingerprint is still in transit. If the signaling path if significantly slower than the media path, this can have a moderate impact on call setup time. Of course, until the fingerprint is verified no media can be sent. Any attempted write will result in SR_BLOCK. This essentially fulfills the requirements of RFC 4572, Section 6.2: Note that when the offer/answer model is being used, it is possible for a media connection to outrace the answer back to the offerer. Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass' role, it MUST (as specified in RFC 4145 [2]) begin listening for an incoming connection as soon as it sends its offer. However, it MUST NOT assume that the data transmitted over the TLS connection is valid until it has received a matching fingerprint in an SDP answer. If the fingerprint, once it arrives, does not match the client's certificate, the server endpoint MUST terminate the media connection with a bad_certificate error, as stated in the previous paragraph. BUG=webrtc:6387 Review-Url: https://codereview.webrtc.org/2163683003 Cr-Commit-Position: refs/heads/master@{#14461}
This commit is contained in:
@ -106,6 +106,12 @@ enum SSLProtocolVersion {
|
||||
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 };
|
||||
@ -173,9 +179,14 @@ class SSLStreamAdapter : public StreamAdapterInterface {
|
||||
// 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.
|
||||
virtual bool SetPeerCertificateDigest(const std::string& digest_alg,
|
||||
const unsigned char* digest_val,
|
||||
size_t digest_len) = 0;
|
||||
//
|
||||
// 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 X.509 certificate, if a connection has been
|
||||
// established. It returns the transmitted over SSL, including the entire
|
||||
@ -211,6 +222,12 @@ class SSLStreamAdapter : public StreamAdapterInterface {
|
||||
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
|
||||
static bool HaveDtls();
|
||||
static bool HaveDtlsSrtp();
|
||||
|
||||
Reference in New Issue
Block a user