mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-21 15:57:31 +09:00
Update NSS to 3.41
This commit is contained in:
parent
d5f6e64f43
commit
5f0986e66f
540 changed files with 49568 additions and 10631 deletions
|
|
@ -52,6 +52,7 @@ CPPSRCS = \
|
|||
tls_hkdf_unittest.cc \
|
||||
tls_filter.cc \
|
||||
tls_protect.cc \
|
||||
tls_esni_unittest.cc \
|
||||
$(NULL)
|
||||
|
||||
INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
|
||||
|
|
|
|||
|
|
@ -206,4 +206,4 @@ static const uint8_t rsa8193[] = {
|
|||
0x13, 0x34, 0x9d, 0x34, 0xb8, 0xef, 0x13, 0x3a, 0x20, 0xf5, 0x74, 0x02,
|
||||
0x70, 0x3b, 0x41, 0x60, 0x1f, 0x5e, 0x76, 0x0a, 0xb1, 0x17, 0xd5, 0xcf,
|
||||
0x79, 0xef, 0xf7, 0xab, 0xe7, 0xd6, 0x0f, 0xad, 0x85, 0x2c, 0x52, 0x67,
|
||||
0xb5, 0xa0, 0x4a, 0xfd, 0xaf};
|
||||
0xb5, 0xa0, 0x4a, 0xfd, 0xaf};
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ extern "C" {
|
|||
|
||||
#include "databuffer.h"
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ const static uint8_t kCannedTls13ClientHello[] = {
|
|||
0xc2, 0xb3, 0xc6, 0x80, 0x72, 0x86, 0x08, 0x86, 0x8f, 0x52, 0xc5, 0xcb,
|
||||
0xbf, 0x2a, 0xb5, 0x59, 0x64, 0xcc, 0x0c, 0x49, 0x95, 0x36, 0xe4, 0xd9,
|
||||
0x2f, 0xd4, 0x24, 0x66, 0x71, 0x6f, 0x5d, 0x70, 0xe2, 0xa0, 0xea, 0x26,
|
||||
0x00, 0x2b, 0x00, 0x03, 0x02, 0x7f, kD13, 0x00, 0x0d, 0x00, 0x20, 0x00,
|
||||
0x00, 0x2b, 0x00, 0x03, 0x02, 0x03, 0x04, 0x00, 0x0d, 0x00, 0x20, 0x00,
|
||||
0x1e, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03, 0x08, 0x04, 0x08,
|
||||
0x05, 0x08, 0x06, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x02, 0x01, 0x04,
|
||||
0x02, 0x05, 0x02, 0x06, 0x02, 0x02, 0x02};
|
||||
|
|
@ -64,8 +64,8 @@ TEST_P(TlsAgentTestClient13, CannedHello) {
|
|||
auto sh = MakeCannedTls13ServerHello();
|
||||
MakeHandshakeMessage(kTlsHandshakeServerHello, sh.data(), sh.len(),
|
||||
&server_hello);
|
||||
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
server_hello.data(), server_hello.len(), &buffer);
|
||||
MakeRecord(ssl_ct_handshake, SSL_LIBRARY_VERSION_TLS_1_3, server_hello.data(),
|
||||
server_hello.len(), &buffer);
|
||||
ProcessMessage(buffer, TlsAgent::STATE_CONNECTING);
|
||||
}
|
||||
|
||||
|
|
@ -79,8 +79,8 @@ TEST_P(TlsAgentTestClient13, EncryptedExtensionsInClear) {
|
|||
&encrypted_extensions, 1);
|
||||
server_hello.Append(encrypted_extensions);
|
||||
DataBuffer buffer;
|
||||
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
server_hello.data(), server_hello.len(), &buffer);
|
||||
MakeRecord(ssl_ct_handshake, SSL_LIBRARY_VERSION_TLS_1_3, server_hello.data(),
|
||||
server_hello.len(), &buffer);
|
||||
EnsureInit();
|
||||
ExpectAlert(kTlsAlertUnexpectedMessage);
|
||||
ProcessMessage(buffer, TlsAgent::STATE_ERROR,
|
||||
|
|
@ -97,11 +97,11 @@ TEST_F(TlsAgentStreamTestClient, EncryptedExtensionsInClearTwoPieces) {
|
|||
&encrypted_extensions, 1);
|
||||
server_hello.Append(encrypted_extensions);
|
||||
DataBuffer buffer;
|
||||
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
server_hello.data(), kFirstFragmentSize, &buffer);
|
||||
MakeRecord(ssl_ct_handshake, SSL_LIBRARY_VERSION_TLS_1_3, server_hello.data(),
|
||||
kFirstFragmentSize, &buffer);
|
||||
|
||||
DataBuffer buffer2;
|
||||
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
MakeRecord(ssl_ct_handshake, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
server_hello.data() + kFirstFragmentSize,
|
||||
server_hello.len() - kFirstFragmentSize, &buffer2);
|
||||
|
||||
|
|
@ -129,11 +129,11 @@ TEST_F(TlsAgentDgramTestClient, EncryptedExtensionsInClearTwoPieces) {
|
|||
&encrypted_extensions, 1);
|
||||
server_hello_frag2.Append(encrypted_extensions);
|
||||
DataBuffer buffer;
|
||||
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
MakeRecord(ssl_ct_handshake, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
server_hello_frag1.data(), server_hello_frag1.len(), &buffer);
|
||||
|
||||
DataBuffer buffer2;
|
||||
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
MakeRecord(ssl_ct_handshake, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
server_hello_frag2.data(), server_hello_frag2.len(), &buffer2, 1);
|
||||
|
||||
EnsureInit();
|
||||
|
|
@ -150,7 +150,7 @@ TEST_F(TlsAgentDgramTestClient, AckWithBogusLengthField) {
|
|||
// Length doesn't match
|
||||
const uint8_t ackBuf[] = {0x00, 0x08, 0x00};
|
||||
DataBuffer record;
|
||||
MakeRecord(variant_, kTlsAckType, SSL_LIBRARY_VERSION_TLS_1_2, ackBuf,
|
||||
MakeRecord(variant_, ssl_ct_ack, SSL_LIBRARY_VERSION_TLS_1_2, ackBuf,
|
||||
sizeof(ackBuf), &record, 0);
|
||||
agent_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
|
|
@ -164,7 +164,7 @@ TEST_F(TlsAgentDgramTestClient, AckWithNonEvenLength) {
|
|||
// Length isn't a multiple of 8
|
||||
const uint8_t ackBuf[] = {0x00, 0x01, 0x00};
|
||||
DataBuffer record;
|
||||
MakeRecord(variant_, kTlsAckType, SSL_LIBRARY_VERSION_TLS_1_2, ackBuf,
|
||||
MakeRecord(variant_, ssl_ct_ack, SSL_LIBRARY_VERSION_TLS_1_2, ackBuf,
|
||||
sizeof(ackBuf), &record, 0);
|
||||
agent_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
|
|
@ -196,7 +196,7 @@ TEST_F(TlsAgentStreamTestClient, Set0RttOptionThenRead) {
|
|||
agent_->StartConnect();
|
||||
agent_->Set0RttEnabled(true);
|
||||
DataBuffer buffer;
|
||||
MakeRecord(kTlsApplicationDataType, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
MakeRecord(ssl_ct_application_data, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
reinterpret_cast<const uint8_t *>(k0RttData), strlen(k0RttData),
|
||||
&buffer);
|
||||
ExpectAlert(kTlsAlertUnexpectedMessage);
|
||||
|
|
@ -214,10 +214,10 @@ TEST_F(TlsAgentStreamTestServer, Set0RttOptionClientHelloThenRead) {
|
|||
agent_->StartConnect();
|
||||
agent_->Set0RttEnabled(true);
|
||||
DataBuffer buffer;
|
||||
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
MakeRecord(ssl_ct_handshake, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
kCannedTls13ClientHello, sizeof(kCannedTls13ClientHello), &buffer);
|
||||
ProcessMessage(buffer, TlsAgent::STATE_CONNECTING);
|
||||
MakeRecord(kTlsApplicationDataType, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
MakeRecord(ssl_ct_application_data, SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
reinterpret_cast<const uint8_t *>(k0RttData), strlen(k0RttData),
|
||||
&buffer);
|
||||
ExpectAlert(kTlsAlertBadRecordMac);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
@ -37,6 +37,50 @@ TEST_P(TlsConnectGeneric, ServerAuthRsaChain) {
|
|||
EXPECT_EQ(2UL, chain_length);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls12Plus, ServerAuthRsaPss) {
|
||||
static const SSLSignatureScheme kSignatureSchemePss[] = {
|
||||
ssl_sig_rsa_pss_pss_sha256};
|
||||
|
||||
Reset(TlsAgent::kServerRsaPss);
|
||||
client_->SetSignatureSchemes(kSignatureSchemePss,
|
||||
PR_ARRAY_SIZE(kSignatureSchemePss));
|
||||
server_->SetSignatureSchemes(kSignatureSchemePss,
|
||||
PR_ARRAY_SIZE(kSignatureSchemePss));
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_pss,
|
||||
ssl_sig_rsa_pss_pss_sha256);
|
||||
}
|
||||
|
||||
// PSS doesn't work with TLS 1.0 or 1.1 because we can't signal it.
|
||||
TEST_P(TlsConnectPre12, ServerAuthRsaPssFails) {
|
||||
static const SSLSignatureScheme kSignatureSchemePss[] = {
|
||||
ssl_sig_rsa_pss_pss_sha256};
|
||||
|
||||
Reset(TlsAgent::kServerRsaPss);
|
||||
client_->SetSignatureSchemes(kSignatureSchemePss,
|
||||
PR_ARRAY_SIZE(kSignatureSchemePss));
|
||||
server_->SetSignatureSchemes(kSignatureSchemePss,
|
||||
PR_ARRAY_SIZE(kSignatureSchemePss));
|
||||
ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
|
||||
server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
}
|
||||
|
||||
// Check that a PSS certificate with no parameters works.
|
||||
TEST_P(TlsConnectTls12Plus, ServerAuthRsaPssNoParameters) {
|
||||
static const SSLSignatureScheme kSignatureSchemePss[] = {
|
||||
ssl_sig_rsa_pss_pss_sha256};
|
||||
|
||||
Reset("rsa_pss_noparam");
|
||||
client_->SetSignatureSchemes(kSignatureSchemePss,
|
||||
PR_ARRAY_SIZE(kSignatureSchemePss));
|
||||
server_->SetSignatureSchemes(kSignatureSchemePss,
|
||||
PR_ARRAY_SIZE(kSignatureSchemePss));
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_pss,
|
||||
ssl_sig_rsa_pss_pss_sha256);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ServerAuthRsaPssChain) {
|
||||
Reset("rsa_pss_chain");
|
||||
Connect();
|
||||
|
|
@ -55,6 +99,76 @@ TEST_P(TlsConnectGeneric, ServerAuthRsaCARsaPssChain) {
|
|||
EXPECT_EQ(2UL, chain_length);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ServerAuthRejected) {
|
||||
EnsureTlsSetup();
|
||||
client_->SetAuthCertificateCallback(
|
||||
[](TlsAgent*, PRBool, PRBool) -> SECStatus { return SECFailure; });
|
||||
ConnectExpectAlert(client_, kTlsAlertBadCertificate);
|
||||
client_->CheckErrorCode(SSL_ERROR_BAD_CERTIFICATE);
|
||||
server_->CheckErrorCode(SSL_ERROR_BAD_CERT_ALERT);
|
||||
EXPECT_EQ(TlsAgent::STATE_ERROR, client_->state());
|
||||
}
|
||||
|
||||
struct AuthCompleteArgs : public PollTarget {
|
||||
AuthCompleteArgs(const std::shared_ptr<TlsAgent>& a, PRErrorCode c)
|
||||
: agent(a), code(c) {}
|
||||
|
||||
std::shared_ptr<TlsAgent> agent;
|
||||
PRErrorCode code;
|
||||
};
|
||||
|
||||
static void CallAuthComplete(PollTarget* target, Event event) {
|
||||
EXPECT_EQ(TIMER_EVENT, event);
|
||||
auto args = reinterpret_cast<AuthCompleteArgs*>(target);
|
||||
std::cerr << args->agent->role_str() << ": call SSL_AuthCertificateComplete "
|
||||
<< (args->code ? PR_ErrorToName(args->code) : "no error")
|
||||
<< std::endl;
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_AuthCertificateComplete(args->agent->ssl_fd(), args->code));
|
||||
args->agent->Handshake(); // Make the TlsAgent aware of the error.
|
||||
delete args;
|
||||
}
|
||||
|
||||
// Install an AuthCertificateCallback that blocks when called. Then
|
||||
// SSL_AuthCertificateComplete is called on a very short timer. This allows any
|
||||
// processing that might follow the callback to complete.
|
||||
static void SetDeferredAuthCertificateCallback(std::shared_ptr<TlsAgent> agent,
|
||||
PRErrorCode code) {
|
||||
auto args = new AuthCompleteArgs(agent, code);
|
||||
agent->SetAuthCertificateCallback(
|
||||
[args](TlsAgent*, PRBool, PRBool) -> SECStatus {
|
||||
// This can't be 0 or we race the message from the client to the server,
|
||||
// and tests assume that we lose that race.
|
||||
std::shared_ptr<Poller::Timer> timer_handle;
|
||||
Poller::Instance()->SetTimer(1U, args, CallAuthComplete, &timer_handle);
|
||||
return SECWouldBlock;
|
||||
});
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ServerAuthRejectAsync) {
|
||||
SetDeferredAuthCertificateCallback(client_, SEC_ERROR_REVOKED_CERTIFICATE);
|
||||
ConnectExpectAlert(client_, kTlsAlertCertificateRevoked);
|
||||
// We only detect the error here when we attempt to handshake, so all the
|
||||
// client learns is that the handshake has already failed.
|
||||
client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_FAILED);
|
||||
server_->CheckErrorCode(SSL_ERROR_REVOKED_CERT_ALERT);
|
||||
}
|
||||
|
||||
// In TLS 1.2 and earlier, this will result in the client sending its Finished
|
||||
// before learning that the server certificate is bad. That means that the
|
||||
// server will believe that the handshake is complete.
|
||||
TEST_P(TlsConnectGenericPre13, ServerAuthRejectAsync) {
|
||||
SetDeferredAuthCertificateCallback(client_, SEC_ERROR_EXPIRED_CERTIFICATE);
|
||||
client_->ExpectSendAlert(kTlsAlertCertificateExpired);
|
||||
server_->ExpectReceiveAlert(kTlsAlertCertificateExpired);
|
||||
ConnectExpectFailOneSide(TlsAgent::CLIENT);
|
||||
client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_FAILED);
|
||||
|
||||
// The server might not receive the alert that the client sends, which would
|
||||
// cause the test to fail when it cleans up. Reset expectations.
|
||||
server_->ExpectReceiveAlert(kTlsAlertCloseNotify, kTlsAlertWarning);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ClientAuth) {
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
|
|
@ -153,6 +267,81 @@ TEST_P(TlsConnectTls12, ClientAuthBigRsaCheckSigAlg) {
|
|||
2048);
|
||||
}
|
||||
|
||||
// Replaces the signature scheme in a CertificateVerify message.
|
||||
class TlsReplaceSignatureSchemeFilter : public TlsHandshakeFilter {
|
||||
public:
|
||||
TlsReplaceSignatureSchemeFilter(const std::shared_ptr<TlsAgent>& a,
|
||||
SSLSignatureScheme scheme)
|
||||
: TlsHandshakeFilter(a, {kTlsHandshakeCertificateVerify}),
|
||||
scheme_(scheme) {
|
||||
EnableDecryption();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output) {
|
||||
*output = input;
|
||||
output->Write(0, scheme_, 2);
|
||||
return CHANGE;
|
||||
}
|
||||
|
||||
private:
|
||||
SSLSignatureScheme scheme_;
|
||||
};
|
||||
|
||||
// Check if CertificateVerify signed with rsa_pss_rsae_* is properly
|
||||
// rejected when the certificate is RSA-PSS.
|
||||
//
|
||||
// This only works under TLS 1.2, because PSS doesn't work with TLS
|
||||
// 1.0 or TLS 1.1 and the TLS 1.3 1-RTT handshake is partially
|
||||
// successful at the client side.
|
||||
TEST_P(TlsConnectTls12, ClientAuthInconsistentRsaeSignatureScheme) {
|
||||
static const SSLSignatureScheme kSignatureSchemePss[] = {
|
||||
ssl_sig_rsa_pss_pss_sha256, ssl_sig_rsa_pss_rsae_sha256};
|
||||
|
||||
Reset(TlsAgent::kServerRsa, "rsa_pss");
|
||||
client_->SetSignatureSchemes(kSignatureSchemePss,
|
||||
PR_ARRAY_SIZE(kSignatureSchemePss));
|
||||
server_->SetSignatureSchemes(kSignatureSchemePss,
|
||||
PR_ARRAY_SIZE(kSignatureSchemePss));
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
|
||||
EnsureTlsSetup();
|
||||
|
||||
MakeTlsFilter<TlsReplaceSignatureSchemeFilter>(client_,
|
||||
ssl_sig_rsa_pss_rsae_sha256);
|
||||
|
||||
ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
|
||||
}
|
||||
|
||||
// Check if CertificateVerify signed with rsa_pss_pss_* is properly
|
||||
// rejected when the certificate is RSA.
|
||||
//
|
||||
// This only works under TLS 1.2, because PSS doesn't work with TLS
|
||||
// 1.0 or TLS 1.1 and the TLS 1.3 1-RTT handshake is partially
|
||||
// successful at the client side.
|
||||
TEST_P(TlsConnectTls12, ClientAuthInconsistentPssSignatureScheme) {
|
||||
static const SSLSignatureScheme kSignatureSchemePss[] = {
|
||||
ssl_sig_rsa_pss_rsae_sha256, ssl_sig_rsa_pss_pss_sha256};
|
||||
|
||||
Reset(TlsAgent::kServerRsa, "rsa");
|
||||
client_->SetSignatureSchemes(kSignatureSchemePss,
|
||||
PR_ARRAY_SIZE(kSignatureSchemePss));
|
||||
server_->SetSignatureSchemes(kSignatureSchemePss,
|
||||
PR_ARRAY_SIZE(kSignatureSchemePss));
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
|
||||
EnsureTlsSetup();
|
||||
|
||||
MakeTlsFilter<TlsReplaceSignatureSchemeFilter>(client_,
|
||||
ssl_sig_rsa_pss_pss_sha256);
|
||||
|
||||
ConnectExpectAlert(server_, kTlsAlertIllegalParameter);
|
||||
}
|
||||
|
||||
class TlsZeroCertificateRequestSigAlgsFilter : public TlsHandshakeFilter {
|
||||
public:
|
||||
TlsZeroCertificateRequestSigAlgsFilter(const std::shared_ptr<TlsAgent>& a)
|
||||
|
|
@ -197,9 +386,9 @@ class TlsZeroCertificateRequestSigAlgsFilter : public TlsHandshakeFilter {
|
|||
}
|
||||
};
|
||||
|
||||
// Check that we fall back to SHA-1 when the server doesn't provide any
|
||||
// Check that we send an alert when the server doesn't provide any
|
||||
// supported_signature_algorithms in the CertificateRequest message.
|
||||
TEST_P(TlsConnectTls12, ClientAuthNoSigAlgsFallback) {
|
||||
TEST_P(TlsConnectTls12, ClientAuthNoSigAlgs) {
|
||||
EnsureTlsSetup();
|
||||
MakeTlsFilter<TlsZeroCertificateRequestSigAlgsFilter>(server_);
|
||||
auto capture_cert_verify = MakeTlsFilter<TlsHandshakeRecorder>(
|
||||
|
|
@ -207,24 +396,19 @@ TEST_P(TlsConnectTls12, ClientAuthNoSigAlgsFallback) {
|
|||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
|
||||
ConnectExpectAlert(server_, kTlsAlertDecryptError);
|
||||
ConnectExpectAlert(client_, kTlsAlertHandshakeFailure);
|
||||
|
||||
// We're expecting a bad signature here because we tampered with a handshake
|
||||
// message (CertReq). Previously, without the SHA-1 fallback, we would've
|
||||
// seen a malformed record alert.
|
||||
server_->CheckErrorCode(SEC_ERROR_BAD_SIGNATURE);
|
||||
client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
|
||||
|
||||
CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pkcs1_sha1, 1024);
|
||||
server_->CheckErrorCode(SSL_ERROR_HANDSHAKE_FAILURE_ALERT);
|
||||
client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
|
||||
}
|
||||
|
||||
static const SSLSignatureScheme SignatureSchemeEcdsaSha384[] = {
|
||||
static const SSLSignatureScheme kSignatureSchemeEcdsaSha384[] = {
|
||||
ssl_sig_ecdsa_secp384r1_sha384};
|
||||
static const SSLSignatureScheme SignatureSchemeEcdsaSha256[] = {
|
||||
static const SSLSignatureScheme kSignatureSchemeEcdsaSha256[] = {
|
||||
ssl_sig_ecdsa_secp256r1_sha256};
|
||||
static const SSLSignatureScheme SignatureSchemeRsaSha384[] = {
|
||||
static const SSLSignatureScheme kSignatureSchemeRsaSha384[] = {
|
||||
ssl_sig_rsa_pkcs1_sha384};
|
||||
static const SSLSignatureScheme SignatureSchemeRsaSha256[] = {
|
||||
static const SSLSignatureScheme kSignatureSchemeRsaSha256[] = {
|
||||
ssl_sig_rsa_pkcs1_sha256};
|
||||
|
||||
static SSLNamedGroup NamedGroupForEcdsa384(uint16_t version) {
|
||||
|
|
@ -241,10 +425,10 @@ static SSLNamedGroup NamedGroupForEcdsa384(uint16_t version) {
|
|||
// 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));
|
||||
client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
|
||||
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
|
||||
ssl_sig_ecdsa_secp384r1_sha384);
|
||||
|
|
@ -273,8 +457,8 @@ TEST_P(TlsConnectGeneric, SignatureAlgorithmClientOnly) {
|
|||
// Defaults on the client include the provided option.
|
||||
TEST_P(TlsConnectGeneric, SignatureAlgorithmServerOnly) {
|
||||
Reset(TlsAgent::kServerEcdsa384);
|
||||
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
|
||||
ssl_sig_ecdsa_secp384r1_sha384);
|
||||
|
|
@ -283,16 +467,16 @@ TEST_P(TlsConnectGeneric, SignatureAlgorithmServerOnly) {
|
|||
// 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));
|
||||
client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
|
||||
Connect();
|
||||
}
|
||||
|
||||
// In TLS 1.3, curve and hash are coupled.
|
||||
TEST_P(TlsConnectTls13, SignatureSchemeCurveMismatch) {
|
||||
Reset(TlsAgent::kServerEcdsa256);
|
||||
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
|
||||
ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
|
||||
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
|
||||
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
|
|
@ -301,16 +485,16 @@ TEST_P(TlsConnectTls13, SignatureSchemeCurveMismatch) {
|
|||
// 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));
|
||||
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
|
||||
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));
|
||||
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
|
||||
ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
|
||||
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
|
||||
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
|
|
@ -319,10 +503,10 @@ TEST_P(TlsConnectTls13, SignatureSchemeBadConfig) {
|
|||
// 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));
|
||||
client_->SetSignatureSchemes(kSignatureSchemeRsaSha384,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeRsaSha384));
|
||||
server_->SetSignatureSchemes(kSignatureSchemeRsaSha256,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeRsaSha256));
|
||||
EnableOnlyStaticRsaCiphers();
|
||||
Connect();
|
||||
CheckKeys(ssl_kea_rsa, ssl_auth_rsa_decrypt);
|
||||
|
|
@ -330,10 +514,10 @@ TEST_P(TlsConnectGenericPre13, SignatureAlgorithmNoOverlapStaticRsa) {
|
|||
|
||||
TEST_P(TlsConnectTls12Plus, SignatureAlgorithmNoOverlapEcdsa) {
|
||||
Reset(TlsAgent::kServerEcdsa256);
|
||||
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
|
||||
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha256,
|
||||
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha256));
|
||||
client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
|
||||
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha256,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha256));
|
||||
ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
|
||||
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
|
||||
|
|
@ -342,10 +526,10 @@ TEST_P(TlsConnectTls12Plus, SignatureAlgorithmNoOverlapEcdsa) {
|
|||
// 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));
|
||||
client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
|
||||
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha256,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha256));
|
||||
Connect();
|
||||
}
|
||||
|
||||
|
|
@ -366,29 +550,6 @@ TEST_P(TlsConnectTls12, SignatureAlgorithmDrop) {
|
|||
server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
|
||||
}
|
||||
|
||||
// Replaces the signature scheme in a TLS 1.3 CertificateVerify message.
|
||||
class TlsReplaceSignatureSchemeFilter : public TlsHandshakeFilter {
|
||||
public:
|
||||
TlsReplaceSignatureSchemeFilter(const std::shared_ptr<TlsAgent>& a,
|
||||
SSLSignatureScheme scheme)
|
||||
: TlsHandshakeFilter(a, {kTlsHandshakeCertificateVerify}),
|
||||
scheme_(scheme) {
|
||||
EnableDecryption();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output) {
|
||||
*output = input;
|
||||
output->Write(0, scheme_, 2);
|
||||
return CHANGE;
|
||||
}
|
||||
|
||||
private:
|
||||
SSLSignatureScheme scheme_;
|
||||
};
|
||||
|
||||
TEST_P(TlsConnectTls13, UnsupportedSignatureSchemeAlert) {
|
||||
EnsureTlsSetup();
|
||||
MakeTlsFilter<TlsReplaceSignatureSchemeFilter>(server_, ssl_sig_none);
|
||||
|
|
@ -411,8 +572,8 @@ TEST_P(TlsConnectTls13, InconsistentSignatureSchemeAlert) {
|
|||
}
|
||||
|
||||
TEST_P(TlsConnectTls12Plus, RequestClientAuthWithSha384) {
|
||||
server_->SetSignatureSchemes(SignatureSchemeRsaSha384,
|
||||
PR_ARRAY_SIZE(SignatureSchemeRsaSha384));
|
||||
server_->SetSignatureSchemes(kSignatureSchemeRsaSha384,
|
||||
PR_ARRAY_SIZE(kSignatureSchemeRsaSha384));
|
||||
server_->RequestClientAuth(false);
|
||||
Connect();
|
||||
}
|
||||
|
|
@ -438,7 +599,7 @@ class BeforeFinished : public TlsRecordFilter {
|
|||
switch (state_) {
|
||||
case BEFORE_CCS:
|
||||
// Awaken when we see the CCS.
|
||||
if (header.content_type() == kTlsChangeCipherSpecType) {
|
||||
if (header.content_type() == ssl_ct_change_cipher_spec) {
|
||||
before_ccs_();
|
||||
|
||||
// Write the CCS out as a separate write, so that we can make
|
||||
|
|
@ -455,7 +616,7 @@ class BeforeFinished : public TlsRecordFilter {
|
|||
break;
|
||||
|
||||
case AFTER_CCS:
|
||||
EXPECT_EQ(kTlsHandshakeType, header.content_type());
|
||||
EXPECT_EQ(ssl_ct_handshake, header.content_type());
|
||||
// This could check that data contains a Finished message, but it's
|
||||
// encrypted, so that's too much extra work.
|
||||
|
||||
|
|
@ -552,25 +713,11 @@ TEST_F(TlsConnectDatagram13, AuthCompleteBeforeFinished) {
|
|||
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 {
|
||||
std::shared_ptr<Poller::Timer> timer_handle;
|
||||
// This is really just to unroll the stack.
|
||||
Poller::Instance()->SetTimer(1U, client_.get(), TriggerAuthComplete,
|
||||
&timer_handle);
|
||||
return SECWouldBlock;
|
||||
});
|
||||
SetDeferredAuthCertificateCallback(client_, 0); // 0 = success.
|
||||
Connect();
|
||||
}
|
||||
|
||||
|
|
@ -754,15 +901,15 @@ TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPkcs1SignAndKEX) {
|
|||
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));
|
||||
EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_pss));
|
||||
|
||||
// Configuring for only rsa_sign, rsa_pss, or rsa_decrypt should work.
|
||||
// Configuring for only rsa_sign 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));
|
||||
EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsa, false,
|
||||
&ServerCertDataRsaPss));
|
||||
}
|
||||
|
||||
// Test RSA cert with usage=[signature].
|
||||
|
|
@ -772,17 +919,17 @@ TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPkcs1Sign) {
|
|||
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));
|
||||
EXPECT_FALSE(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.
|
||||
// Configuring for only rsa_sign should work.
|
||||
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsaSign, false,
|
||||
&ServerCertDataRsaPkcs1Sign));
|
||||
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsaSign, false,
|
||||
&ServerCertDataRsaPss));
|
||||
EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaSign, false,
|
||||
&ServerCertDataRsaPss));
|
||||
}
|
||||
|
||||
// Test RSA cert with usage=[encipherment].
|
||||
|
|
|
|||
|
|
@ -84,6 +84,18 @@ class TlsCipherSuiteTestBase : public TlsConnectTestBase {
|
|||
Reset(TlsAgent::kRsa2048);
|
||||
auth_type_ = ssl_auth_rsa_sign;
|
||||
break;
|
||||
case ssl_sig_rsa_pss_pss_sha256:
|
||||
Reset(TlsAgent::kServerRsaPss);
|
||||
auth_type_ = ssl_auth_rsa_pss;
|
||||
break;
|
||||
case ssl_sig_rsa_pss_pss_sha384:
|
||||
Reset("rsa_pss384");
|
||||
auth_type_ = ssl_auth_rsa_pss;
|
||||
break;
|
||||
case ssl_sig_rsa_pss_pss_sha512:
|
||||
Reset("rsa_pss512");
|
||||
auth_type_ = ssl_auth_rsa_pss;
|
||||
break;
|
||||
case ssl_sig_ecdsa_secp256r1_sha256:
|
||||
Reset(TlsAgent::kServerEcdsa256);
|
||||
auth_type_ = ssl_auth_ecdsa;
|
||||
|
|
@ -270,7 +282,7 @@ TEST_P(TlsCipherSuiteTest, ReadLimit) {
|
|||
} else {
|
||||
epoch = 0;
|
||||
}
|
||||
TlsAgentTestBase::MakeRecord(variant_, kTlsApplicationDataType, version_,
|
||||
TlsAgentTestBase::MakeRecord(variant_, ssl_ct_application_data, version_,
|
||||
payload, sizeof(payload), &record,
|
||||
(epoch << 48) | record_limit());
|
||||
client_->SendDirect(record);
|
||||
|
|
@ -310,14 +322,13 @@ static const auto kDummyNamedGroupParams = ::testing::Values(ssl_grp_none);
|
|||
static const auto kDummySignatureSchemesParams =
|
||||
::testing::Values(ssl_sig_none);
|
||||
|
||||
#ifndef NSS_DISABLE_TLS_1_3
|
||||
static SSLSignatureScheme kSignatureSchemesParamsArr[] = {
|
||||
ssl_sig_rsa_pkcs1_sha256, ssl_sig_rsa_pkcs1_sha384,
|
||||
ssl_sig_rsa_pkcs1_sha512, ssl_sig_ecdsa_secp256r1_sha256,
|
||||
ssl_sig_ecdsa_secp384r1_sha384, ssl_sig_rsa_pss_rsae_sha256,
|
||||
ssl_sig_rsa_pss_rsae_sha384, ssl_sig_rsa_pss_rsae_sha512,
|
||||
};
|
||||
#endif
|
||||
ssl_sig_rsa_pss_pss_sha256, ssl_sig_rsa_pss_pss_sha384,
|
||||
ssl_sig_rsa_pss_pss_sha512};
|
||||
|
||||
INSTANTIATE_CIPHER_TEST_P(RC4, Stream, V10ToV12, kDummyNamedGroupParams,
|
||||
kDummySignatureSchemesParams,
|
||||
|
|
@ -372,6 +383,14 @@ INSTANTIATE_CIPHER_TEST_P(
|
|||
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
|
||||
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA);
|
||||
INSTANTIATE_CIPHER_TEST_P(
|
||||
TLS12SigSchemes, All, V12, ::testing::ValuesIn(kFasterDHEGroups),
|
||||
::testing::ValuesIn(kSignatureSchemesParamsArr),
|
||||
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA256,
|
||||
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
|
||||
TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
|
||||
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256);
|
||||
#ifndef NSS_DISABLE_TLS_1_3
|
||||
INSTANTIATE_CIPHER_TEST_P(TLS13, All, V13,
|
||||
::testing::ValuesIn(kFasterDHEGroups),
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ TEST_F(TlsConnectStreamTls13, CustomExtensionEmptyWriterServer) {
|
|||
// Sending extensions that the client doesn't expect leads to extensions
|
||||
// appearing even if the client didn't send one, or in the wrong messages.
|
||||
client_->ExpectSendAlert(kTlsAlertUnsupportedExtension);
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
ConnectExpectFail();
|
||||
}
|
||||
|
||||
|
|
@ -350,7 +350,7 @@ TEST_F(TlsConnectStreamTls13, CustomExtensionUnsolicitedServer) {
|
|||
auto capture = MakeTlsFilter<TlsExtensionCapture>(server_, extension_code);
|
||||
|
||||
client_->ExpectSendAlert(kTlsAlertUnsupportedExtension);
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
ConnectExpectFail();
|
||||
|
||||
EXPECT_TRUE(capture->captured());
|
||||
|
|
@ -401,7 +401,7 @@ TEST_F(TlsConnectStreamTls13, CustomExtensionClientReject) {
|
|||
EXPECT_EQ(SECSuccess, rv);
|
||||
|
||||
client_->ExpectSendAlert(kTlsAlertHandshakeFailure);
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
ConnectExpectFail();
|
||||
}
|
||||
|
||||
|
|
@ -451,7 +451,7 @@ TEST_F(TlsConnectStreamTls13, CustomExtensionClientRejectAlert) {
|
|||
EXPECT_EQ(SECSuccess, rv);
|
||||
|
||||
client_->ExpectSendAlert(kCustomAlert);
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
ConnectExpectFail();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include "sslproto.h"
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
@ -643,4 +643,43 @@ TEST_P(TlsConnectGenericPre13, InvalidDERSignatureFfdhe) {
|
|||
client_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
|
||||
}
|
||||
|
||||
// Replace SignatureAndHashAlgorithm of a SKE.
|
||||
class DHEServerKEXSigAlgReplacer : public TlsHandshakeFilter {
|
||||
public:
|
||||
DHEServerKEXSigAlgReplacer(const std::shared_ptr<TlsAgent>& server,
|
||||
SSLSignatureScheme sig_scheme)
|
||||
: TlsHandshakeFilter(server, {kTlsHandshakeServerKeyExchange}),
|
||||
sig_scheme_(sig_scheme) {}
|
||||
|
||||
protected:
|
||||
virtual PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output) {
|
||||
*output = input;
|
||||
|
||||
uint32_t len;
|
||||
uint32_t idx = 0;
|
||||
EXPECT_TRUE(output->Read(idx, 2, &len));
|
||||
idx += 2 + len;
|
||||
EXPECT_TRUE(output->Read(idx, 2, &len));
|
||||
idx += 2 + len;
|
||||
EXPECT_TRUE(output->Read(idx, 2, &len));
|
||||
idx += 2 + len;
|
||||
output->Write(idx, sig_scheme_, 2);
|
||||
|
||||
return CHANGE;
|
||||
}
|
||||
|
||||
private:
|
||||
SSLSignatureScheme sig_scheme_;
|
||||
};
|
||||
|
||||
TEST_P(TlsConnectTls12, ConnectInconsistentSigAlgDHE) {
|
||||
EnableOnlyDheCiphers();
|
||||
|
||||
MakeTlsFilter<DHEServerKEXSigAlgReplacer>(server_,
|
||||
ssl_sig_ecdsa_secp256r1_sha256);
|
||||
ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
@ -123,7 +123,7 @@ class TlsDropDatagram13 : public TlsConnectDatagram13,
|
|||
|
||||
void Init(const std::shared_ptr<TlsAgent>& agent) {
|
||||
records_ = std::make_shared<TlsRecordRecorder>(agent);
|
||||
ack_ = std::make_shared<TlsRecordRecorder>(agent, content_ack);
|
||||
ack_ = std::make_shared<TlsRecordRecorder>(agent, ssl_ct_ack);
|
||||
ack_->EnableDecryption();
|
||||
drop_ = std::make_shared<SelectiveRecordDropFilter>(agent, 0, false);
|
||||
chain_ = std::make_shared<ChainedPacketFilter>(
|
||||
|
|
@ -670,7 +670,7 @@ TEST_P(TlsDropDatagram13, SendOutOfOrderAppWithHandshakeKey) {
|
|||
ASSERT_NE(nullptr, spec.get());
|
||||
ASSERT_EQ(2, spec->epoch());
|
||||
ASSERT_TRUE(client_->SendEncryptedRecord(spec, 0x0002000000000002,
|
||||
kTlsApplicationDataType,
|
||||
ssl_ct_application_data,
|
||||
DataBuffer(buf, sizeof(buf))));
|
||||
|
||||
// Now have the server consume the bogus message.
|
||||
|
|
@ -696,7 +696,7 @@ TEST_P(TlsDropDatagram13, SendOutOfOrderHsNonsenseWithHandshakeKey) {
|
|||
ASSERT_NE(nullptr, spec.get());
|
||||
ASSERT_EQ(2, spec->epoch());
|
||||
ASSERT_TRUE(client_->SendEncryptedRecord(spec, 0x0002000000000002,
|
||||
kTlsHandshakeType,
|
||||
ssl_ct_handshake,
|
||||
DataBuffer(buf, sizeof(buf))));
|
||||
server_->Handshake();
|
||||
EXPECT_EQ(2UL, server_filters_.ack_->count());
|
||||
|
|
@ -899,7 +899,7 @@ class TlsReplaceFirstRecordWithJunk : public TlsRecordFilter {
|
|||
}
|
||||
replaced_ = true;
|
||||
TlsRecordHeader out_header(header.variant(), header.version(),
|
||||
kTlsApplicationDataType,
|
||||
ssl_ct_application_data,
|
||||
header.sequence_number());
|
||||
|
||||
static const uint8_t junk[] = {1, 2, 3, 4};
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include "sslproto.h"
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@
|
|||
#include "sslerr.h"
|
||||
#include "sslproto.h"
|
||||
|
||||
// This is only to get DTLS_1_3_DRAFT_VERSION
|
||||
#include "ssl3prot.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "tls_connect.h"
|
||||
|
|
@ -41,28 +44,6 @@ class TlsExtensionTruncator : public TlsExtensionFilter {
|
|||
size_t length_;
|
||||
};
|
||||
|
||||
class TlsExtensionDamager : public TlsExtensionFilter {
|
||||
public:
|
||||
TlsExtensionDamager(const std::shared_ptr<TlsAgent>& a, uint16_t extension,
|
||||
size_t index)
|
||||
: TlsExtensionFilter(a), extension_(extension), index_(index) {}
|
||||
virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output) {
|
||||
if (extension_type != extension_) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
*output = input;
|
||||
output->data()[index_] += 73; // Increment selected for maximum damage
|
||||
return CHANGE;
|
||||
}
|
||||
|
||||
private:
|
||||
uint16_t extension_;
|
||||
size_t index_;
|
||||
};
|
||||
|
||||
class TlsExtensionAppender : public TlsHandshakeFilter {
|
||||
public:
|
||||
TlsExtensionAppender(const std::shared_ptr<TlsAgent>& a,
|
||||
|
|
@ -454,6 +435,25 @@ TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmsOddLength) {
|
|||
client_, ssl_signature_algorithms_xtn, extension));
|
||||
}
|
||||
|
||||
TEST_F(TlsExtensionTest13Stream, SignatureAlgorithmsPrecedingGarbage) {
|
||||
// 31 unknown signature algorithms followed by sha-256, rsa
|
||||
const uint8_t val[] = {
|
||||
0x00, 0x40, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x01};
|
||||
DataBuffer extension(val, sizeof(val));
|
||||
MakeTlsFilter<TlsExtensionReplacer>(client_, ssl_signature_algorithms_xtn,
|
||||
extension);
|
||||
client_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
ConnectExpectFail();
|
||||
client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
|
||||
server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTestGeneric, NoSupportedGroups) {
|
||||
ClientHelloErrorTest(
|
||||
std::make_shared<TlsExtensionDropper>(client_, ssl_supported_groups_xtn),
|
||||
|
|
@ -563,10 +563,10 @@ TEST_F(TlsExtensionTest13Stream, DropServerKeyShare) {
|
|||
EnsureTlsSetup();
|
||||
MakeTlsFilter<TlsExtensionDropper>(server_, ssl_tls13_key_share_xtn);
|
||||
client_->ExpectSendAlert(kTlsAlertMissingExtension);
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
ConnectExpectFail();
|
||||
EXPECT_EQ(SSL_ERROR_MISSING_KEY_SHARE, client_->error_code());
|
||||
EXPECT_EQ(SSL_ERROR_BAD_MAC_READ, server_->error_code());
|
||||
EXPECT_EQ(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE, server_->error_code());
|
||||
}
|
||||
|
||||
TEST_F(TlsExtensionTest13Stream, WrongServerKeyShare) {
|
||||
|
|
@ -583,13 +583,12 @@ TEST_F(TlsExtensionTest13Stream, WrongServerKeyShare) {
|
|||
EnsureTlsSetup();
|
||||
MakeTlsFilter<TlsExtensionReplacer>(server_, ssl_tls13_key_share_xtn, buf);
|
||||
client_->ExpectSendAlert(kTlsAlertIllegalParameter);
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
ConnectExpectFail();
|
||||
EXPECT_EQ(SSL_ERROR_RX_MALFORMED_KEY_SHARE, client_->error_code());
|
||||
EXPECT_EQ(SSL_ERROR_BAD_MAC_READ, server_->error_code());
|
||||
EXPECT_EQ(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE, server_->error_code());
|
||||
}
|
||||
|
||||
// TODO(ekr@rtfm.com): This is the wrong error code. See bug 1307269.
|
||||
TEST_F(TlsExtensionTest13Stream, UnknownServerKeyShare) {
|
||||
const uint16_t wrong_group = 0xffff;
|
||||
|
||||
|
|
@ -603,11 +602,11 @@ TEST_F(TlsExtensionTest13Stream, UnknownServerKeyShare) {
|
|||
DataBuffer buf(key_share, sizeof(key_share));
|
||||
EnsureTlsSetup();
|
||||
MakeTlsFilter<TlsExtensionReplacer>(server_, ssl_tls13_key_share_xtn, buf);
|
||||
client_->ExpectSendAlert(kTlsAlertMissingExtension);
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
client_->ExpectSendAlert(kTlsAlertIllegalParameter);
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
ConnectExpectFail();
|
||||
EXPECT_EQ(SSL_ERROR_MISSING_KEY_SHARE, client_->error_code());
|
||||
EXPECT_EQ(SSL_ERROR_BAD_MAC_READ, server_->error_code());
|
||||
EXPECT_EQ(SSL_ERROR_RX_MALFORMED_KEY_SHARE, client_->error_code());
|
||||
EXPECT_EQ(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE, server_->error_code());
|
||||
}
|
||||
|
||||
TEST_F(TlsExtensionTest13Stream, AddServerSignatureAlgorithmsOnResumption) {
|
||||
|
|
@ -616,10 +615,10 @@ TEST_F(TlsExtensionTest13Stream, AddServerSignatureAlgorithmsOnResumption) {
|
|||
MakeTlsFilter<TlsExtensionInjector>(server_, ssl_signature_algorithms_xtn,
|
||||
empty);
|
||||
client_->ExpectSendAlert(kTlsAlertUnsupportedExtension);
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
ConnectExpectFail();
|
||||
EXPECT_EQ(SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION, client_->error_code());
|
||||
EXPECT_EQ(SSL_ERROR_BAD_MAC_READ, server_->error_code());
|
||||
EXPECT_EQ(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE, server_->error_code());
|
||||
}
|
||||
|
||||
struct PskIdentity {
|
||||
|
|
@ -912,23 +911,32 @@ TEST_P(TlsExtensionTest13, RemoveTls13FromVersionListServerV12) {
|
|||
// 3. Server supports 1.2 and 1.3, client supports 1.2 and 1.3
|
||||
// but advertises 1.2 (because we changed things).
|
||||
TEST_P(TlsExtensionTest13, RemoveTls13FromVersionListBothV12) {
|
||||
client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
#ifndef TLS_1_3_DRAFT_VERSION
|
||||
ExpectAlert(server_, kTlsAlertIllegalParameter);
|
||||
#else
|
||||
ExpectAlert(server_, kTlsAlertDecryptError);
|
||||
// The downgrade check is disabled in DTLS 1.3, so all that happens when we
|
||||
// tamper with the supported versions is that the Finished check fails.
|
||||
#ifdef DTLS_1_3_DRAFT_VERSION
|
||||
if (variant_ == ssl_variant_datagram) {
|
||||
ExpectAlert(server_, kTlsAlertDecryptError);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ExpectAlert(client_, kTlsAlertIllegalParameter);
|
||||
}
|
||||
ConnectWithReplacementVersionList(SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
#ifndef TLS_1_3_DRAFT_VERSION
|
||||
client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
|
||||
server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
|
||||
#else
|
||||
client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
|
||||
server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
|
||||
#ifdef DTLS_1_3_DRAFT_VERSION
|
||||
if (variant_ == ssl_variant_datagram) {
|
||||
client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
|
||||
server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
|
||||
server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(TlsExtensionTest13, HrrThenRemoveSignatureAlgorithms) {
|
||||
|
|
@ -1017,7 +1025,7 @@ class TlsBogusExtensionTest13 : public TlsBogusExtensionTest {
|
|||
client_->ExpectSendAlert(alert);
|
||||
client_->Handshake();
|
||||
if (variant_ == ssl_variant_stream) {
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
}
|
||||
server_->Handshake();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include "sslproto.h"
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
@ -106,8 +106,8 @@ class RecordFragmenter : public PacketFilter {
|
|||
}
|
||||
|
||||
// Just rewrite the sequence number (CCS only).
|
||||
if (header.content_type() != kTlsHandshakeType) {
|
||||
EXPECT_EQ(kTlsChangeCipherSpecType, header.content_type());
|
||||
if (header.content_type() != ssl_ct_handshake) {
|
||||
EXPECT_EQ(ssl_ct_change_cipher_spec, header.content_type());
|
||||
WriteRecord(header, record);
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class TlsApplicationDataRecorder : public TlsRecordFilter {
|
|||
virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output) {
|
||||
if (header.content_type() == kTlsApplicationDataType) {
|
||||
if (header.content_type() == ssl_ct_application_data) {
|
||||
buffer_.Append(input);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ class GatherV2ClientHelloTest : public TlsConnectTestBase {
|
|||
|
||||
void ConnectExpectMalformedClientHello(const DataBuffer &data) {
|
||||
EnsureTlsSetup();
|
||||
server_->SetOption(SSL_ENABLE_V2_COMPATIBLE_HELLO, PR_TRUE);
|
||||
server_->ExpectSendAlert(kTlsAlertIllegalParameter);
|
||||
client_->SendDirect(data);
|
||||
server_->StartConnect();
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
'tls_connect.cc',
|
||||
'tls_filter.cc',
|
||||
'tls_hkdf_unittest.cc',
|
||||
'tls_esni_unittest.cc',
|
||||
'tls_protect.cc'
|
||||
],
|
||||
'dependencies': [
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@
|
|||
#include "sslerr.h"
|
||||
#include "sslproto.h"
|
||||
|
||||
// This is internal, just to get TLS_1_3_DRAFT_VERSION.
|
||||
// This is internal, just to get DTLS_1_3_DRAFT_VERSION.
|
||||
#include "ssl3prot.h"
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
@ -76,7 +76,7 @@ class CorrectMessageSeqAfterHrrFilter : public TlsRecordFilter {
|
|||
PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
|
||||
const DataBuffer& record, size_t* offset,
|
||||
DataBuffer* output) {
|
||||
if (filtered_packets() > 0 || header.content_type() != content_handshake) {
|
||||
if (filtered_packets() > 0 || header.content_type() != ssl_ct_handshake) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
|
|
@ -718,6 +718,86 @@ TEST_F(TlsConnectStreamTls13, RetryStatelessDamageSecondClientHello) {
|
|||
client_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
|
||||
}
|
||||
|
||||
// Stream because SSL_SendSessionTicket only supports that.
|
||||
TEST_F(TlsConnectStreamTls13, SecondClientHelloSendSameTicket) {
|
||||
// This simulates the scenario described at:
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1481271#c7
|
||||
//
|
||||
// Here two connections are interleaved. Tickets are issued on one
|
||||
// connection. A HelloRetryRequest is triggered on the second connection,
|
||||
// meaning that there are two ClientHellos. We need to check that both
|
||||
// ClientHellos have the same ticket, even if a new ticket is issued on the
|
||||
// other connection in the meantime.
|
||||
//
|
||||
// Connection 1: <handshake>
|
||||
// Connection 1: S->C: NST=X
|
||||
// Connection 2: C->S: CH [PSK_ID=X]
|
||||
// Connection 1: S->C: NST=Y
|
||||
// Connection 2: S->C: HRR
|
||||
// Connection 2: C->S: CH [PSK_ID=Y]
|
||||
|
||||
// Connection 1, send a ticket after handshake is complete.
|
||||
ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET);
|
||||
|
||||
Connect();
|
||||
|
||||
// Set this token so that RetryHelloWithToken() will check that this
|
||||
// is the token that it receives in the HelloRetryRequest callback.
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_SendSessionTicket(server_->ssl_fd(), kApplicationToken,
|
||||
sizeof(kApplicationToken)));
|
||||
SendReceive(50);
|
||||
|
||||
// Connection 2, trigger HRR.
|
||||
auto client2 =
|
||||
std::make_shared<TlsAgent>(client_->name(), TlsAgent::CLIENT, variant_);
|
||||
auto server2 =
|
||||
std::make_shared<TlsAgent>(server_->name(), TlsAgent::SERVER, variant_);
|
||||
|
||||
client2->SetPeer(server2);
|
||||
server2->SetPeer(client2);
|
||||
|
||||
client_.swap(client2);
|
||||
server_.swap(server2);
|
||||
|
||||
ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET);
|
||||
|
||||
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
|
||||
client_->StartConnect();
|
||||
server_->StartConnect();
|
||||
|
||||
size_t cb_called = 0;
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_HelloRetryRequestCallback(server_->ssl_fd(),
|
||||
RetryHelloWithToken, &cb_called));
|
||||
client_->Handshake(); // Send ClientHello.
|
||||
server_->Handshake(); // Process ClientHello, send HelloRetryRequest.
|
||||
|
||||
EXPECT_EQ(1U, cb_called) << "callback should be called once here";
|
||||
|
||||
// Connection 1, send another ticket.
|
||||
client_.swap(client2);
|
||||
server_.swap(server2);
|
||||
|
||||
// If the client uses this token, RetryHelloWithToken() will fail the test.
|
||||
const uint8_t kAnotherApplicationToken[] = {0x92, 0x44, 0x01};
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_SendSessionTicket(server_->ssl_fd(), kAnotherApplicationToken,
|
||||
sizeof(kAnotherApplicationToken)));
|
||||
SendReceive(60);
|
||||
|
||||
// Connection 2, continue the handshake.
|
||||
// The client should use kApplicationToken, not kAnotherApplicationToken.
|
||||
client_.swap(client2);
|
||||
server_.swap(server2);
|
||||
|
||||
client_->Handshake();
|
||||
server_->Handshake();
|
||||
|
||||
EXPECT_EQ(2U, cb_called) << "callback should be called twice here";
|
||||
}
|
||||
|
||||
// Read the cipher suite from the HRR and disable it on the identified agent.
|
||||
static void DisableSuiteFromHrr(
|
||||
std::shared_ptr<TlsAgent>& agent,
|
||||
|
|
@ -844,10 +924,10 @@ TEST_F(TlsConnectStreamTls13, RetryWithDifferentCipherSuite) {
|
|||
TLS_CHACHA20_POLY1305_SHA256);
|
||||
|
||||
client_->ExpectSendAlert(kTlsAlertIllegalParameter);
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
ConnectExpectFail();
|
||||
EXPECT_EQ(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, client_->error_code());
|
||||
EXPECT_EQ(SSL_ERROR_BAD_MAC_READ, server_->error_code());
|
||||
EXPECT_EQ(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE, server_->error_code());
|
||||
}
|
||||
|
||||
// This tests that the second attempt at sending a ClientHello (after receiving
|
||||
|
|
@ -1007,14 +1087,17 @@ class HelloRetryRequestAgentTest : public TlsAgentTestClient {
|
|||
// Now the supported version.
|
||||
i = hrr_data.Write(i, ssl_tls13_supported_versions_xtn, 2);
|
||||
i = hrr_data.Write(i, 2, 2);
|
||||
i = hrr_data.Write(i, 0x7f00 | TLS_1_3_DRAFT_VERSION, 2);
|
||||
i = hrr_data.Write(i, (variant_ == ssl_variant_datagram)
|
||||
? (0x7f00 | DTLS_1_3_DRAFT_VERSION)
|
||||
: SSL_LIBRARY_VERSION_TLS_1_3,
|
||||
2);
|
||||
if (len) {
|
||||
hrr_data.Write(i, body, len);
|
||||
}
|
||||
DataBuffer hrr;
|
||||
MakeHandshakeMessage(kTlsHandshakeServerHello, hrr_data.data(),
|
||||
hrr_data.len(), &hrr, seq_num);
|
||||
MakeRecord(kTlsHandshakeType, SSL_LIBRARY_VERSION_TLS_1_3, hrr.data(),
|
||||
MakeRecord(ssl_ct_handshake, SSL_LIBRARY_VERSION_TLS_1_3, hrr.data(),
|
||||
hrr.len(), hrr_record, seq_num);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
@ -65,7 +65,7 @@ class TlsAlertRecorder : public TlsRecordFilter {
|
|||
if (level_ != 255) { // Already captured.
|
||||
return KEEP;
|
||||
}
|
||||
if (header.content_type() != kTlsAlertType) {
|
||||
if (header.content_type() != ssl_ct_alert) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ TEST_P(TlsConnectTls13, CaptureAlertClient) {
|
|||
client_->Handshake();
|
||||
if (variant_ == ssl_variant_stream) {
|
||||
// DTLS just drops the alert it can't decrypt.
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
}
|
||||
server_->Handshake();
|
||||
EXPECT_EQ(kTlsAlertFatal, alert_recorder->level());
|
||||
|
|
@ -320,6 +320,53 @@ TEST_F(TlsConnectStreamTls13, DropRecordClient) {
|
|||
SendReceive();
|
||||
}
|
||||
|
||||
// Check that a server can use 0.5 RTT if client authentication isn't enabled.
|
||||
TEST_P(TlsConnectTls13, WriteBeforeClientFinished) {
|
||||
EnsureTlsSetup();
|
||||
StartConnect();
|
||||
client_->Handshake(); // ClientHello
|
||||
server_->Handshake(); // ServerHello
|
||||
|
||||
server_->SendData(10);
|
||||
client_->ReadBytes(10); // Client should emit the Finished as a side-effect.
|
||||
server_->Handshake(); // Server consumes the Finished.
|
||||
CheckConnected();
|
||||
}
|
||||
|
||||
// We don't allow 0.5 RTT if client authentication is requested.
|
||||
TEST_P(TlsConnectTls13, WriteBeforeClientFinishedClientAuth) {
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(false);
|
||||
StartConnect();
|
||||
client_->Handshake(); // ClientHello
|
||||
server_->Handshake(); // ServerHello
|
||||
|
||||
static const uint8_t data[] = {1, 2, 3};
|
||||
EXPECT_GT(0, PR_Write(server_->ssl_fd(), data, sizeof(data)));
|
||||
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
||||
|
||||
Handshake();
|
||||
CheckConnected();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
// 0.5 RTT should fail with client authentication required.
|
||||
TEST_P(TlsConnectTls13, WriteBeforeClientFinishedClientAuthRequired) {
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
StartConnect();
|
||||
client_->Handshake(); // ClientHello
|
||||
server_->Handshake(); // ServerHello
|
||||
|
||||
static const uint8_t data[] = {1, 2, 3};
|
||||
EXPECT_GT(0, PR_Write(server_->ssl_fd(), data, sizeof(data)));
|
||||
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
||||
|
||||
Handshake();
|
||||
CheckConnected();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
// The next two tests takes advantage of the fact that we
|
||||
// automatically read the first 1024 bytes, so if
|
||||
// we provide 1200 bytes, they overrun the read buffer
|
||||
|
|
@ -426,13 +473,15 @@ class TlsPreCCSHeaderInjector : public TlsRecordFilter {
|
|||
virtual PacketFilter::Action FilterRecord(
|
||||
const TlsRecordHeader& record_header, const DataBuffer& input,
|
||||
size_t* offset, DataBuffer* output) override {
|
||||
if (record_header.content_type() != kTlsChangeCipherSpecType) return KEEP;
|
||||
if (record_header.content_type() != ssl_ct_change_cipher_spec) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
std::cerr << "Injecting Finished header before CCS\n";
|
||||
const uint8_t hhdr[] = {kTlsHandshakeFinished, 0x00, 0x00, 0x0c};
|
||||
DataBuffer hhdr_buf(hhdr, sizeof(hhdr));
|
||||
TlsRecordHeader nhdr(record_header.variant(), record_header.version(),
|
||||
kTlsHandshakeType, 0);
|
||||
ssl_ct_handshake, 0);
|
||||
*offset = nhdr.Write(output, *offset, hhdr_buf);
|
||||
*offset = record_header.Write(output, *offset, input);
|
||||
return CHANGE;
|
||||
|
|
@ -477,6 +526,26 @@ TEST_P(TlsConnectTls13, AlertWrongLevel) {
|
|||
client_->WaitForErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT, 2000);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, UnknownRecord) {
|
||||
static const uint8_t kUknownRecord[] = {
|
||||
0xff, SSL_LIBRARY_VERSION_TLS_1_2 >> 8,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2 & 0xff, 0, 0};
|
||||
|
||||
Connect();
|
||||
if (variant_ == ssl_variant_stream) {
|
||||
// DTLS just drops the record with an invalid type.
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
}
|
||||
client_->SendDirect(DataBuffer(kUknownRecord, sizeof(kUknownRecord)));
|
||||
server_->ExpectReadWriteError();
|
||||
server_->ReadBytes();
|
||||
if (variant_ == ssl_variant_stream) {
|
||||
EXPECT_EQ(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE, server_->error_code());
|
||||
} else {
|
||||
EXPECT_EQ(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE, server_->error_code());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TlsConnectStreamTls13, Tls13FailedWriteSecondFlight) {
|
||||
EnsureTlsSetup();
|
||||
StartConnect();
|
||||
|
|
@ -539,6 +608,126 @@ TEST_F(TlsConnectTest, OneNRecordSplitting) {
|
|||
EXPECT_EQ(ExpectedCbcLen(20), records->record(2).buffer.len());
|
||||
}
|
||||
|
||||
// We can't test for randomness easily here, but we can test that we don't
|
||||
// produce a zero value, or produce the same value twice. There are 5 values
|
||||
// here: two ClientHello.random, two ServerHello.random, and one zero value.
|
||||
// Matrix them and fail if any are the same.
|
||||
TEST_P(TlsConnectGeneric, CheckRandoms) {
|
||||
ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
|
||||
|
||||
static const size_t random_len = 32;
|
||||
uint8_t crandom1[random_len], srandom1[random_len];
|
||||
uint8_t z[random_len] = {0};
|
||||
|
||||
auto ch = MakeTlsFilter<TlsHandshakeRecorder>(client_, ssl_hs_client_hello);
|
||||
auto sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello);
|
||||
Connect();
|
||||
ASSERT_TRUE(ch->buffer().len() > (random_len + 2));
|
||||
ASSERT_TRUE(sh->buffer().len() > (random_len + 2));
|
||||
memcpy(crandom1, ch->buffer().data() + 2, random_len);
|
||||
memcpy(srandom1, sh->buffer().data() + 2, random_len);
|
||||
EXPECT_NE(0, memcmp(crandom1, srandom1, random_len));
|
||||
EXPECT_NE(0, memcmp(crandom1, z, random_len));
|
||||
EXPECT_NE(0, memcmp(srandom1, z, random_len));
|
||||
|
||||
Reset();
|
||||
ch = MakeTlsFilter<TlsHandshakeRecorder>(client_, ssl_hs_client_hello);
|
||||
sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello);
|
||||
Connect();
|
||||
ASSERT_TRUE(ch->buffer().len() > (random_len + 2));
|
||||
ASSERT_TRUE(sh->buffer().len() > (random_len + 2));
|
||||
const uint8_t* crandom2 = ch->buffer().data() + 2;
|
||||
const uint8_t* srandom2 = sh->buffer().data() + 2;
|
||||
|
||||
EXPECT_NE(0, memcmp(crandom2, srandom2, random_len));
|
||||
EXPECT_NE(0, memcmp(crandom2, z, random_len));
|
||||
EXPECT_NE(0, memcmp(srandom2, z, random_len));
|
||||
|
||||
EXPECT_NE(0, memcmp(crandom1, crandom2, random_len));
|
||||
EXPECT_NE(0, memcmp(crandom1, srandom2, random_len));
|
||||
EXPECT_NE(0, memcmp(srandom1, crandom2, random_len));
|
||||
EXPECT_NE(0, memcmp(srandom1, srandom2, random_len));
|
||||
}
|
||||
|
||||
void FailOnCloseNotify(const PRFileDesc* fd, void* arg, const SSLAlert* alert) {
|
||||
ADD_FAILURE() << "received alert " << alert->description;
|
||||
}
|
||||
|
||||
void CheckCloseNotify(const PRFileDesc* fd, void* arg, const SSLAlert* alert) {
|
||||
*reinterpret_cast<bool*>(arg) = true;
|
||||
EXPECT_EQ(close_notify, alert->description);
|
||||
EXPECT_EQ(alert_warning, alert->level);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ShutdownOneSide) {
|
||||
Connect();
|
||||
|
||||
// Setup to check alerts.
|
||||
EXPECT_EQ(SECSuccess, SSL_AlertSentCallback(server_->ssl_fd(),
|
||||
FailOnCloseNotify, nullptr));
|
||||
EXPECT_EQ(SECSuccess, SSL_AlertReceivedCallback(client_->ssl_fd(),
|
||||
FailOnCloseNotify, nullptr));
|
||||
|
||||
bool client_sent = false;
|
||||
EXPECT_EQ(SECSuccess, SSL_AlertSentCallback(client_->ssl_fd(),
|
||||
CheckCloseNotify, &client_sent));
|
||||
bool server_received = false;
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_AlertReceivedCallback(server_->ssl_fd(), CheckCloseNotify,
|
||||
&server_received));
|
||||
EXPECT_EQ(PR_SUCCESS, PR_Shutdown(client_->ssl_fd(), PR_SHUTDOWN_SEND));
|
||||
|
||||
// Make sure that the server reads out the close_notify.
|
||||
uint8_t buf[10];
|
||||
EXPECT_EQ(0, PR_Read(server_->ssl_fd(), buf, sizeof(buf)));
|
||||
|
||||
// Reading and writing should still work in the one open direction.
|
||||
EXPECT_TRUE(client_sent);
|
||||
EXPECT_TRUE(server_received);
|
||||
server_->SendData(10, 10);
|
||||
client_->ReadBytes(10);
|
||||
|
||||
// Now close the other side and do the same checks.
|
||||
bool server_sent = false;
|
||||
EXPECT_EQ(SECSuccess, SSL_AlertSentCallback(server_->ssl_fd(),
|
||||
CheckCloseNotify, &server_sent));
|
||||
bool client_received = false;
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_AlertReceivedCallback(client_->ssl_fd(), CheckCloseNotify,
|
||||
&client_received));
|
||||
EXPECT_EQ(PR_SUCCESS, PR_Shutdown(server_->ssl_fd(), PR_SHUTDOWN_SEND));
|
||||
|
||||
EXPECT_EQ(0, PR_Read(client_->ssl_fd(), buf, sizeof(buf)));
|
||||
EXPECT_TRUE(server_sent);
|
||||
EXPECT_TRUE(client_received);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ShutdownOneSideThenCloseTcp) {
|
||||
Connect();
|
||||
|
||||
bool client_sent = false;
|
||||
EXPECT_EQ(SECSuccess, SSL_AlertSentCallback(client_->ssl_fd(),
|
||||
CheckCloseNotify, &client_sent));
|
||||
bool server_received = false;
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_AlertReceivedCallback(server_->ssl_fd(), CheckCloseNotify,
|
||||
&server_received));
|
||||
EXPECT_EQ(PR_SUCCESS, PR_Shutdown(client_->ssl_fd(), PR_SHUTDOWN_SEND));
|
||||
|
||||
// Make sure that the server reads out the close_notify.
|
||||
uint8_t buf[10];
|
||||
EXPECT_EQ(0, PR_Read(server_->ssl_fd(), buf, sizeof(buf)));
|
||||
|
||||
// Now simulate the underlying connection closing.
|
||||
client_->adapter()->Reset();
|
||||
|
||||
// Now close the other side and see that things don't explode.
|
||||
EXPECT_EQ(PR_SUCCESS, PR_Shutdown(server_->ssl_fd(), PR_SHUTDOWN_SEND));
|
||||
|
||||
EXPECT_GT(0, PR_Read(client_->ssl_fd(), buf, sizeof(buf)));
|
||||
EXPECT_EQ(PR_NOT_CONNECTED_ERROR, PR_GetError());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
GenericStream, TlsConnectGeneric,
|
||||
::testing::Combine(TlsConnectTestBase::kTlsVariantsStream,
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ class RecordReplacer : public TlsRecordFilter {
|
|||
PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
|
||||
const DataBuffer& data,
|
||||
DataBuffer* changed) override {
|
||||
EXPECT_EQ(kTlsApplicationDataType, header.content_type());
|
||||
EXPECT_EQ(ssl_ct_application_data, header.content_type());
|
||||
changed->Allocate(size_);
|
||||
|
||||
for (size_t i = 0; i < size_; ++i) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include "sslproto.h"
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
@ -34,7 +34,7 @@ class TlsRecordMaximum : public TlsRecordFilter {
|
|||
DataBuffer* output) override {
|
||||
std::cerr << "max: " << record << std::endl;
|
||||
// Ignore unprotected packets.
|
||||
if (header.content_type() != kTlsApplicationDataType) {
|
||||
if (header.content_type() != ssl_ct_application_data) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +187,7 @@ class TlsRecordExpander : public TlsRecordFilter {
|
|||
virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
|
||||
const DataBuffer& data,
|
||||
DataBuffer* changed) {
|
||||
if (header.content_type() != kTlsApplicationDataType) {
|
||||
if (header.content_type() != ssl_ct_application_data) {
|
||||
return KEEP;
|
||||
}
|
||||
changed->Allocate(data.len() + expansion_);
|
||||
|
|
@ -252,7 +252,7 @@ class TlsRecordPadder : public TlsRecordFilter {
|
|||
PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
|
||||
const DataBuffer& record, size_t* offset,
|
||||
DataBuffer* output) override {
|
||||
if (header.content_type() != kTlsApplicationDataType) {
|
||||
if (header.content_type() != ssl_ct_application_data) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
|
|
@ -262,7 +262,7 @@ class TlsRecordPadder : public TlsRecordFilter {
|
|||
return KEEP;
|
||||
}
|
||||
|
||||
if (inner_content_type != kTlsApplicationDataType) {
|
||||
if (inner_content_type != ssl_ct_application_data) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "scoped_ptrs_ssl.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
@ -171,23 +172,145 @@ TEST_P(TlsConnectGenericResumption, ConnectResumeClientNoneServerBoth) {
|
|||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGenericPre13, ConnectResumeWithHigherVersion) {
|
||||
TEST_P(TlsConnectGenericPre13, ResumeWithHigherVersionTls13) {
|
||||
uint16_t lower_version = version_;
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
Connect();
|
||||
SendReceive();
|
||||
CheckKeys();
|
||||
|
||||
Reset();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
EnsureTlsSetup();
|
||||
auto psk_ext = std::make_shared<TlsExtensionCapture>(
|
||||
client_, ssl_tls13_pre_shared_key_xtn);
|
||||
auto ticket_ext =
|
||||
std::make_shared<TlsExtensionCapture>(client_, ssl_session_ticket_xtn);
|
||||
client_->SetFilter(std::make_shared<ChainedPacketFilter>(
|
||||
ChainedPacketFilterInit({psk_ext, ticket_ext})));
|
||||
SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
client_->SetVersionRange(lower_version, SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
server_->SetVersionRange(lower_version, SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
ExpectResumption(RESUME_NONE);
|
||||
Connect();
|
||||
|
||||
// The client shouldn't have sent a PSK, though it will send a ticket.
|
||||
EXPECT_FALSE(psk_ext->captured());
|
||||
EXPECT_TRUE(ticket_ext->captured());
|
||||
}
|
||||
|
||||
class CaptureSessionId : public TlsHandshakeFilter {
|
||||
public:
|
||||
CaptureSessionId(const std::shared_ptr<TlsAgent>& a)
|
||||
: TlsHandshakeFilter(
|
||||
a, {kTlsHandshakeClientHello, kTlsHandshakeServerHello}),
|
||||
sid_() {}
|
||||
|
||||
const DataBuffer& sid() const { return sid_; }
|
||||
|
||||
protected:
|
||||
PacketFilter::Action FilterHandshake(const HandshakeHeader& header,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output) override {
|
||||
// The session_id is in the same place in both Hello messages:
|
||||
size_t offset = 2 + 32; // Version(2) + Random(32)
|
||||
uint32_t len = 0;
|
||||
EXPECT_TRUE(input.Read(offset, 1, &len));
|
||||
offset++;
|
||||
if (input.len() < offset + len) {
|
||||
ADD_FAILURE() << "session_id overflows the Hello message";
|
||||
return KEEP;
|
||||
}
|
||||
sid_.Assign(input.data() + offset, len);
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
private:
|
||||
DataBuffer sid_;
|
||||
};
|
||||
|
||||
// Attempting to resume from TLS 1.2 when 1.3 is possible should not result in
|
||||
// resumption, though it will appear to be TLS 1.3 compatibility mode if the
|
||||
// server uses a session ID.
|
||||
TEST_P(TlsConnectGenericPre13, ResumeWithHigherVersionTls13SessionId) {
|
||||
uint16_t lower_version = version_;
|
||||
ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID);
|
||||
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_1);
|
||||
SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_1);
|
||||
auto original_sid = MakeTlsFilter<CaptureSessionId>(server_);
|
||||
Connect();
|
||||
CheckKeys();
|
||||
EXPECT_EQ(32U, original_sid->sid().len());
|
||||
|
||||
// The client should now attempt to resume with the session ID from the last
|
||||
// connection. This looks like compatibility mode, we just want to ensure
|
||||
// that we get TLS 1.3 rather than 1.2 (and no resumption).
|
||||
Reset();
|
||||
auto client_sid = MakeTlsFilter<CaptureSessionId>(client_);
|
||||
auto server_sid = MakeTlsFilter<CaptureSessionId>(server_);
|
||||
ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID);
|
||||
SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
client_->SetVersionRange(lower_version, SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
server_->SetVersionRange(lower_version, SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
ExpectResumption(RESUME_NONE);
|
||||
|
||||
Connect();
|
||||
SendReceive();
|
||||
|
||||
EXPECT_EQ(client_sid->sid(), original_sid->sid());
|
||||
if (variant_ == ssl_variant_stream) {
|
||||
EXPECT_EQ(client_sid->sid(), server_sid->sid());
|
||||
} else {
|
||||
// DTLS servers don't echo the session ID.
|
||||
EXPECT_EQ(0U, server_sid->sid().len());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectPre12, ResumeWithHigherVersionTls12) {
|
||||
uint16_t lower_version = version_;
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
Connect();
|
||||
|
||||
Reset();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
EnsureTlsSetup();
|
||||
SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
client_->SetVersionRange(lower_version, SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
server_->SetVersionRange(lower_version, SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
ExpectResumption(RESUME_NONE);
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGenericPre13, ResumeWithLowerVersionFromTls13) {
|
||||
uint16_t original_version = version_;
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
Connect();
|
||||
SendReceive();
|
||||
CheckKeys();
|
||||
|
||||
Reset();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
ConfigureVersion(original_version);
|
||||
ExpectResumption(RESUME_NONE);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectPre12, ResumeWithLowerVersionFromTls12) {
|
||||
uint16_t original_version = version_;
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
Connect();
|
||||
SendReceive();
|
||||
CheckKeys();
|
||||
|
||||
Reset();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
ConfigureVersion(original_version);
|
||||
ExpectResumption(RESUME_NONE);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGeneric, ConnectResumeClientBothTicketServerTicketForget) {
|
||||
// This causes a ticket resumption.
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
|
|
@ -276,8 +399,13 @@ TEST_P(TlsConnectGeneric, ConnectResumeCorruptTicket) {
|
|||
ASSERT_NE(nullptr, hmac_key);
|
||||
SSLInt_SetSelfEncryptMacKey(hmac_key);
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
ConnectExpectAlert(server_, illegal_parameter);
|
||||
server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
|
||||
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
ExpectResumption(RESUME_NONE);
|
||||
Connect();
|
||||
} else {
|
||||
ConnectExpectAlert(server_, illegal_parameter);
|
||||
server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
|
||||
}
|
||||
}
|
||||
|
||||
// This callback switches out the "server" cert used on the server with
|
||||
|
|
@ -394,6 +522,64 @@ TEST_P(TlsConnectTls13, TestTls13ResumeDifferentGroup) {
|
|||
ssl_sig_rsa_pss_rsae_sha256);
|
||||
}
|
||||
|
||||
// Verify that TLS 1.3 server doesn't request certificate in the main
|
||||
// handshake, after resumption.
|
||||
TEST_P(TlsConnectTls13, TestTls13ResumeNoCertificateRequest) {
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
Connect();
|
||||
SendReceive(); // Need to read so that we absorb the session ticket.
|
||||
ScopedCERTCertificate cert1(SSL_LocalCertificate(client_->ssl_fd()));
|
||||
|
||||
Reset();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
server_->RequestClientAuth(false);
|
||||
auto cr_capture =
|
||||
MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_certificate_request);
|
||||
cr_capture->EnableDecryption();
|
||||
Connect();
|
||||
SendReceive();
|
||||
EXPECT_EQ(0U, cr_capture->buffer().len()) << "expect nothing captured yet";
|
||||
|
||||
// Sanity check whether the client certificate matches the one
|
||||
// decrypted from ticket.
|
||||
ScopedCERTCertificate cert2(SSL_PeerCertificate(server_->ssl_fd()));
|
||||
EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
|
||||
}
|
||||
|
||||
// Here we test that 0.5 RTT is available at the server when resuming, even if
|
||||
// configured to request a client certificate. The resumed handshake relies on
|
||||
// the authentication from the original handshake, so no certificate is
|
||||
// requested this time around. The server can write before the handshake
|
||||
// completes because the PSK binder is sufficient authentication for the client.
|
||||
TEST_P(TlsConnectTls13, WriteBeforeHandshakeCompleteOnResumption) {
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
client_->SetupClientAuth();
|
||||
server_->RequestClientAuth(true);
|
||||
Connect();
|
||||
SendReceive(); // Absorb the session ticket.
|
||||
ScopedCERTCertificate cert1(SSL_LocalCertificate(client_->ssl_fd()));
|
||||
|
||||
Reset();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
server_->RequestClientAuth(false);
|
||||
StartConnect();
|
||||
client_->Handshake(); // ClientHello
|
||||
server_->Handshake(); // ServerHello
|
||||
|
||||
server_->SendData(10);
|
||||
client_->ReadBytes(10); // Client should emit the Finished as a side-effect.
|
||||
server_->Handshake(); // Server consumes the Finished.
|
||||
CheckConnected();
|
||||
|
||||
// Check whether the client certificate matches the one from the ticket.
|
||||
ScopedCERTCertificate cert2(SSL_PeerCertificate(server_->ssl_fd()));
|
||||
EXPECT_TRUE(SECITEM_ItemsAreEqual(&cert1->derCert, &cert2->derCert));
|
||||
}
|
||||
|
||||
// We need to enable different cipher suites at different times in the following
|
||||
// tests. Those cipher suites need to be suited to the version.
|
||||
static uint16_t ChooseOneCipher(uint16_t version) {
|
||||
|
|
@ -467,7 +653,7 @@ TEST_P(TlsConnectStream, TestResumptionOverrideCipher) {
|
|||
|
||||
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
client_->ExpectSendAlert(kTlsAlertIllegalParameter);
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
} else {
|
||||
ExpectAlert(client_, kTlsAlertHandshakeFailure);
|
||||
}
|
||||
|
|
@ -476,7 +662,7 @@ TEST_P(TlsConnectStream, TestResumptionOverrideCipher) {
|
|||
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
// The reason this test is stream only: the server is unable to decrypt
|
||||
// the alert that the client sends, see bug 1304603.
|
||||
server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
|
||||
server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE);
|
||||
} else {
|
||||
server_->CheckErrorCode(SSL_ERROR_HANDSHAKE_FAILURE_ALERT);
|
||||
}
|
||||
|
|
@ -760,6 +946,36 @@ TEST_F(TlsConnectDatagram13, SendSessionTicketDtls) {
|
|||
EXPECT_EQ(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_VERSION, PORT_GetError());
|
||||
}
|
||||
|
||||
TEST_F(TlsConnectStreamTls13, ExternalResumptionUseSecondTicket) {
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
|
||||
struct ResumptionTicketState {
|
||||
std::vector<uint8_t> ticket;
|
||||
size_t invoked = 0;
|
||||
} ticket_state;
|
||||
auto cb = [](PRFileDesc* fd, const PRUint8* ticket, unsigned int ticket_len,
|
||||
void* arg) -> SECStatus {
|
||||
auto state = reinterpret_cast<ResumptionTicketState*>(arg);
|
||||
state->ticket.assign(ticket, ticket + ticket_len);
|
||||
state->invoked++;
|
||||
return SECSuccess;
|
||||
};
|
||||
SSL_SetResumptionTokenCallback(client_->ssl_fd(), cb, &ticket_state);
|
||||
|
||||
Connect();
|
||||
EXPECT_EQ(SECSuccess, SSL_SendSessionTicket(server_->ssl_fd(), nullptr, 0));
|
||||
SendReceive();
|
||||
EXPECT_EQ(2U, ticket_state.invoked);
|
||||
|
||||
Reset();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
client_->SetResumptionToken(ticket_state.ticket);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
Connect();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_F(TlsConnectTest, TestTls13ResumptionDowngrade) {
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
|
||||
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
|
|
@ -830,10 +1046,10 @@ TEST_F(TlsConnectTest, TestTls13ResumptionForcedDowngrade) {
|
|||
// client expects to receive an unencrypted TLS 1.2 Certificate message.
|
||||
// The server can't decrypt the alert.
|
||||
client_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac); // Server can't read
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage); // Server can't read
|
||||
ConnectExpectFail();
|
||||
client_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA);
|
||||
server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
|
||||
server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGenericResumption, ReConnectTicket) {
|
||||
|
|
@ -908,6 +1124,36 @@ void CheckGetInfoResult(uint32_t alpnSize, uint32_t earlyDataSize,
|
|||
EXPECT_EQ(0, memcmp("a", token->alpnSelection, token->alpnSelectionLen));
|
||||
|
||||
ASSERT_EQ(earlyDataSize, token->maxEarlyDataSize);
|
||||
|
||||
ASSERT_LT(ssl_TimeUsec(), token->expirationTime);
|
||||
}
|
||||
|
||||
// The client should generate a new, randomized session_id
|
||||
// when resuming using an external token.
|
||||
TEST_P(TlsConnectGenericResumptionToken, CheckSessionId) {
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
auto original_sid = MakeTlsFilter<CaptureSessionId>(client_);
|
||||
Connect();
|
||||
SendReceive();
|
||||
|
||||
Reset();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
|
||||
StartConnect();
|
||||
ASSERT_TRUE(client_->MaybeSetResumptionToken());
|
||||
auto resumed_sid = MakeTlsFilter<CaptureSessionId>(client_);
|
||||
|
||||
Handshake();
|
||||
CheckConnected();
|
||||
SendReceive();
|
||||
|
||||
if (version_ < SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
EXPECT_NE(resumed_sid->sid(), original_sid->sid());
|
||||
EXPECT_EQ(32U, resumed_sid->sid().len());
|
||||
} else {
|
||||
EXPECT_EQ(0U, resumed_sid->sid().len());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectGenericResumptionToken, ConnectResumeGetInfo) {
|
||||
|
|
@ -1026,4 +1272,34 @@ TEST_P(TlsConnectGenericResumption, ConnectResumeClientAuth) {
|
|||
SendReceive();
|
||||
}
|
||||
|
||||
TEST_F(TlsConnectStreamTls13, ExternalTokenAfterHrr) {
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
Connect();
|
||||
SendReceive();
|
||||
|
||||
Reset();
|
||||
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
|
||||
ExpectResumption(RESUME_TICKET);
|
||||
|
||||
static const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1,
|
||||
ssl_grp_ec_secp521r1};
|
||||
server_->ConfigNamedGroups(groups);
|
||||
|
||||
StartConnect();
|
||||
ASSERT_TRUE(client_->MaybeSetResumptionToken());
|
||||
|
||||
client_->Handshake(); // Send ClientHello.
|
||||
server_->Handshake(); // Process ClientHello, send HelloRetryRequest.
|
||||
|
||||
auto& token = client_->GetResumptionToken();
|
||||
SECStatus rv =
|
||||
SSL_SetResumptionToken(client_->ssl_fd(), token.data(), token.size());
|
||||
ASSERT_EQ(SECFailure, rv);
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_ARGS, PORT_GetError());
|
||||
|
||||
Handshake();
|
||||
CheckConnected();
|
||||
SendReceive();
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class TlsHandshakeSkipFilter : public TlsRecordFilter {
|
|||
virtual PacketFilter::Action FilterRecord(
|
||||
const TlsRecordHeader& record_header, const DataBuffer& input,
|
||||
DataBuffer* output) {
|
||||
if (record_header.content_type() != kTlsHandshakeType) {
|
||||
if (record_header.content_type() != ssl_ct_handshake) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ class Tls13CompatTest : public TlsConnectStreamTls13 {
|
|||
// Only the second record can be a CCS.
|
||||
bool expected_match = expected && (i == 1);
|
||||
EXPECT_EQ(expected_match,
|
||||
kTlsChangeCipherSpecType ==
|
||||
ssl_ct_change_cipher_spec ==
|
||||
records_->record(i).header.content_type());
|
||||
}
|
||||
}
|
||||
|
|
@ -299,15 +299,15 @@ TEST_F(TlsConnectTest, TLS13NonCompatModeSessionID) {
|
|||
|
||||
MakeTlsFilter<TlsSessionIDInjectFilter>(server_);
|
||||
client_->ExpectSendAlert(kTlsAlertIllegalParameter);
|
||||
server_->ExpectSendAlert(kTlsAlertBadRecordMac);
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
ConnectExpectFail();
|
||||
|
||||
client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
|
||||
server_->CheckErrorCode(SSL_ERROR_BAD_MAC_READ);
|
||||
server_->CheckErrorCode(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE);
|
||||
}
|
||||
|
||||
static const uint8_t kCannedCcs[] = {
|
||||
kTlsChangeCipherSpecType,
|
||||
ssl_ct_change_cipher_spec,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2 >> 8,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2 & 0xff,
|
||||
0,
|
||||
|
|
@ -362,6 +362,19 @@ TEST_F(TlsConnectStreamTls13, ChangeCipherSpecBeforeClientHello12) {
|
|||
client_->CheckErrorCode(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT);
|
||||
}
|
||||
|
||||
TEST_F(TlsConnectStreamTls13, ChangeCipherSpecAfterFinished13) {
|
||||
EnsureTlsSetup();
|
||||
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
Connect();
|
||||
SendReceive(10);
|
||||
// Client sends CCS after the handshake.
|
||||
client_->SendDirect(DataBuffer(kCannedCcs, sizeof(kCannedCcs)));
|
||||
server_->ExpectSendAlert(kTlsAlertUnexpectedMessage);
|
||||
server_->ExpectReadWriteError();
|
||||
server_->ReadBytes();
|
||||
EXPECT_EQ(SSL_ERROR_RX_UNEXPECTED_RECORD_TYPE, server_->error_code());
|
||||
}
|
||||
|
||||
TEST_F(TlsConnectDatagram13, CompatModeDtlsClient) {
|
||||
EnsureTlsSetup();
|
||||
client_->SetOption(SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE);
|
||||
|
|
@ -370,14 +383,14 @@ TEST_F(TlsConnectDatagram13, CompatModeDtlsClient) {
|
|||
Connect();
|
||||
|
||||
ASSERT_EQ(2U, client_records->count()); // CH, Fin
|
||||
EXPECT_EQ(kTlsHandshakeType, client_records->record(0).header.content_type());
|
||||
EXPECT_EQ(kTlsApplicationDataType,
|
||||
EXPECT_EQ(ssl_ct_handshake, client_records->record(0).header.content_type());
|
||||
EXPECT_EQ(ssl_ct_application_data,
|
||||
client_records->record(1).header.content_type());
|
||||
|
||||
ASSERT_EQ(6U, server_records->count()); // SH, EE, CT, CV, Fin, Ack
|
||||
EXPECT_EQ(kTlsHandshakeType, server_records->record(0).header.content_type());
|
||||
EXPECT_EQ(ssl_ct_handshake, server_records->record(0).header.content_type());
|
||||
for (size_t i = 1; i < server_records->count(); ++i) {
|
||||
EXPECT_EQ(kTlsApplicationDataType,
|
||||
EXPECT_EQ(ssl_ct_application_data,
|
||||
server_records->record(i).header.content_type());
|
||||
}
|
||||
}
|
||||
|
|
@ -422,12 +435,12 @@ TEST_F(TlsConnectDatagram13, CompatModeDtlsServer) {
|
|||
client_->Handshake();
|
||||
|
||||
ASSERT_EQ(1U, client_records->count());
|
||||
EXPECT_EQ(kTlsHandshakeType, client_records->record(0).header.content_type());
|
||||
EXPECT_EQ(ssl_ct_handshake, client_records->record(0).header.content_type());
|
||||
|
||||
ASSERT_EQ(5U, server_records->count()); // SH, EE, CT, CV, Fin
|
||||
EXPECT_EQ(kTlsHandshakeType, server_records->record(0).header.content_type());
|
||||
EXPECT_EQ(ssl_ct_handshake, server_records->record(0).header.content_type());
|
||||
for (size_t i = 1; i < server_records->count(); ++i) {
|
||||
EXPECT_EQ(kTlsApplicationDataType,
|
||||
EXPECT_EQ(ssl_ct_application_data,
|
||||
server_records->record(i).header.content_type());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@ class SSLv2ClientHelloTestF : public TlsConnectTestBase {
|
|||
void SetUp() override {
|
||||
TlsConnectTestBase::SetUp();
|
||||
filter_ = MakeTlsFilter<SSLv2ClientHelloFilter>(client_, version_);
|
||||
server_->SetOption(SSL_ENABLE_V2_COMPATIBLE_HELLO, PR_TRUE);
|
||||
}
|
||||
|
||||
void SetExpectedVersion(uint16_t version) {
|
||||
|
|
@ -197,6 +198,27 @@ TEST_P(SSLv2ClientHelloTest, Connect) {
|
|||
Connect();
|
||||
}
|
||||
|
||||
TEST_P(SSLv2ClientHelloTest, ConnectDisabled) {
|
||||
server_->SetOption(SSL_ENABLE_V2_COMPATIBLE_HELLO, PR_FALSE);
|
||||
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
|
||||
|
||||
StartConnect();
|
||||
client_->Handshake(); // Send the modified ClientHello.
|
||||
server_->Handshake(); // Read some.
|
||||
// The problem here is that the v2 ClientHello puts the version where the v3
|
||||
// ClientHello puts a version number. So the version number (0x0301+) appears
|
||||
// to be a length and server blocks waiting for that much data.
|
||||
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
|
||||
|
||||
// This is usually what happens with v2-compatible: the server hangs.
|
||||
// But to be certain, feed in more data to see if an error comes out.
|
||||
uint8_t zeros[SSL_LIBRARY_VERSION_TLS_1_2] = {0};
|
||||
client_->SendDirect(DataBuffer(zeros, sizeof(zeros)));
|
||||
ExpectAlert(server_, kTlsAlertIllegalParameter);
|
||||
server_->Handshake();
|
||||
client_->Handshake();
|
||||
}
|
||||
|
||||
// Sending a v2 ClientHello after a no-op v3 record must fail.
|
||||
TEST_P(SSLv2ClientHelloTest, ConnectAfterEmptyV3Record) {
|
||||
DataBuffer buffer;
|
||||
|
|
@ -328,6 +350,30 @@ TEST_P(SSLv2ClientHelloTest, RequireSafeRenegotiationWithSCSV) {
|
|||
Connect();
|
||||
}
|
||||
|
||||
TEST_P(SSLv2ClientHelloTest, CheckServerRandom) {
|
||||
ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
|
||||
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
|
||||
|
||||
static const size_t random_len = 32;
|
||||
uint8_t srandom1[random_len];
|
||||
uint8_t z[random_len] = {0};
|
||||
|
||||
auto sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello);
|
||||
Connect();
|
||||
ASSERT_TRUE(sh->buffer().len() > (random_len + 2));
|
||||
memcpy(srandom1, sh->buffer().data() + 2, random_len);
|
||||
EXPECT_NE(0, memcmp(srandom1, z, random_len));
|
||||
|
||||
Reset();
|
||||
sh = MakeTlsFilter<TlsHandshakeRecorder>(server_, ssl_hs_server_hello);
|
||||
Connect();
|
||||
ASSERT_TRUE(sh->buffer().len() > (random_len + 2));
|
||||
const uint8_t* srandom2 = sh->buffer().data() + 2;
|
||||
|
||||
EXPECT_NE(0, memcmp(srandom2, z, random_len));
|
||||
EXPECT_NE(0, memcmp(srandom1, srandom2, random_len));
|
||||
}
|
||||
|
||||
// Connect to the server with TLS 1.1, signalling that this is a fallback from
|
||||
// a higher version. As the server doesn't support anything higher than TLS 1.1
|
||||
// it must accept the connection.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include "sslproto.h"
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
@ -48,7 +48,6 @@ TEST_P(TlsConnectGeneric, ServerNegotiateTls12) {
|
|||
SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
Connect();
|
||||
}
|
||||
#ifndef TLS_1_3_DRAFT_VERSION
|
||||
|
||||
// Test the ServerRandom version hack from
|
||||
// [draft-ietf-tls-tls13-11 Section 6.3.1.1].
|
||||
|
|
@ -56,71 +55,116 @@ TEST_P(TlsConnectGeneric, ServerNegotiateTls12) {
|
|||
// two validate that we can also detect fallback using the
|
||||
// SSL_SetDowngradeCheckVersion() API.
|
||||
TEST_F(TlsConnectTest, TestDowngradeDetectionToTls11) {
|
||||
client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE);
|
||||
MakeTlsFilter<TlsClientHelloVersionSetter>(client_,
|
||||
SSL_LIBRARY_VERSION_TLS_1_1);
|
||||
ConnectExpectFail();
|
||||
ASSERT_EQ(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, client_->error_code());
|
||||
ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
|
||||
client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
|
||||
server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
|
||||
}
|
||||
|
||||
/* Attempt to negotiate the bogus DTLS 1.1 version. */
|
||||
// Attempt to negotiate the bogus DTLS 1.1 version.
|
||||
TEST_F(DtlsConnectTest, TestDtlsVersion11) {
|
||||
MakeTlsFilter<TlsClientHelloVersionSetter>(client_, ((~0x0101) & 0xffff));
|
||||
ConnectExpectFail();
|
||||
ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
|
||||
// It's kind of surprising that SSL_ERROR_NO_CYPHER_OVERLAP is
|
||||
// what is returned here, but this is deliberate in ssl3_HandleAlert().
|
||||
EXPECT_EQ(SSL_ERROR_NO_CYPHER_OVERLAP, client_->error_code());
|
||||
EXPECT_EQ(SSL_ERROR_UNSUPPORTED_VERSION, server_->error_code());
|
||||
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
|
||||
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_VERSION);
|
||||
}
|
||||
|
||||
// Disabled as long as we have draft version.
|
||||
TEST_F(TlsConnectTest, TestDowngradeDetectionToTls12) {
|
||||
EnsureTlsSetup();
|
||||
MakeTlsFilter<TlsClientHelloVersionSetter>(client_,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE);
|
||||
MakeTlsFilter<TlsExtensionDropper>(client_, ssl_tls13_supported_versions_xtn);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
ConnectExpectFail();
|
||||
ASSERT_EQ(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, client_->error_code());
|
||||
ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
|
||||
client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
|
||||
server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
|
||||
}
|
||||
|
||||
// Disabling downgrade checks will be caught when the Finished MAC check fails.
|
||||
TEST_F(TlsConnectTest, TestDisableDowngradeDetection) {
|
||||
client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_FALSE);
|
||||
MakeTlsFilter<TlsExtensionDropper>(client_, ssl_tls13_supported_versions_xtn);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
ConnectExpectAlert(server_, kTlsAlertDecryptError);
|
||||
client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
|
||||
server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
|
||||
}
|
||||
|
||||
// TLS 1.1 clients do not check the random values, so we should
|
||||
// instead get a handshake failure alert from the server.
|
||||
TEST_F(TlsConnectTest, TestDowngradeDetectionToTls10) {
|
||||
// Setting the option here has no effect.
|
||||
client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE);
|
||||
MakeTlsFilter<TlsClientHelloVersionSetter>(client_,
|
||||
SSL_LIBRARY_VERSION_TLS_1_0);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
|
||||
SSL_LIBRARY_VERSION_TLS_1_1);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_0,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
ConnectExpectFail();
|
||||
ASSERT_EQ(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE, server_->error_code());
|
||||
ASSERT_EQ(SSL_ERROR_DECRYPT_ERROR_ALERT, client_->error_code());
|
||||
ConnectExpectAlert(server_, kTlsAlertDecryptError);
|
||||
server_->CheckErrorCode(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
|
||||
client_->CheckErrorCode(SSL_ERROR_DECRYPT_ERROR_ALERT);
|
||||
}
|
||||
|
||||
TEST_F(TlsConnectTest, TestFallbackFromTls12) {
|
||||
EnsureTlsSetup();
|
||||
client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE);
|
||||
client_->SetDowngradeCheckVersion(SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_1);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
ConnectExpectFail();
|
||||
ASSERT_EQ(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, client_->error_code());
|
||||
ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
|
||||
client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
|
||||
server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
|
||||
}
|
||||
|
||||
static SECStatus AllowFalseStart(PRFileDesc* fd, void* arg,
|
||||
PRBool* can_false_start) {
|
||||
bool* false_start_attempted = reinterpret_cast<bool*>(arg);
|
||||
*false_start_attempted = true;
|
||||
*can_false_start = PR_TRUE;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
// If we disable the downgrade check, the sentinel is still generated, and we
|
||||
// disable false start instead.
|
||||
TEST_F(TlsConnectTest, DisableFalseStartOnFallback) {
|
||||
// Don't call client_->EnableFalseStart(), because that sets the client up for
|
||||
// success, and we want false start to fail.
|
||||
client_->SetOption(SSL_ENABLE_FALSE_START, PR_TRUE);
|
||||
bool false_start_attempted = false;
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_SetCanFalseStartCallback(client_->ssl_fd(), AllowFalseStart,
|
||||
&false_start_attempted));
|
||||
|
||||
client_->SetDowngradeCheckVersion(SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
Connect();
|
||||
EXPECT_FALSE(false_start_attempted);
|
||||
}
|
||||
|
||||
TEST_F(TlsConnectTest, TestFallbackFromTls13) {
|
||||
EnsureTlsSetup();
|
||||
client_->SetOption(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, PR_TRUE);
|
||||
client_->SetDowngradeCheckVersion(SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
ConnectExpectFail();
|
||||
ASSERT_EQ(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, client_->error_code());
|
||||
ConnectExpectAlert(client_, kTlsAlertIllegalParameter);
|
||||
client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
|
||||
server_->CheckErrorCode(SSL_ERROR_ILLEGAL_PARAMETER_ALERT);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_P(TlsConnectGeneric, TestFallbackSCSVVersionMatch) {
|
||||
client_->SetOption(SSL_ENABLE_FALLBACK_SCSV, PR_TRUE);
|
||||
|
|
@ -132,6 +176,7 @@ TEST_P(TlsConnectGenericPre13, TestFallbackSCSVVersionMismatch) {
|
|||
server_->SetVersionRange(version_, version_ + 1);
|
||||
ConnectExpectAlert(server_, kTlsAlertInappropriateFallback);
|
||||
client_->CheckErrorCode(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT);
|
||||
server_->CheckErrorCode(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT);
|
||||
}
|
||||
|
||||
// The TLS v1.3 spec section C.4 states that 'Implementations MUST NOT send or
|
||||
|
|
@ -158,7 +203,7 @@ TEST_P(TlsConnectGeneric, AlertBeforeServerHello) {
|
|||
static const uint8_t kWarningAlert[] = {kTlsAlertWarning,
|
||||
kTlsAlertUnrecognizedName};
|
||||
DataBuffer alert;
|
||||
TlsAgentTestBase::MakeRecord(variant_, kTlsAlertType,
|
||||
TlsAgentTestBase::MakeRecord(variant_, ssl_ct_alert,
|
||||
SSL_LIBRARY_VERSION_TLS_1_0, kWarningAlert,
|
||||
PR_ARRAY_SIZE(kWarningAlert), &alert);
|
||||
client_->adapter()->PacketReceived(alert);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "sslproto.h"
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "tls_connect.h"
|
||||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
|
|
|||
|
|
@ -31,6 +31,20 @@ ScopedPRFileDesc DummyPrSocket::CreateFD() {
|
|||
return DummyIOLayerMethods::CreateFD(test_fd_identity, this);
|
||||
}
|
||||
|
||||
void DummyPrSocket::Reset() {
|
||||
auto p = peer_.lock();
|
||||
peer_.reset();
|
||||
if (p) {
|
||||
p->peer_.reset();
|
||||
p->Reset();
|
||||
}
|
||||
while (!input_.empty()) {
|
||||
input_.pop();
|
||||
}
|
||||
filter_ = nullptr;
|
||||
write_error_ = 0;
|
||||
}
|
||||
|
||||
void DummyPrSocket::PacketReceived(const DataBuffer &packet) {
|
||||
input_.push(Packet(packet));
|
||||
}
|
||||
|
|
@ -42,6 +56,12 @@ int32_t DummyPrSocket::Read(PRFileDesc *f, void *data, int32_t len) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
auto dst = peer_.lock();
|
||||
if (!dst) {
|
||||
PR_SetError(PR_NOT_CONNECTED_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (input_.empty()) {
|
||||
LOGV("Read --> wouldblock " << len);
|
||||
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
|
||||
|
|
@ -74,6 +94,12 @@ int32_t DummyPrSocket::Recv(PRFileDesc *f, void *buf, int32_t buflen,
|
|||
return Read(f, buf, buflen);
|
||||
}
|
||||
|
||||
auto dst = peer_.lock();
|
||||
if (!dst) {
|
||||
PR_SetError(PR_NOT_CONNECTED_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (input_.empty()) {
|
||||
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
|
||||
return -1;
|
||||
|
|
@ -101,7 +127,7 @@ int32_t DummyPrSocket::Write(PRFileDesc *f, const void *buf, int32_t length) {
|
|||
|
||||
auto dst = peer_.lock();
|
||||
if (!dst) {
|
||||
PR_SetError(PR_IO_ERROR, 0);
|
||||
PR_SetError(PR_NOT_CONNECTED_ERROR, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
#include "databuffer.h"
|
||||
#include "dummy_io.h"
|
||||
#include "prio.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "sslt.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@
|
|||
#include "tls_filter.h"
|
||||
#include "tls_parser.h"
|
||||
|
||||
// This is an internal header, used to get DTLS_1_3_DRAFT_VERSION.
|
||||
#include "ssl3prot.h"
|
||||
|
||||
extern "C" {
|
||||
// This is not something that should make you happy.
|
||||
#include "libssl_internals.h"
|
||||
|
|
@ -23,7 +26,7 @@ extern "C" {
|
|||
#define GTEST_HAS_RTTI 0
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
|
||||
extern std::string g_working_dir_path;
|
||||
|
||||
|
|
@ -53,7 +56,7 @@ static const uint8_t kCannedTls13ServerHello[] = {
|
|||
0x00, 0x1d, 0x00, 0x20, 0xc2, 0xcf, 0x23, 0x17, 0x64, 0x23, 0x03,
|
||||
0xf0, 0xfb, 0x45, 0x98, 0x26, 0xd1, 0x65, 0x24, 0xa1, 0x6c, 0xa9,
|
||||
0x80, 0x8f, 0x2c, 0xac, 0x0a, 0xea, 0x53, 0x3a, 0xcb, 0xe3, 0x08,
|
||||
0x84, 0xae, 0x19, 0x00, 0x2b, 0x00, 0x02, 0x7f, kD13};
|
||||
0x84, 0xae, 0x19, 0x00, 0x2b, 0x00, 0x02, 0x03, 0x04};
|
||||
|
||||
TlsAgent::TlsAgent(const std::string& nm, Role rl, SSLProtocolVariant var)
|
||||
: name_(nm),
|
||||
|
|
@ -226,6 +229,7 @@ bool TlsAgent::EnsureTlsSetup(PRFileDesc* modelSocket) {
|
|||
|
||||
bool TlsAgent::MaybeSetResumptionToken() {
|
||||
if (!resumption_token_.empty()) {
|
||||
LOG("setting external resumption token");
|
||||
SECStatus rv = SSL_SetResumptionToken(ssl_fd(), resumption_token_.data(),
|
||||
resumption_token_.size());
|
||||
|
||||
|
|
@ -583,6 +587,7 @@ void TlsAgent::CheckAuthType(SSLAuthType auth,
|
|||
// switch statement because default label is different.
|
||||
switch (auth) {
|
||||
case ssl_auth_rsa_sign:
|
||||
case ssl_auth_rsa_pss:
|
||||
EXPECT_EQ(ssl_auth_rsa_decrypt, csinfo_.authAlgorithm)
|
||||
<< "authAlgorithm for RSA is always decrypt";
|
||||
break;
|
||||
|
|
@ -934,8 +939,8 @@ void TlsAgent::SendRecordDirect(const TlsRecord& record) {
|
|||
SendDirect(buf);
|
||||
}
|
||||
|
||||
static bool ErrorIsNonFatal(PRErrorCode code) {
|
||||
return code == PR_WOULD_BLOCK_ERROR || code == SSL_ERROR_RX_SHORT_DTLS_READ;
|
||||
static bool ErrorIsFatal(PRErrorCode code) {
|
||||
return code != PR_WOULD_BLOCK_ERROR && code != SSL_ERROR_RX_SHORT_DTLS_READ;
|
||||
}
|
||||
|
||||
void TlsAgent::SendData(size_t bytes, size_t blocksize) {
|
||||
|
|
@ -975,7 +980,7 @@ bool TlsAgent::SendEncryptedRecord(const std::shared_ptr<TlsCipherSpec>& spec,
|
|||
LOGV("Encrypting " << buf.len() << " bytes");
|
||||
// Ensure that we are doing TLS 1.3.
|
||||
EXPECT_GE(expected_version_, SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
TlsRecordHeader header(variant_, expected_version_, kTlsApplicationDataType,
|
||||
TlsRecordHeader header(variant_, expected_version_, ssl_ct_application_data,
|
||||
seq);
|
||||
DataBuffer padded = buf;
|
||||
padded.Write(padded.len(), ct, 1);
|
||||
|
|
@ -994,28 +999,39 @@ bool TlsAgent::SendEncryptedRecord(const std::shared_ptr<TlsCipherSpec>& spec,
|
|||
void TlsAgent::ReadBytes(size_t amount) {
|
||||
uint8_t block[16384];
|
||||
|
||||
int32_t rv = PR_Read(ssl_fd(), block, (std::min)(amount, sizeof(block)));
|
||||
LOGV("ReadBytes " << rv);
|
||||
int32_t err;
|
||||
size_t remaining = amount;
|
||||
while (remaining > 0) {
|
||||
int32_t rv = PR_Read(ssl_fd(), block, (std::min)(amount, sizeof(block)));
|
||||
LOGV("ReadBytes " << rv);
|
||||
|
||||
if (rv >= 0) {
|
||||
size_t count = static_cast<size_t>(rv);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
ASSERT_EQ(recv_ctr_ & 0xff, block[i]);
|
||||
recv_ctr_++;
|
||||
}
|
||||
} else {
|
||||
err = PR_GetError();
|
||||
LOG("Read error " << PORT_ErrorToName(err) << ": "
|
||||
<< PORT_ErrorToString(err));
|
||||
if (err != PR_WOULD_BLOCK_ERROR && expect_readwrite_error_) {
|
||||
error_code_ = err;
|
||||
expect_readwrite_error_ = false;
|
||||
if (rv > 0) {
|
||||
size_t count = static_cast<size_t>(rv);
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
ASSERT_EQ(recv_ctr_ & 0xff, block[i]);
|
||||
recv_ctr_++;
|
||||
}
|
||||
remaining -= rv;
|
||||
} else {
|
||||
PRErrorCode err = 0;
|
||||
if (rv < 0) {
|
||||
err = PR_GetError();
|
||||
LOG("Read error " << PORT_ErrorToName(err) << ": "
|
||||
<< PORT_ErrorToString(err));
|
||||
if (err != PR_WOULD_BLOCK_ERROR && expect_readwrite_error_) {
|
||||
error_code_ = err;
|
||||
expect_readwrite_error_ = false;
|
||||
}
|
||||
}
|
||||
if (err != 0 && ErrorIsFatal(err)) {
|
||||
// If we hit a fatal error, we're done.
|
||||
remaining = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If closed, then don't bother waiting around.
|
||||
if (rv > 0 || (rv < 0 && ErrorIsNonFatal(err))) {
|
||||
if (remaining) {
|
||||
LOGV("Re-arming");
|
||||
Poller::Instance()->Wait(READABLE_EVENT, adapter_, this,
|
||||
&TlsAgent::ReadableCallback);
|
||||
|
|
@ -1104,7 +1120,7 @@ void TlsAgentTestBase::MakeRecord(SSLProtocolVariant variant, uint8_t type,
|
|||
if (variant == ssl_variant_stream) {
|
||||
index = out->Write(index, version, 2);
|
||||
} else if (version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
|
||||
type == kTlsApplicationDataType) {
|
||||
type == ssl_ct_application_data) {
|
||||
uint32_t epoch = (sequence_number >> 48) & 0x3;
|
||||
uint32_t seqno = sequence_number & ((1ULL << 30) - 1);
|
||||
index = out->Write(index, (epoch << 30) | seqno, 4);
|
||||
|
|
@ -1157,10 +1173,10 @@ void TlsAgentTestBase::MakeTrivialHandshakeRecord(uint8_t hs_type,
|
|||
size_t hs_len,
|
||||
DataBuffer* out) {
|
||||
size_t index = 0;
|
||||
index = out->Write(index, kTlsHandshakeType, 1); // Content Type
|
||||
index = out->Write(index, 3, 1); // Version high
|
||||
index = out->Write(index, 1, 1); // Version low
|
||||
index = out->Write(index, 4 + hs_len, 2); // Length
|
||||
index = out->Write(index, ssl_ct_handshake, 1); // Content Type
|
||||
index = out->Write(index, 3, 1); // Version high
|
||||
index = out->Write(index, 1, 1); // Version low
|
||||
index = out->Write(index, 4 + hs_len, 2); // Length
|
||||
|
||||
index = out->Write(index, hs_type, 1); // Handshake record type.
|
||||
index = out->Write(index, hs_len, 3); // Handshake length
|
||||
|
|
@ -1173,6 +1189,11 @@ DataBuffer TlsAgentTestBase::MakeCannedTls13ServerHello() {
|
|||
DataBuffer sh(kCannedTls13ServerHello, sizeof(kCannedTls13ServerHello));
|
||||
if (variant_ == ssl_variant_datagram) {
|
||||
sh.Write(0, SSL_LIBRARY_VERSION_DTLS_1_2_WIRE, 2);
|
||||
// The version should be at the end.
|
||||
uint32_t v;
|
||||
EXPECT_TRUE(sh.Read(sh.len() - 2, 2, &v));
|
||||
EXPECT_EQ(static_cast<uint32_t>(SSL_LIBRARY_VERSION_TLS_1_3), v);
|
||||
sh.Write(sh.len() - 2, 0x7f00 | DTLS_1_3_DRAFT_VERSION, 2);
|
||||
}
|
||||
return sh;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@
|
|||
#include "prio.h"
|
||||
#include "ssl.h"
|
||||
|
||||
// This is an internal header, used to get TLS_1_3_DRAFT_VERSION.
|
||||
#include "ssl3prot.h"
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
||||
|
|
@ -20,7 +17,8 @@
|
|||
|
||||
#define GTEST_HAS_RTTI 0
|
||||
#include "gtest/gtest.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "scoped_ptrs_ssl.h"
|
||||
|
||||
extern bool g_ssl_gtest_verbose;
|
||||
|
||||
|
|
@ -60,8 +58,6 @@ typedef std::function<int32_t(TlsAgent* agent, const SECItem* srvNameArr,
|
|||
PRUint32 srvNameArrSize)>
|
||||
SniCallbackFunction;
|
||||
|
||||
static const uint8_t kD13 = TLS_1_3_DRAFT_VERSION;
|
||||
|
||||
class TlsAgent : public PollTarget {
|
||||
public:
|
||||
enum Role { CLIENT, SERVER };
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ extern "C" {
|
|||
|
||||
#include "databuffer.h"
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
#include "sslproto.h"
|
||||
|
||||
extern std::string g_working_dir_path;
|
||||
|
|
@ -559,13 +559,15 @@ void TlsConnectTestBase::CheckResumption(SessionResumptionMode expected) {
|
|||
EXPECT_EQ(stateless_count, stats->hsh_sid_stateless_resumes);
|
||||
|
||||
if (expected != RESUME_NONE) {
|
||||
if (client_->version() < SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
if (client_->version() < SSL_LIBRARY_VERSION_TLS_1_3 &&
|
||||
client_->GetResumptionToken().size() == 0) {
|
||||
// Check that the last two session ids match.
|
||||
ASSERT_EQ(1U + expected_resumptions_, session_ids_.size());
|
||||
EXPECT_EQ(session_ids_[session_ids_.size() - 1],
|
||||
session_ids_[session_ids_.size() - 2]);
|
||||
} else {
|
||||
// TLS 1.3 only uses tickets.
|
||||
// We've either chosen TLS 1.3 or are using an external resumption token,
|
||||
// both of which only use tickets.
|
||||
EXPECT_TRUE(expected & RESUME_TICKET);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
470
security/nss/gtests/ssl_gtest/tls_esni_unittest.cc
Normal file
470
security/nss/gtests/ssl_gtest/tls_esni_unittest.cc
Normal file
|
|
@ -0,0 +1,470 @@
|
|||
/* -*- 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 <ctime>
|
||||
|
||||
#include "secerr.h"
|
||||
#include "ssl.h"
|
||||
|
||||
#include "gtest_utils.h"
|
||||
#include "tls_agent.h"
|
||||
#include "tls_connect.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
static const char* kDummySni("dummy.invalid");
|
||||
|
||||
std::vector<uint16_t> kDefaultSuites = {TLS_AES_256_GCM_SHA384,
|
||||
TLS_AES_128_GCM_SHA256};
|
||||
std::vector<uint16_t> kChaChaSuite = {TLS_CHACHA20_POLY1305_SHA256};
|
||||
std::vector<uint16_t> kBogusSuites = {0};
|
||||
std::vector<uint16_t> kTls12Suites = {
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256};
|
||||
|
||||
static void NamedGroup2ECParams(SSLNamedGroup group, SECItem* params) {
|
||||
auto groupDef = ssl_LookupNamedGroup(group);
|
||||
ASSERT_NE(nullptr, groupDef);
|
||||
|
||||
auto oidData = SECOID_FindOIDByTag(groupDef->oidTag);
|
||||
ASSERT_NE(nullptr, oidData);
|
||||
ASSERT_NE(nullptr,
|
||||
SECITEM_AllocItem(nullptr, params, (2 + oidData->oid.len)));
|
||||
|
||||
/*
|
||||
* params->data needs to contain the ASN encoding of an object ID (OID)
|
||||
* representing the named curve. The actual OID is in
|
||||
* oidData->oid.data so we simply prepend 0x06 and OID length
|
||||
*/
|
||||
params->data[0] = SEC_ASN1_OBJECT_ID;
|
||||
params->data[1] = oidData->oid.len;
|
||||
memcpy(params->data + 2, oidData->oid.data, oidData->oid.len);
|
||||
}
|
||||
|
||||
/* Checksum is a 4-byte array. */
|
||||
static void UpdateEsniKeysChecksum(DataBuffer* buf) {
|
||||
SECStatus rv;
|
||||
PRUint8 sha256[32];
|
||||
|
||||
/* Stomp the checksum. */
|
||||
PORT_Memset(buf->data() + 2, 0, 4);
|
||||
|
||||
rv = PK11_HashBuf(ssl3_HashTypeToOID(ssl_hash_sha256), sha256, buf->data(),
|
||||
buf->len());
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
buf->Write(2, sha256, 4);
|
||||
}
|
||||
|
||||
static void GenerateEsniKey(time_t windowStart, SSLNamedGroup group,
|
||||
std::vector<uint16_t>& cipher_suites,
|
||||
DataBuffer* record,
|
||||
ScopedSECKEYPublicKey* pubKey = nullptr,
|
||||
ScopedSECKEYPrivateKey* privKey = nullptr) {
|
||||
SECKEYECParams ecParams = {siBuffer, NULL, 0};
|
||||
NamedGroup2ECParams(group, &ecParams);
|
||||
|
||||
SECKEYPublicKey* pub = nullptr;
|
||||
SECKEYPrivateKey* priv = SECKEY_CreateECPrivateKey(&ecParams, &pub, nullptr);
|
||||
ASSERT_NE(nullptr, priv);
|
||||
SECITEM_FreeItem(&ecParams, PR_FALSE);
|
||||
PRUint8 encoded[1024];
|
||||
unsigned int encoded_len;
|
||||
|
||||
SECStatus rv = SSL_EncodeESNIKeys(
|
||||
&cipher_suites[0], cipher_suites.size(), group, pub, 100, windowStart,
|
||||
windowStart + 10, encoded, &encoded_len, sizeof(encoded));
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
ASSERT_GT(encoded_len, 0U);
|
||||
|
||||
if (pubKey) {
|
||||
pubKey->reset(pub);
|
||||
} else {
|
||||
SECKEY_DestroyPublicKey(pub);
|
||||
}
|
||||
if (privKey) {
|
||||
privKey->reset(priv);
|
||||
} else {
|
||||
SECKEY_DestroyPrivateKey(priv);
|
||||
}
|
||||
record->Truncate(0);
|
||||
record->Write(0, encoded, encoded_len);
|
||||
}
|
||||
|
||||
static void SetupEsni(const std::shared_ptr<TlsAgent>& client,
|
||||
const std::shared_ptr<TlsAgent>& server,
|
||||
SSLNamedGroup group = ssl_grp_ec_curve25519) {
|
||||
ScopedSECKEYPublicKey pub;
|
||||
ScopedSECKEYPrivateKey priv;
|
||||
DataBuffer record;
|
||||
|
||||
GenerateEsniKey(time(nullptr), ssl_grp_ec_curve25519, kDefaultSuites, &record,
|
||||
&pub, &priv);
|
||||
SECStatus rv = SSL_SetESNIKeyPair(server->ssl_fd(), priv.get(), record.data(),
|
||||
record.len());
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
|
||||
rv = SSL_EnableESNI(client->ssl_fd(), record.data(), record.len(), kDummySni);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
}
|
||||
|
||||
static void CheckSniExtension(const DataBuffer& data) {
|
||||
TlsParser parser(data.data(), data.len());
|
||||
uint32_t tmp;
|
||||
ASSERT_TRUE(parser.Read(&tmp, 2));
|
||||
ASSERT_EQ(parser.remaining(), tmp);
|
||||
ASSERT_TRUE(parser.Read(&tmp, 1));
|
||||
ASSERT_EQ(0U, tmp); /* sni_nametype_hostname */
|
||||
DataBuffer name;
|
||||
ASSERT_TRUE(parser.ReadVariable(&name, 2));
|
||||
ASSERT_EQ(0U, parser.remaining());
|
||||
DataBuffer expected(reinterpret_cast<const uint8_t*>(kDummySni),
|
||||
strlen(kDummySni));
|
||||
ASSERT_EQ(expected, name);
|
||||
}
|
||||
|
||||
static void ClientInstallEsni(std::shared_ptr<TlsAgent>& agent,
|
||||
const DataBuffer& record, PRErrorCode err = 0) {
|
||||
SECStatus rv =
|
||||
SSL_EnableESNI(agent->ssl_fd(), record.data(), record.len(), kDummySni);
|
||||
if (err == 0) {
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
} else {
|
||||
ASSERT_EQ(SECFailure, rv);
|
||||
ASSERT_EQ(err, PORT_GetError());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(TlsAgentTestClient13, EsniInstall) {
|
||||
EnsureInit();
|
||||
DataBuffer record;
|
||||
GenerateEsniKey(time(0), ssl_grp_ec_curve25519, kDefaultSuites, &record);
|
||||
ClientInstallEsni(agent_, record);
|
||||
}
|
||||
|
||||
// The next set of tests fail at setup time.
|
||||
TEST_P(TlsAgentTestClient13, EsniInvalidHash) {
|
||||
EnsureInit();
|
||||
DataBuffer record;
|
||||
GenerateEsniKey(time(0), ssl_grp_ec_curve25519, kDefaultSuites, &record);
|
||||
record.data()[2]++;
|
||||
ClientInstallEsni(agent_, record, SSL_ERROR_RX_MALFORMED_ESNI_KEYS);
|
||||
}
|
||||
|
||||
TEST_P(TlsAgentTestClient13, EsniInvalidVersion) {
|
||||
EnsureInit();
|
||||
DataBuffer record;
|
||||
GenerateEsniKey(time(0), ssl_grp_ec_curve25519, kDefaultSuites, &record);
|
||||
record.Write(0, 0xffff, 2);
|
||||
ClientInstallEsni(agent_, record, SSL_ERROR_UNSUPPORTED_VERSION);
|
||||
}
|
||||
|
||||
TEST_P(TlsAgentTestClient13, EsniShort) {
|
||||
EnsureInit();
|
||||
DataBuffer record;
|
||||
GenerateEsniKey(time(0), ssl_grp_ec_curve25519, kDefaultSuites, &record);
|
||||
record.Truncate(record.len() - 1);
|
||||
UpdateEsniKeysChecksum(&record);
|
||||
ClientInstallEsni(agent_, record, SSL_ERROR_RX_MALFORMED_ESNI_KEYS);
|
||||
}
|
||||
|
||||
TEST_P(TlsAgentTestClient13, EsniLong) {
|
||||
EnsureInit();
|
||||
DataBuffer record;
|
||||
GenerateEsniKey(time(0), ssl_grp_ec_curve25519, kDefaultSuites, &record);
|
||||
record.Write(record.len(), 1, 1);
|
||||
UpdateEsniKeysChecksum(&record);
|
||||
ClientInstallEsni(agent_, record, SSL_ERROR_RX_MALFORMED_ESNI_KEYS);
|
||||
}
|
||||
|
||||
TEST_P(TlsAgentTestClient13, EsniExtensionMismatch) {
|
||||
EnsureInit();
|
||||
DataBuffer record;
|
||||
GenerateEsniKey(time(0), ssl_grp_ec_curve25519, kDefaultSuites, &record);
|
||||
record.Write(record.len() - 1, 1, 1);
|
||||
UpdateEsniKeysChecksum(&record);
|
||||
ClientInstallEsni(agent_, record, SSL_ERROR_RX_MALFORMED_ESNI_KEYS);
|
||||
}
|
||||
|
||||
// The following tests fail by ignoring the Esni block.
|
||||
TEST_P(TlsAgentTestClient13, EsniUnknownGroup) {
|
||||
EnsureInit();
|
||||
DataBuffer record;
|
||||
GenerateEsniKey(time(0), ssl_grp_ec_curve25519, kDefaultSuites, &record);
|
||||
record.Write(8, 0xffff, 2); // Fake group
|
||||
UpdateEsniKeysChecksum(&record);
|
||||
ClientInstallEsni(agent_, record, 0);
|
||||
auto filter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(agent_, ssl_tls13_encrypted_sni_xtn);
|
||||
agent_->Handshake();
|
||||
ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state());
|
||||
ASSERT_TRUE(!filter->captured());
|
||||
}
|
||||
|
||||
TEST_P(TlsAgentTestClient13, EsniUnknownCS) {
|
||||
EnsureInit();
|
||||
DataBuffer record;
|
||||
GenerateEsniKey(time(0), ssl_grp_ec_curve25519, kBogusSuites, &record);
|
||||
ClientInstallEsni(agent_, record, 0);
|
||||
auto filter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(agent_, ssl_tls13_encrypted_sni_xtn);
|
||||
agent_->Handshake();
|
||||
ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state());
|
||||
ASSERT_TRUE(!filter->captured());
|
||||
}
|
||||
|
||||
TEST_P(TlsAgentTestClient13, EsniInvalidCS) {
|
||||
EnsureInit();
|
||||
DataBuffer record;
|
||||
GenerateEsniKey(time(0), ssl_grp_ec_curve25519, kTls12Suites, &record);
|
||||
UpdateEsniKeysChecksum(&record);
|
||||
ClientInstallEsni(agent_, record, 0);
|
||||
auto filter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(agent_, ssl_tls13_encrypted_sni_xtn);
|
||||
agent_->Handshake();
|
||||
ASSERT_EQ(TlsAgent::STATE_CONNECTING, agent_->state());
|
||||
ASSERT_TRUE(!filter->captured());
|
||||
}
|
||||
|
||||
TEST_P(TlsAgentTestClient13, EsniNotReady) {
|
||||
EnsureInit();
|
||||
DataBuffer record;
|
||||
GenerateEsniKey(time(0) + 1000, ssl_grp_ec_curve25519, kDefaultSuites,
|
||||
&record);
|
||||
ClientInstallEsni(agent_, record, 0);
|
||||
auto filter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(agent_, ssl_tls13_encrypted_sni_xtn);
|
||||
agent_->Handshake();
|
||||
ASSERT_TRUE(!filter->captured());
|
||||
}
|
||||
|
||||
TEST_P(TlsAgentTestClient13, EsniExpired) {
|
||||
EnsureInit();
|
||||
DataBuffer record;
|
||||
GenerateEsniKey(time(0) - 1000, ssl_grp_ec_curve25519, kDefaultSuites,
|
||||
&record);
|
||||
ClientInstallEsni(agent_, record, 0);
|
||||
auto filter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(agent_, ssl_tls13_encrypted_sni_xtn);
|
||||
agent_->Handshake();
|
||||
ASSERT_TRUE(!filter->captured());
|
||||
}
|
||||
|
||||
TEST_P(TlsAgentTestClient13, NoSniSoNoEsni) {
|
||||
EnsureInit();
|
||||
DataBuffer record;
|
||||
GenerateEsniKey(time(0), ssl_grp_ec_curve25519, kDefaultSuites, &record);
|
||||
SSL_SetURL(agent_->ssl_fd(), "");
|
||||
ClientInstallEsni(agent_, record, 0);
|
||||
auto filter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(agent_, ssl_tls13_encrypted_sni_xtn);
|
||||
agent_->Handshake();
|
||||
ASSERT_TRUE(!filter->captured());
|
||||
}
|
||||
|
||||
static int32_t SniCallback(TlsAgent* agent, const SECItem* srvNameAddr,
|
||||
PRUint32 srvNameArrSize) {
|
||||
EXPECT_EQ(1U, srvNameArrSize);
|
||||
SECItem expected = {
|
||||
siBuffer, reinterpret_cast<unsigned char*>(const_cast<char*>("server")),
|
||||
6};
|
||||
EXPECT_TRUE(!SECITEM_CompareItem(&expected, &srvNameAddr[0]));
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ConnectEsni) {
|
||||
EnsureTlsSetup();
|
||||
SetupEsni(client_, server_);
|
||||
auto cFilterSni =
|
||||
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_server_name_xtn);
|
||||
auto cFilterEsni =
|
||||
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_tls13_encrypted_sni_xtn);
|
||||
client_->SetFilter(std::make_shared<ChainedPacketFilter>(
|
||||
ChainedPacketFilterInit({cFilterSni, cFilterEsni})));
|
||||
auto sfilter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(server_, ssl_server_name_xtn);
|
||||
sfilter->EnableDecryption();
|
||||
server_->SetSniCallback(SniCallback);
|
||||
Connect();
|
||||
CheckSniExtension(cFilterSni->extension());
|
||||
ASSERT_TRUE(cFilterEsni->captured());
|
||||
// Check that our most preferred suite got chosen.
|
||||
uint32_t suite;
|
||||
ASSERT_TRUE(cFilterEsni->extension().Read(0, 2, &suite));
|
||||
ASSERT_EQ(TLS_AES_128_GCM_SHA256, static_cast<PRUint16>(suite));
|
||||
ASSERT_TRUE(!sfilter->captured());
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ConnectEsniHrr) {
|
||||
EnsureTlsSetup();
|
||||
const std::vector<SSLNamedGroup> groups = {ssl_grp_ec_secp384r1};
|
||||
server_->ConfigNamedGroups(groups);
|
||||
SetupEsni(client_, server_);
|
||||
auto hrr_capture = MakeTlsFilter<TlsHandshakeRecorder>(
|
||||
server_, kTlsHandshakeHelloRetryRequest);
|
||||
auto filter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_server_name_xtn);
|
||||
auto cfilter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_server_name_xtn);
|
||||
server_->SetSniCallback(SniCallback);
|
||||
Connect();
|
||||
CheckSniExtension(cfilter->extension());
|
||||
EXPECT_NE(0UL, hrr_capture->buffer().len());
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ConnectEsniNoDummy) {
|
||||
EnsureTlsSetup();
|
||||
ScopedSECKEYPublicKey pub;
|
||||
ScopedSECKEYPrivateKey priv;
|
||||
DataBuffer record;
|
||||
|
||||
GenerateEsniKey(time(nullptr), ssl_grp_ec_curve25519, kDefaultSuites, &record,
|
||||
&pub, &priv);
|
||||
SECStatus rv = SSL_SetESNIKeyPair(server_->ssl_fd(), priv.get(),
|
||||
record.data(), record.len());
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = SSL_EnableESNI(client_->ssl_fd(), record.data(), record.len(), "");
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
|
||||
auto cfilter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_server_name_xtn);
|
||||
auto sfilter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(server_, ssl_server_name_xtn);
|
||||
server_->SetSniCallback(SniCallback);
|
||||
Connect();
|
||||
ASSERT_TRUE(!cfilter->captured());
|
||||
ASSERT_TRUE(!sfilter->captured());
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ConnectEsniNullDummy) {
|
||||
EnsureTlsSetup();
|
||||
ScopedSECKEYPublicKey pub;
|
||||
ScopedSECKEYPrivateKey priv;
|
||||
DataBuffer record;
|
||||
|
||||
GenerateEsniKey(time(nullptr), ssl_grp_ec_curve25519, kDefaultSuites, &record,
|
||||
&pub, &priv);
|
||||
SECStatus rv = SSL_SetESNIKeyPair(server_->ssl_fd(), priv.get(),
|
||||
record.data(), record.len());
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = SSL_EnableESNI(client_->ssl_fd(), record.data(), record.len(), nullptr);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
|
||||
auto cfilter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_server_name_xtn);
|
||||
auto sfilter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(server_, ssl_server_name_xtn);
|
||||
server_->SetSniCallback(SniCallback);
|
||||
Connect();
|
||||
ASSERT_TRUE(!cfilter->captured());
|
||||
ASSERT_TRUE(!sfilter->captured());
|
||||
}
|
||||
|
||||
/* Tell the client that it supports AES but the server that it supports ChaCha
|
||||
*/
|
||||
TEST_P(TlsConnectTls13, ConnectEsniCSMismatch) {
|
||||
EnsureTlsSetup();
|
||||
ScopedSECKEYPublicKey pub;
|
||||
ScopedSECKEYPrivateKey priv;
|
||||
DataBuffer record;
|
||||
|
||||
GenerateEsniKey(time(nullptr), ssl_grp_ec_curve25519, kDefaultSuites, &record,
|
||||
&pub, &priv);
|
||||
PRUint8 encoded[1024];
|
||||
unsigned int encoded_len;
|
||||
|
||||
SECStatus rv = SSL_EncodeESNIKeys(
|
||||
&kChaChaSuite[0], kChaChaSuite.size(), ssl_grp_ec_curve25519, pub.get(),
|
||||
100, time(0), time(0) + 10, encoded, &encoded_len, sizeof(encoded));
|
||||
rv = SSL_SetESNIKeyPair(server_->ssl_fd(), priv.get(), encoded, encoded_len);
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = SSL_EnableESNI(client_->ssl_fd(), record.data(), record.len(), "");
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
ConnectExpectAlert(server_, illegal_parameter);
|
||||
server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ConnectEsniP256) {
|
||||
EnsureTlsSetup();
|
||||
SetupEsni(client_, server_, ssl_grp_ec_secp256r1);
|
||||
auto cfilter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(client_, ssl_server_name_xtn);
|
||||
auto sfilter =
|
||||
MakeTlsFilter<TlsExtensionCapture>(server_, ssl_server_name_xtn);
|
||||
server_->SetSniCallback(SniCallback);
|
||||
Connect();
|
||||
CheckSniExtension(cfilter->extension());
|
||||
ASSERT_TRUE(!sfilter->captured());
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ConnectMismatchedEsniKeys) {
|
||||
EnsureTlsSetup();
|
||||
SetupEsni(client_, server_);
|
||||
// Now install a new set of keys on the client, so we have a mismatch.
|
||||
DataBuffer record;
|
||||
GenerateEsniKey(time(0), ssl_grp_ec_curve25519, kDefaultSuites, &record);
|
||||
ClientInstallEsni(client_, record, 0);
|
||||
ConnectExpectAlert(server_, illegal_parameter);
|
||||
server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ConnectDamagedEsniExtensionCH) {
|
||||
EnsureTlsSetup();
|
||||
SetupEsni(client_, server_);
|
||||
auto filter = MakeTlsFilter<TlsExtensionDamager>(
|
||||
client_, ssl_tls13_encrypted_sni_xtn, 50); // in the ciphertext
|
||||
ConnectExpectAlert(server_, illegal_parameter);
|
||||
server_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ConnectRemoveEsniExtensionEE) {
|
||||
EnsureTlsSetup();
|
||||
SetupEsni(client_, server_);
|
||||
auto filter =
|
||||
MakeTlsFilter<TlsExtensionDropper>(server_, ssl_tls13_encrypted_sni_xtn);
|
||||
filter->EnableDecryption();
|
||||
ConnectExpectAlert(client_, missing_extension);
|
||||
client_->CheckErrorCode(SSL_ERROR_MISSING_ESNI_EXTENSION);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ConnectShortEsniExtensionEE) {
|
||||
EnsureTlsSetup();
|
||||
SetupEsni(client_, server_);
|
||||
DataBuffer shortNonce;
|
||||
auto filter = MakeTlsFilter<TlsExtensionReplacer>(
|
||||
server_, ssl_tls13_encrypted_sni_xtn, shortNonce);
|
||||
filter->EnableDecryption();
|
||||
ConnectExpectAlert(client_, illegal_parameter);
|
||||
client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_ESNI_EXTENSION);
|
||||
}
|
||||
|
||||
TEST_P(TlsConnectTls13, ConnectBogusEsniExtensionEE) {
|
||||
EnsureTlsSetup();
|
||||
SetupEsni(client_, server_);
|
||||
const uint8_t bogusNonceBuf[16] = {0};
|
||||
DataBuffer bogusNonce(bogusNonceBuf, sizeof(bogusNonceBuf));
|
||||
auto filter = MakeTlsFilter<TlsExtensionReplacer>(
|
||||
server_, ssl_tls13_encrypted_sni_xtn, bogusNonce);
|
||||
filter->EnableDecryption();
|
||||
ConnectExpectAlert(client_, illegal_parameter);
|
||||
client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_ESNI_EXTENSION);
|
||||
}
|
||||
|
||||
// ESNI is a commitment to doing TLS 1.3 or above.
|
||||
// The TLS 1.2 server ignores ESNI and processes the dummy SNI.
|
||||
// The client then aborts when it sees the server did TLS 1.2.
|
||||
TEST_P(TlsConnectTls13, EsniButTLS12Server) {
|
||||
EnsureTlsSetup();
|
||||
SetupEsni(client_, server_);
|
||||
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_2,
|
||||
SSL_LIBRARY_VERSION_TLS_1_2);
|
||||
ConnectExpectAlert(client_, kTlsAlertProtocolVersion);
|
||||
client_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_VERSION);
|
||||
server_->CheckErrorCode(SSL_ERROR_PROTOCOL_VERSION_ALERT);
|
||||
ASSERT_FALSE(SSLInt_ExtensionNegotiated(server_->ssl_fd(),
|
||||
ssl_tls13_encrypted_sni_xtn));
|
||||
}
|
||||
}
|
||||
|
|
@ -131,7 +131,7 @@ PacketFilter::Action TlsRecordFilter::Filter(const DataBuffer& input,
|
|||
// spec to another active cipher spec (KeyUpdate for instance) AND writes
|
||||
// are consolidated across that change, this code could use the wrong
|
||||
// sequence numbers when re-encrypting records with the old keys.
|
||||
if (header.content_type() == kTlsApplicationDataType) {
|
||||
if (header.content_type() == ssl_ct_application_data) {
|
||||
in_sequence_number_ =
|
||||
(std::max)(in_sequence_number_, header.sequence_number() + 1);
|
||||
}
|
||||
|
|
@ -194,7 +194,7 @@ PacketFilter::Action TlsRecordFilter::FilterRecord(
|
|||
|
||||
uint64_t seq_num;
|
||||
if (header.is_dtls() || !cipher_spec_ ||
|
||||
header.content_type() != kTlsApplicationDataType) {
|
||||
header.content_type() != ssl_ct_application_data) {
|
||||
seq_num = header.sequence_number();
|
||||
} else {
|
||||
seq_num = out_sequence_number_++;
|
||||
|
|
@ -277,7 +277,7 @@ bool TlsRecordHeader::Parse(bool is_dtls13, uint64_t seqno, TlsParser* parser,
|
|||
|
||||
#ifndef UNSAFE_FUZZER_MODE
|
||||
// Deal with the 7 octet header.
|
||||
if (content_type_ == kTlsApplicationDataType) {
|
||||
if (content_type_ == ssl_ct_application_data) {
|
||||
uint32_t tmp;
|
||||
if (!parser->Read(&tmp, 4)) {
|
||||
return false;
|
||||
|
|
@ -298,7 +298,7 @@ bool TlsRecordHeader::Parse(bool is_dtls13, uint64_t seqno, TlsParser* parser,
|
|||
}
|
||||
// Need to use the low 5 bits of the first octet too.
|
||||
tmp |= (content_type_ & 0x1f) << 8;
|
||||
content_type_ = kTlsApplicationDataType;
|
||||
content_type_ = ssl_ct_application_data;
|
||||
sequence_number_ = ParseSequenceNumber(seqno, tmp, 12, 1);
|
||||
|
||||
if (!parser->ReadFromMark(&header_, parser->consumed() - mark, mark)) {
|
||||
|
|
@ -308,9 +308,9 @@ bool TlsRecordHeader::Parse(bool is_dtls13, uint64_t seqno, TlsParser* parser,
|
|||
}
|
||||
|
||||
// The full 13 octet header can only be used for a few types.
|
||||
EXPECT_TRUE(content_type_ == kTlsAlertType ||
|
||||
content_type_ == kTlsHandshakeType ||
|
||||
content_type_ == kTlsAckType);
|
||||
EXPECT_TRUE(content_type_ == ssl_ct_alert ||
|
||||
content_type_ == ssl_ct_handshake ||
|
||||
content_type_ == ssl_ct_ack);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -347,7 +347,7 @@ size_t TlsRecordHeader::WriteHeader(DataBuffer* buffer, size_t offset,
|
|||
size_t body_len) const {
|
||||
offset = buffer->Write(offset, content_type_, 1);
|
||||
if (is_dtls() && version_ >= SSL_LIBRARY_VERSION_TLS_1_3 &&
|
||||
content_type() == kTlsApplicationDataType) {
|
||||
content_type() == ssl_ct_application_data) {
|
||||
// application_data records in TLS 1.3 have a different header format.
|
||||
// Always use the long header here for simplicity.
|
||||
uint32_t e = (sequence_number_ >> 48) & 0x3;
|
||||
|
|
@ -377,7 +377,7 @@ bool TlsRecordFilter::Unprotect(const TlsRecordHeader& header,
|
|||
const DataBuffer& ciphertext,
|
||||
uint8_t* inner_content_type,
|
||||
DataBuffer* plaintext) {
|
||||
if (!cipher_spec_ || header.content_type() != kTlsApplicationDataType) {
|
||||
if (!cipher_spec_ || header.content_type() != ssl_ct_application_data) {
|
||||
*inner_content_type = header.content_type();
|
||||
*plaintext = ciphertext;
|
||||
return true;
|
||||
|
|
@ -411,7 +411,7 @@ bool TlsRecordFilter::Protect(const TlsRecordHeader& header,
|
|||
uint8_t inner_content_type,
|
||||
const DataBuffer& plaintext,
|
||||
DataBuffer* ciphertext, size_t padding) {
|
||||
if (!cipher_spec_ || header.content_type() != kTlsApplicationDataType) {
|
||||
if (!cipher_spec_ || header.content_type() != ssl_ct_application_data) {
|
||||
*ciphertext = plaintext;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -453,8 +453,7 @@ PacketFilter::Action TlsHandshakeFilter::FilterRecord(
|
|||
const TlsRecordHeader& record_header, const DataBuffer& input,
|
||||
DataBuffer* output) {
|
||||
// Check that the first byte is as requested.
|
||||
if ((record_header.content_type() != kTlsHandshakeType) &&
|
||||
(record_header.content_type() != kTlsAltHandshakeType)) {
|
||||
if (record_header.content_type() != ssl_ct_handshake) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
|
|
@ -879,6 +878,17 @@ PacketFilter::Action TlsExtensionDropper::FilterExtension(
|
|||
return KEEP;
|
||||
}
|
||||
|
||||
PacketFilter::Action TlsExtensionDamager::FilterExtension(
|
||||
uint16_t extension_type, const DataBuffer& input, DataBuffer* output) {
|
||||
if (extension_type != extension_) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
*output = input;
|
||||
output->data()[index_] += 73; // Increment selected for maximum damage
|
||||
return CHANGE;
|
||||
}
|
||||
|
||||
PacketFilter::Action TlsExtensionInjector::FilterHandshake(
|
||||
const HandshakeHeader& header, const DataBuffer& input,
|
||||
DataBuffer* output) {
|
||||
|
|
|
|||
|
|
@ -172,20 +172,19 @@ inline std::ostream& operator<<(std::ostream& stream,
|
|||
hdr.WriteStream(stream);
|
||||
stream << ' ';
|
||||
switch (hdr.content_type()) {
|
||||
case kTlsChangeCipherSpecType:
|
||||
case ssl_ct_change_cipher_spec:
|
||||
stream << "CCS";
|
||||
break;
|
||||
case kTlsAlertType:
|
||||
case ssl_ct_alert:
|
||||
stream << "Alert";
|
||||
break;
|
||||
case kTlsHandshakeType:
|
||||
case kTlsAltHandshakeType:
|
||||
case ssl_ct_handshake:
|
||||
stream << "Handshake";
|
||||
break;
|
||||
case kTlsApplicationDataType:
|
||||
case ssl_ct_application_data:
|
||||
stream << "Data";
|
||||
break;
|
||||
case kTlsAckType:
|
||||
case ssl_ct_ack:
|
||||
stream << "ACK";
|
||||
break;
|
||||
default:
|
||||
|
|
@ -301,7 +300,7 @@ class TlsRecordRecorder : public TlsRecordFilter {
|
|||
TlsRecordRecorder(const std::shared_ptr<TlsAgent>& a)
|
||||
: TlsRecordFilter(a),
|
||||
filter_(false),
|
||||
ct_(content_handshake), // dummy (<optional> is C++14)
|
||||
ct_(ssl_ct_handshake), // dummy (<optional> is C++14)
|
||||
records_() {}
|
||||
virtual PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
|
||||
const DataBuffer& input,
|
||||
|
|
@ -466,6 +465,20 @@ class TlsExtensionInjector : public TlsHandshakeFilter {
|
|||
const DataBuffer data_;
|
||||
};
|
||||
|
||||
class TlsExtensionDamager : public TlsExtensionFilter {
|
||||
public:
|
||||
TlsExtensionDamager(const std::shared_ptr<TlsAgent>& a, uint16_t extension,
|
||||
size_t index)
|
||||
: TlsExtensionFilter(a), extension_(extension), index_(index) {}
|
||||
virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
|
||||
const DataBuffer& input,
|
||||
DataBuffer* output);
|
||||
|
||||
private:
|
||||
uint16_t extension_;
|
||||
size_t index_;
|
||||
};
|
||||
|
||||
typedef std::function<void(void)> VoidFunction;
|
||||
|
||||
class AfterRecordN : public TlsRecordFilter {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include "databuffer.h"
|
||||
#include "gtest_utils.h"
|
||||
#include "scoped_ptrs.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
|
|
@ -60,9 +60,11 @@ const std::string kHashName[] = {"None", "MD5", "SHA-1", "SHA-224",
|
|||
"SHA-256", "SHA-384", "SHA-512"};
|
||||
|
||||
static void ImportKey(ScopedPK11SymKey* to, const DataBuffer& key,
|
||||
PK11SlotInfo* slot) {
|
||||
SSLHashType hash_type, PK11SlotInfo* slot) {
|
||||
ASSERT_LT(hash_type, sizeof(kHashLength));
|
||||
ASSERT_LE(kHashLength[hash_type], key.len());
|
||||
SECItem key_item = {siBuffer, const_cast<uint8_t*>(key.data()),
|
||||
static_cast<unsigned int>(key.len())};
|
||||
static_cast<unsigned int>(kHashLength[hash_type])};
|
||||
|
||||
PK11SymKey* inner =
|
||||
PK11_ImportSymKey(slot, CKM_SSL3_MASTER_KEY_DERIVE, PK11_OriginUnwrap,
|
||||
|
|
@ -106,8 +108,8 @@ class TlsHkdfTest : public ::testing::Test,
|
|||
}
|
||||
|
||||
void SetUp() {
|
||||
ImportKey(&k1_, kKey1, slot_.get());
|
||||
ImportKey(&k2_, kKey2, slot_.get());
|
||||
ImportKey(&k1_, kKey1, hash_type_, slot_.get());
|
||||
ImportKey(&k2_, kKey2, hash_type_, slot_.get());
|
||||
}
|
||||
|
||||
void VerifyKey(const ScopedPK11SymKey& key, const DataBuffer& expected) {
|
||||
|
|
@ -183,9 +185,9 @@ TEST_P(TlsHkdfTest, HkdfKey1Only) {
|
|||
{/* ssl_hash_md5 */},
|
||||
{/* ssl_hash_sha1 */},
|
||||
{/* ssl_hash_sha224 */},
|
||||
{0x11, 0x87, 0x38, 0x28, 0xa9, 0x19, 0x78, 0x11, 0x33, 0x91, 0x24,
|
||||
0xb5, 0x8a, 0x1b, 0xb0, 0x9f, 0x7f, 0x0d, 0x8d, 0xbb, 0x10, 0xf4,
|
||||
0x9c, 0x54, 0xbd, 0x1f, 0xd8, 0x85, 0xcd, 0x15, 0x30, 0x33},
|
||||
{0x41, 0x6c, 0x53, 0x92, 0xb9, 0xf3, 0x6d, 0xf1, 0x88, 0xe9, 0x0e,
|
||||
0xb1, 0x4d, 0x17, 0xbf, 0x0d, 0xa1, 0x90, 0xbf, 0xdb, 0x7f, 0x1f,
|
||||
0x49, 0x56, 0xe6, 0xe5, 0x66, 0xa5, 0x69, 0xc8, 0xb1, 0x5c},
|
||||
{0x51, 0xb1, 0xd5, 0xb4, 0x59, 0x79, 0x79, 0x08, 0x4a, 0x15, 0xb2, 0xdb,
|
||||
0x84, 0xd3, 0xd6, 0xbc, 0xfc, 0x93, 0x45, 0xd9, 0xdc, 0x74, 0xda, 0x1a,
|
||||
0x57, 0xc2, 0x76, 0x9f, 0x3f, 0x83, 0x45, 0x2f, 0xf6, 0xf3, 0x56, 0x1f,
|
||||
|
|
@ -201,11 +203,9 @@ TEST_P(TlsHkdfTest, HkdfKey2Only) {
|
|||
{/* ssl_hash_md5 */},
|
||||
{/* ssl_hash_sha1 */},
|
||||
{/* ssl_hash_sha224 */},
|
||||
{
|
||||
0x2f, 0x5f, 0x78, 0xd0, 0xa4, 0xc4, 0x36, 0xee, 0x6c, 0x8a, 0x4e,
|
||||
0xf9, 0xd0, 0x43, 0x81, 0x02, 0x13, 0xfd, 0x47, 0x83, 0x63, 0x3a,
|
||||
0xd2, 0xe1, 0x40, 0x6d, 0x2d, 0x98, 0x00, 0xfd, 0xc1, 0x87,
|
||||
},
|
||||
{0x16, 0xaf, 0x00, 0x54, 0x3a, 0x56, 0xc8, 0x26, 0xa2, 0xa7, 0xfc,
|
||||
0xb6, 0x34, 0x66, 0x8a, 0xfd, 0x36, 0xdc, 0x8e, 0xce, 0xc4, 0xd2,
|
||||
0x6c, 0x7a, 0xdc, 0xe3, 0x70, 0x36, 0x3d, 0x60, 0xfa, 0x0b},
|
||||
{0x7b, 0x40, 0xf9, 0xef, 0x91, 0xff, 0xc9, 0xd1, 0x29, 0x24, 0x5c, 0xbf,
|
||||
0xf8, 0x82, 0x76, 0x68, 0xae, 0x4b, 0x63, 0xe8, 0x03, 0xdd, 0x39, 0xa8,
|
||||
0xd4, 0x6a, 0xf6, 0xe5, 0xec, 0xea, 0xf8, 0x7d, 0x91, 0x71, 0x81, 0xf1,
|
||||
|
|
@ -221,11 +221,9 @@ TEST_P(TlsHkdfTest, HkdfKey1Key2) {
|
|||
{/* ssl_hash_md5 */},
|
||||
{/* ssl_hash_sha1 */},
|
||||
{/* ssl_hash_sha224 */},
|
||||
{
|
||||
0x79, 0x53, 0xb8, 0xdd, 0x6b, 0x98, 0xce, 0x00, 0xb7, 0xdc, 0xe8,
|
||||
0x03, 0x70, 0x8c, 0xe3, 0xac, 0x06, 0x8b, 0x22, 0xfd, 0x0e, 0x34,
|
||||
0x48, 0xe6, 0xe5, 0xe0, 0x8a, 0xd6, 0x16, 0x18, 0xe5, 0x48,
|
||||
},
|
||||
{0xa5, 0x68, 0x02, 0x5a, 0x95, 0xc9, 0x7f, 0x55, 0x38, 0xbc, 0xf7,
|
||||
0x97, 0xcc, 0x0f, 0xd5, 0xf6, 0xa8, 0x8d, 0x15, 0xbc, 0x0e, 0x85,
|
||||
0x74, 0x70, 0x3c, 0xa3, 0x65, 0xbd, 0x76, 0xcf, 0x9f, 0xd3},
|
||||
{0x01, 0x93, 0xc0, 0x07, 0x3f, 0x6a, 0x83, 0x0e, 0x2e, 0x4f, 0xb2, 0x58,
|
||||
0xe4, 0x00, 0x08, 0x5c, 0x68, 0x9c, 0x37, 0x32, 0x00, 0x37, 0xff, 0xc3,
|
||||
0x1c, 0x5b, 0x98, 0x0b, 0x02, 0x92, 0x3f, 0xfd, 0x73, 0x5a, 0x6f, 0x2a,
|
||||
|
|
@ -241,9 +239,9 @@ TEST_P(TlsHkdfTest, HkdfExpandLabel) {
|
|||
{/* ssl_hash_md5 */},
|
||||
{/* ssl_hash_sha1 */},
|
||||
{/* ssl_hash_sha224 */},
|
||||
{0xc6, 0xdd, 0x6e, 0xc4, 0x76, 0xb8, 0x55, 0xf2, 0xa4, 0xfc, 0x59,
|
||||
0x04, 0xa4, 0x90, 0xdc, 0xa7, 0xa7, 0x0d, 0x94, 0x8f, 0xc2, 0xdc,
|
||||
0x15, 0x6d, 0x48, 0x93, 0x9d, 0x05, 0xbb, 0x9a, 0xbc, 0xc1},
|
||||
{0x3e, 0x4e, 0x6e, 0xd0, 0xbc, 0xc4, 0xf4, 0xff, 0xf0, 0xf5, 0x69,
|
||||
0xd0, 0x6c, 0x1e, 0x0e, 0x10, 0x32, 0xaa, 0xd7, 0xa3, 0xef, 0xf6,
|
||||
0xa8, 0x65, 0x8e, 0xbe, 0xee, 0xc7, 0x1f, 0x01, 0x6d, 0x3c},
|
||||
{0x41, 0xea, 0x77, 0x09, 0x8c, 0x90, 0x04, 0x10, 0xec, 0xbc, 0x37, 0xd8,
|
||||
0x5b, 0x54, 0xcd, 0x7b, 0x08, 0x15, 0x13, 0x20, 0xed, 0x1e, 0x3f, 0x54,
|
||||
0x74, 0xf7, 0x8b, 0x06, 0x38, 0x28, 0x06, 0x37, 0x75, 0x23, 0xa2, 0xb7,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue