mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-22 16:37:31 +09:00
Replace NSS with Pale Moon's
This commit is contained in:
parent
ff1e5e48bf
commit
8c2e376f94
2870 changed files with 1762232 additions and 1374220 deletions
|
|
@ -1,4 +1,5 @@
|
|||
/* -*- 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/. */
|
||||
|
|
@ -48,6 +49,7 @@ const std::string TlsAgent::kServerEcdhEcdsa = "ecdh_ecdsa";
|
|||
const std::string TlsAgent::kServerDsa = "dsa";
|
||||
const std::string TlsAgent::kDelegatorEcdsa256 = "delegator_ecdsa256";
|
||||
const std::string TlsAgent::kDelegatorRsae2048 = "delegator_rsae2048";
|
||||
const std::string TlsAgent::kDelegatorRsaPss2048 = "delegator_rsa_pss2048";
|
||||
|
||||
static const uint8_t kCannedTls13ServerHello[] = {
|
||||
0x03, 0x03, 0x9c, 0xbc, 0x14, 0x9b, 0x0e, 0x2e, 0xfa, 0x0d, 0xf3,
|
||||
|
|
@ -71,8 +73,9 @@ TlsAgent::TlsAgent(const std::string& nm, Role rl, SSLProtocolVariant var)
|
|||
falsestart_enabled_(false),
|
||||
expected_version_(0),
|
||||
expected_cipher_suite_(0),
|
||||
expect_resumption_(false),
|
||||
expect_client_auth_(false),
|
||||
expect_ech_(false),
|
||||
expect_psk_(ssl_psk_none),
|
||||
can_falsestart_hook_called_(false),
|
||||
sni_hook_called_(false),
|
||||
auth_certificate_hook_called_(false),
|
||||
|
|
@ -90,7 +93,8 @@ TlsAgent::TlsAgent(const std::string& nm, Role rl, SSLProtocolVariant var)
|
|||
auth_certificate_callback_(),
|
||||
sni_callback_(),
|
||||
skip_version_checks_(false),
|
||||
resumption_token_() {
|
||||
resumption_token_(),
|
||||
policy_() {
|
||||
memset(&info_, 0, sizeof(info_));
|
||||
memset(&csinfo_, 0, sizeof(csinfo_));
|
||||
SECStatus rv = SSL_VersionRangeGetDefault(variant_, &vrange_);
|
||||
|
|
@ -224,6 +228,7 @@ bool TlsAgent::ConfigServerCert(const std::string& id, bool updateKeyBits,
|
|||
bool TlsAgent::EnsureTlsSetup(PRFileDesc* modelSocket) {
|
||||
// Don't set up twice
|
||||
if (ssl_fd_) return true;
|
||||
NssManagePolicy policyManage(policy_, option_);
|
||||
|
||||
ScopedPRFileDesc dummy_fd(adapter_->CreateFD());
|
||||
EXPECT_NE(nullptr, dummy_fd);
|
||||
|
|
@ -299,7 +304,7 @@ bool TlsAgent::MaybeSetResumptionToken() {
|
|||
|
||||
// rv is SECFailure with error set to SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR
|
||||
// if the resumption token was bad (expired/malformed/etc.).
|
||||
if (expect_resumption_) {
|
||||
if (expect_psk_ == ssl_psk_resume) {
|
||||
// Only in case we expect resumption this has to be successful. We might
|
||||
// not expect resumption due to some reason but the token is totally fine.
|
||||
EXPECT_EQ(SECSuccess, rv);
|
||||
|
|
@ -307,8 +312,8 @@ bool TlsAgent::MaybeSetResumptionToken() {
|
|||
if (rv != SECSuccess) {
|
||||
EXPECT_EQ(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR, PORT_GetError());
|
||||
resumption_token_.clear();
|
||||
EXPECT_FALSE(expect_resumption_);
|
||||
if (expect_resumption_) return false;
|
||||
EXPECT_FALSE(expect_psk_ == ssl_psk_resume);
|
||||
if (expect_psk_ == ssl_psk_resume) return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -316,13 +321,22 @@ bool TlsAgent::MaybeSetResumptionToken() {
|
|||
}
|
||||
|
||||
void TlsAgent::SetAntiReplayContext(ScopedSSLAntiReplayContext& ctx) {
|
||||
EXPECT_EQ(SECSuccess, SSL_SetAntiReplayContext(ssl_fd_.get(), ctx.get()));
|
||||
EXPECT_EQ(SECSuccess, SSL_SetAntiReplayContext(ssl_fd(), ctx.get()));
|
||||
}
|
||||
|
||||
void TlsAgent::SetupClientAuth() {
|
||||
// Defaults to a Sync callback returning success
|
||||
void TlsAgent::SetupClientAuth(ClientAuthCallbackType callbackType,
|
||||
bool callbackSuccess) {
|
||||
EXPECT_TRUE(EnsureTlsSetup());
|
||||
ASSERT_EQ(CLIENT, role_);
|
||||
|
||||
client_auth_callback_type_ = callbackType;
|
||||
client_auth_callback_success_ = callbackSuccess;
|
||||
|
||||
if (callbackType == ClientAuthCallbackType::kNone && !callbackSuccess) {
|
||||
// Don't set a callback for this case.
|
||||
return;
|
||||
}
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_GetClientAuthDataHook(ssl_fd(), GetClientAuthDataHook,
|
||||
reinterpret_cast<void*>(this)));
|
||||
|
|
@ -339,26 +353,95 @@ void CheckCertReqAgainstDefaultCAs(const CERTDistNames* caNames) {
|
|||
}
|
||||
}
|
||||
|
||||
// Complete processing of Client Certificate Selection
|
||||
// A No-op if the agent is using synchronous client cert selection.
|
||||
// Otherwise, calls SSL_ClientCertCallbackComplete.
|
||||
// kAsyncDelay triggers a call to SSL_ForceHandshake prior to completion to
|
||||
// ensure that the socket is correctly blocked.
|
||||
void TlsAgent::ClientAuthCallbackComplete() {
|
||||
ASSERT_EQ(CLIENT, role_);
|
||||
|
||||
if (client_auth_callback_type_ != ClientAuthCallbackType::kAsyncDelay &&
|
||||
client_auth_callback_type_ != ClientAuthCallbackType::kAsyncImmediate) {
|
||||
return;
|
||||
}
|
||||
client_auth_callback_fired_++;
|
||||
EXPECT_TRUE(client_auth_callback_awaiting_);
|
||||
|
||||
std::cerr << "client: calling SSL_ClientCertCallbackComplete with status "
|
||||
<< (client_auth_callback_success_ ? "success" : "failed")
|
||||
<< std::endl;
|
||||
|
||||
client_auth_callback_awaiting_ = false;
|
||||
|
||||
if (client_auth_callback_type_ == ClientAuthCallbackType::kAsyncDelay) {
|
||||
std::cerr
|
||||
<< "Running Handshake prior to running SSL_ClientCertCallbackComplete"
|
||||
<< std::endl;
|
||||
SECStatus rv = SSL_ForceHandshake(ssl_fd());
|
||||
EXPECT_EQ(rv, SECFailure);
|
||||
EXPECT_EQ(PORT_GetError(), PR_WOULD_BLOCK_ERROR);
|
||||
}
|
||||
|
||||
ScopedCERTCertificate cert;
|
||||
ScopedSECKEYPrivateKey priv;
|
||||
if (client_auth_callback_success_) {
|
||||
ASSERT_TRUE(TlsAgent::LoadCertificate(name(), &cert, &priv));
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_ClientCertCallbackComplete(ssl_fd(), SECSuccess,
|
||||
priv.release(), cert.release()));
|
||||
} else {
|
||||
EXPECT_EQ(SECSuccess, SSL_ClientCertCallbackComplete(ssl_fd(), SECFailure,
|
||||
nullptr, nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
SECStatus TlsAgent::GetClientAuthDataHook(void* self, PRFileDesc* fd,
|
||||
CERTDistNames* caNames,
|
||||
CERTCertificate** clientCert,
|
||||
SECKEYPrivateKey** clientKey) {
|
||||
TlsAgent* agent = reinterpret_cast<TlsAgent*>(self);
|
||||
ScopedCERTCertificate peerCert(SSL_PeerCertificate(agent->ssl_fd()));
|
||||
EXPECT_TRUE(peerCert) << "Client should be able to see the server cert";
|
||||
EXPECT_EQ(CLIENT, agent->role_);
|
||||
agent->client_auth_callback_fired_++;
|
||||
|
||||
// See bug 1573945
|
||||
// CheckCertReqAgainstDefaultCAs(caNames);
|
||||
switch (agent->client_auth_callback_type_) {
|
||||
case ClientAuthCallbackType::kAsyncDelay:
|
||||
case ClientAuthCallbackType::kAsyncImmediate:
|
||||
std::cerr << "Waiting for complete call" << std::endl;
|
||||
agent->client_auth_callback_awaiting_ = true;
|
||||
return SECWouldBlock;
|
||||
case ClientAuthCallbackType::kSync:
|
||||
case ClientAuthCallbackType::kNone:
|
||||
// Handle the sync case. None && Success is treated as Sync and Success.
|
||||
if (!agent->client_auth_callback_success_) {
|
||||
return SECFailure;
|
||||
}
|
||||
ScopedCERTCertificate peerCert(SSL_PeerCertificate(agent->ssl_fd()));
|
||||
EXPECT_TRUE(peerCert) << "Client should be able to see the server cert";
|
||||
|
||||
ScopedCERTCertificate cert;
|
||||
ScopedSECKEYPrivateKey priv;
|
||||
if (!TlsAgent::LoadCertificate(agent->name(), &cert, &priv)) {
|
||||
return SECFailure;
|
||||
// See bug 1573945
|
||||
// CheckCertReqAgainstDefaultCAs(caNames);
|
||||
|
||||
ScopedCERTCertificate cert;
|
||||
ScopedSECKEYPrivateKey priv;
|
||||
if (!TlsAgent::LoadCertificate(agent->name(), &cert, &priv)) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
*clientCert = cert.release();
|
||||
*clientKey = priv.release();
|
||||
return SECSuccess;
|
||||
}
|
||||
/* This is unreachable, but some old compilers can't tell that. */
|
||||
PORT_Assert(0);
|
||||
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
*clientCert = cert.release();
|
||||
*clientKey = priv.release();
|
||||
return SECSuccess;
|
||||
// Increments by 1 for each callback
|
||||
bool TlsAgent::CheckClientAuthCallbacksCompleted(uint8_t expected) {
|
||||
EXPECT_EQ(CLIENT, role_);
|
||||
return expected == client_auth_callback_fired_;
|
||||
}
|
||||
|
||||
bool TlsAgent::GetPeerChainLength(size_t* count) {
|
||||
|
|
@ -632,7 +715,9 @@ void TlsAgent::CheckAuthType(SSLAuthType auth,
|
|||
SSLSignatureScheme sig_scheme) const {
|
||||
EXPECT_EQ(STATE_CONNECTED, state_);
|
||||
EXPECT_EQ(auth, info_.authType);
|
||||
EXPECT_EQ(server_key_bits_, info_.authKeyBits);
|
||||
if (auth != ssl_auth_psk) {
|
||||
EXPECT_EQ(server_key_bits_, info_.authKeyBits);
|
||||
}
|
||||
if (expected_version_ < SSL_LIBRARY_VERSION_TLS_1_2) {
|
||||
switch (auth) {
|
||||
case ssl_auth_rsa_sign:
|
||||
|
|
@ -683,13 +768,33 @@ void TlsAgent::EnableFalseStart() {
|
|||
SetOption(SSL_ENABLE_FALSE_START, PR_TRUE);
|
||||
}
|
||||
|
||||
void TlsAgent::ExpectResumption() { expect_resumption_ = true; }
|
||||
void TlsAgent::ExpectEch(bool expected) { expect_ech_ = expected; }
|
||||
|
||||
void TlsAgent::ExpectPsk(SSLPskType psk) { expect_psk_ = psk; }
|
||||
|
||||
void TlsAgent::ExpectResumption() { expect_psk_ = ssl_psk_resume; }
|
||||
|
||||
void TlsAgent::EnableAlpn(const uint8_t* val, size_t len) {
|
||||
EXPECT_TRUE(EnsureTlsSetup());
|
||||
EXPECT_EQ(SECSuccess, SSL_SetNextProtoNego(ssl_fd(), val, len));
|
||||
}
|
||||
|
||||
void TlsAgent::AddPsk(const ScopedPK11SymKey& psk, std::string label,
|
||||
SSLHashType hash, uint16_t zeroRttSuite) {
|
||||
EXPECT_TRUE(EnsureTlsSetup());
|
||||
EXPECT_EQ(SECSuccess, SSL_AddExternalPsk0Rtt(
|
||||
ssl_fd(), psk.get(),
|
||||
reinterpret_cast<const uint8_t*>(label.data()),
|
||||
label.length(), hash, zeroRttSuite, 1000));
|
||||
}
|
||||
|
||||
void TlsAgent::RemovePsk(std::string label) {
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSL_RemoveExternalPsk(
|
||||
ssl_fd(), reinterpret_cast<const uint8_t*>(label.data()),
|
||||
label.length()));
|
||||
}
|
||||
|
||||
void TlsAgent::CheckAlpn(SSLNextProtoState expected_state,
|
||||
const std::string& expected) const {
|
||||
SSLNextProtoState alpn_state;
|
||||
|
|
@ -798,7 +903,6 @@ void TlsAgent::CheckPreliminaryInfo() {
|
|||
SSL_GetPreliminaryChannelInfo(ssl_fd(), &preinfo, sizeof(preinfo)));
|
||||
EXPECT_EQ(sizeof(preinfo), preinfo.length);
|
||||
EXPECT_TRUE(preinfo.valuesSet & ssl_preinfo_version);
|
||||
EXPECT_TRUE(preinfo.valuesSet & ssl_preinfo_cipher_suite);
|
||||
|
||||
// A version of 0 is invalid and indicates no expectation. This value is
|
||||
// initialized to 0 so that tests that don't explicitly set an expected
|
||||
|
|
@ -819,22 +923,22 @@ void TlsAgent::CheckPreliminaryInfo() {
|
|||
void TlsAgent::CheckCallbacks() const {
|
||||
// If false start happens, the handshake is reported as being complete at the
|
||||
// point that false start happens.
|
||||
if (expect_resumption_ || !falsestart_enabled_) {
|
||||
if (expect_psk_ == ssl_psk_resume || !falsestart_enabled_) {
|
||||
EXPECT_TRUE(handshake_callback_called_);
|
||||
}
|
||||
|
||||
// These callbacks shouldn't fire if we are resuming, except on TLS 1.3.
|
||||
if (role_ == SERVER) {
|
||||
PRBool have_sni = SSLInt_ExtensionNegotiated(ssl_fd(), ssl_server_name_xtn);
|
||||
EXPECT_EQ(((!expect_resumption_ && have_sni) ||
|
||||
EXPECT_EQ(((expect_psk_ != ssl_psk_resume && have_sni) ||
|
||||
expected_version_ >= SSL_LIBRARY_VERSION_TLS_1_3),
|
||||
sni_hook_called_);
|
||||
} else {
|
||||
EXPECT_EQ(!expect_resumption_, auth_certificate_hook_called_);
|
||||
EXPECT_EQ(expect_psk_ == ssl_psk_none, auth_certificate_hook_called_);
|
||||
// Note that this isn't unconditionally called, even with false start on.
|
||||
// But the callback is only skipped if a cipher that is ridiculously weak
|
||||
// (80 bits) is chosen. Don't test that: plan to remove bad ciphers.
|
||||
EXPECT_EQ(falsestart_enabled_ && !expect_resumption_,
|
||||
EXPECT_EQ(falsestart_enabled_ && expect_psk_ != ssl_psk_resume,
|
||||
can_falsestart_hook_called_);
|
||||
}
|
||||
}
|
||||
|
|
@ -845,8 +949,8 @@ void TlsAgent::ResetPreliminaryInfo() {
|
|||
}
|
||||
|
||||
void TlsAgent::UpdatePreliminaryChannelInfo() {
|
||||
SECStatus rv = SSL_GetPreliminaryChannelInfo(ssl_fd_.get(), &pre_info_,
|
||||
sizeof(pre_info_));
|
||||
SECStatus rv =
|
||||
SSL_GetPreliminaryChannelInfo(ssl_fd(), &pre_info_, sizeof(pre_info_));
|
||||
EXPECT_EQ(SECSuccess, rv);
|
||||
EXPECT_EQ(sizeof(pre_info_), pre_info_.length);
|
||||
}
|
||||
|
|
@ -870,7 +974,7 @@ void TlsAgent::ValidateCipherSpecs() {
|
|||
} else {
|
||||
// For DTLS 1.1 and 1.2, the last endpoint to send maintains a cipher spec
|
||||
// until the holddown timer runs down.
|
||||
if (expect_resumption_) {
|
||||
if (expect_psk_ == ssl_psk_resume) {
|
||||
if (role_ == CLIENT) {
|
||||
expected = 3;
|
||||
}
|
||||
|
|
@ -908,7 +1012,9 @@ void TlsAgent::Connected() {
|
|||
EXPECT_EQ(SECSuccess, rv);
|
||||
EXPECT_EQ(sizeof(info_), info_.length);
|
||||
|
||||
EXPECT_EQ(expect_resumption_, info_.resumed == PR_TRUE);
|
||||
EXPECT_EQ(expect_psk_ == ssl_psk_resume, info_.resumed == PR_TRUE);
|
||||
EXPECT_EQ(expect_psk_, info_.pskType);
|
||||
EXPECT_EQ(expect_ech_, info_.echAccepted);
|
||||
|
||||
// Preliminary values are exposed through callbacks during the handshake.
|
||||
// If either expected values were set or the callbacks were called, check
|
||||
|
|
@ -926,6 +1032,24 @@ void TlsAgent::Connected() {
|
|||
SetState(STATE_CONNECTED);
|
||||
}
|
||||
|
||||
void TlsAgent::CheckClientAuthCompleted(uint8_t handshakes) {
|
||||
EXPECT_FALSE(client_auth_callback_awaiting_);
|
||||
switch (client_auth_callback_type_) {
|
||||
case ClientAuthCallbackType::kNone:
|
||||
if (!client_auth_callback_success_) {
|
||||
EXPECT_TRUE(CheckClientAuthCallbacksCompleted(0));
|
||||
break;
|
||||
}
|
||||
case ClientAuthCallbackType::kSync:
|
||||
EXPECT_TRUE(CheckClientAuthCallbacksCompleted(handshakes));
|
||||
break;
|
||||
case ClientAuthCallbackType::kAsyncDelay:
|
||||
case ClientAuthCallbackType::kAsyncImmediate:
|
||||
EXPECT_TRUE(CheckClientAuthCallbacksCompleted(2 * handshakes));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void TlsAgent::EnableExtendedMasterSecret() {
|
||||
SetOption(SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE);
|
||||
}
|
||||
|
|
@ -960,6 +1084,10 @@ void TlsAgent::SetDowngradeCheckVersion(uint16_t ver) {
|
|||
void TlsAgent::Handshake() {
|
||||
LOGV("Handshake");
|
||||
SECStatus rv = SSL_ForceHandshake(ssl_fd());
|
||||
if (client_auth_callback_awaiting_) {
|
||||
ClientAuthCallbackComplete();
|
||||
rv = SSL_ForceHandshake(ssl_fd());
|
||||
}
|
||||
if (rv == SECSuccess) {
|
||||
Connected();
|
||||
Poller::Instance()->Wait(READABLE_EVENT, adapter_, this,
|
||||
|
|
@ -1063,21 +1191,28 @@ void TlsAgent::SendBuffer(const DataBuffer& buf) {
|
|||
bool TlsAgent::SendEncryptedRecord(const std::shared_ptr<TlsCipherSpec>& spec,
|
||||
uint64_t seq, uint8_t ct,
|
||||
const DataBuffer& buf) {
|
||||
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_, ssl_ct_application_data,
|
||||
seq);
|
||||
if (variant_ != ssl_variant_datagram) {
|
||||
ADD_FAILURE();
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGV("Encrypting " << buf.len() << " bytes");
|
||||
uint8_t dtls13_ct = kCtDtlsCiphertext | kCtDtlsCiphertext16bSeqno |
|
||||
kCtDtlsCiphertextLengthPresent;
|
||||
TlsRecordHeader header(variant_, expected_version_, dtls13_ct, seq);
|
||||
TlsRecordHeader out_header(header);
|
||||
DataBuffer padded = buf;
|
||||
padded.Write(padded.len(), ct, 1);
|
||||
DataBuffer ciphertext;
|
||||
if (!spec->Protect(header, padded, &ciphertext)) {
|
||||
if (!spec->Protect(header, padded, &ciphertext, &out_header)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DataBuffer record;
|
||||
auto rv = header.Write(&record, 0, ciphertext);
|
||||
EXPECT_EQ(header.header_length() + ciphertext.len(), rv);
|
||||
auto rv = out_header.Write(&record, 0, ciphertext);
|
||||
EXPECT_EQ(out_header.header_length() + ciphertext.len(), rv);
|
||||
SendDirect(record);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1124,7 +1259,7 @@ void TlsAgent::ReadBytes(size_t amount) {
|
|||
}
|
||||
}
|
||||
|
||||
void TlsAgent::ResetSentBytes() { send_ctr_ = 0; }
|
||||
void TlsAgent::ResetSentBytes(size_t bytes) { send_ctr_ = bytes; }
|
||||
|
||||
void TlsAgent::SetOption(int32_t option, int value) {
|
||||
ASSERT_TRUE(EnsureTlsSetup());
|
||||
|
|
@ -1137,9 +1272,9 @@ void TlsAgent::ConfigureSessionCache(SessionResumptionMode mode) {
|
|||
mode & RESUME_TICKET ? PR_TRUE : PR_FALSE);
|
||||
}
|
||||
|
||||
void TlsAgent::DisableECDHEServerKeyReuse() {
|
||||
void TlsAgent::EnableECDHEServerKeyReuse() {
|
||||
ASSERT_EQ(TlsAgent::SERVER, role_);
|
||||
SetOption(SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
|
||||
SetOption(SSL_REUSE_SERVER_ECDHE_KEY, PR_TRUE);
|
||||
}
|
||||
|
||||
static const std::string kTlsRolesAllArr[] = {"CLIENT", "SERVER"};
|
||||
|
|
@ -1201,16 +1336,26 @@ void TlsAgentTestBase::MakeRecord(SSLProtocolVariant variant, uint8_t type,
|
|||
uint16_t version, const uint8_t* buf,
|
||||
size_t len, DataBuffer* out,
|
||||
uint64_t sequence_number) {
|
||||
// Fixup the content type for DTLSCiphertext
|
||||
if (variant == ssl_variant_datagram &&
|
||||
version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
|
||||
type == ssl_ct_application_data) {
|
||||
type = kCtDtlsCiphertext | kCtDtlsCiphertext16bSeqno |
|
||||
kCtDtlsCiphertextLengthPresent;
|
||||
}
|
||||
|
||||
size_t index = 0;
|
||||
index = out->Write(index, type, 1);
|
||||
if (variant == ssl_variant_stream) {
|
||||
index = out->Write(index, type, 1);
|
||||
index = out->Write(index, version, 2);
|
||||
} else if (version >= SSL_LIBRARY_VERSION_TLS_1_3 &&
|
||||
type == ssl_ct_application_data) {
|
||||
(type & kCtDtlsCiphertextMask) == kCtDtlsCiphertext) {
|
||||
uint32_t epoch = (sequence_number >> 48) & 0x3;
|
||||
uint32_t seqno = sequence_number & ((1ULL << 30) - 1);
|
||||
index = out->Write(index, (epoch << 30) | seqno, 4);
|
||||
index = out->Write(index, type | epoch, 1);
|
||||
uint32_t seqno = sequence_number & ((1ULL << 16) - 1);
|
||||
index = out->Write(index, seqno, 2);
|
||||
} else {
|
||||
index = out->Write(index, type, 1);
|
||||
index = out->Write(index, TlsVersionToDtlsVersion(version), 2);
|
||||
index = out->Write(index, sequence_number >> 32, 4);
|
||||
index = out->Write(index, sequence_number & PR_UINT32_MAX, 4);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue