icecat: add release icecat-140.10.1-1gnu1 for ecne
This commit is contained in:
parent
a5f93cb214
commit
ff85d7c623
1256 changed files with 63469 additions and 24141 deletions
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include <stddef.h>
|
||||
|
||||
static const PRTime kCTExpirationTime = INT64_C(1779695596000000);
|
||||
static const PRTime kCTExpirationTime = INT64_C(1782114585000000);
|
||||
|
||||
namespace mozilla::ct {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
/* 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 "PSMRunnable.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace psm {
|
||||
|
||||
SyncRunnableBase::SyncRunnableBase()
|
||||
: Runnable("psm::SyncRunnableBase"), monitor("SyncRunnableBase::monitor") {}
|
||||
|
||||
nsresult SyncRunnableBase::DispatchToMainThreadAndWait() {
|
||||
nsresult rv;
|
||||
if (NS_IsMainThread()) {
|
||||
RunOnTargetThread();
|
||||
rv = NS_OK;
|
||||
} else {
|
||||
mozilla::MonitorAutoLock lock(monitor);
|
||||
rv = NS_DispatchToMainThread(this);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
lock.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SyncRunnableBase::Run() {
|
||||
RunOnTargetThread();
|
||||
mozilla::MonitorAutoLock(monitor).Notify();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NotifyObserverRunnable::Run() {
|
||||
mObserver->Observe(nullptr, mTopic, nullptr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace psm
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
#ifndef PSMRunnable_h
|
||||
#define PSMRunnable_h
|
||||
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace psm {
|
||||
|
||||
// Wait for the event to run on the target thread without spinning the event
|
||||
// loop on the calling thread. (Dispatching events to a thread using
|
||||
// NS_DispatchAndSpinEventLoopUntilComplete would cause the event loop on the
|
||||
// calling thread to spin.)
|
||||
class SyncRunnableBase : public Runnable {
|
||||
public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
nsresult DispatchToMainThreadAndWait();
|
||||
|
||||
protected:
|
||||
SyncRunnableBase();
|
||||
virtual void RunOnTargetThread() = 0;
|
||||
|
||||
private:
|
||||
mozilla::Monitor monitor MOZ_UNANNOTATED;
|
||||
};
|
||||
|
||||
class NotifyObserverRunnable : public Runnable {
|
||||
public:
|
||||
NotifyObserverRunnable(nsIObserver* observer, const char* topicStringLiteral)
|
||||
: Runnable("psm::NotifyObserverRunnable"),
|
||||
mObserver(new nsMainThreadPtrHolder<nsIObserver>(
|
||||
"psm::NotifyObserverRunnable::mObserver", observer)),
|
||||
mTopic(topicStringLiteral) {}
|
||||
NS_DECL_NSIRUNNABLE
|
||||
private:
|
||||
nsMainThreadPtrHandle<nsIObserver> mObserver;
|
||||
const char* const mTopic;
|
||||
};
|
||||
|
||||
} // namespace psm
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -99,7 +99,6 @@
|
|||
#include "ExtendedValidation.h"
|
||||
#include "NSSCertDBTrustDomain.h"
|
||||
#include "NSSSocketControl.h"
|
||||
#include "PSMRunnable.h"
|
||||
#include "RootCertificateTelemetryUtils.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "SharedCertVerifier.h"
|
||||
|
|
|
|||
|
|
@ -726,4 +726,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
|
|||
|
||||
static const int32_t kUnknownId = -1;
|
||||
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1782114773318000);
|
||||
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1784533762555000);
|
||||
|
|
|
|||
|
|
@ -127,7 +127,6 @@ UNIFIED_SOURCES += [
|
|||
"nsTLSSocketProvider.cpp",
|
||||
"OSKeyStore.cpp",
|
||||
"PKCS11ModuleDB.cpp",
|
||||
"PSMRunnable.cpp",
|
||||
"PublicKeyPinningService.cpp",
|
||||
"RootCertificateTelemetryUtils.cpp",
|
||||
"SecretDecoderRing.cpp",
|
||||
|
|
@ -192,7 +191,11 @@ if CONFIG["OS_ARCH"] == "WINNT":
|
|||
"ntdll",
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
# CredentialManagerSecret.cpp includes <windows.h> without WIN32_LEAN_AND_MEAN,
|
||||
# which pulls in <winsock.h> and conflicts with <winsock2.h> included by other
|
||||
# files in the same unified translation unit. Compile independently to prevent
|
||||
# that interference.
|
||||
SOURCES += [
|
||||
"CredentialManagerSecret.cpp",
|
||||
]
|
||||
# Version string comparison is generally wrong, but by the time it would
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#include "nsNSSCallbacks.h"
|
||||
|
||||
#include "NSSSocketControl.h"
|
||||
#include "PSMRunnable.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "SharedCertVerifier.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
|
|
@ -20,6 +19,7 @@
|
|||
#include "mozilla/SpinEventLoopUntil.h"
|
||||
#include "mozilla/StaticPrefs_security.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/SyncRunnable.h"
|
||||
#include "mozilla/glean/SecurityManagerSslMetrics.h"
|
||||
#include "mozilla/intl/Localization.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
|
@ -40,6 +40,7 @@
|
|||
#include "nsNetUtil.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozpkix/pkixtypes.h"
|
||||
#include "ssl.h"
|
||||
#include "sslproto.h"
|
||||
|
|
@ -546,28 +547,36 @@ static char* ShowProtectedAuthPrompt(PK11SlotInfo* slot, nsIPrompt* prompt) {
|
|||
}
|
||||
}
|
||||
|
||||
class PK11PasswordPromptRunnable : public SyncRunnableBase {
|
||||
class PK11PasswordPromptRunnable final : public nsIRunnable {
|
||||
public:
|
||||
PK11PasswordPromptRunnable(PK11SlotInfo* slot, nsIInterfaceRequestor* ir)
|
||||
: mResult(nullptr), mSlot(slot), mIR(ir) {}
|
||||
virtual ~PK11PasswordPromptRunnable() = default;
|
||||
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
char* mResult; // out
|
||||
virtual void RunOnTargetThread() override;
|
||||
|
||||
private:
|
||||
~PK11PasswordPromptRunnable() = default;
|
||||
|
||||
// Accessed only on the main thread. True if any instance of
|
||||
// PK11PasswordPromptRunnable is already running.
|
||||
static bool mRunning;
|
||||
|
||||
PK11SlotInfo* mSlot;
|
||||
nsIInterfaceRequestor* mIR;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(PK11PasswordPromptRunnable, nsIRunnable)
|
||||
|
||||
bool PK11PasswordPromptRunnable::mRunning = false;
|
||||
|
||||
void PK11PasswordPromptRunnable::RunOnTargetThread() {
|
||||
NS_IMETHODIMP
|
||||
PK11PasswordPromptRunnable::Run() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!NS_IsMainThread()) {
|
||||
return;
|
||||
return NS_ERROR_NOT_SAME_THREAD;
|
||||
}
|
||||
|
||||
// If we've reentered due to the nested event loop implicit in using
|
||||
|
|
@ -577,7 +586,7 @@ void PK11PasswordPromptRunnable::RunOnTargetThread() {
|
|||
// to fail, but this is better than littering the screen with a bunch of
|
||||
// password prompts that the user will probably just cancel anyway.
|
||||
if (mRunning) {
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
mRunning = true;
|
||||
auto setRunningToFalseOnExit = MakeScopeExit([&]() { mRunning = false; });
|
||||
|
|
@ -587,7 +596,7 @@ void PK11PasswordPromptRunnable::RunOnTargetThread() {
|
|||
if (!mIR) {
|
||||
rv = nsNSSComponent::GetNewPrompter(getter_AddRefs(prompt));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
prompt = do_GetInterface(mIR);
|
||||
|
|
@ -595,12 +604,12 @@ void PK11PasswordPromptRunnable::RunOnTargetThread() {
|
|||
}
|
||||
|
||||
if (!prompt) {
|
||||
return;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (PK11_ProtectedAuthenticationPath(mSlot)) {
|
||||
mResult = ShowProtectedAuthPrompt(mSlot, prompt);
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString promptString;
|
||||
|
|
@ -613,7 +622,7 @@ void PK11PasswordPromptRunnable::RunOnTargetThread() {
|
|||
promptString);
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsString password;
|
||||
|
|
@ -621,10 +630,11 @@ void PK11PasswordPromptRunnable::RunOnTargetThread() {
|
|||
rv = prompt->PromptPassword(nullptr, promptString.get(),
|
||||
getter_Copies(password), &userClickedOK);
|
||||
if (NS_FAILED(rv) || !userClickedOK) {
|
||||
return;
|
||||
return rv;
|
||||
}
|
||||
|
||||
mResult = ToNewUTF8String(password);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
char* PK11PasswordPrompt(PK11SlotInfo* slot, PRBool /*retry*/, void* arg) {
|
||||
|
|
@ -633,7 +643,8 @@ char* PK11PasswordPrompt(PK11SlotInfo* slot, PRBool /*retry*/, void* arg) {
|
|||
}
|
||||
RefPtr<PK11PasswordPromptRunnable> runnable(new PK11PasswordPromptRunnable(
|
||||
slot, static_cast<nsIInterfaceRequestor*>(arg)));
|
||||
runnable->DispatchToMainThreadAndWait();
|
||||
MOZ_ALWAYS_SUCCEEDS(SyncRunnable::DispatchToThread(
|
||||
GetMainThreadSerialEventTarget(), runnable));
|
||||
return runnable->mResult;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include "NSSCertDBTrustDomain.h"
|
||||
#include "NSSErrorsService.h"
|
||||
#include "NSSSocketControl.h"
|
||||
#include "PSMRunnable.h"
|
||||
#include "SSLServerCertVerification.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "TLSClientAuthCertSelection.h"
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -26,23 +26,19 @@
|
|||
|
||||
{
|
||||
"chromium_data" : {
|
||||
"cert_file_url": "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/net/http/transport_security_state_static.pins?format=TEXT",
|
||||
"json_file_url": "https://chromium.googlesource.com/chromium/src/+/refs/heads/main/net/http/transport_security_state_static_pins.json?format=TEXT",
|
||||
"cert_file_url": "https://raw.githubusercontent.com/chromium/chromium/refs/heads/main/net/http/transport_security_state_static.pins",
|
||||
"json_file_url": "https://raw.githubusercontent.com/chromium/chromium/refs/heads/main/net/http/transport_security_state_static_pins.json",
|
||||
"substitute_pinsets": {
|
||||
// Use the larger google_root_pems pinset instead of google
|
||||
"google": "google_root_pems"
|
||||
},
|
||||
"production_pinsets": [
|
||||
"google_root_pems",
|
||||
"facebook",
|
||||
"ncsccs"
|
||||
"google_root_pems"
|
||||
],
|
||||
"production_domains": [
|
||||
// Chrome's test domains.
|
||||
"pinningtest.appspot.com",
|
||||
"pinning-test.badssl.com",
|
||||
// SpiderOak
|
||||
"spideroak.com"
|
||||
"pinning-test.badssl.com"
|
||||
],
|
||||
"exclude_domains" : []
|
||||
},
|
||||
|
|
@ -85,11 +81,6 @@
|
|||
{
|
||||
"name": "google_root_pems",
|
||||
"sha256_hashes": [
|
||||
"AffirmTrust Commercial",
|
||||
"AffirmTrust Networking",
|
||||
"AffirmTrust Premium",
|
||||
"AffirmTrust Premium ECC",
|
||||
"Baltimore CyberTrust Root",
|
||||
"Comodo AAA Services root",
|
||||
"COMODO Certification Authority",
|
||||
"COMODO ECC Certification Authority",
|
||||
|
|
@ -102,10 +93,6 @@
|
|||
"DigiCert Global Root G3",
|
||||
"DigiCert High Assurance EV Root CA",
|
||||
"DigiCert Trusted Root G4",
|
||||
"Entrust Root Certification Authority",
|
||||
"Entrust Root Certification Authority - EC1",
|
||||
"Entrust Root Certification Authority - G2",
|
||||
"Entrust.net Premium 2048 Secure Server CA",
|
||||
"GlobalSign ECC Root CA - R4",
|
||||
"GlobalSign ECC Root CA - R5",
|
||||
"GlobalSign Root CA",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"version": "85.16",
|
||||
"log_list_timestamp": "2026-03-15T13:34:00Z",
|
||||
"version": "85.43",
|
||||
"log_list_timestamp": "2026-04-12T13:36:12Z",
|
||||
"operators": [
|
||||
{
|
||||
"name": "Google",
|
||||
|
|
|
|||
1
icecat/security/nss/TAG-INFO
Normal file
1
icecat/security/nss/TAG-INFO
Normal file
|
|
@ -0,0 +1 @@
|
|||
NSS_3_112_5_RTM
|
||||
|
|
@ -56,6 +56,15 @@ struct ScopedDelete {
|
|||
void operator()(SEC_PKCS12DecoderContext* dcx) {
|
||||
SEC_PKCS12DecoderFinish(dcx);
|
||||
}
|
||||
void operator()(SEC_PKCS7DecoderContext* dcx) {
|
||||
SEC_PKCS7ContentInfo* cinfo = SEC_PKCS7DecoderFinish(dcx);
|
||||
if (cinfo) {
|
||||
SEC_PKCS7DestroyContentInfo(cinfo);
|
||||
}
|
||||
}
|
||||
void operator()(SEC_PKCS7ContentInfo* cinfo) {
|
||||
SEC_PKCS7DestroyContentInfo(cinfo);
|
||||
}
|
||||
void operator()(NSSInitContext* init) { NSS_ShutdownContext(init); }
|
||||
};
|
||||
|
||||
|
|
@ -96,6 +105,8 @@ SCOPED(SECKEYPrivateKeyList);
|
|||
SCOPED(SECKEYPublicKey);
|
||||
SCOPED(SECMODModule);
|
||||
SCOPED(SEC_PKCS12DecoderContext);
|
||||
SCOPED(SEC_PKCS7DecoderContext);
|
||||
SCOPED(SEC_PKCS7ContentInfo);
|
||||
|
||||
#undef SCOPED
|
||||
|
||||
|
|
|
|||
52
icecat/security/nss/doc/rst/releases/nss_3_112_4.rst
Normal file
52
icecat/security/nss/doc/rst/releases/nss_3_112_4.rst
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
.. _mozilla_projects_nss_nss_3_112_4_release_notes:
|
||||
|
||||
NSS 3.112.4 release notes
|
||||
========================
|
||||
|
||||
`Introduction <#introduction>`__
|
||||
--------------------------------
|
||||
|
||||
.. container::
|
||||
|
||||
Network Security Services (NSS) 3.112.4 was released on *13 April 2026**.
|
||||
|
||||
`Distribution Information <#distribution_information>`__
|
||||
--------------------------------------------------------
|
||||
|
||||
.. container::
|
||||
|
||||
The HG tag is NSS_3_112_4_RTM. NSS 3.112.4 requires NSPR 4.36 or newer.
|
||||
|
||||
NSS 3.112.4 source distributions are available on ftp.mozilla.org for secure HTTPS download:
|
||||
|
||||
- Source tarballs:
|
||||
https://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/NSS_3_112_4_RTM/src/
|
||||
|
||||
Other releases are available :ref:`mozilla_projects_nss_releases`.
|
||||
|
||||
.. _changes_in_nss_3.112.4:
|
||||
|
||||
`Changes in NSS 3.112.4 <#changes_in_nss_3.112.4>`__
|
||||
------------------------------------------------------------------
|
||||
|
||||
.. container::
|
||||
|
||||
- Bug 2030135 - improve error handling in PK11_ImportPrivateKeyInfoAndReturnKey.
|
||||
- Bug 2029752 - Improving the allocation of S/MIME DecryptSymKey.
|
||||
- Bug 2029462 - store email on subject cache_entry in NSS trust domain.
|
||||
- Bug 2029425 - Heap use-after-free in cert_VerifyCertChainOld via dangling certsList[] entry on NameConstraints violation.
|
||||
- Bug 2029323 - Improve size calculations in CMS content buffering.
|
||||
- Bug 2028001 - avoid integer overflow while escaping RFC822 Names.
|
||||
- Bug 2027378 - Reject excessively large ASN.1 SEQUENCE OF in quickder.
|
||||
- Bug 2027365 - Deep copy profile data in CERT_FindSMimeProfile.
|
||||
- Bug 2027345 - Improve input validation in DSAU signature decoding.
|
||||
- Bug 2026311 - avoid integer overflow in RSA_EMSAEncodePSS.
|
||||
- Bug 2019357 - RSA_EMSAEncodePSS should validate the length of mHash.
|
||||
- Bug 2026156 - Add a maximum cert uncompressed len and tests.
|
||||
- Bug 2026089 - Clarify extension negotiation mechanism for TLS Handshakes.
|
||||
- Bug 2023209 - ensure permittedSubtrees don't match wildcards that could be outside the permitted tree.
|
||||
- Bug 2023207 - Fix integer underflow in tls13_AEAD when ciphertext is shorter than tag.
|
||||
- Bug 2019224 - Remove invalid PORT_Free().
|
||||
- Bug 1964722 - free digest objects in SEC_PKCS7DecoderFinish if they haven't already been freed.
|
||||
- Bug 1935995 - make ss->ssl3.hs.cookie an owned-copy of the cookie.
|
||||
|
||||
36
icecat/security/nss/doc/rst/releases/nss_3_112_5.rst
Normal file
36
icecat/security/nss/doc/rst/releases/nss_3_112_5.rst
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
.. _mozilla_projects_nss_nss_3_112_5_release_notes:
|
||||
|
||||
NSS 3.112.5 release notes
|
||||
=========================
|
||||
|
||||
`Introduction <#introduction>`__
|
||||
--------------------------------
|
||||
|
||||
.. container::
|
||||
|
||||
Network Security Services (NSS) 3.112.5 was released on *23 April 2026*.
|
||||
|
||||
`Distribution Information <#distribution_information>`__
|
||||
--------------------------------------------------------
|
||||
|
||||
.. container::
|
||||
|
||||
The HG tag is NSS_3_112_5_RTM. NSS 3.112.5 requires NSPR 4.38.2 or newer.
|
||||
|
||||
NSS 3.112.5 source distributions are available on ftp.mozilla.org for secure HTTPS download:
|
||||
|
||||
- Source tarballs:
|
||||
https://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/NSS_3_112_5_RTM/src/
|
||||
|
||||
Other releases are available :ref:`mozilla_projects_nss_releases`.
|
||||
|
||||
.. _changes_in_nss_3.112.5:
|
||||
|
||||
`Changes in NSS 3.112.5 <#changes_in_nss_3.112.5>`__
|
||||
------------------------------------------------------------------
|
||||
|
||||
.. container::
|
||||
|
||||
- Bug 2033783 - reject DTLS 1.3 Server Hello after HVR without capping ss->vrange.max.
|
||||
- Bug 2034185 - update to version 2.84 of builtins module.
|
||||
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
'der_getint_unittest.cc',
|
||||
'der_quickder_unittest.cc',
|
||||
'p12_import_unittest.cc',
|
||||
'p7_import_unittest.cc',
|
||||
'secasn1decode_unittest.cc',
|
||||
'<(DEPTH)/gtests/common/gtests.cc'
|
||||
],
|
||||
|
|
|
|||
|
|
@ -231,6 +231,13 @@ static const uint8_t cert_p12[] = {
|
|||
0x51, 0x04, 0x08, 0xa1, 0x52, 0xdd, 0x64, 0x46, 0xe9, 0x9e, 0x3e, 0x02,
|
||||
0x02, 0x08, 0x00};
|
||||
|
||||
unsigned char leak_p12[] = {
|
||||
0x30, 0x82, 0x20, 0x20, 0x02, 0x01, 0xff, 0x30, 0x82, 0x09, 0x20, 0x06,
|
||||
0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x50,
|
||||
0x30, 0x3f, 0x02, 0x01, 0x20, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60,
|
||||
0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x30, 0x20, 0x06, 0x09,
|
||||
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01};
|
||||
|
||||
class PK12ImportTest : public ::testing::Test {};
|
||||
|
||||
TEST_F(PK12ImportTest, ImportPK12With2P7) {
|
||||
|
|
@ -248,4 +255,20 @@ TEST_F(PK12ImportTest, ImportPK12With2P7) {
|
|||
ASSERT_EQ(SECFailure, rv);
|
||||
}
|
||||
|
||||
TEST_F(PK12ImportTest, FailsToImportButShouldNotLeak) {
|
||||
SECItem password = {siBuffer, nullptr, 0};
|
||||
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
|
||||
ScopedSEC_PKCS12DecoderContext dcx(
|
||||
SEC_PKCS12DecoderStart(&password, slot.get(), nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr));
|
||||
ASSERT_TRUE(dcx);
|
||||
SECStatus rv = SEC_PKCS12DecoderUpdate(
|
||||
dcx.get(), const_cast<uint8_t *>(leak_p12), sizeof(leak_p12));
|
||||
ASSERT_EQ(SECSuccess, rv);
|
||||
rv = SEC_PKCS12DecoderVerify(dcx.get());
|
||||
// This is not a valid PKCS12 file, so a failing return value is expected.
|
||||
// However, the implementation shouldn't leak memory as a result.
|
||||
ASSERT_EQ(SECFailure, rv);
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
||||
|
|
|
|||
60
icecat/security/nss/gtests/der_gtest/p7_import_unittest.cc
Normal file
60
icecat/security/nss/gtests/der_gtest/p7_import_unittest.cc
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- 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 "nss.h"
|
||||
#include "secpkcs7.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "nss_scoped_ptrs.h"
|
||||
|
||||
namespace nss_test {
|
||||
|
||||
// This is an invalid PKCS7 message. Among other things, it contains some
|
||||
// unknown hash OIDs. This should fail to parse, but it should be safe to try.
|
||||
static const uint8_t p7_with_unknown_hashes[] = {
|
||||
0x30, 0x4d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
|
||||
0x02, 0xa0, 0x40, 0x30, 0x3e, 0x02, 0x01, 0x20, 0x31, 0x27, 0x30, 0x0b,
|
||||
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x05, 0x30,
|
||||
0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x05,
|
||||
0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
|
||||
0x04, 0x30, 0x10, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
||||
0x07, 0x01, 0xa0, 0x03, 0x04, 0x01, 0x00};
|
||||
|
||||
// This is an invalid PKCS7 message. It contains multiple hash OIDs (that's not
|
||||
// what makes it invalid). When it fails to parse, the associated digest data
|
||||
// structures should be freed correctly.
|
||||
static const uint8_t p7_with_multiple_hashes[] = {
|
||||
0x30, 0x4d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07,
|
||||
0x02, 0xa0, 0x40, 0x30, 0x3e, 0x02, 0x01, 0x20, 0x31, 0x27, 0x30, 0x0b,
|
||||
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30,
|
||||
0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
|
||||
0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
|
||||
0x04, 0x30, 0x10, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
|
||||
0x07, 0x01, 0xa0, 0x03, 0x04, 0x01, 0x00};
|
||||
|
||||
class P7ImportTest : public ::testing::Test {};
|
||||
|
||||
TEST_F(P7ImportTest, FailSafeWithUnknownHashes) {
|
||||
ScopedSEC_PKCS7DecoderContext dcx(SEC_PKCS7DecoderStart(
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||
ASSERT_TRUE(dcx);
|
||||
SECStatus rv = SEC_PKCS7DecoderUpdate(
|
||||
dcx.get(), reinterpret_cast<const char*>(p7_with_unknown_hashes),
|
||||
sizeof(p7_with_unknown_hashes));
|
||||
ASSERT_EQ(SECFailure, rv);
|
||||
}
|
||||
|
||||
TEST_F(P7ImportTest, NoLeakWithMultipleHashes) {
|
||||
ScopedSEC_PKCS7DecoderContext dcx(SEC_PKCS7DecoderStart(
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||
ASSERT_TRUE(dcx);
|
||||
SECStatus rv = SEC_PKCS7DecoderUpdate(
|
||||
dcx.get(), reinterpret_cast<const char*>(p7_with_multiple_hashes),
|
||||
sizeof(p7_with_multiple_hashes));
|
||||
ASSERT_EQ(SECFailure, rv);
|
||||
}
|
||||
|
||||
} // namespace nss_test
|
||||
|
|
@ -2132,6 +2132,45 @@ static const NameConstraintParams NAME_CONSTRAINT_PARAMS[] =
|
|||
Result::ERROR_BAD_DER, Result::ERROR_BAD_DER
|
||||
},
|
||||
|
||||
// Wildcard SANs have subtle outcomes.
|
||||
{ ByteString(), DNSName("*.example.com"),
|
||||
GeneralSubtree(DNSName(".example.com")),
|
||||
Success,
|
||||
Result::ERROR_CERT_NOT_IN_NAME_SPACE
|
||||
},
|
||||
{ ByteString(), DNSName("*.example.com"),
|
||||
GeneralSubtree(DNSName("example.com")),
|
||||
Success,
|
||||
Result::ERROR_CERT_NOT_IN_NAME_SPACE
|
||||
},
|
||||
// A certificate with a wildcard SAN entry like `*.example.com` can't be
|
||||
// issued by a CA with a DNSName name constraint entry like `foo.example.com`
|
||||
// in either the permitted or excluded subtrees. If in the permitted subtree,
|
||||
// the certificate would be valid for `bar.example.com`, which would violate
|
||||
// the constraint. If in the excluded subtree, the certificate would be valid
|
||||
// for `foo.example.com`, which would violate the constraint.
|
||||
{ ByteString(), DNSName("*.example.com"),
|
||||
GeneralSubtree(DNSName("foo.example.com")),
|
||||
Result::ERROR_CERT_NOT_IN_NAME_SPACE,
|
||||
Result::ERROR_CERT_NOT_IN_NAME_SPACE
|
||||
},
|
||||
{ ByteString(), DNSName("*.foo.example.com"),
|
||||
GeneralSubtree(DNSName("example.com")),
|
||||
Success,
|
||||
Result::ERROR_CERT_NOT_IN_NAME_SPACE
|
||||
},
|
||||
{ ByteString(), DNSName("*.example.com"),
|
||||
GeneralSubtree(DNSName("foo.example.org")),
|
||||
Result::ERROR_CERT_NOT_IN_NAME_SPACE,
|
||||
Success
|
||||
},
|
||||
// `*invalid.example.com` is an invalid presented DNSID.
|
||||
{ ByteString(), DNSName("*invalid.example.com"),
|
||||
GeneralSubtree(DNSName("invalid.example.com")),
|
||||
Result::ERROR_BAD_DER,
|
||||
Result::ERROR_BAD_DER
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Basic IP Address constraints (non-CN-ID)
|
||||
|
||||
|
|
|
|||
|
|
@ -272,6 +272,25 @@ static SECStatus SimpleXorWithDifferentValueDecode(const SECItem* input,
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* Decode function that does NOT check input->len != outputLen (unlike
|
||||
* SimpleXorCertCompDecode). It always sets receivedOutputLen = outputLen and
|
||||
* returns SECSuccess, bypassing the actualCertLen != decodedCertLen fallback
|
||||
* so that only the explicit uncompressed_length bounds check blocks an
|
||||
* oversized allocation. */
|
||||
static int called_count = 0;
|
||||
static SECStatus PermissiveXorCertCompDecode(const SECItem* input,
|
||||
uint8_t* output, size_t outputLen,
|
||||
size_t* receivedOutputLen) {
|
||||
called_count++;
|
||||
size_t copy = PR_MIN(input->len, outputLen);
|
||||
PORT_Memcpy(output, input->data, copy);
|
||||
for (size_t i = 0; i < copy; i++) {
|
||||
output[i] ^= 0x55;
|
||||
}
|
||||
*receivedOutputLen = outputLen;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/* These tests are checking the behaviour
|
||||
* using the different compression algorithms.
|
||||
*
|
||||
|
|
@ -500,8 +519,6 @@ TEST_F(TlsConnectStreamTls13,
|
|||
|
||||
EXPECT_TRUE(SSLInt_ExtensionNegotiated(server_->ssl_fd(),
|
||||
ssl_certificate_compression_xtn));
|
||||
EXPECT_TRUE(SSLInt_ExtensionNegotiated(client_->ssl_fd(),
|
||||
ssl_certificate_compression_xtn));
|
||||
|
||||
uint16_t certCompressionAlg = filterExtension->getCertCompressionAlg();
|
||||
EXPECT_EQ(certCompressionAlg, serverPreferableAlg.id);
|
||||
|
|
@ -964,6 +981,56 @@ static SECStatus SimpleXorCertCompEncode_returns_buffer_size_0(
|
|||
* } CompressedCertificate;
|
||||
*/
|
||||
|
||||
/* Overwrites the uncompressed_length field of a CompressedCertificate message
|
||||
* with an arbitrary uint24 value, enabling precise boundary-value testing. */
|
||||
class TLSCompressedCertUncompressedLenSetter : public TlsRecordFilter {
|
||||
public:
|
||||
TLSCompressedCertUncompressedLenSetter(const std::shared_ptr<TlsAgent>& a,
|
||||
uint32_t len)
|
||||
: TlsRecordFilter(a), len_(len) {
|
||||
EnableDecryption();
|
||||
}
|
||||
|
||||
protected:
|
||||
PacketFilter::Action FilterRecord(const TlsRecordHeader& header,
|
||||
const DataBuffer& record, size_t* offset,
|
||||
DataBuffer* output) override {
|
||||
uint8_t inner_content_type;
|
||||
DataBuffer plaintext;
|
||||
uint16_t protection_epoch = 0;
|
||||
TlsRecordHeader out_header(header);
|
||||
|
||||
if (!Unprotect(header, record, &protection_epoch, &inner_content_type,
|
||||
&plaintext, &out_header)) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
uint64_t skip =
|
||||
findPointerToHandshakeType(plaintext, ssl_hs_compressed_certificate);
|
||||
if (skip >= plaintext.len() ||
|
||||
plaintext.data()[skip] != ssl_hs_compressed_certificate) {
|
||||
return KEEP;
|
||||
}
|
||||
|
||||
/* uncompressed_length is a uint24 at offset 6 from the HandshakeType byte.
|
||||
*/
|
||||
plaintext.Write(skip + 6, len_, 3);
|
||||
|
||||
DataBuffer ciphertext;
|
||||
bool ok = Protect(spec(protection_epoch), out_header, inner_content_type,
|
||||
plaintext, &ciphertext, &out_header);
|
||||
EXPECT_TRUE(ok);
|
||||
if (!ok) {
|
||||
return KEEP;
|
||||
}
|
||||
*offset = out_header.Write(output, *offset, ciphertext);
|
||||
return CHANGE;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t len_;
|
||||
};
|
||||
|
||||
TEST_F(TlsConnectStreamTls13,
|
||||
CertificateCompression_CompressionFunctionCreatesABufferOfSize0) {
|
||||
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
|
|
@ -1214,6 +1281,47 @@ TEST_F(TlsConnectStreamTls13,
|
|||
client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CERTIFICATE);
|
||||
}
|
||||
|
||||
/* Boundary test for the 100KB uncompressed_length cap.
|
||||
* At limit (100KB): passes bounds check, Certificate parser sees trailing
|
||||
* zeros and fires illegal_parameter (tls13con.c:4362) — proves the bounds
|
||||
* check did not trigger.
|
||||
* One over (100KB+1): caught by the bounds check (tls13con.c:4220) and fires
|
||||
* bad_certificate. */
|
||||
TEST_F(TlsConnectStreamTls13, CertificateCompression_UncompressedLenBoundary) {
|
||||
SSLCertificateCompressionAlgorithm t = {0xff01, "test function",
|
||||
SimpleXorCertCompEncode,
|
||||
PermissiveXorCertCompDecode};
|
||||
|
||||
auto run = [&](uint32_t len, uint8_t expected_alert, bool expect_decoded) {
|
||||
called_count = 0;
|
||||
Reset();
|
||||
EnsureTlsSetup();
|
||||
MakeTlsFilter<TLSCompressedCertUncompressedLenSetter>(server_, len);
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSLExp_SetCertificateCompressionAlgorithm(server_->ssl_fd(), t));
|
||||
EXPECT_EQ(SECSuccess,
|
||||
SSLExp_SetCertificateCompressionAlgorithm(client_->ssl_fd(), t));
|
||||
ExpectAlert(client_, expected_alert);
|
||||
StartConnect();
|
||||
client_->SetServerKeyBits(server_->server_key_bits());
|
||||
client_->Handshake();
|
||||
server_->Handshake();
|
||||
ASSERT_TRUE_WAIT((client_->state() != TlsAgent::STATE_CONNECTING), 5000);
|
||||
ASSERT_EQ(TlsAgent::STATE_ERROR, client_->state());
|
||||
client_->ExpectSendAlert(kTlsAlertCloseNotify);
|
||||
server_->ExpectReceiveAlert(kTlsAlertCloseNotify);
|
||||
client_->CheckErrorCode(SSL_ERROR_RX_MALFORMED_CERTIFICATE);
|
||||
if (expect_decoded) {
|
||||
EXPECT_EQ(called_count, 1);
|
||||
} else {
|
||||
EXPECT_EQ(0, called_count);
|
||||
}
|
||||
};
|
||||
|
||||
run(100 * 1024, kTlsAlertIllegalParameter, true);
|
||||
run(100 * 1024 + 1, kTlsAlertBadCertificate, false);
|
||||
}
|
||||
|
||||
TEST_F(TlsConnectStreamTls13,
|
||||
CertificateCompression_ReceivedCertificateTooLong) {
|
||||
EnsureTlsSetup();
|
||||
|
|
@ -1391,8 +1499,6 @@ TEST_F(TlsConnectStreamTls13, CertificateCompression_PostAuth) {
|
|||
server_->ReadBytes(50);
|
||||
|
||||
EXPECT_EQ(1U, called);
|
||||
EXPECT_TRUE(SSLInt_ExtensionNegotiated(client_->ssl_fd(),
|
||||
ssl_certificate_compression_xtn));
|
||||
|
||||
SendReceive(60);
|
||||
client_->CheckClientAuthCompleted();
|
||||
|
|
@ -1469,8 +1575,6 @@ TEST_F(TlsConnectStreamTls13,
|
|||
server_->ReadBytes(50);
|
||||
|
||||
EXPECT_EQ(1U, called);
|
||||
EXPECT_TRUE(SSLInt_ExtensionNegotiated(client_->ssl_fd(),
|
||||
ssl_certificate_compression_xtn));
|
||||
|
||||
SendReceive(60);
|
||||
client_->CheckClientAuthCompleted();
|
||||
|
|
|
|||
|
|
@ -1400,13 +1400,13 @@ appendItemToBuf(char* dest, SECItem* src, PRUint32* pRemaining)
|
|||
if (dest && src && src->data && src->len && src->data[0]) {
|
||||
PRUint32 len = src->len;
|
||||
PRUint32 i;
|
||||
PRUint32 reqLen = len + 1;
|
||||
PRUint64 reqLen = (PRUint64)len + 1;
|
||||
/* are there any embedded control characters ? */
|
||||
for (i = 0; i < len; i++) {
|
||||
if (NEEDS_HEX_ESCAPE(src->data[i]))
|
||||
reqLen += 2;
|
||||
}
|
||||
if (*pRemaining > reqLen) {
|
||||
if (*pRemaining >= reqLen) {
|
||||
for (i = 0; i < len; ++i) {
|
||||
PRUint8 c = src->data[i];
|
||||
if (NEEDS_HEX_ESCAPE(c)) {
|
||||
|
|
@ -1422,7 +1422,7 @@ appendItemToBuf(char* dest, SECItem* src, PRUint32* pRemaining)
|
|||
}
|
||||
}
|
||||
*dest++ = '\0';
|
||||
*pRemaining -= reqLen;
|
||||
*pRemaining -= (PRUint32)reqLen;
|
||||
}
|
||||
}
|
||||
return dest;
|
||||
|
|
@ -1440,7 +1440,7 @@ cert_GetCertificateEmailAddresses(CERTCertificate* cert)
|
|||
char* pBuf = NULL;
|
||||
PORTCheapArenaPool tmpArena;
|
||||
PRUint32 maxLen = 0;
|
||||
PRInt32 finalLen = 0;
|
||||
PRUint32 finalLen = 0;
|
||||
SECStatus rv;
|
||||
SECItem subAltName;
|
||||
|
||||
|
|
|
|||
|
|
@ -1045,10 +1045,15 @@ CERT_FindSMimeProfile(CERTCertificate *cert)
|
|||
nssSMIMEProfile *stanProfile;
|
||||
stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c);
|
||||
if (stanProfile) {
|
||||
rvItem =
|
||||
SECITEM_AllocItem(NULL, NULL, stanProfile->profileData->size);
|
||||
if (rvItem) {
|
||||
rvItem->data = stanProfile->profileData->data;
|
||||
if (stanProfile->profileData) {
|
||||
rvItem =
|
||||
SECITEM_AllocItem(NULL, NULL,
|
||||
stanProfile->profileData->size);
|
||||
if (rvItem) {
|
||||
PORT_Memcpy(rvItem->data,
|
||||
stanProfile->profileData->data,
|
||||
stanProfile->profileData->size);
|
||||
}
|
||||
}
|
||||
nssSMIMEProfile_Destroy(stanProfile);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -736,7 +736,7 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
|
|||
certsList = tmpCertsList;
|
||||
}
|
||||
for (i = 0; i < subjectNameListLen; i++) {
|
||||
certsList[namesCount + i] = subjectCert;
|
||||
certsList[namesCount + i] = CERT_DupCertificate(subjectCert);
|
||||
}
|
||||
namesCount += subjectNameListLen;
|
||||
namesList = cert_CombineNamesLists(namesList, subjectNameList);
|
||||
|
|
@ -993,6 +993,11 @@ loser:
|
|||
rv = SECFailure;
|
||||
done:
|
||||
if (certsList != NULL) {
|
||||
for (int i = 0; i < namesCount; i++) {
|
||||
if (certsList[i]) {
|
||||
CERT_DestroyCertificate(certsList[i]);
|
||||
}
|
||||
}
|
||||
PORT_Free(certsList);
|
||||
}
|
||||
if (issuerCert) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -46,8 +46,8 @@
|
|||
* It's recommend to switch back to 0 after having reached version 98/99.
|
||||
*/
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION_MAJOR 2
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 76
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION "2.76"
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION_MINOR 84
|
||||
#define NSS_BUILTINS_LIBRARY_VERSION "2.84"
|
||||
|
||||
/* These version numbers detail the semantic changes to the ckfw engine. */
|
||||
#define NSS_BUILTINS_HARDWARE_VERSION_MAJOR 1
|
||||
|
|
|
|||
|
|
@ -72,19 +72,18 @@ DSAU_ConvertSignedToFixedUnsigned(SECItem *dest, SECItem *src)
|
|||
unsigned char *pDst = dest->data;
|
||||
unsigned int cntSrc = src->len;
|
||||
unsigned int cntDst = dest->len;
|
||||
int zCount = cntDst - cntSrc;
|
||||
|
||||
if (zCount > 0) {
|
||||
if (cntSrc <= cntDst) {
|
||||
unsigned int zCount = cntDst - cntSrc;
|
||||
PORT_Memset(pDst, 0, zCount);
|
||||
PORT_Memcpy(pDst + zCount, pSrc, cntSrc);
|
||||
return SECSuccess;
|
||||
}
|
||||
if (zCount <= 0) {
|
||||
/* Source is longer than destination. Check for leading zeros. */
|
||||
while (zCount++ < 0) {
|
||||
if (*pSrc++ != 0)
|
||||
goto loser;
|
||||
}
|
||||
/* Source is longer than destination: extra leading bytes must be zero. */
|
||||
unsigned int extra = cntSrc - cntDst;
|
||||
while (extra--) {
|
||||
if (*pSrc++ != 0)
|
||||
goto loser;
|
||||
}
|
||||
PORT_Memcpy(pDst, pSrc, cntDst);
|
||||
return SECSuccess;
|
||||
|
|
@ -190,6 +189,12 @@ common_DecodeDerSig(const SECItem *item, unsigned int len)
|
|||
if (status != SECSuccess)
|
||||
goto loser;
|
||||
|
||||
/* A valid DER INTEGER for r or s is at most len+1 bytes (len bytes of
|
||||
** magnitude plus at most one leading zero sign byte). Reject anything
|
||||
** larger before attempting the conversion to avoid pathological inputs. */
|
||||
if (sig.r.len > len + 1 || sig.s.len > len + 1)
|
||||
goto loser;
|
||||
|
||||
/* Convert sig.r and sig.s from variable length signed integers to
|
||||
** fixed length unsigned integers.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ RSA_EMSAEncodePSS(unsigned char *em,
|
|||
unsigned int emLen,
|
||||
unsigned int emBits,
|
||||
const unsigned char *mHash,
|
||||
unsigned int mHashLen,
|
||||
HASH_HashType hashAlg,
|
||||
HASH_HashType maskHashAlg,
|
||||
const unsigned char *salt,
|
||||
|
|
|
|||
|
|
@ -200,7 +200,8 @@ RSABlinding_Blind(HASH_HashType hashAlg, PRUint8* blindedMsg, size_t blindedMsgL
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
rv = RSA_EMSAEncodePSS(encoded_msg, pkS->modulus.len, bit_len_n, msgHash, hashAlg, hashAlg, salt, saltLen);
|
||||
rv = RSA_EMSAEncodePSS(encoded_msg, pkS->modulus.len, bit_len_n, msgHash,
|
||||
sizeof(msgHash), hashAlg, hashAlg, salt, saltLen);
|
||||
|
||||
/* 2. If EMSA-PSS-ENCODE raises an error, raise the error and stop. */
|
||||
if (rv != SECSuccess) {
|
||||
|
|
|
|||
|
|
@ -1239,6 +1239,7 @@ RSA_EMSAEncodePSS(unsigned char *em,
|
|||
unsigned int emLen,
|
||||
unsigned int emBits,
|
||||
const unsigned char *mHash,
|
||||
unsigned int mHashLen,
|
||||
HASH_HashType hashAlg,
|
||||
HASH_HashType maskHashAlg,
|
||||
const unsigned char *salt,
|
||||
|
|
@ -1252,14 +1253,22 @@ RSA_EMSAEncodePSS(unsigned char *em,
|
|||
SECStatus rv;
|
||||
|
||||
hash = HASH_GetRawHashObject(hashAlg);
|
||||
dbMaskLen = emLen - hash->length - 1;
|
||||
PORT_Assert(hash);
|
||||
|
||||
if (mHashLen < hash->length) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Step 3 */
|
||||
if (emLen < hash->length + saltLen + 2) {
|
||||
if ((saltLen > emLen) ||
|
||||
(hash->length + 2 > emLen - saltLen)) {
|
||||
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
dbMaskLen = emLen - hash->length - 1;
|
||||
|
||||
/* Step 4 */
|
||||
if (salt == NULL) {
|
||||
rv = RNG_GenerateGlobalRandomBytes(&em[dbMaskLen - saltLen], saltLen);
|
||||
|
|
@ -1336,15 +1345,17 @@ emsa_pss_verify(const unsigned char *mHash,
|
|||
SECStatus rv;
|
||||
|
||||
hash = HASH_GetRawHashObject(hashAlg);
|
||||
dbMaskLen = emLen - hash->length - 1;
|
||||
|
||||
/* Step 3 + 4 */
|
||||
if ((emLen < (hash->length + saltLen + 2)) ||
|
||||
if ((saltLen > emLen) ||
|
||||
(hash->length + 2 > emLen - saltLen) ||
|
||||
(em[emLen - 1] != 0xbc)) {
|
||||
PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
dbMaskLen = emLen - hash->length - 1;
|
||||
|
||||
/* Step 6 */
|
||||
zeroBits = 8 * emLen - emBits;
|
||||
if (em[0] >> (8 - zeroBits)) {
|
||||
|
|
@ -1458,7 +1469,7 @@ RSA_SignPSS(RSAPrivateKey *key,
|
|||
emLen--;
|
||||
em++;
|
||||
}
|
||||
rv = RSA_EMSAEncodePSS(em, emLen, modulusBits - 1, input, hashAlg,
|
||||
rv = RSA_EMSAEncodePSS(em, emLen, modulusBits - 1, input, inputLen, hashAlg,
|
||||
maskHashAlg, salt, saltLength);
|
||||
if (rv != SECSuccess)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -172,6 +172,12 @@ enum class IDRole
|
|||
NameConstraint = 2,
|
||||
};
|
||||
|
||||
enum class NameConstraintsSubtrees : uint8_t
|
||||
{
|
||||
permittedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 0,
|
||||
excludedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 1
|
||||
};
|
||||
|
||||
enum class AllowWildcards { No = 0, Yes = 1 };
|
||||
|
||||
// DNSName constraints implicitly allow subdomain matching when there is no
|
||||
|
|
@ -184,16 +190,22 @@ enum class AllowDotlessSubdomainMatches { No = 0, Yes = 1 };
|
|||
bool IsValidDNSID(Input hostname, IDRole idRole,
|
||||
AllowWildcards allowWildcards);
|
||||
|
||||
// `subtreesType` is relevant only when `referenceDNSIDRole` is
|
||||
// `IDRole::NameConstraint`.
|
||||
Result MatchPresentedDNSIDWithReferenceDNSID(
|
||||
Input presentedDNSID,
|
||||
AllowWildcards allowWildcards,
|
||||
AllowDotlessSubdomainMatches allowDotlessSubdomainMatches,
|
||||
IDRole referenceDNSIDRole,
|
||||
/*optional*/ const NameConstraintsSubtrees* subtreesType,
|
||||
Input referenceDNSID,
|
||||
/*out*/ bool& matches);
|
||||
|
||||
// `subtreesType` is relevant only when `referenceDNSIDRole` is
|
||||
// `IDRole::NameConstraint`.
|
||||
Result MatchPresentedRFC822NameWithReferenceRFC822Name(
|
||||
Input presentedRFC822Name, IDRole referenceRFC822NameRole,
|
||||
/*optional*/ const NameConstraintsSubtrees* subtreesType,
|
||||
Input referenceRFC822Name, /*out*/ bool& matches);
|
||||
|
||||
} // namespace
|
||||
|
|
@ -212,7 +224,7 @@ MatchPresentedDNSIDWithReferenceDNSID(Input presentedDNSID,
|
|||
return MatchPresentedDNSIDWithReferenceDNSID(
|
||||
presentedDNSID, AllowWildcards::Yes,
|
||||
AllowDotlessSubdomainMatches::Yes, IDRole::ReferenceID,
|
||||
referenceDNSID, matches);
|
||||
nullptr, referenceDNSID, matches);
|
||||
}
|
||||
|
||||
// Verify that the given end-entity cert, which is assumed to have been already
|
||||
|
|
@ -731,7 +743,7 @@ MatchPresentedIDWithReferenceID(GeneralNameType presentedIDType,
|
|||
rv = MatchPresentedDNSIDWithReferenceDNSID(
|
||||
presentedID, AllowWildcards::Yes,
|
||||
AllowDotlessSubdomainMatches::Yes, IDRole::ReferenceID,
|
||||
referenceID, foundMatch);
|
||||
nullptr, referenceID, foundMatch);
|
||||
break;
|
||||
|
||||
case GeneralNameType::iPAddress:
|
||||
|
|
@ -741,7 +753,7 @@ MatchPresentedIDWithReferenceID(GeneralNameType presentedIDType,
|
|||
|
||||
case GeneralNameType::rfc822Name:
|
||||
rv = MatchPresentedRFC822NameWithReferenceRFC822Name(
|
||||
presentedID, IDRole::ReferenceID, referenceID, foundMatch);
|
||||
presentedID, IDRole::ReferenceID, nullptr, referenceID, foundMatch);
|
||||
break;
|
||||
|
||||
case GeneralNameType::directoryName:
|
||||
|
|
@ -767,20 +779,16 @@ MatchPresentedIDWithReferenceID(GeneralNameType presentedIDType,
|
|||
return Success;
|
||||
}
|
||||
|
||||
enum class NameConstraintsSubtrees : uint8_t
|
||||
{
|
||||
permittedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 0,
|
||||
excludedSubtrees = der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 1
|
||||
};
|
||||
|
||||
Result CheckPresentedIDConformsToNameConstraintsSubtrees(
|
||||
GeneralNameType presentedIDType,
|
||||
Input presentedID,
|
||||
Reader& nameConstraints,
|
||||
NameConstraintsSubtrees subtreesType);
|
||||
|
||||
Result MatchPresentedIPAddressWithConstraint(Input presentedID,
|
||||
Input iPAddressConstraint,
|
||||
/*out*/ bool& foundMatch);
|
||||
|
||||
Result MatchPresentedDirectoryNameWithConstraint(
|
||||
NameConstraintsSubtrees subtreesType, Input presentedID,
|
||||
Input directoryNameConstraint, /*out*/ bool& matches);
|
||||
|
|
@ -886,7 +894,7 @@ CheckPresentedIDConformsToNameConstraintsSubtrees(
|
|||
rv = MatchPresentedDNSIDWithReferenceDNSID(
|
||||
presentedID, AllowWildcards::Yes,
|
||||
AllowDotlessSubdomainMatches::Yes, IDRole::NameConstraint,
|
||||
base, matches);
|
||||
&subtreesType, base, matches);
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -911,7 +919,7 @@ CheckPresentedIDConformsToNameConstraintsSubtrees(
|
|||
|
||||
case GeneralNameType::rfc822Name:
|
||||
rv = MatchPresentedRFC822NameWithReferenceRFC822Name(
|
||||
presentedID, IDRole::NameConstraint, base, matches);
|
||||
presentedID, IDRole::NameConstraint, &subtreesType, base, matches);
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -1094,6 +1102,7 @@ MatchPresentedDNSIDWithReferenceDNSID(
|
|||
AllowWildcards allowWildcards,
|
||||
AllowDotlessSubdomainMatches allowDotlessSubdomainMatches,
|
||||
IDRole referenceDNSIDRole,
|
||||
/*optional*/ const NameConstraintsSubtrees* subtreesType,
|
||||
Input referenceDNSID,
|
||||
/*out*/ bool& matches)
|
||||
{
|
||||
|
|
@ -1184,18 +1193,28 @@ MatchPresentedDNSIDWithReferenceDNSID(
|
|||
return NotReached("Skipping '*' failed",
|
||||
Result::FATAL_ERROR_LIBRARY_FAILURE);
|
||||
}
|
||||
do {
|
||||
// This will happen if reference is a single, relative label
|
||||
if (reference.AtEnd()) {
|
||||
matches = false;
|
||||
return Success;
|
||||
}
|
||||
uint8_t referenceByte;
|
||||
if (reference.Read(referenceByte) != Success) {
|
||||
return NotReached("invalid reference ID",
|
||||
Result::FATAL_ERROR_INVALID_ARGS);
|
||||
}
|
||||
} while (!reference.Peek('.'));
|
||||
// For the permittedSubtrees of a name constraint, wildcard presented
|
||||
// DNSIDs of the form `*.example.com` only match if the name constraint is
|
||||
// of the form `.example.com` or `example.com`. To put it another way, a
|
||||
// permittedSubtrees of `foo.example.com` does not match a wildcard
|
||||
// presented DNSID of `*.example.com`, because in that case, the
|
||||
// certificate could be valid for `bar.example.com`, which does not match
|
||||
// the name constraint.
|
||||
if (referenceDNSIDRole != IDRole::NameConstraint ||
|
||||
(subtreesType && *subtreesType != NameConstraintsSubtrees::permittedSubtrees)) {
|
||||
do {
|
||||
// This will happen if reference is a single, relative label
|
||||
if (reference.AtEnd()) {
|
||||
matches = false;
|
||||
return Success;
|
||||
}
|
||||
uint8_t referenceByte;
|
||||
if (reference.Read(referenceByte) != Success) {
|
||||
return NotReached("invalid reference ID",
|
||||
Result::FATAL_ERROR_INVALID_ARGS);
|
||||
}
|
||||
} while (!reference.Peek('.'));
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
|
|
@ -1552,11 +1571,13 @@ IsValidRFC822Name(Input input)
|
|||
}
|
||||
}
|
||||
|
||||
// `subtreesType` is relevant only when `referenceRFC822NameRole` is
|
||||
// `IDRole::NameConstraint`.
|
||||
Result
|
||||
MatchPresentedRFC822NameWithReferenceRFC822Name(Input presentedRFC822Name,
|
||||
IDRole referenceRFC822NameRole,
|
||||
Input referenceRFC822Name,
|
||||
/*out*/ bool& matches)
|
||||
MatchPresentedRFC822NameWithReferenceRFC822Name(
|
||||
Input presentedRFC822Name, IDRole referenceRFC822NameRole,
|
||||
/*optional*/ const NameConstraintsSubtrees* subtreesType,
|
||||
Input referenceRFC822Name, /*out*/ bool& matches)
|
||||
{
|
||||
if (!IsValidRFC822Name(presentedRFC822Name)) {
|
||||
return Result::ERROR_BAD_DER;
|
||||
|
|
@ -1599,6 +1620,7 @@ MatchPresentedRFC822NameWithReferenceRFC822Name(Input presentedRFC822Name,
|
|||
return MatchPresentedDNSIDWithReferenceDNSID(
|
||||
presentedDNSID, AllowWildcards::No,
|
||||
AllowDotlessSubdomainMatches::No, IDRole::NameConstraint,
|
||||
subtreesType,
|
||||
referenceRFC822Name, matches);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@
|
|||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
|
||||
*/
|
||||
#define NSS_VERSION "3.112.3" _NSS_CUSTOMIZED
|
||||
#define NSS_VERSION "3.112.5" _NSS_CUSTOMIZED
|
||||
#define NSS_VMAJOR 3
|
||||
#define NSS_VMINOR 112
|
||||
#define NSS_VPATCH 3
|
||||
#define NSS_VPATCH 5
|
||||
#define NSS_VBUILD 0
|
||||
#define NSS_BETA PR_FALSE
|
||||
|
||||
|
|
|
|||
|
|
@ -733,12 +733,15 @@ PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
|
|||
|
||||
rv = PK11_ImportAndReturnPrivateKey(slot, lpk, nickname, publicValue, isPerm,
|
||||
isPrivate, keyUsage, privk, wincx);
|
||||
loser:
|
||||
if (arena != NULL) {
|
||||
PORT_FreeArena(arena, PR_TRUE);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
PORT_FreeArena(arena, PR_TRUE);
|
||||
return SECSuccess;
|
||||
|
||||
return rv;
|
||||
loser:
|
||||
PORT_FreeArena(arena, PR_TRUE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
|
|
|
|||
|
|
@ -230,6 +230,8 @@ sec_pkcs7_decoder_start_digests(SEC_PKCS7DecoderContext *p7dcx, int depth,
|
|||
{
|
||||
int i, digcnt;
|
||||
|
||||
p7dcx->worker.digcnt = 0;
|
||||
|
||||
if (digestalgs == NULL)
|
||||
return SECSuccess;
|
||||
|
||||
|
|
@ -257,7 +259,6 @@ sec_pkcs7_decoder_start_digests(SEC_PKCS7DecoderContext *p7dcx, int depth,
|
|||
}
|
||||
|
||||
p7dcx->worker.depth = depth;
|
||||
p7dcx->worker.digcnt = 0;
|
||||
|
||||
/*
|
||||
* Create a digest context for each algorithm.
|
||||
|
|
@ -277,7 +278,6 @@ sec_pkcs7_decoder_start_digests(SEC_PKCS7DecoderContext *p7dcx, int depth,
|
|||
* but we cannot know that until later.
|
||||
*/
|
||||
if (digobj == NULL) {
|
||||
p7dcx->worker.digcnt--;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -306,25 +306,19 @@ sec_pkcs7_decoder_finish_digests(SEC_PKCS7DecoderContext *p7dcx,
|
|||
PLArenaPool *poolp,
|
||||
SECItem ***digestsp)
|
||||
{
|
||||
struct sec_pkcs7_decoder_worker *worker;
|
||||
const SECHashObject *digobj;
|
||||
void *digcx;
|
||||
SECItem **digests, *digest;
|
||||
int i;
|
||||
void *mark;
|
||||
|
||||
/*
|
||||
* XXX Handling nested contents would mean that there is a chain
|
||||
* of workers -- one per each level of content. The following
|
||||
* would want to find the last worker in the chain.
|
||||
*/
|
||||
worker = &(p7dcx->worker);
|
||||
struct sec_pkcs7_decoder_worker *worker = &(p7dcx->worker);
|
||||
|
||||
/*
|
||||
* If no digests, then we have nothing to do.
|
||||
*/
|
||||
if (worker->digcnt == 0)
|
||||
if (worker->digcnt == 0) {
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
* No matter what happens after this, we want to stop filtering.
|
||||
|
|
@ -340,46 +334,46 @@ sec_pkcs7_decoder_finish_digests(SEC_PKCS7DecoderContext *p7dcx,
|
|||
* was digested.
|
||||
*/
|
||||
if (!worker->saw_contents) {
|
||||
for (i = 0; i < worker->digcnt; i++) {
|
||||
digcx = worker->digcxs[i];
|
||||
digobj = worker->digobjs[i];
|
||||
for (int i = 0; i < worker->digcnt; i++) {
|
||||
void *digcx = worker->digcxs[i];
|
||||
const SECHashObject *digobj = worker->digobjs[i];
|
||||
(*digobj->destroy)(digcx, PR_TRUE);
|
||||
}
|
||||
worker->digcnt = 0;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
mark = PORT_ArenaMark(poolp);
|
||||
void *mark = PORT_ArenaMark(poolp);
|
||||
|
||||
/*
|
||||
* Close out each digest context, saving digest away.
|
||||
*/
|
||||
digests =
|
||||
(SECItem **)PORT_ArenaAlloc(poolp, (worker->digcnt + 1) * sizeof(SECItem *));
|
||||
digest = (SECItem *)PORT_ArenaAlloc(poolp, worker->digcnt * sizeof(SECItem));
|
||||
if (digests == NULL || digest == NULL) {
|
||||
SECItem **digests =
|
||||
(SECItem **)PORT_ArenaZAlloc(poolp, (worker->digcnt + 1) * sizeof(SECItem *));
|
||||
if (digests == NULL) {
|
||||
p7dcx->error = PORT_GetError();
|
||||
PORT_ArenaRelease(poolp, mark);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
for (i = 0; i < worker->digcnt; i++, digest++) {
|
||||
digcx = worker->digcxs[i];
|
||||
digobj = worker->digobjs[i];
|
||||
|
||||
digest->data = (unsigned char *)PORT_ArenaAlloc(poolp, digobj->length);
|
||||
if (digest->data == NULL) {
|
||||
for (int i = 0; i < worker->digcnt; i++) {
|
||||
const SECHashObject *digobj = worker->digobjs[i];
|
||||
digests[i] = SECITEM_AllocItem(poolp, NULL, digobj->length);
|
||||
if (!digests[i]) {
|
||||
p7dcx->error = PORT_GetError();
|
||||
PORT_ArenaRelease(poolp, mark);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
digest->len = digobj->length;
|
||||
(*digobj->end)(digcx, digest->data, &(digest->len), digest->len);
|
||||
(*digobj->destroy)(digcx, PR_TRUE);
|
||||
|
||||
digests[i] = digest;
|
||||
}
|
||||
digests[i] = NULL;
|
||||
|
||||
for (int i = 0; i < worker->digcnt; i++) {
|
||||
void *digcx = worker->digcxs[i];
|
||||
const SECHashObject *digobj = worker->digobjs[i];
|
||||
|
||||
(*digobj->end)(digcx, digests[i]->data, &(digests[i]->len), digests[i]->len);
|
||||
(*digobj->destroy)(digcx, PR_TRUE);
|
||||
}
|
||||
worker->digcnt = 0;
|
||||
*digestsp = digests;
|
||||
|
||||
PORT_ArenaUnmark(poolp, mark);
|
||||
|
|
@ -1084,6 +1078,13 @@ SEC_PKCS7DecoderFinish(SEC_PKCS7DecoderContext *p7dcx)
|
|||
if (p7dcx->worker.decryptobj) {
|
||||
sec_PKCS7DestroyDecryptObject(p7dcx->worker.decryptobj);
|
||||
}
|
||||
for (int i = 0; i < p7dcx->worker.digcnt; i++) {
|
||||
void *digcx = p7dcx->worker.digcxs[i];
|
||||
const SECHashObject *digobj = p7dcx->worker.digobjs[i];
|
||||
(*digobj->destroy)(digcx, PR_TRUE);
|
||||
}
|
||||
p7dcx->worker.digcnt = 0;
|
||||
|
||||
PORT_FreeArena(p7dcx->tmp_poolp, PR_FALSE);
|
||||
PORT_Free(p7dcx);
|
||||
return cinfo;
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ struct cache_entry_str {
|
|||
PRTime lastHit;
|
||||
NSSArena *arena;
|
||||
NSSUTF8 *nickname;
|
||||
NSSASCII7 *email;
|
||||
};
|
||||
|
||||
typedef struct cache_entry_str cache_entry;
|
||||
|
|
@ -229,6 +230,7 @@ remove_subject_entry(
|
|||
NSSCertificate *cert,
|
||||
nssList **subjectList,
|
||||
NSSUTF8 **nickname,
|
||||
NSSASCII7 **email,
|
||||
NSSArena **arena)
|
||||
{
|
||||
PRStatus nssrv;
|
||||
|
|
@ -242,6 +244,7 @@ remove_subject_entry(
|
|||
nssList_Remove(ce->entry.list, cert);
|
||||
*subjectList = ce->entry.list;
|
||||
*nickname = ce->nickname;
|
||||
*email = ce->email;
|
||||
*arena = ce->arena;
|
||||
nssrv = PR_SUCCESS;
|
||||
#ifdef DEBUG_CACHE
|
||||
|
|
@ -276,35 +279,34 @@ remove_nickname_entry(
|
|||
static PRStatus
|
||||
remove_email_entry(
|
||||
nssTDCertificateCache *cache,
|
||||
NSSCertificate *cert,
|
||||
NSSASCII7 *email,
|
||||
nssList *subjectList)
|
||||
{
|
||||
PRStatus nssrv = PR_FAILURE;
|
||||
cache_entry *ce;
|
||||
/* Find the subject list in the email hash */
|
||||
if (cert->email) {
|
||||
ce = (cache_entry *)nssHash_Lookup(cache->email, cert->email);
|
||||
if (email) {
|
||||
ce = (cache_entry *)nssHash_Lookup(cache->email, email);
|
||||
if (ce) {
|
||||
nssList *subjects = ce->entry.list;
|
||||
/* Remove the subject list from the email hash */
|
||||
if (subjects) {
|
||||
nssList_Remove(subjects, subjectList);
|
||||
#ifdef DEBUG_CACHE
|
||||
log_item_dump("removed subject list", &cert->subject);
|
||||
PR_LOG(s_log, PR_LOG_DEBUG, ("for email %s", cert->email));
|
||||
PR_LOG(s_log, PR_LOG_DEBUG,
|
||||
("removed subject list for email %s", email));
|
||||
#endif
|
||||
if (nssList_Count(subjects) == 0) {
|
||||
/* No more subject lists for email, delete list and
|
||||
* remove hash entry
|
||||
*/
|
||||
(void)nssList_Destroy(subjects);
|
||||
nssHash_Remove(cache->email, cert->email);
|
||||
nssHash_Remove(cache->email, email);
|
||||
/* there are no entries left for this address, free space
|
||||
* used for email entries
|
||||
*/
|
||||
nssArena_Destroy(ce->arena);
|
||||
#ifdef DEBUG_CACHE
|
||||
PR_LOG(s_log, PR_LOG_DEBUG, ("removed email %s", cert->email));
|
||||
PR_LOG(s_log, PR_LOG_DEBUG, ("removed email %s", email));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -323,6 +325,7 @@ nssTrustDomain_RemoveCertFromCacheLOCKED(
|
|||
cache_entry *ce;
|
||||
NSSArena *arena;
|
||||
NSSUTF8 *nickname = NULL;
|
||||
NSSASCII7 *email = NULL;
|
||||
|
||||
#ifdef DEBUG_CACHE
|
||||
log_cert_ref("attempt to remove cert", cert);
|
||||
|
|
@ -339,10 +342,10 @@ nssTrustDomain_RemoveCertFromCacheLOCKED(
|
|||
}
|
||||
(void)remove_issuer_and_serial_entry(td->cache, cert);
|
||||
(void)remove_subject_entry(td->cache, cert, &subjectList,
|
||||
&nickname, &arena);
|
||||
&nickname, &email, &arena);
|
||||
if (nssList_Count(subjectList) == 0) {
|
||||
(void)remove_nickname_entry(td->cache, nickname, subjectList);
|
||||
(void)remove_email_entry(td->cache, cert, subjectList);
|
||||
(void)remove_email_entry(td->cache, email, subjectList);
|
||||
(void)nssList_Destroy(subjectList);
|
||||
nssHash_Remove(td->cache->subject, &cert->subject);
|
||||
/* there are no entries left for this subject, free the space used
|
||||
|
|
@ -537,6 +540,9 @@ add_subject_entry(
|
|||
if (nickname) {
|
||||
ce->nickname = nssUTF8_Duplicate(nickname, arena);
|
||||
}
|
||||
if (cert->email) {
|
||||
ce->email = nssUTF8_Duplicate(cert->email, arena);
|
||||
}
|
||||
nssList_SetSortFunction(list, nssCertificate_SubjectListSort);
|
||||
/* Add the cert entry to this list of subjects */
|
||||
nssrv = nssList_AddUnique(list, cert);
|
||||
|
|
@ -710,6 +716,7 @@ add_cert_to_cache(
|
|||
PRUint32 added = 0;
|
||||
cache_entry *ce;
|
||||
NSSCertificate *rvCert = NULL;
|
||||
NSSASCII7 *email = NULL;
|
||||
NSSUTF8 *certNickname = nssCertificate_GetNickname(cert, NULL);
|
||||
|
||||
/* Set cc->trust and cc->nssCertificate before taking td->cache->lock.
|
||||
|
|
@ -817,13 +824,13 @@ loser:
|
|||
}
|
||||
if (added >= 2) {
|
||||
(void)remove_subject_entry(td->cache, cert, &subjectList,
|
||||
&certNickname, &arena);
|
||||
&certNickname, &email, &arena);
|
||||
}
|
||||
if (added == 3 || added == 5) {
|
||||
(void)remove_nickname_entry(td->cache, certNickname, subjectList);
|
||||
}
|
||||
if (added >= 4) {
|
||||
(void)remove_email_entry(td->cache, cert, subjectList);
|
||||
(void)remove_email_entry(td->cache, email, subjectList);
|
||||
}
|
||||
if (subjectList) {
|
||||
nssHash_Remove(td->cache->subject, &cert->subject);
|
||||
|
|
|
|||
|
|
@ -322,7 +322,6 @@ nss_cms_before_data(NSSCMSDecoderContext *p7dcx)
|
|||
loser:
|
||||
if (mark)
|
||||
PORT_ArenaRelease(poolp, mark);
|
||||
PORT_Free(childp7dcx);
|
||||
p7dcx->childp7dcx = NULL;
|
||||
return SECFailure;
|
||||
}
|
||||
|
|
@ -555,8 +554,19 @@ nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx,
|
|||
SECItem *dataItem = &decoderData->data;
|
||||
|
||||
offset = dataItem->len;
|
||||
/* Reject if accumulated size would exceed unsigned int storage. */
|
||||
if (len > (unsigned long)(PR_UINT32_MAX - dataItem->len)) {
|
||||
p7dcx->error = SEC_ERROR_INPUT_LEN;
|
||||
goto loser;
|
||||
}
|
||||
if (dataItem->len + len > decoderData->totalBufferSize) {
|
||||
int needLen = (dataItem->len + len) * 2;
|
||||
/* Use size_t to avoid truncating the 64-bit sum to int.
|
||||
* Double to amortize repeated reallocations across chunks. */
|
||||
size_t needLen = (size_t)dataItem->len + len;
|
||||
/* Only double if the result still fits in unsigned int. */
|
||||
if (needLen <= PR_UINT32_MAX / 2) {
|
||||
needLen *= 2;
|
||||
}
|
||||
dest = (unsigned char *)
|
||||
PORT_ArenaAlloc(p7dcx->cmsg->poolp, needLen);
|
||||
if (dest == NULL) {
|
||||
|
|
@ -567,7 +577,7 @@ nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx,
|
|||
if (dataItem->len) {
|
||||
PORT_Memcpy(dest, dataItem->data, dataItem->len);
|
||||
}
|
||||
decoderData->totalBufferSize = needLen;
|
||||
decoderData->totalBufferSize = (unsigned int)needLen;
|
||||
dataItem->data = dest;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -566,6 +566,7 @@ NSS_CMSUtil_DecryptSymKey_ECDH(SECKEYPrivateKey *privkey, SECItem *encKey,
|
|||
SECStatus rv;
|
||||
|
||||
PORT_Memset(&keyWrapAlg, 0, sizeof(SECAlgorithmID));
|
||||
PORT_Memset(&originatorpublickey, 0, sizeof(SECKEYPublicKey));
|
||||
|
||||
PORT_Assert(bulkalgtag != SEC_OID_UNKNOWN);
|
||||
target = PK11_AlgtagToMechanism(bulkalgtag);
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@
|
|||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
|
||||
*/
|
||||
#define SOFTOKEN_VERSION "3.112.3" SOFTOKEN_ECC_STRING
|
||||
#define SOFTOKEN_VERSION "3.112.5" SOFTOKEN_ECC_STRING
|
||||
#define SOFTOKEN_VMAJOR 3
|
||||
#define SOFTOKEN_VMINOR 112
|
||||
#define SOFTOKEN_VPATCH 3
|
||||
#define SOFTOKEN_VPATCH 5
|
||||
#define SOFTOKEN_VBUILD 0
|
||||
#define SOFTOKEN_BETA PR_FALSE
|
||||
|
||||
|
|
|
|||
|
|
@ -1101,7 +1101,7 @@ dtls_HandleHelloVerifyRequest(sslSocket *ss, PRUint8 *b, PRUint32 length)
|
|||
{
|
||||
int errCode = SSL_ERROR_RX_MALFORMED_HELLO_VERIFY_REQUEST;
|
||||
SECStatus rv;
|
||||
SSL3ProtocolVersion temp;
|
||||
SSL3ProtocolVersion version;
|
||||
SSL3AlertDescription desc = illegal_parameter;
|
||||
|
||||
SSL_TRC(3, ("%d: SSL3[%d]: handle hello_verify_request handshake",
|
||||
|
|
@ -1130,22 +1130,29 @@ dtls_HandleHelloVerifyRequest(sslSocket *ss, PRUint8 *b, PRUint32 length)
|
|||
* Therefore we do not do anything to enforce a match, just
|
||||
* read and check that this value is sane.
|
||||
*/
|
||||
rv = ssl_ClientReadVersion(ss, &b, &length, &temp);
|
||||
rv = ssl_ClientReadVersion(ss, &b, &length, &version);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser; /* alert has been sent */
|
||||
}
|
||||
|
||||
/* Read the cookie.
|
||||
* IMPORTANT: The value of ss->ssl3.hs.cookie is only valid while the
|
||||
* HelloVerifyRequest message remains valid. */
|
||||
rv = ssl3_ConsumeHandshakeVariable(ss, &ss->ssl3.hs.cookie, 1, &b, &length);
|
||||
/* Read the cookie. */
|
||||
SECItem cookie;
|
||||
rv = ssl3_ConsumeHandshakeVariable(ss, &cookie, 1, &b, &length);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser; /* alert has been sent */
|
||||
}
|
||||
if (ss->ssl3.hs.cookie.len > DTLS_COOKIE_BYTES) {
|
||||
if (cookie.len > DTLS_COOKIE_BYTES) {
|
||||
desc = decode_error;
|
||||
goto alert_loser; /* malformed. */
|
||||
}
|
||||
PORT_Assert(!ss->ssl3.hs.cookie.data && !ss->ssl3.hs.cookie.len);
|
||||
SECITEM_FreeItem(&ss->ssl3.hs.cookie, PR_FALSE);
|
||||
rv = SECITEM_CopyItem(NULL, &ss->ssl3.hs.cookie, &cookie);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
ss->ssl3.hs.dtlsReceivedHVR = PR_TRUE;
|
||||
|
||||
ssl_GetXmitBufLock(ss); /*******************************/
|
||||
|
||||
|
|
@ -1154,6 +1161,8 @@ dtls_HandleHelloVerifyRequest(sslSocket *ss, PRUint8 *b, PRUint32 length)
|
|||
|
||||
ssl_ReleaseXmitBufLock(ss); /*******************************/
|
||||
|
||||
SECITEM_FreeItem(&ss->ssl3.hs.cookie, PR_FALSE);
|
||||
|
||||
if (rv == SECSuccess)
|
||||
return rv;
|
||||
|
||||
|
|
|
|||
|
|
@ -7201,6 +7201,15 @@ ssl3_HandleServerHello(sslSocket *ss, PRUint8 *b, PRUint32 length)
|
|||
goto alert_loser;
|
||||
}
|
||||
|
||||
/* A server that sent HelloVerifyRequest is DTLS 1.2 or earlier;
|
||||
* reject a subsequent TLS 1.3 ServerHello as illegal. */
|
||||
if (ss->ssl3.hs.dtlsReceivedHVR &&
|
||||
ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
desc = illegal_parameter;
|
||||
errCode = SSL_ERROR_RX_MALFORMED_SERVER_HELLO;
|
||||
goto alert_loser;
|
||||
}
|
||||
|
||||
/* There are three situations in which the server must pick
|
||||
* TLS 1.3.
|
||||
*
|
||||
|
|
@ -13917,6 +13926,8 @@ ssl3_InitState(sslSocket *ss)
|
|||
sizeof(ss->ssl3.hs.newSessionTicket));
|
||||
|
||||
ss->ssl3.hs.zeroRttState = ssl_0rtt_none;
|
||||
|
||||
ss->ssl3.hs.dtlsReceivedHVR = PR_FALSE;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
|
@ -14266,6 +14277,7 @@ ssl3_DestroySSL3Info(sslSocket *ss)
|
|||
SECITEM_FreeItem(&ss->ssl3.hs.newSessionTicket.ticket, PR_FALSE);
|
||||
SECITEM_FreeItem(&ss->ssl3.hs.srvVirtName, PR_FALSE);
|
||||
SECITEM_FreeItem(&ss->ssl3.hs.fakeSid, PR_FALSE);
|
||||
SECITEM_FreeItem(&ss->ssl3.hs.cookie, PR_FALSE);
|
||||
|
||||
/* Destroy the DTLS data */
|
||||
if (IS_DTLS(ss)) {
|
||||
|
|
|
|||
|
|
@ -336,6 +336,26 @@ ssl3_ExtensionAdvertised(const sslSocket *ss, PRUint16 ex_type)
|
|||
xtnData->numAdvertised, ex_type);
|
||||
}
|
||||
|
||||
void
|
||||
ssl3_RecordExtensionNegotiated(const sslSocket *ss, TLSExtensionData *xtnData,
|
||||
PRUint16 ex_type)
|
||||
{
|
||||
/* Record that an extension was negotiated during a full TLS handshake.
|
||||
* This function must NOT be used to track extensions carried in
|
||||
* post-handshake messages (e.g. CertificateRequest during PHA);
|
||||
* their negotiation state should instead be stored in dedicated fields on
|
||||
* TLSExtensionData or sslSocket (e.g. xtnData->compressionAlg for
|
||||
* certificate compression). */
|
||||
PORT_Assert(!ss->firstHsDone ||
|
||||
ss->opt.enableRenegotiation != SSL_RENEGOTIATE_NEVER);
|
||||
PORT_Assert(!arrayContainsExtension(xtnData->negotiated,
|
||||
xtnData->numNegotiated, ex_type));
|
||||
PORT_Assert(xtnData->numNegotiated < SSL_MAX_EXTENSIONS);
|
||||
if (xtnData->numNegotiated < SSL_MAX_EXTENSIONS) {
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ex_type;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
ssl3_ExtensionAdvertisedClientHelloInner(const sslSocket *ss, PRUint16 ex_type)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -175,6 +175,9 @@ void ssl3_ResetExtensionData(TLSExtensionData *xtnData, const sslSocket *ss);
|
|||
|
||||
PRBool ssl3_ExtensionNegotiated(const sslSocket *ss, PRUint16 ex_type);
|
||||
PRBool ssl3_ExtensionAdvertised(const sslSocket *ss, PRUint16 ex_type);
|
||||
void ssl3_RecordExtensionNegotiated(const sslSocket *ss,
|
||||
TLSExtensionData *xtnData,
|
||||
PRUint16 ex_type);
|
||||
|
||||
SECStatus ssl3_RegisterExtensionSender(const sslSocket *ss,
|
||||
TLSExtensionData *xtnData,
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ ssl3_HandleServerNameXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
ssl3_FreeSniNameArray(xtnData);
|
||||
xtnData->sniNameArr = names;
|
||||
xtnData->sniNameArrSize = 1;
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_server_name_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_server_name_xtn);
|
||||
}
|
||||
return SECSuccess;
|
||||
|
||||
|
|
@ -345,7 +345,7 @@ ssl3_SelectAppProtocol(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
}
|
||||
|
||||
xtnData->nextProtoState = SSL_NEXT_PROTO_NEGOTIATED;
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = extension;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, extension);
|
||||
return SECITEM_CopyItem(NULL, &xtnData->nextProto, &result);
|
||||
}
|
||||
|
||||
|
|
@ -447,7 +447,7 @@ ssl3_ClientHandleAppProtoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
|
||||
SECITEM_FreeItem(&xtnData->nextProto, PR_FALSE);
|
||||
xtnData->nextProtoState = SSL_NEXT_PROTO_SELECTED;
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_app_layer_protocol_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_app_layer_protocol_xtn);
|
||||
return SECITEM_CopyItem(NULL, &xtnData->nextProto, &protocol_name);
|
||||
}
|
||||
|
||||
|
|
@ -528,7 +528,7 @@ ssl3_ServerHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData
|
|||
PORT_Assert(ss->sec.isServer);
|
||||
|
||||
/* remember that we got this extension. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_cert_status_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_cert_status_xtn);
|
||||
|
||||
if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) {
|
||||
sender = tls13_ServerSendStatusRequestXtn;
|
||||
|
|
@ -606,7 +606,7 @@ ssl3_ClientHandleStatusRequestXtn(const sslSocket *ss, TLSExtensionData *xtnData
|
|||
}
|
||||
|
||||
/* Keep track of negotiated extensions. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_cert_status_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_cert_status_xtn);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
|
@ -859,7 +859,7 @@ ssl3_ClientHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData
|
|||
}
|
||||
|
||||
/* Keep track of negotiated extensions. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_session_ticket_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_session_ticket_xtn);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
|
@ -1309,7 +1309,7 @@ ssl3_ServerHandleSessionTicketXtn(const sslSocket *ss, TLSExtensionData *xtnData
|
|||
}
|
||||
|
||||
/* Keep track of negotiated extensions. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_session_ticket_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_session_ticket_xtn);
|
||||
|
||||
/* Parse the received ticket sent in by the client. We are
|
||||
* lenient about some parse errors, falling back to a fullshake
|
||||
|
|
@ -1387,7 +1387,7 @@ ssl3_HandleRenegotiationInfoXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
/* remember that we got this extension and it was correct. */
|
||||
CONST_CAST(sslSocket, ss)
|
||||
->peerRequestedProtection = 1;
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_renegotiation_info_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_renegotiation_info_xtn);
|
||||
if (ss->sec.isServer) {
|
||||
/* prepare to send back the appropriate response */
|
||||
rv = ssl3_RegisterExtensionSender(ss, xtnData,
|
||||
|
|
@ -1522,7 +1522,7 @@ ssl3_ClientHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
}
|
||||
|
||||
/* OK, this looks fine. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_use_srtp_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_use_srtp_xtn);
|
||||
xtnData->dtlsSRTPCipherSuite = cipher;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
@ -1593,7 +1593,7 @@ ssl3_ServerHandleUseSRTPXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
|
||||
/* OK, we have a valid cipher and we've selected it */
|
||||
xtnData->dtlsSRTPCipherSuite = cipher;
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_use_srtp_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_use_srtp_xtn);
|
||||
|
||||
return ssl3_RegisterExtensionSender(ss, xtnData,
|
||||
ssl_use_srtp_xtn,
|
||||
|
|
@ -1639,8 +1639,12 @@ ssl3_HandleSigAlgsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Keep track of negotiated extensions. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_signature_algorithms_xtn;
|
||||
/* Keep track of negotiated extensions. Only the server consumes this
|
||||
* entry; on the client, skipping prevents numNegotiated overflow
|
||||
* during repeated post-handshake CertificateRequests. */
|
||||
if (ss->sec.isServer) {
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_signature_algorithms_xtn);
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
|
@ -1711,7 +1715,7 @@ ssl3_HandleExtendedMasterSecretXtn(const sslSocket *ss, TLSExtensionData *xtnDat
|
|||
SSL_GETPID(), ss->fd));
|
||||
|
||||
/* Keep track of negotiated extensions. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_extended_master_secret_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_extended_master_secret_xtn);
|
||||
|
||||
if (ss->sec.isServer) {
|
||||
return ssl3_RegisterExtensionSender(ss, xtnData,
|
||||
|
|
@ -1758,7 +1762,7 @@ ssl3_ClientHandleSignedCertTimestampXtn(const sslSocket *ss, TLSExtensionData *x
|
|||
}
|
||||
*scts = *data;
|
||||
/* Keep track of negotiated extensions. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_signed_cert_timestamp_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_signed_cert_timestamp_xtn);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
|
@ -1794,7 +1798,7 @@ ssl3_ServerHandleSignedCertTimestampXtn(const sslSocket *ss,
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_signed_cert_timestamp_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_signed_cert_timestamp_xtn);
|
||||
PORT_Assert(ss->sec.isServer);
|
||||
return ssl3_RegisterExtensionSender(ss, xtnData,
|
||||
ssl_signed_cert_timestamp_xtn,
|
||||
|
|
@ -1934,7 +1938,7 @@ ssl_HandleSupportedGroupsXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
}
|
||||
|
||||
/* Remember that we negotiated this extension. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_supported_groups_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_supported_groups_xtn);
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
@ -1975,7 +1979,7 @@ ssl_HandleRecordSizeLimitXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
/* We can't enforce the maximum on a server. But we do need to ensure
|
||||
* that we don't apply a limit that is too large. */
|
||||
xtnData->recordSizeLimit = PR_MIN(maxLimit, limit);
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_record_size_limit_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_record_size_limit_xtn);
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -760,6 +760,8 @@ typedef struct SSL3HandshakeStateStr {
|
|||
* on server.*/
|
||||
PRBool helloRetry; /* True if HelloRetryRequest has been sent
|
||||
* or received. */
|
||||
PRBool dtlsReceivedHVR; /* True if a DTLS HelloVerifyRequest was
|
||||
* received. */
|
||||
PRBool receivedCcs; /* A server received ChangeCipherSpec
|
||||
* before the handshake started. */
|
||||
PRBool rejectCcs; /* Excessive ChangeCipherSpecs are rejected. */
|
||||
|
|
|
|||
|
|
@ -3031,6 +3031,7 @@ tls13_HandleHelloRetryRequest(sslSocket *ss, const PRUint8 *savedMsg,
|
|||
rv = ssl3_HandleParsedExtensions(ss, ssl_hs_hello_retry_request);
|
||||
ssl3_DestroyRemoteExtensions(&ss->ssl3.hs.remoteExtensions);
|
||||
if (rv != SECSuccess) {
|
||||
SECITEM_FreeItem(&ss->ssl3.hs.cookie, PR_FALSE);
|
||||
return SECFailure; /* Error code set below */
|
||||
}
|
||||
rv = tls13_MaybeHandleEchSignal(ss, savedMsg, savedLength, PR_TRUE);
|
||||
|
|
@ -3064,10 +3065,12 @@ tls13_HandleHelloRetryRequest(sslSocket *ss, const PRUint8 *savedMsg,
|
|||
}
|
||||
|
||||
ssl_ReleaseXmitBufLock(ss);
|
||||
SECITEM_FreeItem(&ss->ssl3.hs.cookie, PR_FALSE);
|
||||
return SECSuccess;
|
||||
|
||||
loser:
|
||||
ssl_ReleaseXmitBufLock(ss);
|
||||
SECITEM_FreeItem(&ss->ssl3.hs.cookie, PR_FALSE);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
|
@ -4060,6 +4063,20 @@ tls13_HandleCertificateDecode(sslSocket *ss, PRUint8 *b, PRUint32 length)
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
/* Cap the decompressed size to prevent memory exhaustion. The wire field
|
||||
* is a uint24 (max 16MB) but the CompressedCertificate path bypasses the
|
||||
* 128KB cap applied to regular handshake messages. 100KB matches the limit
|
||||
* enforced by OpenSSL and BoringSSL. */
|
||||
#define MAX_CERT_UNCOMPRESSED_LEN (100 * 1024)
|
||||
if (decodedCertLen > MAX_CERT_UNCOMPRESSED_LEN) {
|
||||
SSL_TRC(50, ("%d: TLS13[%d]: %s uncompressed_length %u exceeds limit %u",
|
||||
SSL_GETPID(), ss->fd, SSL_ROLE(ss),
|
||||
decodedCertLen, MAX_CERT_UNCOMPRESSED_LEN));
|
||||
FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_CERTIFICATE, bad_certificate);
|
||||
return SECFailure;
|
||||
}
|
||||
#undef MAX_CERT_UNCOMPRESSED_LEN
|
||||
|
||||
/* opaque compressed_certificate_message<1..2^24-1>; */
|
||||
PRUint32 compressedCertLen = 0;
|
||||
rv = ssl3_ConsumeHandshakeNumber(ss, &compressedCertLen, 3, &b, &length);
|
||||
|
|
@ -4989,6 +5006,10 @@ tls13_AEAD(PK11Context *context, PRBool decrypt,
|
|||
PORT_Memcpy(ivOut, ivIn, ivLen);
|
||||
}
|
||||
if (decrypt) {
|
||||
if (inLen < tagLen) {
|
||||
PORT_SetError(SEC_ERROR_INPUT_LEN);
|
||||
return SECFailure;
|
||||
}
|
||||
inLen = inLen - tagLen;
|
||||
tag = (unsigned char *)in + inLen;
|
||||
/* tag is const on decrypt, but returned on encrypt */
|
||||
|
|
|
|||
|
|
@ -2442,7 +2442,7 @@ tls13_MaybeHandleEchSignal(sslSocket *ss, const PRUint8 *sh, PRUint32 shLen, PRB
|
|||
PORT_SetError(SSL_ERROR_BAD_2ND_CLIENT_HELLO);
|
||||
return SECFailure;
|
||||
}
|
||||
ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ssl_tls13_encrypted_client_hello_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, &ss->xtnData, ssl_tls13_encrypted_client_hello_xtn);
|
||||
|
||||
/* Only overwrite client_random with client_inner_random if CHInner was
|
||||
* succesfully used for handshake (NOT if HRR is received). */
|
||||
|
|
|
|||
|
|
@ -446,8 +446,7 @@ tls13_ServerHandleKeyShareXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
}
|
||||
|
||||
/* Keep track of negotiated extensions. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] =
|
||||
ssl_tls13_key_share_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_tls13_key_share_xtn);
|
||||
|
||||
return SECSuccess;
|
||||
|
||||
|
|
@ -746,7 +745,7 @@ tls13_ServerHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData
|
|||
return SECSuccess;
|
||||
}
|
||||
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_tls13_pre_shared_key_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_tls13_pre_shared_key_xtn);
|
||||
return SECSuccess;
|
||||
|
||||
alert_loser:
|
||||
|
|
@ -816,7 +815,7 @@ tls13_ClientHandlePreSharedKeyXtn(const sslSocket *ss, TLSExtensionData *xtnData
|
|||
}
|
||||
|
||||
/* Keep track of negotiated extensions. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_tls13_pre_shared_key_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_tls13_pre_shared_key_xtn);
|
||||
xtnData->selectedPsk = candidate;
|
||||
|
||||
return SECSuccess;
|
||||
|
|
@ -860,7 +859,7 @@ tls13_ServerHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_tls13_early_data_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_tls13_early_data_xtn);
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
@ -885,7 +884,7 @@ tls13_ClientHandleEarlyDataXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
}
|
||||
|
||||
/* Keep track of negotiated extensions. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_tls13_early_data_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_tls13_early_data_xtn);
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
@ -1036,20 +1035,27 @@ tls13_ClientHandleHrrCookie(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
|
||||
PORT_Assert(ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_3);
|
||||
|
||||
/* IMPORTANT: this is only valid while the HelloRetryRequest is still valid. */
|
||||
SECItem cookie;
|
||||
rv = ssl3_ExtConsumeHandshakeVariable(
|
||||
ss, &CONST_CAST(sslSocket, ss)->ssl3.hs.cookie, 2,
|
||||
ss, &cookie, 2,
|
||||
&data->data, &data->len);
|
||||
if (rv != SECSuccess) {
|
||||
PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
|
||||
return SECFailure;
|
||||
}
|
||||
if (!ss->ssl3.hs.cookie.len || data->len) {
|
||||
if (!cookie.len || data->len) {
|
||||
ssl3_ExtSendAlert(ss, alert_fatal, decode_error);
|
||||
PORT_SetError(SSL_ERROR_RX_MALFORMED_HELLO_RETRY_REQUEST);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
PORT_Assert(!ss->ssl3.hs.cookie.data && !ss->ssl3.hs.cookie.len);
|
||||
SECITEM_FreeItem(&CONST_CAST(sslSocket, ss)->ssl3.hs.cookie, PR_FALSE);
|
||||
rv = SECITEM_CopyItem(NULL, &CONST_CAST(sslSocket, ss)->ssl3.hs.cookie, &cookie);
|
||||
if (rv != SECSuccess) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
|
|
@ -1101,7 +1107,7 @@ tls13_ServerHandleCookieXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
}
|
||||
|
||||
/* Keep track of negotiated extensions. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_tls13_cookie_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_tls13_cookie_xtn);
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
@ -1138,7 +1144,7 @@ tls13_ServerHandlePostHandshakeAuthXtn(const sslSocket *ss,
|
|||
* NST immediately following the client Finished. */
|
||||
if (!IS_DTLS(ss)) {
|
||||
/* Keep track of negotiated extensions. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_tls13_post_handshake_auth_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_tls13_post_handshake_auth_xtn);
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
|
|
@ -1209,8 +1215,7 @@ tls13_ServerHandlePskModesXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
}
|
||||
|
||||
/* Keep track of negotiated extensions. */
|
||||
xtnData->negotiated[xtnData->numNegotiated++] =
|
||||
ssl_tls13_psk_key_exchange_modes_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_tls13_psk_key_exchange_modes_xtn);
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
|
@ -1554,8 +1559,7 @@ tls13_ClientHandleDelegatedCredentialsXtn(const sslSocket *ss,
|
|||
}
|
||||
|
||||
xtnData->peerDelegCred = dc;
|
||||
xtnData->negotiated[xtnData->numNegotiated++] =
|
||||
ssl_delegated_credentials_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_delegated_credentials_xtn);
|
||||
return SECSuccess;
|
||||
alert_loser:
|
||||
ssl3_ExtSendAlert(ss, alert_fatal, illegal_parameter);
|
||||
|
|
@ -1619,8 +1623,7 @@ tls13_ServerHandleDelegatedCredentialsXtn(const sslSocket *ss,
|
|||
|
||||
/* Keep track of negotiated extensions. */
|
||||
xtnData->peerRequestedDelegCred = PR_TRUE;
|
||||
xtnData->negotiated[xtnData->numNegotiated++] =
|
||||
ssl_delegated_credentials_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_delegated_credentials_xtn);
|
||||
|
||||
return ssl3_RegisterExtensionSender(
|
||||
ss, xtnData, ssl_delegated_credentials_xtn,
|
||||
|
|
@ -1709,7 +1712,7 @@ tls13_ServerHandleInnerEchXtn(const sslSocket *ss, TLSExtensionData *xtnData,
|
|||
}
|
||||
|
||||
xtnData->ech->receivedInnerXtn = PR_TRUE;
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_tls13_encrypted_client_hello_xtn;
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_tls13_encrypted_client_hello_xtn);
|
||||
return SECSuccess;
|
||||
|
||||
alert_loser:
|
||||
|
|
@ -1995,7 +1998,9 @@ ssl3_HandleCertificateCompressionXtn(const sslSocket *ss,
|
|||
for (int j = 0; j < ss->ssl3.supportedCertCompressionAlgorithmsCount; j++) {
|
||||
if (ss->ssl3.supportedCertCompressionAlgorithms[j].id == alg) {
|
||||
xtnData->compressionAlg = alg;
|
||||
xtnData->negotiated[xtnData->numNegotiated++] = ssl_certificate_compression_xtn;
|
||||
if (ss->sec.isServer) {
|
||||
ssl3_RecordExtensionNegotiated(ss, xtnData, ssl_certificate_compression_xtn);
|
||||
}
|
||||
algFound = SECSuccess;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@
|
|||
* The format of the version string should be
|
||||
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
|
||||
*/
|
||||
#define NSSUTIL_VERSION "3.112.3"
|
||||
#define NSSUTIL_VERSION "3.112.5"
|
||||
#define NSSUTIL_VMAJOR 3
|
||||
#define NSSUTIL_VMINOR 112
|
||||
#define NSSUTIL_VPATCH 3
|
||||
#define NSSUTIL_VPATCH 5
|
||||
#define NSSUTIL_VBUILD 0
|
||||
#define NSSUTIL_BETA PR_FALSE
|
||||
|
||||
|
|
|
|||
|
|
@ -522,11 +522,18 @@ DecodeGroup(void* dest,
|
|||
}
|
||||
} while ((SECSuccess == rv) && (counter.len));
|
||||
|
||||
/* Limit entry data to 1 GiB. */
|
||||
if (SECSuccess == rv && subTemplate->size &&
|
||||
totalEntries > ((size_t)1 << 30) / subTemplate->size) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
rv = SECFailure;
|
||||
}
|
||||
|
||||
if (SECSuccess == rv) {
|
||||
/* allocate room for pointer array and entries */
|
||||
/* we want to allocate the array even if there is 0 entry */
|
||||
entries = (void**)PORT_ArenaZAlloc(arena, sizeof(void*) * (totalEntries + 1) + /* the extra one is for NULL termination */
|
||||
subTemplate->size * totalEntries);
|
||||
(size_t)subTemplate->size * totalEntries);
|
||||
|
||||
if (entries) {
|
||||
entries[totalEntries] = NULL; /* terminate the array */
|
||||
|
|
@ -540,7 +547,7 @@ DecodeGroup(void* dest,
|
|||
PRUint32 entriesIndex = 0;
|
||||
for (entriesIndex = 0; entriesIndex < totalEntries; entriesIndex++) {
|
||||
entries[entriesIndex] =
|
||||
(char*)entriesData + (subTemplate->size * entriesIndex);
|
||||
(char*)entriesData + ((size_t)subTemplate->size * entriesIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ origin:
|
|||
description: nss
|
||||
url: https://hg-edge.mozilla.org/projects/nss
|
||||
|
||||
release: e65740334234fa690d1a80c807fb578bb030ed2b (2026-02-13T14:13:57Z).
|
||||
revision: e65740334234fa690d1a80c807fb578bb030ed2b
|
||||
release: fddd54c0fb1444c710f442c872de3af8eaa9aec9 (2026-04-23T19:27:46Z).
|
||||
revision: fddd54c0fb1444c710f442c872de3af8eaa9aec9
|
||||
|
||||
license: MPL-2.0
|
||||
license-file: COPYING
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue