123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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 "CSTrustDomain.h"
- #include "mozilla/Base64.h"
- #include "mozilla/Preferences.h"
- #include "nsNSSCertificate.h"
- #include "nsNSSComponent.h"
- #include "nsServiceManagerUtils.h"
- #include "nsThreadUtils.h"
- #include "pkix/pkixnss.h"
- using namespace mozilla::pkix;
- namespace mozilla { namespace psm {
- static LazyLogModule gTrustDomainPRLog("CSTrustDomain");
- #define CSTrust_LOG(args) MOZ_LOG(gTrustDomainPRLog, LogLevel::Debug, args)
- CSTrustDomain::CSTrustDomain(UniqueCERTCertList& certChain)
- : mCertChain(certChain)
- , mCertBlocklist(do_GetService(NS_CERTBLOCKLIST_CONTRACTID))
- {
- }
- Result
- CSTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
- const CertPolicyId& policy, Input candidateCertDER,
- /*out*/ TrustLevel& trustLevel)
- {
- MOZ_ASSERT(policy.IsAnyPolicy());
- if (!policy.IsAnyPolicy()) {
- return Result::FATAL_ERROR_INVALID_ARGS;
- }
- SECItem candidateCertDERSECItem = UnsafeMapInputToSECItem(candidateCertDER);
- UniqueCERTCertificate candidateCert(
- CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &candidateCertDERSECItem,
- nullptr, false, true));
- if (!candidateCert) {
- return MapPRErrorCodeToResult(PR_GetError());
- }
- bool isCertRevoked;
- nsresult nsrv = mCertBlocklist->IsCertRevoked(
- candidateCert->derIssuer.data,
- candidateCert->derIssuer.len,
- candidateCert->serialNumber.data,
- candidateCert->serialNumber.len,
- candidateCert->derSubject.data,
- candidateCert->derSubject.len,
- candidateCert->derPublicKey.data,
- candidateCert->derPublicKey.len,
- &isCertRevoked);
- if (NS_FAILED(nsrv)) {
- return Result::FATAL_ERROR_LIBRARY_FAILURE;
- }
- if (isCertRevoked) {
- CSTrust_LOG(("CSTrustDomain: certificate is revoked\n"));
- return Result::ERROR_REVOKED_CERTIFICATE;
- }
- // Is this cert our built-in content signing root?
- bool isRoot = false;
- nsCOMPtr<nsINSSComponent> component(do_GetService(PSM_COMPONENT_CONTRACTID));
- if (!component) {
- return Result::FATAL_ERROR_LIBRARY_FAILURE;
- }
- nsrv = component->IsCertContentSigningRoot(candidateCert.get(), isRoot);
- if (NS_FAILED(nsrv)) {
- return Result::FATAL_ERROR_LIBRARY_FAILURE;
- }
- if (isRoot) {
- CSTrust_LOG(("CSTrustDomain: certificate is a trust anchor\n"));
- trustLevel = TrustLevel::TrustAnchor;
- return Success;
- }
- CSTrust_LOG(("CSTrustDomain: certificate is *not* a trust anchor\n"));
- trustLevel = TrustLevel::InheritsTrust;
- return Success;
- }
- Result
- CSTrustDomain::FindIssuer(Input encodedIssuerName, IssuerChecker& checker,
- Time time)
- {
- // Loop over the chain, look for a matching subject
- for (CERTCertListNode* n = CERT_LIST_HEAD(mCertChain);
- !CERT_LIST_END(n, mCertChain); n = CERT_LIST_NEXT(n)) {
- Input certDER;
- Result rv = certDER.Init(n->cert->derCert.data, n->cert->derCert.len);
- if (rv != Success) {
- continue; // probably too big
- }
- // if the subject does not match, try the next certificate
- Input subjectDER;
- rv = subjectDER.Init(n->cert->derSubject.data, n->cert->derSubject.len);
- if (rv != Success) {
- continue; // just try the next one
- }
- if (!InputsAreEqual(subjectDER, encodedIssuerName)) {
- CSTrust_LOG(("CSTrustDomain: subjects don't match\n"));
- continue;
- }
- // If the subject does match, try the next step
- bool keepGoing;
- rv = checker.Check(certDER, nullptr/*additionalNameConstraints*/,
- keepGoing);
- if (rv != Success) {
- return rv;
- }
- if (!keepGoing) {
- CSTrust_LOG(("CSTrustDomain: don't keep going\n"));
- break;
- }
- }
- return Success;
- }
- Result
- CSTrustDomain::CheckRevocation(EndEntityOrCA endEntityOrCA,
- const CertID& certID, Time time,
- Duration validityDuration,
- /*optional*/ const Input* stapledOCSPresponse,
- /*optional*/ const Input* aiaExtension,
- /*optional*/ const Input* sctExtension)
- {
- // We're relying solely on the CertBlocklist for revocation - and we're
- // performing checks on this in GetCertTrust (as per nsNSSCertDBTrustDomain)
- return Success;
- }
- Result
- CSTrustDomain::IsChainValid(const DERArray& certChain, Time time,
- const CertPolicyId& requiredPolicy)
- {
- // Check that our chain is not empty
- if (certChain.GetLength() == 0) {
- return Result::FATAL_ERROR_LIBRARY_FAILURE;
- }
- return Success;
- }
- Result
- CSTrustDomain::CheckSignatureDigestAlgorithm(DigestAlgorithm digestAlg,
- EndEntityOrCA endEntityOrCA,
- Time notBefore)
- {
- if (digestAlg == DigestAlgorithm::sha1) {
- return Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED;
- }
- return Success;
- }
- Result
- CSTrustDomain::CheckRSAPublicKeyModulusSizeInBits(
- EndEntityOrCA endEntityOrCA, unsigned int modulusSizeInBits)
- {
- if (modulusSizeInBits < 2048) {
- return Result::ERROR_INADEQUATE_KEY_SIZE;
- }
- return Success;
- }
- Result
- CSTrustDomain::VerifyRSAPKCS1SignedDigest(const SignedDigest& signedDigest,
- Input subjectPublicKeyInfo)
- {
- return VerifyRSAPKCS1SignedDigestNSS(signedDigest, subjectPublicKeyInfo,
- nullptr);
- }
- Result
- CSTrustDomain::CheckECDSACurveIsAcceptable(EndEntityOrCA endEntityOrCA,
- NamedCurve curve)
- {
- switch (curve) {
- case NamedCurve::secp256r1: // fall through
- case NamedCurve::secp384r1: // fall through
- case NamedCurve::secp521r1:
- return Success;
- }
- return Result::ERROR_UNSUPPORTED_ELLIPTIC_CURVE;
- }
- Result
- CSTrustDomain::VerifyECDSASignedDigest(const SignedDigest& signedDigest,
- Input subjectPublicKeyInfo)
- {
- return VerifyECDSASignedDigestNSS(signedDigest, subjectPublicKeyInfo,
- nullptr);
- }
- Result
- CSTrustDomain::CheckValidityIsAcceptable(Time notBefore, Time notAfter,
- EndEntityOrCA endEntityOrCA,
- KeyPurposeId keyPurpose)
- {
- return Success;
- }
- Result
- CSTrustDomain::NetscapeStepUpMatchesServerAuth(Time notBefore,
- /*out*/ bool& matches)
- {
- matches = false;
- return Success;
- }
- void
- CSTrustDomain::NoteAuxiliaryExtension(AuxiliaryExtension /*extension*/,
- Input /*extensionData*/)
- {
- }
- Result
- CSTrustDomain::DigestBuf(Input item, DigestAlgorithm digestAlg,
- /*out*/ uint8_t* digestBuf, size_t digestBufLen)
- {
- return DigestBufNSS(item, digestAlg, digestBuf, digestBufLen);
- }
- } } // end namespace mozilla::psm
|