author | Sean Feng <sefeng@mozilla.com> |
Fri, 22 Nov 2019 19:25:31 +0000 | |
changeset 503415 | 2aaf1c7b7f1c2e6b6b9a8ab3880fe7acacf0a3f1 |
parent 503414 | 2c912e46295e4f8a3fa5824a7f378e06760ec7dd |
child 503416 | 436e3e84cb9e70beeac8c46a35c4f7e997cb85fb |
push id | 36834 |
push user | nbeleuzu@mozilla.com |
push date | Sat, 23 Nov 2019 09:47:42 +0000 |
treeherder | mozilla-central@cf114f3b7494 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | keeler |
bugs | 1580304 |
milestone | 72.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/security/apps/AppSignatureVerification.cpp +++ b/security/apps/AppSignatureVerification.cpp @@ -1277,17 +1277,16 @@ nsresult OpenSignedAppFile(AppTrustedRoo } // Return the reader to the caller if they want it if (aZipReader) { zip.forget(aZipReader); } // Return the signer's certificate to the reader if they want it. - // XXX: We should return an nsIX509CertList with the whole validated chain. if (aSignerCert) { // The COSE certificate is authoritative. if (aPolicy.COSERequired() || (coseCertItem && coseCertItem->len != 0)) { if (!coseCertItem || coseCertItem->len == 0) { return NS_ERROR_FAILURE; } CERTCertDBHandle* dbHandle = CERT_GetDefaultCertDB(); if (!dbHandle) {
--- a/security/manager/ssl/SSLServerCertVerification.cpp +++ b/security/manager/ssl/SSLServerCertVerification.cpp @@ -454,17 +454,17 @@ static nsresult OverrideAllowedForHost( class SSLServerCertVerificationJob : public Runnable { public: // Must be called only on the socket transport thread static SECStatus Dispatch(const RefPtr<SharedCertVerifier>& certVerifier, const void* fdForLogging, TransportSecurityInfo* infoObject, const UniqueCERTCertificate& serverCert, - const UniqueCERTCertList& peerCertChain, + UniqueCERTCertList& peerCertChain, Maybe<nsTArray<uint8_t>>& stapledOCSPResponse, Maybe<nsTArray<uint8_t>>& sctsFromTLSExtension, Maybe<DelegatedCredentialInfo>& dcInfo, uint32_t providerFlags, Time time, PRTime prtime, uint32_t certVerifierFlags); private: NS_DECL_NSIRUNNABLE @@ -1145,41 +1145,34 @@ Result AuthCertificate(CertVerifier& cer rv == Success); return rv; } /*static*/ SECStatus SSLServerCertVerificationJob::Dispatch( const RefPtr<SharedCertVerifier>& certVerifier, const void* fdForLogging, TransportSecurityInfo* infoObject, const UniqueCERTCertificate& serverCert, - const UniqueCERTCertList& peerCertChain, + UniqueCERTCertList& peerCertChain, Maybe<nsTArray<uint8_t>>& stapledOCSPResponse, Maybe<nsTArray<uint8_t>>& sctsFromTLSExtension, Maybe<DelegatedCredentialInfo>& dcInfo, uint32_t providerFlags, Time time, PRTime prtime, uint32_t certVerifierFlags) { // Runs on the socket transport thread if (!certVerifier || !infoObject || !serverCert) { NS_ERROR("Invalid parameters for SSL server cert validation"); PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); return SECFailure; } if (!gCertVerificationThreadPool) { PR_SetError(PR_INVALID_STATE_ERROR, 0); return SECFailure; } - // Copy the certificate list so the runnable can take ownership of it in the - // constructor. - UniqueCERTCertList peerCertChainCopy = - nsNSSCertList::DupCertList(peerCertChain); - if (!peerCertChainCopy) { - PR_SetError(SEC_ERROR_NO_MEMORY, 0); - return SECFailure; - } + UniqueCERTCertList peerCertChainCopy = std::move(peerCertChain); RefPtr<SSLServerCertVerificationJob> job(new SSLServerCertVerificationJob( certVerifier, fdForLogging, infoObject, serverCert, std::move(peerCertChainCopy), stapledOCSPResponse, sctsFromTLSExtension, dcInfo, providerFlags, time, prtime, certVerifierFlags)); nsresult nrv = gCertVerificationThreadPool->Dispatch(job, NS_DISPATCH_NORMAL); if (NS_FAILED(nrv)) {
--- a/security/manager/ssl/TransportSecurityInfo.cpp +++ b/security/manager/ssl/TransportSecurityInfo.cpp @@ -450,61 +450,16 @@ nsresult TransportSecurityInfo::ReadCert return NS_ERROR_UNEXPECTED; } RefPtr<nsIX509Cert> castedCert(cert.get()); aCertList.AppendElement(castedCert); } return NS_OK; } -nsresult TransportSecurityInfo::ConvertCertArrayToCertList( - const nsTArray<RefPtr<nsIX509Cert>>& aCertArray, - nsIX509CertList** aCertList) { - NS_ENSURE_ARG_POINTER(aCertList); - *aCertList = nullptr; - - // aCertList will be null if aCertArray is empty, this also matches - // the original certList behaviour - if (aCertArray.IsEmpty()) { - return NS_OK; - } - - nsCOMPtr<nsIX509CertList> certList = new nsNSSCertList(); - for (const auto& cert : aCertArray) { - nsresult rv = certList->AddCert(cert); - if (NS_FAILED(rv)) { - return rv; - } - } - - certList.forget(aCertList); - - return NS_OK; -} - -nsresult TransportSecurityInfo::ConvertCertListToCertArray( - const nsCOMPtr<nsIX509CertList>& aCertList, - nsTArray<RefPtr<nsIX509Cert>>& aCertArray) { - MOZ_ASSERT(aCertList); - if (!aCertList) { - return NS_ERROR_INVALID_ARG; - } - - aCertArray.Clear(); - RefPtr<nsNSSCertList> certList = aCertList->GetCertList(); - - return certList->ForEachCertificateInChain( - [&aCertArray](nsCOMPtr<nsIX509Cert>& aCert, bool aHasMore, - bool& aContinue) { - RefPtr<nsIX509Cert> cert(aCert.get()); - aCertArray.AppendElement(cert); - return NS_OK; - }); -} - // NB: Any updates (except disk-only fields) must be kept in sync with // |DeserializeFromIPC|. NS_IMETHODIMP TransportSecurityInfo::Read(nsIObjectInputStream* aStream) { nsID id; nsresult rv = aStream->ReadID(&id); CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); if (NS_FAILED(rv)) {
--- a/security/manager/ssl/TransportSecurityInfo.h +++ b/security/manager/ssl/TransportSecurityInfo.h @@ -105,20 +105,16 @@ class TransportSecurityInfo : public nsI bool mIsEV; bool mHasIsEVStatus; bool mHaveCipherSuiteAndProtocol; /* mHaveCertErrrorBits is relied on to determine whether or not a SPDY connection is eligible for joining in nsNSSSocketInfo::JoinConnection() */ bool mHaveCertErrorBits; - - static nsresult ConvertCertArrayToCertList( - const nsTArray<RefPtr<nsIX509Cert>>& aCertArray, - nsIX509CertList** aCertList); private: // True if SetCanceled has been called (or if this was deserialized with a // non-zero mErrorCode, which can only be the case if SetCanceled was called // on the original TransportSecurityInfo). Atomic<bool> mCanceled; mutable ::mozilla::Mutex mMutex; @@ -136,19 +132,16 @@ class TransportSecurityInfo : public nsI OriginAttributes mOriginAttributes; nsCOMPtr<nsIX509Cert> mServerCert; /* Peer cert chain for failed connections (for error reporting) */ nsTArray<RefPtr<nsIX509Cert>> mFailedCertChain; nsresult ReadSSLStatus(nsIObjectInputStream* aStream); - static nsresult ConvertCertListToCertArray( - const nsCOMPtr<nsIX509CertList>& aCertList, - nsTArray<RefPtr<nsIX509Cert>>& aCertArray); // This function is used to read the binary that are serialized // by using nsIX509CertList nsresult ReadCertList(nsIObjectInputStream* aStream, nsTArray<RefPtr<nsIX509Cert>>& aCertList); nsresult ReadCertificatesFromStream(nsIObjectInputStream* aStream, uint32_t aSize, nsTArray<RefPtr<nsIX509Cert>>& aCertList);
--- a/security/manager/ssl/components.conf +++ b/security/manager/ssl/components.conf @@ -85,22 +85,16 @@ Classes = [ }, { 'cid': '{fb0bbc5c-452e-4783-b32c-80124693d871}', 'contract_ids': ['@mozilla.org/security/x509certdb;1'], 'type': 'nsNSSCertificateDB', 'legacy_constructor': 'mozilla::psm::NSSConstructor<nsNSSCertificateDB>', }, { - 'cid': '{959fb165-6517-487f-ab9b-d8913be53197}', - 'contract_ids': ['@mozilla.org/security/x509certlist;1'], - 'type': 'nsNSSCertList', - 'legacy_constructor': 'mozilla::psm::NSSConstructor<nsNSSCertList>', - }, - { 'cid': '{36a1d3b3-d886-4317-96ff-87b0005cfef7}', 'contract_ids': ['@mozilla.org/security/hash;1'], 'type': 'nsCryptoHash', 'legacy_constructor': 'mozilla::psm::NSSConstructor<nsCryptoHash>', }, { 'cid': '{a496d0a2-dff7-4e23-bd65-1ca742fa178a}', 'contract_ids': ['@mozilla.org/security/hmac;1'],
--- a/security/manager/ssl/moz.build +++ b/security/manager/ssl/moz.build @@ -37,17 +37,16 @@ XPIDL_SOURCES += [ 'nsIProtectedAuthThread.idl', 'nsISecretDecoderRing.idl', 'nsISecurityUITelemetry.idl', 'nsISiteSecurityService.idl', 'nsITokenDialogs.idl', 'nsITokenPasswordDialogs.idl', 'nsIX509Cert.idl', 'nsIX509CertDB.idl', - 'nsIX509CertList.idl', 'nsIX509CertValidity.idl', ] if CONFIG['MOZ_XUL']: XPIDL_SOURCES += [ 'nsICertTree.idl', ]
--- a/security/manager/ssl/nsINSSComponent.idl +++ b/security/manager/ssl/nsINSSComponent.idl @@ -7,18 +7,16 @@ #include "nsISupports.idl" %{C++ #include "cert.h" #include "SharedCertVerifier.h" #define PSM_COMPONENT_CONTRACTID "@mozilla.org/psm;1" %} -interface nsIX509CertList; - [ptr] native CERTCertificatePtr(CERTCertificate); [ptr] native SharedCertVerifierPtr(mozilla::psm::SharedCertVerifier); [scriptable, uuid(a0a8f52b-ea18-4abc-a3ca-eccf704ffe63)] interface nsINSSComponent : nsISupports { /** * When we log out of a PKCS#11 token, any TLS connections that may have * involved a client certificate stored on that token must be closed. Since we
deleted file mode 100644 --- a/security/manager/ssl/nsIX509CertList.idl +++ /dev/null @@ -1,62 +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 "nsISupports.idl" - -interface nsISimpleEnumerator; -interface nsIX509Cert; - -%{C++ -namespace IPC { - class Message; -} -class PickleIterator; -class nsNSSCertList; -%} - -[ptr] native nsNSSCertListPtr(nsNSSCertList); -[ptr] native IpcMessagePtr(IPC::Message); -[ptr] native PickleIteratorPtr(PickleIterator); - -[scriptable, builtinclass, uuid(ae74cda5-cd2f-473f-96f5-f0b7fff62c68)] -interface nsIX509CertList : nsISupports { - [must_use] - void addCert(in nsIX509Cert cert); - [must_use] - nsISimpleEnumerator getEnumerator(); - - /** - * Test whether two certificate list instances represent the same - * certificate list. - * - * @return Whether the certificate lists are equal - */ - [must_use] - boolean equals(in nsIX509CertList other); - - /** - * Retrieves the PSM helper class that wraps the NSS certificate list - */ - [notxpcom, noscript, must_use] - nsNSSCertListPtr getCertList(); - - [notxpcom, noscript] - void SerializeToIPC(in IpcMessagePtr aMsg); - - [notxpcom, noscript] - bool DeserializeFromIPC([const] in IpcMessagePtr aMsg, in PickleIteratorPtr aIter); -}; - -%{C++ - -#define NS_X509CERTLIST_CID { /* 959fb165-6517-487f-ab9b-d8913be53197 */ \ - 0x959fb165, \ - 0x6517, \ - 0x487f, \ - {0xab, 0x9b, 0xd8, 0x91, 0x3b, 0xe5, 0x31, 0x97} \ - } - -#define NS_X509CERTLIST_CONTRACTID "@mozilla.org/security/x509certlist;1" - -%}
--- a/security/manager/ssl/nsNSSCertificate.cpp +++ b/security/manager/ssl/nsNSSCertificate.cpp @@ -52,35 +52,16 @@ # include <winsock.h> // for htonl #endif using namespace mozilla; using namespace mozilla::psm; extern LazyLogModule gPIPNSSLog; -class nsNSSCertListEnumerator : public nsSimpleEnumerator { - public: - NS_DECL_NSISIMPLEENUMERATOR - - const nsID& DefaultInterface() override { return NS_GET_IID(nsIX509Cert); } - - explicit nsNSSCertListEnumerator( - const std::vector<UniqueCERTCertificate>& certs); - - nsNSSCertListEnumerator(const nsNSSCertListEnumerator&) = delete; - void operator=(const nsNSSCertListEnumerator&) = delete; - - private: - virtual ~nsNSSCertListEnumerator() = default; - - std::vector<UniqueCERTCertificate> mCerts; - std::vector<UniqueCERTCertificate>::const_iterator mPosition; -}; - // This is being stored in an uint32_t that can otherwise // only take values from nsIX509Cert's list of cert types. // As nsIX509Cert is frozen, we choose a value not contained // in the list to mean not yet initialized. #define CERT_TYPE_NOT_YET_INITIALIZED (1 << 30) NS_IMPL_ISUPPORTS(nsNSSCertificate, nsIX509Cert, nsISerializable, nsIClassInfo) @@ -791,344 +772,16 @@ SECStatus ConstructCERTCertListFromRever Unused << cert.release(); // cert is now owned by certList. } return SECSuccess; } } // namespace mozilla -NS_IMPL_CLASSINFO(nsNSSCertList, nullptr, - // inferred from nsIX509Cert - nsIClassInfo::THREADSAFE, NS_X509CERTLIST_CID) - -NS_IMPL_ISUPPORTS_CI(nsNSSCertList, nsIX509CertList, nsISerializable) - -nsNSSCertList::nsNSSCertList(UniqueCERTCertList certList) { - // Commonly we'll store only 3 certificates. If this is a verified certificate - // chain, it may be as many as 8 certificates. If this is a list of all known - // certificates, it may be a few hundred. We'll optimize for the common case - // (i.e. a verified certificate chain). - mCerts.reserve(8); - if (certList.get()) { - for (CERTCertListNode* node = CERT_LIST_HEAD(certList.get()); - !CERT_LIST_END(node, certList.get()); node = CERT_LIST_NEXT(node)) { - UniqueCERTCertificate cert(CERT_DupCertificate(node->cert)); - mCerts.push_back(std::move(cert)); - } - } -} - -nsNSSCertList::nsNSSCertList() { - // Commonly we'll store only 3 certificates. If this is a verified certificate - // chain, it may be as many as 8 certificates. If this is a list of all known - // certificates, it may be a few hundred. We'll optimize for the common case - // (i.e. a verified certificate chain). - mCerts.reserve(8); -} - -// This is the implementation of nsIX509CertList.getCertList(). -nsNSSCertList* nsNSSCertList::GetCertList() { return this; } - -NS_IMETHODIMP -nsNSSCertList::AddCert(nsIX509Cert* aCert) { - if (!aCert) { - return NS_ERROR_INVALID_ARG; - } - - // We need an owning handle when calling nsIX509Cert::GetCert(). - UniqueCERTCertificate cert(aCert->GetCert()); - if (!cert) { - NS_ERROR("Somehow got nullptr for mCertificate in nsNSSCertificate."); - return NS_ERROR_FAILURE; - } - mCerts.push_back(std::move(cert)); - return NS_OK; -} - -UniqueCERTCertList nsNSSCertList::DupCertList( - const UniqueCERTCertList& certList) { - if (!certList) { - return nullptr; - } - - UniqueCERTCertList newList(CERT_NewCertList()); - if (!newList) { - return nullptr; - } - - for (CERTCertListNode* node = CERT_LIST_HEAD(certList); - !CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node)) { - UniqueCERTCertificate cert(CERT_DupCertificate(node->cert)); - if (!cert) { - return nullptr; - } - - if (CERT_AddCertToListTail(newList.get(), cert.get()) != SECSuccess) { - return nullptr; - } - - Unused << cert.release(); // Ownership transferred to the cert list. - } - return newList; -} - -// NB: Any updates (except disk-only fields) must be kept in sync with -// |SerializeToIPC|. -NS_IMETHODIMP -nsNSSCertList::Write(nsIObjectOutputStream* aStream) { - // Write the length of the list - nsresult rv = aStream->Write32(mCerts.size()); - - // Serialize each certificate - for (const auto& certRef : mCerts) { - nsCOMPtr<nsIX509Cert> cert = nsNSSCertificate::Create(certRef.get()); - if (!cert) { - rv = NS_ERROR_OUT_OF_MEMORY; - break; - } - - nsCOMPtr<nsISerializable> serializableCert = do_QueryInterface(cert); - rv = aStream->WriteCompoundObject(serializableCert, NS_GET_IID(nsIX509Cert), - true); - if (NS_FAILED(rv)) { - break; - } - } - - return rv; -} - -// NB: Any updates (except disk-only fields) must be kept in sync with -// |DeserializeFromIPC|. -NS_IMETHODIMP -nsNSSCertList::Read(nsIObjectInputStream* aStream) { - uint32_t certListLen; - nsresult rv = aStream->Read32(&certListLen); - if (NS_FAILED(rv)) { - return rv; - } - - for (uint32_t i = 0; i < certListLen; ++i) { - nsCOMPtr<nsISupports> certSupports; - rv = aStream->ReadObject(true, getter_AddRefs(certSupports)); - if (NS_FAILED(rv)) { - return rv; - } - nsCOMPtr<nsIX509Cert> cert = do_QueryInterface(certSupports); - if (!cert) { - return NS_ERROR_UNEXPECTED; - } - rv = AddCert(cert); - if (NS_FAILED(rv)) { - return rv; - } - } - - return NS_OK; -} - -void nsNSSCertList::SerializeToIPC(IPC::Message* aMsg) { - const size_t certCount = static_cast<size_t>(mCerts.size()); - WriteParam(aMsg, certCount); - - for (const auto& certRef : mCerts) { - RefPtr<nsIX509Cert> cert = nsNSSCertificate::Create(certRef.get()); - MOZ_RELEASE_ASSERT(cert); - - WriteParam(aMsg, cert); - } -} - -bool nsNSSCertList::DeserializeFromIPC(const IPC::Message* aMsg, - PickleIterator* aIter) { - size_t count = 0; - if (!ReadParam(aMsg, aIter, &count)) { - return false; - } - - for (size_t i = 0; i < count; i++) { - RefPtr<nsIX509Cert> cert; - if (!ReadParam(aMsg, aIter, &cert) || !cert || NS_FAILED(AddCert(cert))) { - return false; - } - } - - return true; -} - -NS_IMETHODIMP -nsNSSCertList::GetEnumerator(nsISimpleEnumerator** _retval) { - nsCOMPtr<nsISimpleEnumerator> enumerator(new nsNSSCertListEnumerator(mCerts)); - enumerator.forget(_retval); - return NS_OK; -} - -NS_IMETHODIMP -nsNSSCertList::Equals(nsIX509CertList* other, bool* result) { - NS_ENSURE_ARG(result); - *result = true; - - nsresult rv; - - nsCOMPtr<nsISimpleEnumerator> selfEnumerator; - rv = GetEnumerator(getter_AddRefs(selfEnumerator)); - if (NS_FAILED(rv)) { - return rv; - } - - nsCOMPtr<nsISimpleEnumerator> otherEnumerator; - rv = other->GetEnumerator(getter_AddRefs(otherEnumerator)); - if (NS_FAILED(rv)) { - return rv; - } - - nsCOMPtr<nsISupports> selfSupports; - nsCOMPtr<nsISupports> otherSupports; - while (NS_SUCCEEDED(selfEnumerator->GetNext(getter_AddRefs(selfSupports)))) { - if (NS_SUCCEEDED(otherEnumerator->GetNext(getter_AddRefs(otherSupports)))) { - nsCOMPtr<nsIX509Cert> selfCert = do_QueryInterface(selfSupports); - nsCOMPtr<nsIX509Cert> otherCert = do_QueryInterface(otherSupports); - - bool certsEqual = false; - rv = selfCert->Equals(otherCert, &certsEqual); - if (NS_FAILED(rv)) { - return rv; - } - if (!certsEqual) { - *result = false; - break; - } - } else { - // other is shorter than self - *result = false; - break; - } - } - - // Make sure self is the same length as other - bool otherHasMore = false; - rv = otherEnumerator->HasMoreElements(&otherHasMore); - if (NS_FAILED(rv)) { - return rv; - } - if (otherHasMore) { - *result = false; - } - - return NS_OK; -} - -nsresult nsNSSCertList::ForEachCertificateInChain( - ForEachCertOperation& aOperation) { - nsCOMPtr<nsISimpleEnumerator> chainElt; - nsresult rv = GetEnumerator(getter_AddRefs(chainElt)); - if (NS_FAILED(rv)) { - return rv; - } - - // Each chain may have multiple certificates. - bool hasMore = false; - rv = chainElt->HasMoreElements(&hasMore); - if (NS_FAILED(rv)) { - return rv; - } - - if (!hasMore) { - return NS_OK; // Empty lists are fine - } - - do { - nsCOMPtr<nsISupports> certSupports; - rv = chainElt->GetNext(getter_AddRefs(certSupports)); - if (NS_FAILED(rv)) { - return rv; - } - - nsCOMPtr<nsIX509Cert> cert = do_QueryInterface(certSupports, &rv); - if (NS_FAILED(rv)) { - return rv; - } - - rv = chainElt->HasMoreElements(&hasMore); - if (NS_FAILED(rv)) { - return rv; - } - - bool continueLoop = true; - rv = aOperation(cert, hasMore, continueLoop); - if (NS_FAILED(rv) || !continueLoop) { - return rv; - } - } while (hasMore); - - return NS_OK; -} - -nsresult nsNSSCertList::SegmentCertificateChain( - /* out */ nsCOMPtr<nsIX509Cert>& aRoot, - /* out */ nsCOMPtr<nsIX509CertList>& aIntermediates, - /* out */ nsCOMPtr<nsIX509Cert>& aEndEntity) { - if (aRoot || aIntermediates || aEndEntity) { - // All passed-in nsCOMPtrs should be empty for the state machine to work - return NS_ERROR_UNEXPECTED; - } - - aIntermediates = new nsNSSCertList(); - - nsresult rv = ForEachCertificateInChain( - [&aRoot, &aIntermediates, &aEndEntity](nsCOMPtr<nsIX509Cert> aCert, - bool hasMore, bool& aContinue) { - if (!aEndEntity) { - // This is the end entity - aEndEntity = aCert; - } else if (!hasMore) { - // This is the root - aRoot = aCert; - } else { - // One of (potentially many) intermediates - if (NS_FAILED(aIntermediates->AddCert(aCert))) { - return NS_ERROR_OUT_OF_MEMORY; - } - } - - return NS_OK; - }); - - if (NS_FAILED(rv)) { - return rv; - } - - if (!aRoot || !aEndEntity) { - // No self-signed (or empty) chains allowed - return NS_ERROR_INVALID_ARG; - } - - return NS_OK; -} - -nsresult nsNSSCertList::GetRootCertificate( - /* out */ nsCOMPtr<nsIX509Cert>& aRoot) { - if (aRoot) { - return NS_ERROR_UNEXPECTED; - } - // If the list is empty, leave aRoot empty. - if (mCerts.size() < 1) { - return NS_OK; - } - const UniqueCERTCertificate& cert = mCerts.back(); - // This increases the refcount on the underlying CERTCertificate, which aRoot - // will own. - aRoot = nsNSSCertificate::Create(cert.get()); - if (!aRoot) { - return NS_ERROR_OUT_OF_MEMORY; - } - return NS_OK; -} - nsresult nsNSSCertificate::SegmentCertificateChain( /* in */ const nsTArray<RefPtr<nsIX509Cert>>& aCertList, /* out */ nsCOMPtr<nsIX509Cert>& aRoot, /* out */ nsTArray<RefPtr<nsIX509Cert>>& aIntermediates, /* out */ nsCOMPtr<nsIX509Cert>& aEndEntity) { if (aRoot || aEndEntity) { // All passed-in nsCOMPtrs should be empty for the state machine to work return NS_ERROR_UNEXPECTED; @@ -1172,52 +825,16 @@ nsresult nsNSSCertificate::GetRootCertif nsCOMPtr<nsIX509Cert> cert(aCertList.LastElement()); aRoot = cert; if (!aRoot) { return NS_ERROR_OUT_OF_MEMORY; } return NS_OK; } -nsNSSCertListEnumerator::nsNSSCertListEnumerator( - const std::vector<UniqueCERTCertificate>& certs) { - mCerts.reserve(certs.size()); - // Unfortunately we can't just clone the vector because we have to ensure the - // reference counts on the CERTCertificates are accurate. - for (const auto& certRef : certs) { - UniqueCERTCertificate cert(CERT_DupCertificate(certRef.get())); - mCerts.push_back(std::move(cert)); - } - mPosition = mCerts.cbegin(); -} - -NS_IMETHODIMP -nsNSSCertListEnumerator::HasMoreElements(bool* _retval) { - *_retval = mPosition != mCerts.cend(); - return NS_OK; -} - -NS_IMETHODIMP -nsNSSCertListEnumerator::GetNext(nsISupports** _retval) { - *_retval = nullptr; - if (mPosition == mCerts.cend()) { - return NS_ERROR_UNEXPECTED; - } - const UniqueCERTCertificate& certRef = *mPosition; - // nsNSSCertificate::Create calls nsNSSCertificate::nsNSSCertificate, which - // increases the reference count on the underlying CERTCertificate itself. - nsCOMPtr<nsIX509Cert> nssCert = nsNSSCertificate::Create(certRef.get()); - if (!nssCert) { - return NS_ERROR_OUT_OF_MEMORY; - } - nssCert.forget(_retval); - mPosition++; - return NS_OK; -} - // NB: Any updates (except disk-only fields) must be kept in sync with // |SerializeToIPC|. NS_IMETHODIMP nsNSSCertificate::Write(nsIObjectOutputStream* aStream) { NS_ENSURE_STATE(mCert); // This field used to be the cached EV status, but it is no longer necessary. nsresult rv = aStream->Write32(0); if (NS_FAILED(rv)) {
--- a/security/manager/ssl/nsNSSCertificate.h +++ b/security/manager/ssl/nsNSSCertificate.h @@ -12,17 +12,16 @@ #include "ScopedNSSTypes.h" #include "certt.h" #include "nsCOMPtr.h" #include "nsIASN1Object.h" #include "nsIClassInfo.h" #include "nsISerializable.h" #include "nsIX509Cert.h" #include "nsIX509CertDB.h" -#include "nsIX509CertList.h" #include "nsSimpleEnumerator.h" #include "nsStringFwd.h" namespace mozilla { namespace pkix { class DERArray; } } // namespace mozilla @@ -90,74 +89,16 @@ class nsNSSCertificate final : public ns namespace mozilla { SECStatus ConstructCERTCertListFromReversedDERArray( const mozilla::pkix::DERArray& certArray, /*out*/ mozilla::UniqueCERTCertList& certList); } // namespace mozilla -typedef const std::function<nsresult(nsCOMPtr<nsIX509Cert>& aCert, - bool aHasMore, /* out */ bool& aContinue)> - ForEachCertOperation; - -class nsNSSCertList : public nsIX509CertList, public nsISerializable { - public: - NS_DECL_THREADSAFE_ISUPPORTS - NS_DECL_NSIX509CERTLIST - NS_DECL_NSISERIALIZABLE - - // The only way to call this is with std::move(some cert list) (because the - // copy constructor should be deleted for UniqueCERTCertList), so we - // effectively take ownership of it. What actually happens is we iterate - // through the list getting our own owned reference to each certificate in the - // list, and then the UniqueCERTCertList is dropped as it goes out of scope - // (thus releasing its own reference to each certificate). - explicit nsNSSCertList(mozilla::UniqueCERTCertList certList); - - nsNSSCertList(); - - static mozilla::UniqueCERTCertList DupCertList( - const mozilla::UniqueCERTCertList& certList); - - // For each certificate in this CertList, run the operation aOperation. - // To end early with NS_OK, set the `aContinue` argument false before - // returning. To end early with an error, return anything except NS_OK. - // The `aHasMore` argument is false when this is the last certificate in the - // chain. - nsresult ForEachCertificateInChain(ForEachCertOperation& aOperation); - - // Split a certificate chain into the root, intermediates (if any), and end - // entity. This method does so blindly, assuming that the current list object - // is ordered [end entity, intermediates..., root]. If that isn't true, this - // method will return the certificates at the two ends without regard to the - // actual chain of trust. Callers are encouraged to check, if there's any - // doubt. - // Will return error if used on self-signed or empty chains. - // This method requires that all arguments be empty, notably the list - // `aIntermediates` must be empty. - nsresult SegmentCertificateChain( - /* out */ nsCOMPtr<nsIX509Cert>& aRoot, - /* out */ nsCOMPtr<nsIX509CertList>& aIntermediates, - /* out */ nsCOMPtr<nsIX509Cert>& aEndEntity); - - // Obtain the root certificate of a certificate chain. This method does so - // blindly, as SegmentCertificateChain; the same restrictions apply. On an - // empty list, leaves aRoot empty and returns OK. - nsresult GetRootCertificate(/* out */ nsCOMPtr<nsIX509Cert>& aRoot); - - private: - virtual ~nsNSSCertList() {} - - std::vector<mozilla::UniqueCERTCertificate> mCerts; - - nsNSSCertList(const nsNSSCertList&) = delete; - void operator=(const nsNSSCertList&) = delete; -}; - #define NS_X509CERT_CID \ { /* 660a3226-915c-4ffb-bb20-8985a632df05 */ \ 0x660a3226, 0x915c, 0x4ffb, { \ 0xbb, 0x20, 0x89, 0x85, 0xa6, 0x32, 0xdf, 0x05 \ } \ } #endif // nsNSSCertificate_h
--- a/security/manager/ssl/nsNSSComponent.h +++ b/security/manager/ssl/nsNSSComponent.h @@ -24,17 +24,16 @@ #ifdef XP_WIN # include "windows.h" // this needs to be before the following includes # include "wincrypt.h" #endif // XP_WIN class nsIDOMWindow; class nsIPrompt; -class nsIX509CertList; class SmartCardThreadList; namespace mozilla { namespace psm { MOZ_MUST_USE ::already_AddRefed<mozilla::psm::SharedCertVerifier> GetDefaultCertVerifier(); UniqueCERTCertList FindNonCACertificatesWithPrivateKeys();
--- a/security/manager/ssl/nsNSSModule.cpp +++ b/security/manager/ssl/nsNSSModule.cpp @@ -129,17 +129,16 @@ static nsresult Constructor(nsISupports* // in necko code (bug 1418752). To prevent it we initialize all such components // on main thread in advance in net_EnsurePSMInit(). Update that function when // new component with ThreadRestriction::MainThreadOnly is added. IMPL(SecretDecoderRing, nullptr) IMPL(nsPK11TokenDB, nullptr) IMPL(PKCS11ModuleDB, nullptr) IMPL(nsNSSCertificate, nullptr, ProcessRestriction::AnyProcess) IMPL(nsNSSCertificateDB, nullptr) -IMPL(nsNSSCertList, nullptr, ProcessRestriction::AnyProcess) #ifdef MOZ_XUL IMPL(nsCertTree, nullptr) #endif IMPL(nsCryptoHash, nullptr, ProcessRestriction::AnyProcess) IMPL(nsCryptoHMAC, nullptr, ProcessRestriction::AnyProcess) IMPL(nsKeyObject, nullptr, ProcessRestriction::AnyProcess) IMPL(nsKeyObjectFactory, nullptr, ProcessRestriction::AnyProcess) IMPL(ContentSignatureVerifier, nullptr)
--- a/security/manager/ssl/tests/gtest/CertListTest.cpp +++ b/security/manager/ssl/tests/gtest/CertListTest.cpp @@ -4,17 +4,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "gtest/gtest.h" #include "nsCOMPtr.h" #include "nsIPrefService.h" #include "nsISimpleEnumerator.h" #include "nsIX509Cert.h" #include "nsIX509CertDB.h" -#include "nsIX509CertList.h" #include "nsNSSCertificate.h" #include "nsServiceManagerUtils.h" #include "nsString.h" // certspec (for pycert.py) // // issuer:ca // subject:ca @@ -130,88 +129,71 @@ class psm_CertList : public ::testing::T << "couldn't set pref 'intl.locale.matchOS'"; nsCOMPtr<nsIX509CertDB> certdb(do_GetService(NS_X509CERTDB_CONTRACTID)); ASSERT_TRUE(certdb) << "couldn't get certdb"; } }; -static nsresult AddCertFromStringToList(const char* aPem, - nsIX509CertList* aCertList) { - if (!aCertList) { - return NS_ERROR_INVALID_ARG; - } - - nsCOMPtr<nsIX509Cert> cert; +static nsresult AddCertFromStringToList( + const char* aPem, nsTArray<RefPtr<nsIX509Cert>>& aCertList) { + RefPtr<nsIX509Cert> cert; cert = nsNSSCertificate::ConstructFromDER(const_cast<char*>(aPem), strlen(aPem)); if (!cert) { return NS_ERROR_FAILURE; } - return aCertList->AddCert(cert); -} - -static int CountCertsInList(nsCOMPtr<nsIX509CertList>& aCertList) { - int counter = 0; - RefPtr<nsNSSCertList> certList = aCertList->GetCertList(); - certList->ForEachCertificateInChain( - [&counter](nsCOMPtr<nsIX509Cert> aCert, bool aHasMore, bool& aContinue) { - counter++; - return NS_OK; - }); - - return counter; + aCertList.AppendElement(cert); + return NS_OK; } TEST_F(psm_CertList, TestInvalidSegmenting) { - RefPtr<nsNSSCertList> certList = new nsNSSCertList(); + nsTArray<RefPtr<nsIX509Cert>> certList; nsCOMPtr<nsIX509Cert> rootCert; - nsCOMPtr<nsIX509CertList> intCerts; + nsTArray<RefPtr<nsIX509Cert>> intCerts; nsCOMPtr<nsIX509Cert> eeCert; - nsresult rv = certList->SegmentCertificateChain(rootCert, intCerts, eeCert); + nsresult rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, + intCerts, eeCert); ASSERT_EQ(rv, NS_ERROR_INVALID_ARG) << "Empty lists can't be segmented"; rv = AddCertFromStringToList(kCaPem, certList); ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; - // We should need to clear out the in-vars, but let's make sure behavior is OK - rv = certList->SegmentCertificateChain(rootCert, intCerts, eeCert); - ASSERT_EQ(rv, NS_ERROR_UNEXPECTED) - << "Don't permit already-filled-in arguments"; - - intCerts = nullptr; + intCerts.Clear(); rootCert = nullptr; eeCert = nullptr; - rv = certList->SegmentCertificateChain(rootCert, intCerts, eeCert); + rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, intCerts, + eeCert); ASSERT_EQ(rv, NS_ERROR_INVALID_ARG) << "Lists of one can't be segmented"; } TEST_F(psm_CertList, TestValidSegmenting) { - RefPtr<nsNSSCertList> certList = new nsNSSCertList(); + nsTArray<RefPtr<nsIX509Cert>> certList; nsresult rv = AddCertFromStringToList(kEePem, certList); ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; rv = AddCertFromStringToList(kCaSecondIntermediatePem, certList); ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; nsCOMPtr<nsIX509Cert> rootCert; - nsCOMPtr<nsIX509CertList> intCerts; + nsTArray<RefPtr<nsIX509Cert>> intCerts; nsCOMPtr<nsIX509Cert> eeCert; - rv = certList->SegmentCertificateChain(rootCert, intCerts, eeCert); + rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, intCerts, + eeCert); ASSERT_EQ(rv, NS_OK) << "Should have segmented OK"; ASSERT_TRUE(rootCert) << "Root cert should be filled in"; ASSERT_TRUE(eeCert) << "End entity cert should be filled in"; - ASSERT_EQ(CountCertsInList(intCerts), 0) + ASSERT_EQ(intCerts.Length(), static_cast<size_t>(0)) << "There should be no intermediates"; bool selfSigned; ASSERT_TRUE(NS_SUCCEEDED(rootCert->GetIsSelfSigned(&selfSigned))) << "Getters should work."; ASSERT_FALSE(selfSigned) << "Roots are self signed, but this was ca-second-intermediate"; @@ -219,43 +201,45 @@ TEST_F(psm_CertList, TestValidSegmenting ASSERT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) << "Getters should work."; ASSERT_TRUE(rootCn.EqualsLiteral("ca-second-intermediate")) << "Second Intermediate CN should match"; rv = AddCertFromStringToList(kCaIntermediatePem, certList); ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; - intCerts = nullptr; + intCerts.Clear(); rootCert = nullptr; eeCert = nullptr; - rv = certList->SegmentCertificateChain(rootCert, intCerts, eeCert); + rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, intCerts, + eeCert); ASSERT_EQ(rv, NS_OK) << "Should have segmented OK"; ASSERT_TRUE(rootCert) << "Root cert should be filled in"; ASSERT_TRUE(eeCert) << "End entity cert should be filled in"; - ASSERT_EQ(CountCertsInList(intCerts), 1) + ASSERT_EQ(intCerts.Length(), static_cast<size_t>(1)) << "There should be one intermediate"; rv = AddCertFromStringToList(kCaPem, certList); ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; - intCerts = nullptr; + intCerts.Clear(); rootCert = nullptr; eeCert = nullptr; - rv = certList->SegmentCertificateChain(rootCert, intCerts, eeCert); + rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, intCerts, + eeCert); ASSERT_EQ(rv, NS_OK) << "Should have segmented OK"; ASSERT_TRUE(rootCert) << "Root cert should be filled in"; ASSERT_TRUE(eeCert) << "End entity cert should be filled in"; - ASSERT_EQ(CountCertsInList(intCerts), 2) + ASSERT_EQ(intCerts.Length(), static_cast<size_t>(2)) << "There should be two intermediates"; ASSERT_TRUE(NS_SUCCEEDED(rootCert->GetIsSelfSigned(&selfSigned))) << "Getters should work."; ASSERT_TRUE(selfSigned) << "Roots are self signed"; ASSERT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) @@ -264,227 +248,107 @@ TEST_F(psm_CertList, TestValidSegmenting << "Root CN should match"; nsAutoString eeCn; ASSERT_TRUE(NS_SUCCEEDED(eeCert->GetCommonName(eeCn))) << "Getters should work."; ASSERT_TRUE(eeCn.EqualsLiteral("ee")) << "EE CN should match"; - rv = intCerts->GetCertList()->ForEachCertificateInChain( - [](nsCOMPtr<nsIX509Cert> aCert, bool aHasMore, bool& aContinue) { - nsAutoString cn; - nsresult rv = aCert->GetCommonName(cn); - if (NS_FAILED(rv)) { - return rv; - } + for (size_t i = 0; i < intCerts.Length(); ++i) { + nsAutoString cn; + const auto& cert = intCerts[i]; + rv = cert->GetCommonName(cn); + if (NS_FAILED(rv)) { + break; + } - if (aHasMore) { - if (!cn.EqualsLiteral("ca-second-intermediate")) { - return NS_ERROR_FAILURE; - } - } else { - if (!cn.EqualsLiteral("ca-intermediate")) { - return NS_ERROR_FAILURE; - } - } - return NS_OK; - }); + if (i < intCerts.Length() - 1) { + if (!cn.EqualsLiteral("ca-second-intermediate")) { + rv = NS_ERROR_FAILURE; + break; + } + } else { + if (!cn.EqualsLiteral("ca-intermediate")) { + rv = NS_ERROR_FAILURE; + break; + } + } + } + ASSERT_EQ(rv, NS_OK) << "Should have looped OK."; } -TEST_F(psm_CertList, TestForEach) { - RefPtr<nsNSSCertList> certList = new nsNSSCertList(); - - bool called = false; - nsresult rv = certList->ForEachCertificateInChain( - [&called](nsCOMPtr<nsIX509Cert> aCert, bool aHasMore, bool& aContinue) { - called = true; - return NS_OK; - }); - ASSERT_EQ(rv, NS_OK) << "Should have iterated OK"; - ASSERT_FALSE(called) - << "There are no certificates in this chain, it shouldn't be called"; - - // Add two certificates - rv = AddCertFromStringToList(kCaPem, certList); - ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; - rv = AddCertFromStringToList(kCaIntermediatePem, certList); - ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; - - int counter = 0; - rv = certList->ForEachCertificateInChain( - [&counter](nsCOMPtr<nsIX509Cert> aCert, bool aHasMore, - bool& aContinue) -> nsresult { - if (!aCert) { - GTEST_NONFATAL_FAILURE_("Unexpected arguments"); - return NS_ERROR_FAILURE; - } - - nsAutoString cn; - nsresult rv = aCert->GetCommonName(cn); - if (NS_FAILED(rv)) { - return rv; - } - - switch (counter) { - case 0: - if (!aHasMore) { - return NS_ERROR_FAILURE; - } - - if (!cn.EqualsLiteral("ca")) { - return NS_ERROR_FAILURE; - } - break; - case 1: - if (aHasMore) { - return NS_ERROR_FAILURE; - } - - if (!cn.EqualsLiteral("ca-intermediate")) { - return NS_ERROR_FAILURE; - } - break; - default: - GTEST_NONFATAL_FAILURE_("Unexpected count"); - return NS_ERROR_UNEXPECTED; - } - counter++; - return NS_OK; - }); - ASSERT_EQ(rv, NS_OK) << "Should have iterated OK"; -} - -TEST_F(psm_CertList, TestForEachContinueSafety) { - RefPtr<nsNSSCertList> certList = new nsNSSCertList(); - - // Add two certificates - nsresult rv = AddCertFromStringToList(kCaSecondIntermediatePem, certList); - ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; - rv = AddCertFromStringToList(kEePem, certList); - ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; - - int counter = 0; - rv = certList->ForEachCertificateInChain( - [&counter](nsCOMPtr<nsIX509Cert> aCert, bool aHasMore, bool& aContinue) { - counter++; - aContinue = true; // Try to keep it going - return NS_OK; - }); - ASSERT_EQ(counter, 2) - << "There should have been only two iterations regardless!"; - ASSERT_EQ(rv, NS_OK) << "Should complete OK."; -} - -TEST_F(psm_CertList, TestForEachStopEarly) { - RefPtr<nsNSSCertList> certList = new nsNSSCertList(); - - // Add two certificates - nsresult rv = AddCertFromStringToList(kCaSecondIntermediatePem, certList); - ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; - rv = AddCertFromStringToList(kEePem, certList); - ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; - - int counter = 0; - rv = certList->ForEachCertificateInChain( - [&counter](nsCOMPtr<nsIX509Cert> aCert, bool aHasMore, bool& aContinue) { - counter++; - aContinue = false; - return NS_OK; - }); - ASSERT_EQ(counter, 1) << "There should have been only the one call"; - ASSERT_EQ(rv, NS_OK) << "Should complete OK."; -} - -TEST_F(psm_CertList, TestForEachStopOnError) { - RefPtr<nsNSSCertList> certList = new nsNSSCertList(); - - // Add two certificates - nsresult rv = AddCertFromStringToList(kCaSecondIntermediatePem, certList); - ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; - rv = AddCertFromStringToList(kEePem, certList); - ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; - - int counter = 0; - rv = certList->ForEachCertificateInChain( - [&counter](nsCOMPtr<nsIX509Cert> aCert, bool aHasMore, bool& aContinue) { - counter++; - return NS_ERROR_FAILURE; - }); - ASSERT_EQ(counter, 1) << "There should have been only the one call"; - ASSERT_EQ(rv, NS_ERROR_FAILURE) << "Should propagate the error."; -} - TEST_F(psm_CertList, TestGetRootCertificateChainTwo) { - RefPtr<nsNSSCertList> certList = new nsNSSCertList(); + nsTArray<RefPtr<nsIX509Cert>> certList; nsresult rv = AddCertFromStringToList(kCaIntermediatePem, certList); ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; rv = AddCertFromStringToList(kCaPem, certList); ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; nsCOMPtr<nsIX509Cert> rootCert; - rv = certList->GetRootCertificate(rootCert); + rv = nsNSSCertificate::GetRootCertificate(certList, rootCert); EXPECT_EQ(NS_OK, rv) << "Should have fetched the root OK"; ASSERT_TRUE(rootCert) << "Root cert should be filled in"; bool selfSigned; EXPECT_TRUE(NS_SUCCEEDED(rootCert->GetIsSelfSigned(&selfSigned))) << "Getters should work."; EXPECT_TRUE(selfSigned) << "Roots are self signed"; nsAutoString rootCn; EXPECT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) << "Getters should work."; EXPECT_TRUE(rootCn.EqualsLiteral("ca")) << "Root CN should match"; // Re-fetch and ensure we get the same certificate. nsCOMPtr<nsIX509Cert> rootCertRepeat; - rv = certList->GetRootCertificate(rootCertRepeat); + rv = nsNSSCertificate::GetRootCertificate(certList, rootCertRepeat); EXPECT_EQ(NS_OK, rv) << "Should have fetched the root OK the second time"; ASSERT_TRUE(rootCertRepeat) << "Root cert should still be filled in"; nsAutoString rootRepeatCn; EXPECT_TRUE(NS_SUCCEEDED(rootCertRepeat->GetCommonName(rootRepeatCn))) << "Getters should work."; EXPECT_TRUE(rootRepeatCn.EqualsLiteral("ca")) << "Root CN should still match"; } TEST_F(psm_CertList, TestGetRootCertificateChainFour) { - RefPtr<nsNSSCertList> certList = new nsNSSCertList(); + nsTArray<RefPtr<nsIX509Cert>> certList; nsresult rv = AddCertFromStringToList(kEePem, certList); ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; rv = AddCertFromStringToList(kCaSecondIntermediatePem, certList); ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; rv = AddCertFromStringToList(kCaIntermediatePem, certList); ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; rv = AddCertFromStringToList(kCaPem, certList); ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; nsCOMPtr<nsIX509Cert> rootCert; - rv = certList->GetRootCertificate(rootCert); + rv = nsNSSCertificate::GetRootCertificate(certList, rootCert); EXPECT_EQ(NS_OK, rv) << "Should have again fetched the root OK"; ASSERT_TRUE(rootCert) << "Root cert should be filled in"; bool selfSigned; EXPECT_TRUE(NS_SUCCEEDED(rootCert->GetIsSelfSigned(&selfSigned))) << "Getters should work."; EXPECT_TRUE(selfSigned) << "Roots are self signed"; nsAutoString rootCn; EXPECT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) << "Getters should work."; EXPECT_TRUE(rootCn.EqualsLiteral("ca")) << "Root CN should match"; } TEST_F(psm_CertList, TestGetRootCertificateChainEmpty) { - RefPtr<nsNSSCertList> certList = new nsNSSCertList(); + nsTArray<RefPtr<nsIX509Cert>> certList; nsCOMPtr<nsIX509Cert> rootCert; - nsresult rv = certList->GetRootCertificate(rootCert); - EXPECT_EQ(NS_OK, rv) << "Should have again fetched the root OK"; + nsresult rv = nsNSSCertificate::GetRootCertificate(certList, rootCert); + EXPECT_EQ(NS_ERROR_FAILURE, rv) + << "Should have returned NS_ERROR_FAILURE because certList was empty"; EXPECT_FALSE(rootCert) << "Root cert should be empty"; }
--- a/security/manager/ssl/tests/gtest/DeserializeCertTest.cpp +++ b/security/manager/ssl/tests/gtest/DeserializeCertTest.cpp @@ -4,17 +4,16 @@ * 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 "gtest/gtest.h" #include "nsCOMPtr.h" #include "nsISimpleEnumerator.h" #include "nsITransportSecurityInfo.h" #include "nsIX509Cert.h" -#include "nsIX509CertList.h" #include "nsSerializationHelper.h" #include "nsString.h" // nsITransportSecurityInfo de-serializatin tests // // These tests verify that we can still deserialize old binary strings // generated for security info. This is necessary because service workers // stores these strings on disk.
--- a/security/manager/ssl/tests/unit/test_cert_chains.js +++ b/security/manager/ssl/tests/unit/test_cert_chains.js @@ -22,37 +22,16 @@ function test_cert_equals() { ); ok( !certA.equals(certC), "equals() on cert objects constructed from files for different certs" + " should return false" ); } -function test_bad_cert_list_serialization() { - // Normally the serialization of an nsIX509CertList consists of some header - // junk (IIDs and whatnot), 4 bytes representing how many nsIX509Cert follow, - // and then the serialization of each nsIX509Cert. This serialization consists - // of the header junk for an nsIX509CertList with 1 "nsIX509Cert", but then - // instead of an nsIX509Cert, the subsequent bytes represent the serialization - // of another nsIX509CertList (with 0 nsIX509Cert). This test ensures that - // nsIX509CertList safely handles this unexpected input when deserializing. - const badCertListSerialization = - "lZ+xZWUXSH+rm9iRO+UxlwAAAAAAAAAAwAAAAAAAAEYAAAABlZ+xZWUXSH+rm9iRO+UxlwAAAAAA" + - "AAAAwAAAAAAAAEYAAAAA"; - let serHelper = Cc["@mozilla.org/network/serialization-helper;1"].getService( - Ci.nsISerializationHelper - ); - throws( - () => serHelper.deserializeObject(badCertListSerialization), - /NS_ERROR_UNEXPECTED/, - "deserializing a bogus nsIX509CertList should throw NS_ERROR_UNEXPECTED" - ); -} - // We hard-code the following certificates for the pkcs7 export tests so that we // don't have to change the test data when the certificates change each year. // Luckily these tests don't depend on the certificates being valid, so it's ok // to let them expire. const gDefaultEEPEM = `-----BEGIN CERTIFICATE----- MIIDiTCCAnGgAwIBAgIUDUo/9G0rz7fJiWTw0hY6TIyPRSIwDQYJKoZIhvcNAQEL BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE3MTEyNzAwMDAwMFoYDzIwMjAw MjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqG @@ -682,21 +661,16 @@ function run_test() { // Test nsIX509Cert.equals add_test(function() { test_cert_equals(); run_next_test(); }); add_test(function() { - test_bad_cert_list_serialization(); - run_next_test(); - }); - - add_test(function() { test_cert_pkcs7_export(); run_next_test(); }); add_test(function() { test_cert_pkcs7_empty_array(); run_next_test(); });
--- a/toolkit/components/downloads/DownloadCore.jsm +++ b/toolkit/components/downloads/DownloadCore.jsm @@ -1935,17 +1935,17 @@ this.DownloadCopySaver.prototype = { /** * Save the SHA-256 hash in raw bytes of the downloaded file. This is null * unless BackgroundFileSaver has successfully completed saving the file. */ _sha256Hash: null, /** - * Save the signature info as an nsIArray of nsIX509CertList of nsIX509Cert + * Save the signature info as an Array of Array of raw bytes of nsIX509Cert * if the file is signed. This is empty if the file is unsigned, and null * unless BackgroundFileSaver has successfully completed saving the file. */ _signatureInfo: null, /** * Save the redirects chain as an nsIArray of nsIPrincipal. */ @@ -2465,17 +2465,17 @@ this.DownloadLegacySaver.prototype = { /** * Save the SHA-256 hash in raw bytes of the downloaded file. This may be * null when nsExternalHelperAppService (and thus BackgroundFileSaver) is not * invoked. */ _sha256Hash: null, /** - * Save the signature info as an nsIArray of nsIX509CertList of nsIX509Cert + * Save the signature info as an Array of Array of raw bytes of nsIX509Cert * if the file is signed. This is empty if the file is unsigned, and null * unless BackgroundFileSaver has successfully completed saving the file. */ _signatureInfo: null, /** * Save the redirect chain as an nsIArray of nsIPrincipal. */
--- a/toolkit/components/securityreporter/SecurityReporter.jsm +++ b/toolkit/components/securityreporter/SecurityReporter.jsm @@ -45,17 +45,17 @@ SecurityReporter.prototype = { "security.ssl.errorReporting.url" ); let reportURI = Services.io.newURI(endpoint); if (reportURI.host == hostname) { return; } - // Convert the nsIX509CertList into a format that can be parsed into + // Convert the array of nsIX509Cert into a format that can be parsed into // JSON let asciiCertChain = []; if (transportSecurityInfo.failedCertChain) { for (let cert of transportSecurityInfo.failedCertChain) { asciiCertChain.push(cert.getBase64DERString()); } }