Bug 1002933: Use Strongly-typed enums more often in mozilla::pkix, r=mmc

--HG--
extra : rebase_source : 3f67f48d1f4150df0830f89e6c07bbbf3a8fc7e8
This commit is contained in:
Brian Smith 2014-04-25 16:29:26 -07:00
parent 456d4f8a4d
commit 9ae1a34e11
15 changed files with 135 additions and 104 deletions

View File

@ -603,8 +603,9 @@ VerifySignature(AppTrustedRoot trustedRoot,
if (trustDomain.SetTrustedRoot(trustedRoot) != SECSuccess) {
return MapSECStatus(SECFailure);
}
if (BuildCertChain(trustDomain, signerCert, PR_Now(), MustBeEndEntity,
KU_DIGITAL_SIGNATURE, SEC_OID_EXT_KEY_USAGE_CODE_SIGN,
if (BuildCertChain(trustDomain, signerCert, PR_Now(),
EndEntityOrCA::MustBeEndEntity, KU_DIGITAL_SIGNATURE,
SEC_OID_EXT_KEY_USAGE_CODE_SIGN,
SEC_OID_X509_ANY_POLICY, nullptr, builtChain)
!= SECSuccess) {
return MapSECStatus(SECFailure);

View File

@ -130,12 +130,12 @@ AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
// CERTDB_TERMINAL_RECORD means "stop trying to inherit trust" so if the
// relevant trust bit isn't set then that means the cert must be considered
// distrusted.
PRUint32 relevantTrustBit = endEntityOrCA == MustBeCA
PRUint32 relevantTrustBit = endEntityOrCA == EndEntityOrCA::MustBeCA
? CERTDB_TRUSTED_CA
: CERTDB_TRUSTED;
if (((flags & (relevantTrustBit | CERTDB_TERMINAL_RECORD)))
== CERTDB_TERMINAL_RECORD) {
*trustLevel = ActivelyDistrusted;
*trustLevel = TrustLevel::ActivelyDistrusted;
return SECSuccess;
}
@ -148,7 +148,7 @@ AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
// needed to consider end-entity certs to be their own trust anchors since
// Gecko implemented nsICertOverrideService.
if (flags & CERTDB_TRUSTED_CA) {
*trustLevel = TrustAnchor;
*trustLevel = TrustLevel::TrustAnchor;
return SECSuccess;
}
#endif
@ -156,11 +156,11 @@ AppTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
// mTrustedRoot is the only trust anchor for this validation.
if (CERT_CompareCerts(mTrustedRoot.get(), candidateCert)) {
*trustLevel = TrustAnchor;
*trustLevel = TrustLevel::TrustAnchor;
return SECSuccess;
}
*trustLevel = InheritsTrust;
*trustLevel = TrustLevel::InheritsTrust;
return SECSuccess;
}

View File

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

View File

@ -308,19 +308,22 @@ BuildCertChainForOneKeyUsage(TrustDomain& trustDomain, CERTCertificate* cert,
PR_ASSERT(ku1);
PR_ASSERT(ku2);
SECStatus rv = BuildCertChain(trustDomain, cert, time, MustBeEndEntity,
ku1, eku, requiredPolicy, stapledOCSPResponse,
builtChain);
SECStatus rv = BuildCertChain(trustDomain, cert, time,
EndEntityOrCA::MustBeEndEntity, ku1,
eku, requiredPolicy,
stapledOCSPResponse, builtChain);
if (rv != SECSuccess && ku2 &&
PR_GetError() == SEC_ERROR_INADEQUATE_KEY_USAGE) {
rv = BuildCertChain(trustDomain, cert, time, MustBeEndEntity,
ku2, eku, requiredPolicy, stapledOCSPResponse,
builtChain);
rv = BuildCertChain(trustDomain, cert, time,
EndEntityOrCA::MustBeEndEntity, ku2,
eku, requiredPolicy,
stapledOCSPResponse, builtChain);
if (rv != SECSuccess && ku3 &&
PR_GetError() == SEC_ERROR_INADEQUATE_KEY_USAGE) {
rv = BuildCertChain(trustDomain, cert, time, MustBeEndEntity,
ku3, eku, requiredPolicy, stapledOCSPResponse,
builtChain);
rv = BuildCertChain(trustDomain, cert, time,
EndEntityOrCA::MustBeEndEntity, ku3,
eku, requiredPolicy,
stapledOCSPResponse, builtChain);
if (rv != SECSuccess) {
PR_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE, 0);
}
@ -386,8 +389,8 @@ CertVerifier::MozillaPKIXVerifyCert(
// just use trustEmail as it is the closest alternative.
NSSCertDBTrustDomain trustDomain(trustEmail, ocspFetching, mOCSPCache,
pinArg);
rv = BuildCertChain(trustDomain, cert, time, MustBeEndEntity,
KU_DIGITAL_SIGNATURE,
rv = BuildCertChain(trustDomain, cert, time,
EndEntityOrCA::MustBeEndEntity, KU_DIGITAL_SIGNATURE,
SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH,
SEC_OID_X509_ANY_POLICY,
stapledOCSPResponse, builtChain);
@ -449,7 +452,7 @@ CertVerifier::MozillaPKIXVerifyCert(
case certificateUsageSSLCA: {
NSSCertDBTrustDomain trustDomain(trustSSL, ocspFetching, mOCSPCache,
pinArg);
rv = BuildCertChain(trustDomain, cert, time, MustBeCA,
rv = BuildCertChain(trustDomain, cert, time, EndEntityOrCA::MustBeCA,
KU_KEY_CERT_SIGN,
SEC_OID_EXT_KEY_USAGE_SERVER_AUTH,
SEC_OID_X509_ANY_POLICY,
@ -460,8 +463,8 @@ CertVerifier::MozillaPKIXVerifyCert(
case certificateUsageEmailSigner: {
NSSCertDBTrustDomain trustDomain(trustEmail, ocspFetching, mOCSPCache,
pinArg);
rv = BuildCertChain(trustDomain, cert, time, MustBeEndEntity,
KU_DIGITAL_SIGNATURE,
rv = BuildCertChain(trustDomain, cert, time,
EndEntityOrCA::MustBeEndEntity, KU_DIGITAL_SIGNATURE,
SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT,
SEC_OID_X509_ANY_POLICY,
stapledOCSPResponse, builtChain);
@ -487,8 +490,8 @@ CertVerifier::MozillaPKIXVerifyCert(
case certificateUsageObjectSigner: {
NSSCertDBTrustDomain trustDomain(trustObjectSigning, ocspFetching,
mOCSPCache, pinArg);
rv = BuildCertChain(trustDomain, cert, time, MustBeEndEntity,
KU_DIGITAL_SIGNATURE,
rv = BuildCertChain(trustDomain, cert, time,
EndEntityOrCA::MustBeEndEntity, KU_DIGITAL_SIGNATURE,
SEC_OID_EXT_KEY_USAGE_CODE_SIGN,
SEC_OID_X509_ANY_POLICY,
stapledOCSPResponse, builtChain);
@ -505,11 +508,11 @@ CertVerifier::MozillaPKIXVerifyCert(
mozilla::pkix::KeyUsages keyUsage;
SECOidTag eku;
if (usage == certificateUsageVerifyCA) {
endEntityOrCA = MustBeCA;
endEntityOrCA = EndEntityOrCA::MustBeCA;
keyUsage = KU_KEY_CERT_SIGN;
eku = SEC_OID_UNKNOWN;
} else {
endEntityOrCA = MustBeEndEntity;
endEntityOrCA = EndEntityOrCA::MustBeEndEntity;
keyUsage = KU_DIGITAL_SIGNATURE;
eku = SEC_OID_OCSP_RESPONDER;
}

View File

@ -100,11 +100,12 @@ NSSCertDBTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
// CERTDB_TERMINAL_RECORD means "stop trying to inherit trust" so if the
// relevant trust bit isn't set then that means the cert must be considered
// distrusted.
PRUint32 relevantTrustBit = endEntityOrCA == MustBeCA ? CERTDB_TRUSTED_CA
: CERTDB_TRUSTED;
PRUint32 relevantTrustBit =
endEntityOrCA == EndEntityOrCA::MustBeCA ? CERTDB_TRUSTED_CA
: CERTDB_TRUSTED;
if (((flags & (relevantTrustBit|CERTDB_TERMINAL_RECORD)))
== CERTDB_TERMINAL_RECORD) {
*trustLevel = ActivelyDistrusted;
*trustLevel = TrustLevel::ActivelyDistrusted;
return SECSuccess;
}
@ -113,19 +114,19 @@ NSSCertDBTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA,
// Gecko implemented nsICertOverrideService.
if (flags & CERTDB_TRUSTED_CA) {
if (policy == SEC_OID_X509_ANY_POLICY) {
*trustLevel = TrustAnchor;
*trustLevel = TrustLevel::TrustAnchor;
return SECSuccess;
}
#ifndef MOZ_NO_EV_CERTS
if (CertIsAuthoritativeForEVPolicy(candidateCert, policy)) {
*trustLevel = TrustAnchor;
*trustLevel = TrustLevel::TrustAnchor;
return SECSuccess;
}
#endif
}
}
*trustLevel = InheritsTrust;
*trustLevel = TrustLevel::InheritsTrust;
return SECSuccess;
}
@ -165,7 +166,7 @@ NSSCertDBTrustDomain::CheckRevocation(
// exception for expired responses because some servers, nginx in particular,
// are known to serve expired responses due to bugs.
if (stapledOCSPResponse) {
PR_ASSERT(endEntityOrCA == MustBeEndEntity);
PR_ASSERT(endEntityOrCA == EndEntityOrCA::MustBeEndEntity);
SECStatus rv = VerifyAndMaybeCacheEncodedOCSPResponse(cert, issuerCert,
time,
stapledOCSPResponse,
@ -250,8 +251,9 @@ NSSCertDBTrustDomain::CheckRevocation(
// you to ever fetch OCSP."
if ((mOCSPFetching == NeverFetchOCSP) ||
(endEntityOrCA == MustBeCA && (mOCSPFetching == FetchOCSPForDVHardFail ||
mOCSPFetching == FetchOCSPForDVSoftFail))) {
(endEntityOrCA == EndEntityOrCA::MustBeCA &&
(mOCSPFetching == FetchOCSPForDVHardFail ||
mOCSPFetching == FetchOCSPForDVSoftFail))) {
// We're not going to be doing any fetching, so if there was a cached
// "unknown" response, say so.
if (cachedResponseErrorCode == SEC_ERROR_OCSP_UNKNOWN_CERT) {

View File

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

View File

@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* Copyright 2013 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Work around missing std::bind, std::ref, std::cref in older compilers. This
// implementation isn't intended to be complete; rather, it is the minimal
// implementation needed to make our use of std::bind work.
#ifndef mozilla_pkix__enumclass_h
#define mozilla_pkix__enumclass_h
#if defined(_MSC_VER) && (_MSC_VER < 1700)
// Microsoft added support for "enum class" in Visual C++ 2012. Before that,
// Visual C++ has supported typed enums for longer than that, but using typed
// enums results in C4480: nonstandard extension used: specifying underlying
// type for enum.
#define MOZILLA_PKIX_ENUM_CLASS __pragma(warning(disable: 4480)) enum
#else
#define MOZILLA_PKIX_ENUM_CLASS enum class
#endif
#endif // mozilla_pkix__enumclass_h

View File

@ -18,6 +18,7 @@
#ifndef mozilla_pkix__pkixtypes_h
#define mozilla_pkix__pkixtypes_h
#include "pkix/enumclass.h"
#include "pkix/ScopedPtr.h"
#include "plarena.h"
#include "cert.h"
@ -35,7 +36,14 @@ typedef ScopedPtr<SECKEYPublicKey, SECKEY_DestroyPublicKey>
typedef unsigned int KeyUsages;
enum EndEntityOrCA { MustBeEndEntity, MustBeCA };
MOZILLA_PKIX_ENUM_CLASS EndEntityOrCA { MustBeEndEntity = 0, MustBeCA = 1 };
MOZILLA_PKIX_ENUM_CLASS TrustLevel {
TrustAnchor = 1, // certificate is a trusted root CA certificate or
// equivalent *for the given policy*.
ActivelyDistrusted = 2, // certificate is known to be bad
InheritsTrust = 3 // certificate must chain to a trust anchor
};
// Applications control the behavior of path building and verification by
// implementing the TrustDomain interface. The TrustDomain is used for all
@ -46,13 +54,6 @@ class TrustDomain
public:
virtual ~TrustDomain() { }
enum TrustLevel {
TrustAnchor = 1, // certificate is a trusted root CA certificate or
// equivalent *for the given policy*.
ActivelyDistrusted = 2, // certificate is known to be bad
InheritsTrust = 3 // certificate must chain to a trust anchor
};
// Determine the level of trust in the given certificate for the given role.
// This will be called for every certificate encountered during path
// building.

View File

@ -128,7 +128,7 @@ BuildForwardInner(TrustDomain& trustDomain,
PORT_Assert(potentialIssuerCertToDup);
BackCert potentialIssuer(potentialIssuerCertToDup, &subject,
BackCert::ExcludeCN);
BackCert::IncludeCN::No);
Result rv = potentialIssuer.Init();
if (rv != Success) {
return rv;
@ -157,12 +157,12 @@ BuildForwardInner(TrustDomain& trustDomain,
}
unsigned int newSubCACount = subCACount;
if (endEntityOrCA == MustBeCA) {
if (endEntityOrCA == EndEntityOrCA::MustBeCA) {
newSubCACount = subCACount + 1;
} else {
PR_ASSERT(newSubCACount == 0);
}
rv = BuildForward(trustDomain, potentialIssuer, time, MustBeCA,
rv = BuildForward(trustDomain, potentialIssuer, time, EndEntityOrCA::MustBeCA,
KU_KEY_CERT_SIGN, requiredEKUIfPresent, requiredPolicy,
nullptr, newSubCACount, results);
if (rv != Success) {
@ -204,7 +204,7 @@ BuildForward(TrustDomain& trustDomain,
Result rv;
TrustDomain::TrustLevel trustLevel;
TrustLevel trustLevel;
// If this is an end-entity and not a trust anchor, we defer reporting
// any error found here until after attempting to find a valid chain.
// See the explanation of error prioritization in pkix.h.
@ -215,15 +215,15 @@ BuildForward(TrustDomain& trustDomain,
subCACount, &trustLevel);
PRErrorCode deferredEndEntityError = 0;
if (rv != Success) {
if (endEntityOrCA == MustBeEndEntity &&
trustLevel != TrustDomain::TrustAnchor) {
if (endEntityOrCA == EndEntityOrCA::MustBeEndEntity &&
trustLevel != TrustLevel::TrustAnchor) {
deferredEndEntityError = PR_GetError();
} else {
return rv;
}
}
if (trustLevel == TrustDomain::TrustAnchor) {
if (trustLevel == TrustLevel::TrustAnchor) {
ScopedCERTCertList certChain(CERT_NewCertList());
if (!certChain) {
PR_SetError(SEC_ERROR_NO_MEMORY, 0);
@ -346,13 +346,13 @@ BuildCertChain(TrustDomain& trustDomain,
// XXX: Support the legacy use of the subject CN field for indicating the
// domain name the certificate is valid for.
BackCert::ConstrainedNameOptions cnOptions
= endEntityOrCA == MustBeEndEntity &&
BackCert::IncludeCN includeCN
= endEntityOrCA == EndEntityOrCA::MustBeEndEntity &&
requiredEKUIfPresent == SEC_OID_EXT_KEY_USAGE_SERVER_AUTH
? BackCert::IncludeCN
: BackCert::ExcludeCN;
? BackCert::IncludeCN::Yes
: BackCert::IncludeCN::No;
BackCert cert(certToDup, nullptr, cnOptions);
BackCert cert(certToDup, nullptr, includeCN);
Result rv = cert.Init();
if (rv != Success) {
return SECFailure;

View File

@ -51,7 +51,7 @@ CheckKeyUsage(EndEntityOrCA endEntityOrCA,
// certificate signatures unless the certificate is a trust anchor, to
// reduce the chances of an end-entity certificate being abused as a CA
// certificate.
// if (endEntityOrCA == MustBeCA && !isTrustAnchor) {
// if (endEntityOrCA == EndEntityOrCA::MustBeCA && !isTrustAnchor) {
// return Fail(RecoverableError, SEC_ERROR_INADEQUATE_KEY_USAGE);
// }
//
@ -77,7 +77,7 @@ CheckKeyUsage(EndEntityOrCA endEntityOrCA,
return Fail(RecoverableError, SEC_ERROR_INADEQUATE_KEY_USAGE);
}
if (endEntityOrCA == MustBeCA) {
if (endEntityOrCA == EndEntityOrCA::MustBeCA) {
// "If the keyUsage extension is present, then the subject public key
// MUST NOT be used to verify signatures on certificates or CRLs unless
// the corresponding keyCertSign or cRLSign bit is set."
@ -129,7 +129,7 @@ CheckCertificatePolicies(BackCert& cert, EndEntityOrCA endEntityOrCA,
// trusted for, so we cannot require the policies to be present in those
// certificates. Instead, the determination of which roots are trusted for
// which policies is made by the TrustDomain's GetCertTrust method.
if (isTrustAnchor && endEntityOrCA == MustBeCA) {
if (isTrustAnchor && endEntityOrCA == EndEntityOrCA::MustBeCA) {
return Success;
}
@ -150,7 +150,7 @@ CheckCertificatePolicies(BackCert& cert, EndEntityOrCA endEntityOrCA,
return Success;
}
// Intermediate certs are allowed to have the anyPolicy OID
if (endEntityOrCA == MustBeCA &&
if (endEntityOrCA == EndEntityOrCA::MustBeCA &&
(*policyInfos)->oid == SEC_OID_X509_ANY_POLICY) {
return Success;
}
@ -248,7 +248,7 @@ CheckBasicConstraints(const BackCert& cert,
// constraints as CAs.
//
// TODO: add check for self-signedness?
if (endEntityOrCA == MustBeCA && isTrustAnchor) {
if (endEntityOrCA == EndEntityOrCA::MustBeCA && isTrustAnchor) {
const CERTCertificate* nssCert = cert.GetNSSCert();
// We only allow trust anchor CA certs to omit the
// basicConstraints extension if they are v1. v1 is encoded
@ -260,7 +260,7 @@ CheckBasicConstraints(const BackCert& cert,
}
}
if (endEntityOrCA == MustBeEndEntity) {
if (endEntityOrCA == EndEntityOrCA::MustBeEndEntity) {
// CA certificates are not trusted as EE certs.
if (basicConstraints.isCA) {
@ -280,7 +280,7 @@ CheckBasicConstraints(const BackCert& cert,
return Success;
}
PORT_Assert(endEntityOrCA == MustBeCA);
PORT_Assert(endEntityOrCA == EndEntityOrCA::MustBeCA);
// End-entity certificates are not allowed to act as CA certs.
if (!basicConstraints.isCA) {
@ -307,7 +307,7 @@ BackCert::GetConstrainedNames(/*out*/ const CERTGeneralName** result)
constrainedNames =
CERT_GetConstrainedCertificateNames(nssCert, arena.get(),
cnOptions == IncludeCN);
includeCN == IncludeCN::Yes);
if (!constrainedNames) {
return MapSECStatus(SECFailure);
}
@ -397,7 +397,7 @@ CheckExtendedKeyUsage(EndEntityOrCA endEntityOrCA, const SECItem* encodedEKUs,
// COMODO has issued certificates that require this behavior
// that don't expire until June 2020!
// TODO 982932: Limit this expection to old certificates
if (endEntityOrCA == MustBeCA &&
if (endEntityOrCA == EndEntityOrCA::MustBeCA &&
requiredEKU == SEC_OID_EXT_KEY_USAGE_SERVER_AUTH &&
oidTag == SEC_OID_NS_KEY_USAGE_GOVT_APPROVED) {
found = true;
@ -417,7 +417,7 @@ CheckExtendedKeyUsage(EndEntityOrCA endEntityOrCA, const SECItem* encodedEKUs,
// pkixocsp.cpp depends on the following additional checks.
if (endEntityOrCA == MustBeEndEntity) {
if (endEntityOrCA == EndEntityOrCA::MustBeEndEntity) {
// When validating anything other than an delegated OCSP signing cert,
// reject any cert that also claims to be an OCSP responder, because such
// a cert does not make sense. For example, if an SSL certificate were to
@ -461,11 +461,11 @@ CheckIssuerIndependentProperties(TrustDomain& trustDomain,
SECOidTag requiredEKUIfPresent,
SECOidTag requiredPolicy,
unsigned int subCACount,
/*optional out*/ TrustDomain::TrustLevel* trustLevelOut)
/*optional out*/ TrustLevel* trustLevelOut)
{
Result rv;
TrustDomain::TrustLevel trustLevel;
TrustLevel trustLevel;
rv = MapSECStatus(trustDomain.GetCertTrust(endEntityOrCA,
requiredPolicy,
cert.GetNSSCert(),
@ -473,11 +473,11 @@ CheckIssuerIndependentProperties(TrustDomain& trustDomain,
if (rv != Success) {
return rv;
}
if (trustLevel == TrustDomain::ActivelyDistrusted) {
if (trustLevel == TrustLevel::ActivelyDistrusted) {
return Fail(RecoverableError, SEC_ERROR_UNTRUSTED_CERT);
}
if (trustLevel != TrustDomain::TrustAnchor &&
trustLevel != TrustDomain::InheritsTrust) {
if (trustLevel != TrustLevel::TrustAnchor &&
trustLevel != TrustLevel::InheritsTrust) {
// The TrustDomain returned a trust level that we weren't expecting.
PORT_SetError(PR_INVALID_STATE_ERROR);
return FatalError;
@ -486,8 +486,8 @@ CheckIssuerIndependentProperties(TrustDomain& trustDomain,
*trustLevelOut = trustLevel;
}
bool isTrustAnchor = endEntityOrCA == MustBeCA &&
trustLevel == TrustDomain::TrustAnchor;
bool isTrustAnchor = endEntityOrCA == EndEntityOrCA::MustBeCA &&
trustLevel == TrustLevel::TrustAnchor;
PLArenaPool* arena = cert.GetArena();
if (!arena) {

View File

@ -32,7 +32,7 @@ Result CheckIssuerIndependentProperties(
SECOidTag requiredEKUIfPresent,
SECOidTag requiredPolicy,
unsigned int subCACount,
/*optional out*/ TrustDomain::TrustLevel* trustLevel = nullptr);
/*optional out*/ TrustLevel* trustLevel = nullptr);
Result CheckNameConstraints(BackCert& cert);

View File

@ -18,6 +18,7 @@
#ifndef mozilla_pkix__pkixder_h
#define mozilla_pkix__pkixder_h
#include "pkix/enumclass.h"
#include "pkix/nullptr.h"
#include "prerror.h"
@ -61,7 +62,7 @@ enum Result
Success = 0
};
enum EmptyAllowed { MayBeEmpty = 0, MustNotBeEmpty = 1 };
MOZILLA_PKIX_ENUM_CLASS EmptyAllowed { No = 0, Yes = 1 };
Result Fail(PRErrorCode errorCode);
@ -324,7 +325,7 @@ NestedOf(Input& input, uint8_t outerTag, uint8_t innerTag,
}
if (inner.AtEnd()) {
if (mayBeEmpty != MayBeEmpty) {
if (mayBeEmpty != EmptyAllowed::Yes) {
return Fail(SEC_ERROR_BAD_DER);
}
return Success;

View File

@ -26,13 +26,6 @@
#include "pk11pub.h"
#include "secder.h"
#ifdef _MSC_VER
// C4480: nonstandard extension used: specifying underlying type for enum
#define ENUM_CLASS __pragma(warning(disable: 4480)) enum
#else
#define ENUM_CLASS enum class
#endif
// TODO: use typed/qualified typedefs everywhere?
// TODO: When should we return SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE?
@ -43,7 +36,7 @@ static const PRTime ONE_DAY
static const PRTime SLOP = ONE_DAY;
// These values correspond to the tag values in the ASN.1 CertStatus
ENUM_CLASS CertStatus : uint8_t {
MOZILLA_PKIX_ENUM_CLASS CertStatus : uint8_t {
Good = der::CONTEXT_SPECIFIC | 0,
Revoked = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
Unknown = der::CONTEXT_SPECIFIC | 2
@ -96,7 +89,7 @@ CheckOCSPResponseSignerCert(TrustDomain& trustDomain,
{
Result rv;
BackCert cert(&potentialSigner, nullptr, BackCert::ExcludeCN);
BackCert cert(&potentialSigner, nullptr, BackCert::IncludeCN::No);
rv = cert.Init();
if (rv != Success) {
return rv;
@ -126,7 +119,7 @@ CheckOCSPResponseSignerCert(TrustDomain& trustDomain,
// TODO(bug 926261): If we're validating for a policy then the policy OID we
// are validating for should be passed to CheckIssuerIndependentProperties.
rv = CheckIssuerIndependentProperties(trustDomain, cert, time,
MustBeEndEntity, 0,
EndEntityOrCA::MustBeEndEntity, 0,
SEC_OID_OCSP_RESPONDER,
SEC_OID_X509_ANY_POLICY, 0);
if (rv != Success) {
@ -157,12 +150,7 @@ CheckOCSPResponseSignerCert(TrustDomain& trustDomain,
return Success;
}
//typedef enum {
// ocspResponderID_byName = 1,
// ocspResponderID_byKey = 2
//} ResponderIDType;
ENUM_CLASS ResponderIDType : uint8_t
MOZILLA_PKIX_ENUM_CLASS ResponderIDType : uint8_t
{
byName = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
byKey = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 2
@ -580,7 +568,7 @@ ResponseData(der::Input& input, Context& context,
// responder will never return an empty response, and handling the case of an
// empty response makes things unnecessarily complicated.
if (der::NestedOf(input, der::SEQUENCE, der::SEQUENCE,
der::MustNotBeEmpty,
der::EmptyAllowed::No,
bind(SingleResponse, _1, ref(context))) != der::Success) {
return der::Failure;
}
@ -866,7 +854,7 @@ CheckExtensionsForCriticality(der::Input& input)
// Extension, which is invalid (der::MayBeEmpty should really be
// der::MustNotBeEmpty).
return der::NestedOf(input, der::SEQUENCE, der::SEQUENCE,
der::MayBeEmpty, CheckExtensionForCriticality);
der::EmptyAllowed::Yes, CheckExtensionForCriticality);
}
// 1. The certificate identified in a received response corresponds to

View File

@ -18,6 +18,7 @@
#ifndef mozilla_pkix__pkixutil_h
#define mozilla_pkix__pkixutil_h
#include "pkix/enumclass.h"
#include "pkix/pkixtypes.h"
#include "prerror.h"
#include "seccomon.h"
@ -81,14 +82,13 @@ MapSECStatus(SECStatus srv)
class BackCert
{
public:
// ExcludeCN means that GetConstrainedNames won't include the subject CN in
// its results. IncludeCN means that GetConstrainedNames will include the
// subject CN in its results.
enum ConstrainedNameOptions { ExcludeCN = 0, IncludeCN = 1 };
// IncludeCN::No means that GetConstrainedNames won't include the subject CN
// in its results. IncludeCN::Yes means that GetConstrainedNames will include
// the subject CN in its results.
MOZILLA_PKIX_ENUM_CLASS IncludeCN { No = 0, Yes = 1 };
// nssCert and childCert must be valid for the lifetime of BackCert
BackCert(CERTCertificate* nssCert, BackCert* childCert,
ConstrainedNameOptions cnOptions)
BackCert(CERTCertificate* nssCert, BackCert* childCert, IncludeCN includeCN)
: encodedBasicConstraints(nullptr)
, encodedCertificatePolicies(nullptr)
, encodedExtendedKeyUsage(nullptr)
@ -98,7 +98,7 @@ public:
, childCert(childCert)
, nssCert(nssCert)
, constrainedNames(nullptr)
, cnOptions(cnOptions)
, includeCN(includeCN)
{
}
@ -137,7 +137,7 @@ private:
ScopedPLArenaPool arena;
CERTGeneralName* constrainedNames;
ConstrainedNameOptions cnOptions;
IncludeCN includeCN;
BackCert(const BackCert&) /* = delete */;
void operator=(const BackCert&); /* = delete */;

View File

@ -550,7 +550,7 @@ TEST_F(pkixder_input_tests, NestedOf)
std::vector<uint8_t> readValues;
ASSERT_EQ(Success,
NestedOf(input, SEQUENCE, INTEGER, MustNotBeEmpty,
NestedOf(input, SEQUENCE, INTEGER, EmptyAllowed::No,
mozilla::pkix::bind(NestedOfHelper, mozilla::pkix::_1,
mozilla::pkix::ref(readValues))));
ASSERT_EQ((size_t) 3, readValues.size());
@ -568,7 +568,7 @@ TEST_F(pkixder_input_tests, NestedOfWithTruncatedData)
std::vector<uint8_t> readValues;
ASSERT_EQ(Failure,
NestedOf(input, SEQUENCE, INTEGER, MustNotBeEmpty,
NestedOf(input, SEQUENCE, INTEGER, EmptyAllowed::No,
mozilla::pkix::bind(NestedOfHelper, mozilla::pkix::_1,
mozilla::pkix::ref(readValues))));
ASSERT_EQ(SEC_ERROR_BAD_DER, PR_GetError());