mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-26 18:37:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
754
security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc
Normal file
754
security/nss/gtests/ssl_gtest/ssl_auth_unittest.cc
Normal file
|
|
@ -0,0 +1,754 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "secerr.h"
|
||||
#include "ssl.h"
|
||||
#include "sslerr.h"
|
||||
#include "sslproto.h"
|
||||
|
||||
extern "C" {
|
||||
// This is not something that should make you happy.
|
||||
#include "libssl_internals.h"
|
||||
}
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
TEST_P(TlsConnectGeneric, ServerAuthBigRsa) {
|
||||
Reset(TlsAgent::kRsa2048);
|
||||
Connect();
|
||||
CheckKeys();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ServerAuthRsaChain) {
|
||||
Reset(TlsAgent::kServerRsaChain);
|
||||
Connect();
|
||||
CheckKeys();
|
||||
size_t chain_length;
|
||||
EXPECT_TRUE(client_->GetPeerChainLength(&chain_length));
|
||||
EXPECT_EQ(2UL, chain_length);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ClientAuth) {
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
Connect();
|
||||
CheckKeys();
|
||||
}
|
||||
|
||||
// In TLS 1.3, the client sends its cert rejection on the
|
||||
// second flight, and since it has already received the
|
||||
// server's Finished, it transitions to complete and
|
||||
// then gets an alert from the server. The test harness
|
||||
// doesn't handle this right yet.
|
||||
TEST_P(TlsConnectStream, DISABLED_ClientAuthRequiredRejected) {
|
||||
server_->RequestClientAuth(true);
|
||||
ConnectExpectFail();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ClientAuthRequestedRejected) {
|
||||
server_->RequestClientAuth(false);
|
||||
Connect();
|
||||
CheckKeys();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ClientAuthEcdsa) {
|
||||
Reset(TlsAgent::kServerEcdsa256);
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ClientAuthBigRsa) {
|
||||
Reset(TlsAgent::kServerRsa, TlsAgent::kRsa2048);
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
Connect();
|
||||
CheckKeys();
|
||||
}
|
||||
|
||||
// Offset is the position in the captured buffer where the signature sits.
|
||||
static void CheckSigScheme(TlsInspectorRecordHandshakeMessage* capture,
|
||||
size_t offset, TlsAgent* peer,
|
||||
uint16_t expected_scheme, size_t expected_size) {
|
||||
EXPECT_LT(offset + 2U, capture->buffer().len());
|
||||
|
||||
uint32_t scheme = 0;
|
||||
capture->buffer().Read(offset, 2, &scheme);
|
||||
EXPECT_EQ(expected_scheme, static_cast<uint16_t>(scheme));
|
||||
|
||||
ScopedCERTCertificate remote_cert(SSL_PeerCertificate(peer->ssl_fd()));
|
||||
ScopedSECKEYPublicKey remote_key(CERT_ExtractPublicKey(remote_cert.get()));
|
||||
EXPECT_EQ(expected_size, SECKEY_PublicKeyStrengthInBits(remote_key.get()));
|
||||
}
|
||||
|
||||
// The server should prefer SHA-256 by default, even for the small key size used
|
||||
// in the default certificate.
|
||||
TEST_P(TlsConnectTls12, ServerAuthCheckSigAlg) {
|
||||
EnsureTlsSetup();
|
||||
auto capture_ske =
|
||||
new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange);
|
||||
server_->SetPacketFilter(capture_ske);
|
||||
Connect();
|
||||
CheckKeys();
|
||||
|
||||
const DataBuffer& buffer = capture_ske->buffer();
|
||||
EXPECT_LT(3U, buffer.len());
|
||||
EXPECT_EQ(3U, buffer.data()[0]) << "curve_type == named_curve";
|
||||
uint32_t tmp;
|
||||
EXPECT_TRUE(buffer.Read(1, 2, &tmp)) << "read NamedCurve";
|
||||
EXPECT_EQ(ssl_grp_ec_curve25519, tmp);
|
||||
EXPECT_TRUE(buffer.Read(3, 1, &tmp)) << " read ECPoint";
|
||||
CheckSigScheme(capture_ske, 4 + tmp, client_, ssl_sig_rsa_pss_sha256, 1024);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls12, ClientAuthCheckSigAlg) {
|
||||
EnsureTlsSetup();
|
||||
auto capture_cert_verify =
|
||||
new TlsInspectorRecordHandshakeMessage(kTlsHandshakeCertificateVerify);
|
||||
client_->SetPacketFilter(capture_cert_verify);
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
Connect();
|
||||
CheckKeys();
|
||||
|
||||
CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pkcs1_sha1, 1024);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls12, ClientAuthBigRsaCheckSigAlg) {
|
||||
Reset(TlsAgent::kServerRsa, TlsAgent::kRsa2048);
|
||||
auto capture_cert_verify =
|
||||
new TlsInspectorRecordHandshakeMessage(kTlsHandshakeCertificateVerify);
|
||||
client_->SetPacketFilter(capture_cert_verify);
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
Connect();
|
||||
CheckKeys();
|
||||
CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pss_sha256, 2048);
|
||||
}
|
||||
|
||||
static const SSLSignatureScheme SignatureSchemeEcdsaSha384[] = {
|
||||
ssl_sig_ecdsa_secp384r1_sha384};
|
||||
static const SSLSignatureScheme SignatureSchemeEcdsaSha256[] = {
|
||||
ssl_sig_ecdsa_secp256r1_sha256};
|
||||
static const SSLSignatureScheme SignatureSchemeRsaSha384[] = {
|
||||
ssl_sig_rsa_pkcs1_sha384};
|
||||
static const SSLSignatureScheme SignatureSchemeRsaSha256[] = {
|
||||
ssl_sig_rsa_pkcs1_sha256};
|
||||
|
||||
static SSLNamedGroup NamedGroupForEcdsa384(uint16_t version) {
|
||||
// NSS tries to match the group size to the symmetric cipher. In TLS 1.1 and
|
||||
// 1.0, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is the highest priority suite, so
|
||||
// we use P-384. With TLS 1.2 on we pick AES-128 GCM so use x25519.
|
||||
if (version <= SSL_LIBRARY_VERSION_TLS_1_1) {
|
||||
return ssl_grp_ec_secp384r1;
|
||||
}
|
||||
return ssl_grp_ec_curve25519;
|
||||
}
|
||||
|
||||
// When signature algorithms match up, this should connect successfully; even
|
||||
// for TLS 1.1 and 1.0, where they should be ignored.
|
||||
TEST_P(TlsConnectGeneric, SignatureAlgorithmServerAuth) {
|
||||
Reset(TlsAgent::kServerEcdsa384);
|
||||
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
|
||||
ssl_sig_ecdsa_secp384r1_sha384);
|
||||
}
|
||||
|
||||
// Here the client picks a single option, which should work in all versions.
|
||||
// Defaults on the server include the first option.
|
||||
TEST_P(TlsConnectGeneric, SignatureAlgorithmClientOnly) {
|
||||
const SSLSignatureAndHashAlg clientAlgorithms[] = {
|
||||
{ssl_hash_sha384, ssl_sign_ecdsa},
|
||||
{ssl_hash_sha384, ssl_sign_rsa}, // supported but unusable
|
||||
{ssl_hash_md5, ssl_sign_ecdsa} // unsupported and ignored
|
||||
};
|
||||
Reset(TlsAgent::kServerEcdsa384);
|
||||
EnsureTlsSetup();
|
||||
// Use the old API for this function.
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_SignaturePrefSet(client_->ssl_fd(), clientAlgorithms,
|
||||
PR_ARRAY_SIZE(clientAlgorithms)));
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
|
||||
ssl_sig_ecdsa_secp384r1_sha384);
|
||||
}
|
||||
|
||||
// Here the server picks a single option, which should work in all versions.
|
||||
// Defaults on the client include the provided option.
|
||||
TEST_P(TlsConnectGeneric, SignatureAlgorithmServerOnly) {
|
||||
Reset(TlsAgent::kServerEcdsa384);
|
||||
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
|
||||
ssl_sig_ecdsa_secp384r1_sha384);
|
||||
}
|
||||
|
||||
// In TLS 1.2, curve and hash aren't bound together.
|
||||
TEST_P(TlsConnectTls12, SignatureSchemeCurveMismatch) {
|
||||
Reset(TlsAgent::kServerEcdsa256);
|
||||
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
Connect();
|
||||
}
|
||||
|
||||
// In TLS 1.3, curve and hash are coupled.
|
||||
TEST_P(TlsConnectTls13, SignatureSchemeCurveMismatch) {
|
||||
Reset(TlsAgent::kServerEcdsa256);
|
||||
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
ConnectExpectFail();
|
||||
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
|
||||
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
}
|
||||
|
||||
// Configuring a P-256 cert with only SHA-384 signatures is OK in TLS 1.2.
|
||||
TEST_P(TlsConnectTls12, SignatureSchemeBadConfig) {
|
||||
Reset(TlsAgent::kServerEcdsa256); // P-256 cert can't be used.
|
||||
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
Connect();
|
||||
}
|
||||
|
||||
// A P-256 certificate in TLS 1.3 needs a SHA-256 signature scheme.
|
||||
TEST_P(TlsConnectTls13, SignatureSchemeBadConfig) {
|
||||
Reset(TlsAgent::kServerEcdsa256); // P-256 cert can't be used.
|
||||
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
ConnectExpectFail();
|
||||
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
|
||||
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
}
|
||||
|
||||
// Where there is no overlap on signature schemes, we still connect successfully
|
||||
// if we aren't going to use a signature.
|
||||
TEST_P(TlsConnectGenericPre13, SignatureAlgorithmNoOverlapStaticRsa) {
|
||||
client_->SetSignatureSchemes(SignatureSchemeRsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeRsaSha384));
|
||||
server_->SetSignatureSchemes(SignatureSchemeRsaSha256,
|
||||
PR_ARRAY_SIZE(SignatureSchemeRsaSha256));
|
||||
EnableOnlyStaticRsaCiphers();
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_rsa, ssl_auth_rsa_decrypt);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls12Plus, SignatureAlgorithmNoOverlapEcdsa) {
|
||||
Reset(TlsAgent::kServerEcdsa256);
|
||||
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha256,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha256));
|
||||
ConnectExpectFail();
|
||||
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
|
||||
}
|
||||
|
||||
// Pre 1.2, a mismatch on signature algorithms shouldn't affect anything.
|
||||
TEST_P(TlsConnectPre12, SignatureAlgorithmNoOverlapEcdsa) {
|
||||
Reset(TlsAgent::kServerEcdsa256);
|
||||
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha256,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha256));
|
||||
Connect();
|
||||
}
|
||||
|
||||
// The signature_algorithms extension is mandatory in TLS 1.3.
|
||||
TEST_P(TlsConnectTls13, SignatureAlgorithmDrop) {
|
||||
client_->SetPacketFilter(
|
||||
new TlsExtensionDropper(ssl_signature_algorithms_xtn));
|
||||
ConnectExpectFail();
|
||||
client_->CheckErrorCode(SSL_ERROR_MISSING_EXTENSION_ALERT);
|
||||
server_->CheckErrorCode(SSL_ERROR_MISSING_SIGNATURE_ALGORITHMS_EXTENSION);
|
||||
}
|
||||
|
||||
// TLS 1.2 has trouble detecting this sort of modification: it uses SHA1 and
|
||||
// only fails when the Finished is checked.
|
||||
TEST_P(TlsConnectTls12, SignatureAlgorithmDrop) {
|
||||
client_->SetPacketFilter(
|
||||
new TlsExtensionDropper(ssl_signature_algorithms_xtn));
|
||||
ConnectExpectFail();
|
||||
client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
|
||||
server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls12Plus, RequestClientAuthWithSha384) {
|
||||
server_->SetSignatureSchemes(SignatureSchemeRsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeRsaSha384));
|
||||
server_->RequestClientAuth(false);
|
||||
Connect();
|
||||
}
|
||||
|
||||
class BeforeFinished : public TlsRecordFilter {
|
||||
private:
|
||||
enum HandshakeState { BEFORE_CCS, AFTER_CCS, DONE };
|
||||
|
||||
public:
|
||||
BeforeFinished(TlsAgent* client, TlsAgent* server, VoidFunction before_ccs,
|
||||
VoidFunction before_finished)
|
||||
: client_(client),
|
||||
server_(server),
|
||||
before_ccs_(before_ccs),
|
||||
before_finished_(before_finished),
|
||||
state_(BEFORE_CCS) {}
|
||||
|
||||
protected:
|
||||
virtual PacketFilter::Action FilterRecord(const RecordHeader& header,
|
||||
const DataBuffer& body,
|
||||
DataBuffer* out) {
|
||||
switch (state_) {
|
||||
case BEFORE_CCS:
|
||||
// Awaken when we see the CCS.
|
||||
if (header.content_type() == kTlsChangeCipherSpecType) {
|
||||
before_ccs_();
|
||||
|
||||
// Write the CCS out as a separate write, so that we can make
|
||||
// progress. Ordinarily, libssl sends the CCS and Finished together,
|
||||
// but that means that they both get processed together.
|
||||
DataBuffer ccs;
|
||||
header.Write(&ccs, 0, body);
|
||||
server_->SendDirect(ccs);
|
||||
client_->Handshake();
|
||||
state_ = AFTER_CCS;
|
||||
// Request that the original record be dropped by the filter.
|
||||
return DROP;
|
||||
}
|
||||
break;
|
||||
|
||||
case AFTER_CCS:
|
||||
EXPECT_EQ(kTlsHandshakeType, header.content_type());
|
||||
// This could check that data contains a Finished message, but it's
|
||||
// encrypted, so that's too much extra work.
|
||||
|
||||
before_finished_();
|
||||
state_ = DONE;
|
||||
break;
|
||||
|
||||
case DONE:
|
||||
break;
|
||||
}
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
private:
|
||||
TlsAgent* client_;
|
||||
TlsAgent* server_;
|
||||
VoidFunction before_ccs_;
|
||||
VoidFunction before_finished_;
|
||||
HandshakeState state_;
|
||||
};
|
||||
|
||||
// Running code after the client has started processing the encrypted part of
|
||||
// the server's first flight, but before the Finished is processed is very hard
|
||||
// in TLS 1.3. These encrypted messages are sent in a single encrypted blob.
|
||||
// The following test uses DTLS to make it possible to force the client to
|
||||
// process the handshake in pieces.
|
||||
//
|
||||
// The first encrypted message from the server is dropped, and the MTU is
|
||||
// reduced to just below the original message size so that the server sends two
|
||||
// messages. The Finished message is then processed separately.
|
||||
class BeforeFinished13 : public PacketFilter {
|
||||
private:
|
||||
enum HandshakeState {
|
||||
INIT,
|
||||
BEFORE_FIRST_FRAGMENT,
|
||||
BEFORE_SECOND_FRAGMENT,
|
||||
DONE
|
||||
};
|
||||
|
||||
public:
|
||||
BeforeFinished13(TlsAgent* client, TlsAgent* server,
|
||||
VoidFunction before_finished)
|
||||
: client_(client),
|
||||
server_(server),
|
||||
before_finished_(before_finished),
|
||||
records_(0) {}
|
||||
|
||||
protected:
|
||||
virtual PacketFilter::Action Filter(const DataBuffer& input,
|
||||
DataBuffer* output) {
|
||||
switch (++records_) {
|
||||
case 1:
|
||||
// Packet 1 is the server's entire first flight. Drop it.
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSLInt_SetMTU(server_->ssl_fd(), input.len() - 1));
|
||||
return DROP;
|
||||
|
||||
// Packet 2 is the first part of the server's retransmitted first
|
||||
// flight. Keep that.
|
||||
|
||||
case 3:
|
||||
// Packet 3 is the second part of the server's retransmitted first
|
||||
// flight. Before passing that on, make sure that the client processes
|
||||
// packet 2, then call the before_finished_() callback.
|
||||
client_->Handshake();
|
||||
before_finished_();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
private:
|
||||
TlsAgent* client_;
|
||||
TlsAgent* server_;
|
||||
VoidFunction before_finished_;
|
||||
size_t records_;
|
||||
};
|
||||
|
||||
static SECStatus AuthCompleteBlock(TlsAgent*, PRBool, PRBool) {
|
||||
return SECWouldBlock;
|
||||
}
|
||||
|
||||
// This test uses an AuthCertificateCallback that blocks. A filter is used to
|
||||
// split the server's first flight into two pieces. Before the second piece is
|
||||
// processed by the client, SSL_AuthCertificateComplete() is called.
|
||||
TEST_F(TlsConnectDatagram13, AuthCompleteBeforeFinished) {
|
||||
client_->SetAuthCertificateCallback(AuthCompleteBlock);
|
||||
server_->SetPacketFilter(new BeforeFinished13(client_, server_, [this]() {
|
||||
EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0));
|
||||
}));
|
||||
Connect();
|
||||
}
|
||||
|
||||
static void TriggerAuthComplete(PollTarget* target, Event event) {
|
||||
std::cerr << "client: call SSL_AuthCertificateComplete" << std::endl;
|
||||
EXPECT_EQ(TIMER_EVENT, event);
|
||||
TlsAgent* client = static_cast<TlsAgent*>(target);
|
||||
EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client->ssl_fd(), 0));
|
||||
}
|
||||
|
||||
// This test uses a simple AuthCertificateCallback. Due to the way that the
|
||||
// entire server flight is processed, the call to SSL_AuthCertificateComplete
|
||||
// will trigger after the Finished message is processed.
|
||||
TEST_F(TlsConnectDatagram13, AuthCompleteAfterFinished) {
|
||||
client_->SetAuthCertificateCallback(
|
||||
[this](TlsAgent*, PRBool, PRBool) -> SECStatus {
|
||||
Poller::Timer* timer_handle;
|
||||
// This is really just to unroll the stack.
|
||||
Poller::Instance()->SetTimer(1U, client_, TriggerAuthComplete,
|
||||
&timer_handle);
|
||||
return SECWouldBlock;
|
||||
});
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGenericPre13, ClientWriteBetweenCCSAndFinishedWithFalseStart) {
|
||||
client_->EnableFalseStart();
|
||||
server_->SetPacketFilter(new BeforeFinished(
|
||||
client_, server_,
|
||||
[this]() { EXPECT_TRUE(client_->can_falsestart_hook_called()); },
|
||||
[this]() {
|
||||
// Write something, which used to fail: bug 1235366.
|
||||
client_->SendData(10);
|
||||
}));
|
||||
|
||||
Connect();
|
||||
server_->SendData(10);
|
||||
Receive(10);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGenericPre13, AuthCompleteBeforeFinishedWithFalseStart) {
|
||||
client_->EnableFalseStart();
|
||||
client_->SetAuthCertificateCallback(AuthCompleteBlock);
|
||||
server_->SetPacketFilter(new BeforeFinished(
|
||||
client_, server_,
|
||||
[]() {
|
||||
// Do nothing before CCS
|
||||
},
|
||||
[this]() {
|
||||
EXPECT_FALSE(client_->can_falsestart_hook_called());
|
||||
// AuthComplete before Finished still enables false start.
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_AuthCertificateComplete(client_->ssl_fd(), 0));
|
||||
EXPECT_TRUE(client_->can_falsestart_hook_called());
|
||||
client_->SendData(10);
|
||||
}));
|
||||
|
||||
Connect();
|
||||
server_->SendData(10);
|
||||
Receive(10);
|
||||
}
|
||||
|
||||
class EnforceNoActivity : public PacketFilter {
|
||||
protected:
|
||||
PacketFilter::Action Filter(const DataBuffer& input,
|
||||
DataBuffer* output) override {
|
||||
std::cerr << "Unexpected packet: " << input << std::endl;
|
||||
EXPECT_TRUE(false) << "should not send anything";
|
||||
return KEEP;
|
||||
}
|
||||
};
|
||||
|
||||
// In this test, we want to make sure that the server completes its handshake,
|
||||
// but the client does not. Because the AuthCertificate callback blocks and we
|
||||
// never call SSL_AuthCertificateComplete(), the client should never report that
|
||||
// it has completed the handshake. Manually call Handshake(), alternating sides
|
||||
// between client and server, until the desired state is reached.
|
||||
TEST_P(TlsConnectGenericPre13, AuthCompleteDelayed) {
|
||||
client_->SetAuthCertificateCallback(AuthCompleteBlock);
|
||||
|
||||
server_->StartConnect();
|
||||
client_->StartConnect();
|
||||
client_->Handshake(); // Send ClientHello
|
||||
server_->Handshake(); // Send ServerHello
|
||||
client_->Handshake(); // Send ClientKeyExchange and Finished
|
||||
server_->Handshake(); // Send Finished
|
||||
// The server should now report that it is connected
|
||||
EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
|
||||
|
||||
// The client should send nothing from here on.
|
||||
client_->SetPacketFilter(new EnforceNoActivity());
|
||||
client_->Handshake();
|
||||
EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
|
||||
|
||||
// This should allow the handshake to complete now.
|
||||
EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0));
|
||||
client_->Handshake(); // Transition to connected
|
||||
EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
|
||||
EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
|
||||
|
||||
// Remove this before closing or the close_notify alert will trigger it.
|
||||
client_->SetPacketFilter(nullptr);
|
||||
}
|
||||
|
||||
// TLS 1.3 handles a delayed AuthComplete callback differently since the
|
||||
// shape of the handshake is different.
|
||||
TEST_P(TlsConnectTls13, AuthCompleteDelayed) {
|
||||
client_->SetAuthCertificateCallback(AuthCompleteBlock);
|
||||
|
||||
server_->StartConnect();
|
||||
client_->StartConnect();
|
||||
client_->Handshake(); // Send ClientHello
|
||||
server_->Handshake(); // Send ServerHello
|
||||
EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
|
||||
EXPECT_EQ(TlsAgent::STATE_CONNECTING, server_->state());
|
||||
|
||||
// The client will send nothing until AuthCertificateComplete is called.
|
||||
client_->SetPacketFilter(new EnforceNoActivity());
|
||||
client_->Handshake();
|
||||
EXPECT_EQ(TlsAgent::STATE_CONNECTING, client_->state());
|
||||
|
||||
// This should allow the handshake to complete now.
|
||||
client_->SetPacketFilter(nullptr);
|
||||
EXPECT_EQ(SECSuccess, SSL_AuthCertificateComplete(client_->ssl_fd(), 0));
|
||||
client_->Handshake(); // Send Finished
|
||||
server_->Handshake(); // Transition to connected and send NewSessionTicket
|
||||
EXPECT_EQ(TlsAgent::STATE_CONNECTED, client_->state());
|
||||
EXPECT_EQ(TlsAgent::STATE_CONNECTED, server_->state());
|
||||
}
|
||||
|
||||
static const SSLExtraServerCertData ServerCertDataRsaPkcs1Decrypt = {
|
||||
ssl_auth_rsa_decrypt, nullptr, nullptr, nullptr};
|
||||
static const SSLExtraServerCertData ServerCertDataRsaPkcs1Sign = {
|
||||
ssl_auth_rsa_sign, nullptr, nullptr, nullptr};
|
||||
static const SSLExtraServerCertData ServerCertDataRsaPss = {
|
||||
ssl_auth_rsa_pss, nullptr, nullptr, nullptr};
|
||||
|
||||
// Test RSA cert with usage=[signature, encipherment].
|
||||
TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPkcs1SignAndKEX) {
|
||||
Reset(TlsAgent::kServerRsa);
|
||||
|
||||
PRFileDesc* ssl_fd = agent_->ssl_fd();
|
||||
EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_decrypt));
|
||||
EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_sign));
|
||||
EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_pss));
|
||||
|
||||
// Configuring for only rsa_sign, rsa_pss, or rsa_decrypt should work.
|
||||
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsa, false,
|
||||
&ServerCertDataRsaPkcs1Decrypt));
|
||||
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsa, false,
|
||||
&ServerCertDataRsaPkcs1Sign));
|
||||
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsa, false,
|
||||
&ServerCertDataRsaPss));
|
||||
}
|
||||
|
||||
// Test RSA cert with usage=[signature].
|
||||
TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPkcs1Sign) {
|
||||
Reset(TlsAgent::kServerRsaSign);
|
||||
|
||||
PRFileDesc* ssl_fd = agent_->ssl_fd();
|
||||
EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_decrypt));
|
||||
EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_sign));
|
||||
EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_pss));
|
||||
|
||||
// Configuring for only rsa_decrypt should fail.
|
||||
EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaSign, false,
|
||||
&ServerCertDataRsaPkcs1Decrypt));
|
||||
|
||||
// Configuring for only rsa_sign or rsa_pss should work.
|
||||
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsaSign, false,
|
||||
&ServerCertDataRsaPkcs1Sign));
|
||||
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsaSign, false,
|
||||
&ServerCertDataRsaPss));
|
||||
}
|
||||
|
||||
// Test RSA cert with usage=[encipherment].
|
||||
TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPkcs1KEX) {
|
||||
Reset(TlsAgent::kServerRsaDecrypt);
|
||||
|
||||
PRFileDesc* ssl_fd = agent_->ssl_fd();
|
||||
EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_decrypt));
|
||||
EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_sign));
|
||||
EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_pss));
|
||||
|
||||
// Configuring for only rsa_sign or rsa_pss should fail.
|
||||
EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaDecrypt, false,
|
||||
&ServerCertDataRsaPkcs1Sign));
|
||||
EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaDecrypt, false,
|
||||
&ServerCertDataRsaPss));
|
||||
|
||||
// Configuring for only rsa_decrypt should work.
|
||||
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsaDecrypt, false,
|
||||
&ServerCertDataRsaPkcs1Decrypt));
|
||||
}
|
||||
|
||||
// Test configuring an RSA-PSS cert.
|
||||
TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPss) {
|
||||
Reset(TlsAgent::kServerRsaPss);
|
||||
|
||||
PRFileDesc* ssl_fd = agent_->ssl_fd();
|
||||
EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_decrypt));
|
||||
EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_sign));
|
||||
EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_pss));
|
||||
|
||||
// Configuring for only rsa_sign or rsa_decrypt should fail.
|
||||
EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaPss, false,
|
||||
&ServerCertDataRsaPkcs1Sign));
|
||||
EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaPss, false,
|
||||
&ServerCertDataRsaPkcs1Decrypt));
|
||||
|
||||
// Configuring for only rsa_pss should work.
|
||||
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsaPss, false,
|
||||
&ServerCertDataRsaPss));
|
||||
}
|
||||
|
||||
// mode, version, certificate, auth type, signature scheme
|
||||
typedef std::tuple<std::string, uint16_t, std::string, SSLAuthType,
|
||||
SSLSignatureScheme>
|
||||
SignatureSchemeProfile;
|
||||
|
||||
class TlsSignatureSchemeConfiguration
|
||||
: public TlsConnectTestBase,
|
||||
public ::testing::WithParamInterface<SignatureSchemeProfile> {
|
||||
public:
|
||||
TlsSignatureSchemeConfiguration()
|
||||
: TlsConnectTestBase(std::get<0>(GetParam()), std::get<1>(GetParam())),
|
||||
certificate_(std::get<2>(GetParam())),
|
||||
auth_type_(std::get<3>(GetParam())),
|
||||
signature_scheme_(std::get<4>(GetParam())) {}
|
||||
|
||||
protected:
|
||||
void TestSignatureSchemeConfig(TlsAgent* configPeer) {
|
||||
EnsureTlsSetup();
|
||||
configPeer->SetSignatureSchemes(&signature_scheme_, 1);
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, auth_type_,
|
||||
signature_scheme_);
|
||||
}
|
||||
|
||||
std::string certificate_;
|
||||
SSLAuthType auth_type_;
|
||||
SSLSignatureScheme signature_scheme_;
|
||||
};
|
||||
|
||||
TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigServer) {
|
||||
Reset(certificate_);
|
||||
TestSignatureSchemeConfig(server_);
|
||||
}
|
||||
|
||||
TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigClient) {
|
||||
Reset(certificate_);
|
||||
TlsExtensionCapture* capture =
|
||||
new TlsExtensionCapture(ssl_signature_algorithms_xtn);
|
||||
client_->SetPacketFilter(capture);
|
||||
TestSignatureSchemeConfig(client_);
|
||||
|
||||
const DataBuffer& ext = capture->extension();
|
||||
ASSERT_EQ(2U + 2U, ext.len());
|
||||
uint32_t v = 0;
|
||||
ASSERT_TRUE(ext.Read(0, 2, &v));
|
||||
EXPECT_EQ(2U, v);
|
||||
ASSERT_TRUE(ext.Read(2, 2, &v));
|
||||
EXPECT_EQ(signature_scheme_, static_cast<SSLSignatureScheme>(v));
|
||||
}
|
||||
|
||||
TEST_P(TlsSignatureSchemeConfiguration, SignatureSchemeConfigBoth) {
|
||||
Reset(certificate_);
|
||||
EnsureTlsSetup();
|
||||
client_->SetSignatureSchemes(&signature_scheme_, 1);
|
||||
server_->SetSignatureSchemes(&signature_scheme_, 1);
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, auth_type_, signature_scheme_);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SignatureSchemeRsa, TlsSignatureSchemeConfiguration,
|
||||
::testing::Combine(
|
||||
TlsConnectTestBase::kTlsModesAll, TlsConnectTestBase::kTlsV12Plus,
|
||||
::testing::Values(TlsAgent::kServerRsaSign),
|
||||
::testing::Values(ssl_auth_rsa_sign),
|
||||
::testing::Values(ssl_sig_rsa_pkcs1_sha256, ssl_sig_rsa_pkcs1_sha384,
|
||||
ssl_sig_rsa_pkcs1_sha512, ssl_sig_rsa_pss_sha256,
|
||||
ssl_sig_rsa_pss_sha384)));
|
||||
// PSS with SHA-512 needs a bigger key to work.
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SignatureSchemeBigRsa, TlsSignatureSchemeConfiguration,
|
||||
::testing::Combine(TlsConnectTestBase::kTlsModesAll,
|
||||
TlsConnectTestBase::kTlsV12Plus,
|
||||
::testing::Values(TlsAgent::kRsa2048),
|
||||
::testing::Values(ssl_auth_rsa_sign),
|
||||
::testing::Values(ssl_sig_rsa_pss_sha512)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SignatureSchemeRsaSha1, TlsSignatureSchemeConfiguration,
|
||||
::testing::Combine(TlsConnectTestBase::kTlsModesAll,
|
||||
TlsConnectTestBase::kTlsV12,
|
||||
::testing::Values(TlsAgent::kServerRsa),
|
||||
::testing::Values(ssl_auth_rsa_sign),
|
||||
::testing::Values(ssl_sig_rsa_pkcs1_sha1)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SignatureSchemeEcdsaP256, TlsSignatureSchemeConfiguration,
|
||||
::testing::Combine(TlsConnectTestBase::kTlsModesAll,
|
||||
TlsConnectTestBase::kTlsV12Plus,
|
||||
::testing::Values(TlsAgent::kServerEcdsa256),
|
||||
::testing::Values(ssl_auth_ecdsa),
|
||||
::testing::Values(ssl_sig_ecdsa_secp256r1_sha256)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SignatureSchemeEcdsaP384, TlsSignatureSchemeConfiguration,
|
||||
::testing::Combine(TlsConnectTestBase::kTlsModesAll,
|
||||
TlsConnectTestBase::kTlsV12Plus,
|
||||
::testing::Values(TlsAgent::kServerEcdsa384),
|
||||
::testing::Values(ssl_auth_ecdsa),
|
||||
::testing::Values(ssl_sig_ecdsa_secp384r1_sha384)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SignatureSchemeEcdsaP521, TlsSignatureSchemeConfiguration,
|
||||
::testing::Combine(TlsConnectTestBase::kTlsModesAll,
|
||||
TlsConnectTestBase::kTlsV12Plus,
|
||||
::testing::Values(TlsAgent::kServerEcdsa521),
|
||||
::testing::Values(ssl_auth_ecdsa),
|
||||
::testing::Values(ssl_sig_ecdsa_secp521r1_sha512)));
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
SignatureSchemeEcdsaSha1, TlsSignatureSchemeConfiguration,
|
||||
::testing::Combine(TlsConnectTestBase::kTlsModesAll,
|
||||
TlsConnectTestBase::kTlsV12,
|
||||
::testing::Values(TlsAgent::kServerEcdsa256,
|
||||
TlsAgent::kServerEcdsa384),
|
||||
::testing::Values(ssl_auth_ecdsa),
|
||||
::testing::Values(ssl_sig_ecdsa_sha1)));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue