Bug 1019814: Remove CERTCertificate dependency from TrustDomain::GetCertTrust, r=keeler

--HG--
extra : rebase_source : 9abf0522f02d00ac2f63f2327ddbe8d119ffc64f
This commit is contained in:
Brian Smith 2014-06-03 10:47:25 -07:00
parent 8b52746412
commit a33f724e49
8 changed files with 43 additions and 19 deletions

View File

@ -104,14 +104,13 @@ AppTrustDomain::FindPotentialIssuers(const SECItem* encodedIssuerName,
SECStatus
AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
const CertPolicyId& policy,
const CERTCertificate* candidateCert,
const SECItem& candidateCertDER,
/*out*/ TrustLevel* trustLevel)
{
MOZ_ASSERT(policy.IsAnyPolicy());
MOZ_ASSERT(candidateCert);
MOZ_ASSERT(trustLevel);
MOZ_ASSERT(mTrustedRoot);
if (!candidateCert || !trustLevel || !policy.IsAnyPolicy()) {
if (!trustLevel || !policy.IsAnyPolicy()) {
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
return SECFailure;
}
@ -121,8 +120,20 @@ AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
}
// Handle active distrust of the certificate.
// XXX: This would be cleaner and more efficient if we could get the trust
// information without constructing a CERTCertificate here, but NSS doesn't
// expose it in any other easy-to-use fashion.
ScopedCERTCertificate candidateCert(
CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
const_cast<SECItem*>(&candidateCertDER), nullptr,
false, true));
if (!candidateCert) {
return SECFailure;
}
CERTCertTrust trust;
if (CERT_GetCertTrust(candidateCert, &trust) == SECSuccess) {
if (CERT_GetCertTrust(candidateCert.get(), &trust) == SECSuccess) {
PRUint32 flags = SEC_GET_TRUST_FLAGS(&trust, trustObjectSigning);
// For DISTRUST, we use the CERTDB_TRUSTED or CERTDB_TRUSTED_CA bit,
@ -141,7 +152,7 @@ AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
}
// mTrustedRoot is the only trust anchor for this validation.
if (CERT_CompareCerts(mTrustedRoot.get(), candidateCert)) {
if (CERT_CompareCerts(mTrustedRoot.get(), candidateCert.get())) {
*trustLevel = TrustLevel::TrustAnchor;
return SECSuccess;
}

View File

@ -22,7 +22,7 @@ public:
SECStatus GetCertTrust(mozilla::pkix::EndEntityOrCA endEntityOrCA,
const mozilla::pkix::CertPolicyId& policy,
const CERTCertificate* candidateCert,
const SECItem& candidateCertDER,
/*out*/ mozilla::pkix::TrustLevel* trustLevel) MOZ_OVERRIDE;
SECStatus FindPotentialIssuers(const SECItem* encodedIssuerName,
PRTime time,

View File

@ -72,13 +72,12 @@ NSSCertDBTrustDomain::FindPotentialIssuers(
SECStatus
NSSCertDBTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
const CertPolicyId& policy,
const CERTCertificate* candidateCert,
const SECItem& candidateCertDER,
/*out*/ TrustLevel* trustLevel)
{
PR_ASSERT(candidateCert);
PR_ASSERT(trustLevel);
if (!candidateCert || !trustLevel) {
if (!trustLevel) {
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
return SECFailure;
}
@ -90,13 +89,27 @@ NSSCertDBTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
}
#endif
// XXX: This would be cleaner and more efficient if we could get the trust
// information without constructing a CERTCertificate here, but NSS doesn't
// expose it in any other easy-to-use fashion. The use of
// CERT_NewTempCertificate to get a CERTCertificate shouldn't be a
// performance problem because NSS will just find the existing
// CERTCertificate in its in-memory cache and return it.
ScopedCERTCertificate candidateCert(
CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
const_cast<SECItem*>(&candidateCertDER), nullptr,
false, true));
if (!candidateCert) {
return SECFailure;
}
// XXX: CERT_GetCertTrust seems to be abusing SECStatus as a boolean, where
// SECSuccess means that there is a trust record and SECFailure means there
// is not a trust record. I looked at NSS's internal uses of
// CERT_GetCertTrust, and all that code uses the result as a boolean meaning
// "We have a trust record."
CERTCertTrust trust;
if (CERT_GetCertTrust(candidateCert, &trust) == SECSuccess) {
if (CERT_GetCertTrust(candidateCert.get(), &trust) == SECSuccess) {
PRUint32 flags = SEC_GET_TRUST_FLAGS(&trust, mCertDBTrustType);
// For DISTRUST, we use the CERTDB_TRUSTED or CERTDB_TRUSTED_CA bit,
@ -122,7 +135,7 @@ NSSCertDBTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
return SECSuccess;
}
#ifndef MOZ_NO_EV_CERTS
if (CertIsAuthoritativeForEVPolicy(candidateCert, policy)) {
if (CertIsAuthoritativeForEVPolicy(candidateCert.get(), policy)) {
*trustLevel = TrustLevel::TrustAnchor;
return SECSuccess;
}

View File

@ -68,7 +68,7 @@ public:
virtual SECStatus GetCertTrust(mozilla::pkix::EndEntityOrCA endEntityOrCA,
const mozilla::pkix::CertPolicyId& policy,
const CERTCertificate* candidateCert,
const SECItem& candidateCertDER,
/*out*/ mozilla::pkix::TrustLevel* trustLevel);
virtual SECStatus VerifySignedData(const CERTSignedData* signedData,

View File

@ -95,7 +95,7 @@ public:
// (assuming the candidate cert is not actively distrusted).
virtual SECStatus GetCertTrust(EndEntityOrCA endEntityOrCA,
const CertPolicyId& policy,
const CERTCertificate* candidateCert,
const SECItem& candidateCertDER,
/*out*/ TrustLevel* trustLevel) = 0;
// Find all certificates (intermediate and/or root) in the certificate

View File

@ -558,10 +558,8 @@ CheckIssuerIndependentProperties(TrustDomain& trustDomain,
Result rv;
TrustLevel trustLevel;
rv = MapSECStatus(trustDomain.GetCertTrust(endEntityOrCA,
requiredPolicy,
cert.GetNSSCert(),
&trustLevel));
rv = MapSECStatus(trustDomain.GetCertTrust(endEntityOrCA, requiredPolicy,
cert.GetDER(), &trustLevel));
if (rv != Success) {
return rv;
}

View File

@ -111,6 +111,8 @@ public:
Result Init();
const SECItem& GetDER() const { return nssCert->derCert; }
const SECItem* encodedBasicConstraints;
const SECItem* encodedCertificatePolicies;
const SECItem* encodedExtendedKeyUsage;

View File

@ -115,10 +115,10 @@ public:
private:
SECStatus GetCertTrust(EndEntityOrCA,
const CertPolicyId&,
const CERTCertificate* candidateCert,
const SECItem& candidateCert,
/*out*/ TrustLevel* trustLevel)
{
if (candidateCert == certChainTail[0].get()) {
if (SECITEM_ItemsAreEqual(&candidateCert, &certChainTail[0]->derCert)) {
*trustLevel = TrustLevel::TrustAnchor;
} else {
*trustLevel = TrustLevel::InheritsTrust;