diff --git a/src/crypto/x509/internal.h b/src/crypto/x509/internal.h index 9e943e09f..62eaa96f4 100644 --- a/src/crypto/x509/internal.h +++ b/src/crypto/x509/internal.h @@ -272,6 +272,14 @@ struct X509_crl_st { // 5280) and C type is |X509_CRL*|. DECLARE_ASN1_ITEM(X509_CRL) +// GENERAL_NAME is an |ASN1_ITEM| whose ASN.1 type is GeneralName and C type is +// |GENERAL_NAME*|. +DECLARE_ASN1_ITEM(GENERAL_NAME) + +// GENERAL_NAMES is an |ASN1_ITEM| whose ASN.1 type is SEQUENCE OF GeneralName +// and C type is |GENERAL_NAMES*|, aka |STACK_OF(GENERAL_NAME)*|. +DECLARE_ASN1_ITEM(GENERAL_NAMES) + struct X509_VERIFY_PARAM_st { int64_t check_time; // POSIX time to use unsigned long flags; // Various verify flags diff --git a/src/crypto/x509/v3_akeya.c b/src/crypto/x509/v3_akeya.c index 4a05aae63..8614b86c8 100644 --- a/src/crypto/x509/v3_akeya.c +++ b/src/crypto/x509/v3_akeya.c @@ -61,6 +61,8 @@ #include #include +#include "internal.h" + ASN1_SEQUENCE(AUTHORITY_KEYID) = { ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0), diff --git a/src/crypto/x509/v3_genn.c b/src/crypto/x509/v3_genn.c index 42cd78790..ec3a282d6 100644 --- a/src/crypto/x509/v3_genn.c +++ b/src/crypto/x509/v3_genn.c @@ -70,7 +70,7 @@ ASN1_SEQUENCE(OTHERNAME) = { ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0), } ASN1_SEQUENCE_END(OTHERNAME) -IMPLEMENT_ASN1_FUNCTIONS_const(OTHERNAME) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(OTHERNAME) ASN1_SEQUENCE(EDIPARTYNAME) = { // DirectoryString is a CHOICE type, so use explicit tagging. @@ -78,7 +78,7 @@ ASN1_SEQUENCE(EDIPARTYNAME) = { ASN1_EXP(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1), } ASN1_SEQUENCE_END(EDIPARTYNAME) -IMPLEMENT_ASN1_FUNCTIONS_const(EDIPARTYNAME) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(EDIPARTYNAME) ASN1_CHOICE(GENERAL_NAME) = { ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME), @@ -208,9 +208,9 @@ void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) { a->type = type; } -void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype) { - if (ptype) { - *ptype = a->type; +void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *out_type) { + if (out_type) { + *out_type = a->type; } switch (a->type) { case GEN_X400: @@ -255,16 +255,16 @@ int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, ASN1_OBJECT *oid, return 1; } -int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, ASN1_OBJECT **poid, - ASN1_TYPE **pvalue) { +int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, ASN1_OBJECT **out_oid, + ASN1_TYPE **out_value) { if (gen->type != GEN_OTHERNAME) { return 0; } - if (poid) { - *poid = gen->d.otherName->type_id; + if (out_oid != NULL) { + *out_oid = gen->d.otherName->type_id; } - if (pvalue) { - *pvalue = gen->d.otherName->value; + if (out_value != NULL) { + *out_value = gen->d.otherName->value; } return 1; } diff --git a/src/fuzz/cert.cc b/src/fuzz/cert.cc index e433450c3..2f4a54702 100644 --- a/src/fuzz/cert.cc +++ b/src/fuzz/cert.cc @@ -19,24 +19,56 @@ #include "../crypto/x509/internal.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) { - X509 *x509 = d2i_X509(NULL, &buf, len); - if (x509 != NULL) { + bssl::UniquePtr x509(d2i_X509(nullptr, &buf, len)); + if (x509 != nullptr) { // Extract the public key. - EVP_PKEY_free(X509_get_pubkey(x509)); + EVP_PKEY_free(X509_get_pubkey(x509.get())); // Fuzz some deferred parsing. - x509v3_cache_extensions(x509); + x509v3_cache_extensions(x509.get()); - // Reserialize the structure. - uint8_t *der = NULL; - i2d_X509(x509, &der); + // Fuzz every supported extension. + for (int i = 0; i < X509_get_ext_count(x509.get()); i++) { + const X509_EXTENSION *ext = X509_get_ext(x509.get(), i); + void *parsed = X509V3_EXT_d2i(ext); + if (parsed != nullptr) { + int nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext)); + BSSL_CHECK(nid != NID_undef); + + // Reserialize the extension. This should succeed if we were able to + // parse it. + // TODO(crbug.com/boringssl/352): Ideally we would also assert that + // |new_ext| is identical to |ext|, but our parser is not strict enough. + bssl::UniquePtr new_ext( + X509V3_EXT_i2d(nid, X509_EXTENSION_get_critical(ext), parsed)); + BSSL_CHECK(new_ext != nullptr); + + // This can only fail if |ext| was not a supported type, but then + // |X509V3_EXT_d2i| should have failed. + BSSL_CHECK(X509V3_EXT_free(nid, parsed)); + } + } + + // Reserialize |x509|. This should succeed if we were able to parse it. + // TODO(crbug.com/boringssl/352): Ideally we would also assert the output + // matches the input, but our parser is not strict enough. + uint8_t *der = nullptr; + int der_len = i2d_X509(x509.get(), &der); + BSSL_CHECK(der_len > 0); + OPENSSL_free(der); + + // Reserialize |x509|'s TBSCertificate without reusing the cached encoding. + // TODO(crbug.com/boringssl/352): Ideally we would also assert the output + // matches the input TBSCertificate, but our parser is not strict enough. + der = nullptr; + der_len = i2d_re_X509_tbs(x509.get(), &der); + BSSL_CHECK(der_len > 0); OPENSSL_free(der); BIO *bio = BIO_new(BIO_s_mem()); - X509_print(bio, x509); + X509_print(bio, x509.get()); BIO_free(bio); } - X509_free(x509); ERR_clear_error(); return 0; } diff --git a/src/include/openssl/x509.h b/src/include/openssl/x509.h index 1fa89fda9..44c01397d 100644 --- a/src/include/openssl/x509.h +++ b/src/include/openssl/x509.h @@ -1336,8 +1336,7 @@ DEFINE_STACK_OF(X509_NAME) // type is |X509_NAME*|. DECLARE_ASN1_ITEM(X509_NAME) -// X509_NAME_new returns a new, empty |X509_NAME_new|, or NULL on -// error. +// X509_NAME_new returns a new, empty |X509_NAME|, or NULL on error. OPENSSL_EXPORT X509_NAME *X509_NAME_new(void); // X509_NAME_free releases memory associated with |name|. @@ -1468,8 +1467,7 @@ OPENSSL_EXPORT int X509_NAME_add_entry_by_txt(X509_NAME *name, ossl_ssize_t len, int loc, int set); -// X509_NAME_ENTRY_new returns a new, empty |X509_NAME_ENTRY_new|, or NULL on -// error. +// X509_NAME_ENTRY_new returns a new, empty |X509_NAME_ENTRY|, or NULL on error. OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_new(void); // X509_NAME_ENTRY_free releases memory associated with |entry|. @@ -1769,6 +1767,181 @@ OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509v3_add_ext( STACK_OF(X509_EXTENSION) **x, const X509_EXTENSION *ex, int loc); +// General names. +// +// A |GENERAL_NAME| represents an X.509 GeneralName structure, defined in RFC +// 5280, Section 4.2.1.6. General names are distinct from names (|X509_NAME|). A +// general name is a CHOICE type which may contain one of several name types, +// most commonly a DNS name or an IP address. General names most commonly appear +// in the subject alternative name (SAN) extension, though they are also used in +// other extensions. +// +// Many extensions contain a SEQUENCE OF GeneralName, or GeneralNames, so +// |STACK_OF(GENERAL_NAME)| is defined and aliased to |GENERAL_NAMES|. + +typedef struct otherName_st { + ASN1_OBJECT *type_id; + ASN1_TYPE *value; +} OTHERNAME; + +typedef struct EDIPartyName_st { + ASN1_STRING *nameAssigner; + ASN1_STRING *partyName; +} EDIPARTYNAME; + +// GEN_* are constants for the |type| field of |GENERAL_NAME|, defined below. +#define GEN_OTHERNAME 0 +#define GEN_EMAIL 1 +#define GEN_DNS 2 +#define GEN_X400 3 +#define GEN_DIRNAME 4 +#define GEN_EDIPARTY 5 +#define GEN_URI 6 +#define GEN_IPADD 7 +#define GEN_RID 8 + +// A |GENERAL_NAME_st|, aka |GENERAL_NAME|, represents an X.509 GeneralName. The +// |type| field determines which member of |d| is active. A |GENERAL_NAME| may +// also be empty, in which case |type| is -1 and |d| is NULL. Empty +// |GENERAL_NAME|s are invalid and will never be returned from the parser, but +// may be created temporarily, e.g. by |GENERAL_NAME_new|. +struct GENERAL_NAME_st { + int type; + union { + char *ptr; + OTHERNAME *otherName; + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; + ASN1_STRING *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; + ASN1_OCTET_STRING *iPAddress; + ASN1_OBJECT *registeredID; + + // Old names + ASN1_OCTET_STRING *ip; // iPAddress + X509_NAME *dirn; // dirn + ASN1_IA5STRING *ia5; // rfc822Name, dNSName, uniformResourceIdentifier + ASN1_OBJECT *rid; // registeredID + } d; +} /* GENERAL_NAME */; + +// GENERAL_NAME_new returns a new, empty |GENERAL_NAME|, or NULL on error. +OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_new(void); + +// GENERAL_NAME_free releases memory associated with |gen|. +OPENSSL_EXPORT void GENERAL_NAME_free(GENERAL_NAME *gen); + +// d2i_GENERAL_NAME parses up to |len| bytes from |*inp| as a DER-encoded X.509 +// GeneralName (RFC 5280), as described in |d2i_SAMPLE|. +OPENSSL_EXPORT GENERAL_NAME *d2i_GENERAL_NAME(GENERAL_NAME **out, + const uint8_t **inp, long len); + +// i2d_GENERAL_NAME marshals |in| as a DER-encoded X.509 GeneralName (RFC 5280), +// as described in |i2d_SAMPLE|. +// +// TODO(https://crbug.com/boringssl/407): This function should be const and +// thread-safe but is currently neither in some cases, notably if |in| is an +// directoryName and the |X509_NAME| has been modified. +OPENSSL_EXPORT int i2d_GENERAL_NAME(GENERAL_NAME *in, uint8_t **outp); + +// GENERAL_NAME_dup returns a newly-allocated copy of |gen|, or NULL on error. +// This function works by serializing the structure, so it will fail if |gen| is +// empty. +// +// TODO(https://crbug.com/boringssl/407): This function should be const and +// thread-safe but is currently neither in some cases, notably if |gen| is an +// directoryName and the |X509_NAME| has been modified. +OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *gen); + +// GENERAL_NAMES_new returns a new, empty |GENERAL_NAMES|, or NULL on error. +OPENSSL_EXPORT GENERAL_NAMES *GENERAL_NAMES_new(void); + +// GENERAL_NAMES_free releases memory associated with |gens|. +OPENSSL_EXPORT void GENERAL_NAMES_free(GENERAL_NAMES *gens); + +// d2i_GENERAL_NAMES parses up to |len| bytes from |*inp| as a DER-encoded +// SEQUENCE OF GeneralName, as described in |d2i_SAMPLE|. +OPENSSL_EXPORT GENERAL_NAMES *d2i_GENERAL_NAMES(GENERAL_NAMES **out, + const uint8_t **inp, long len); + +// i2d_GENERAL_NAMES marshals |in| as a DER-encoded SEQUENCE OF GeneralName, as +// described in |i2d_SAMPLE|. +// +// TODO(https://crbug.com/boringssl/407): This function should be const and +// thread-safe but is currently neither in some cases, notably if some element +// of |in| is an directoryName and the |X509_NAME| has been modified. +OPENSSL_EXPORT int i2d_GENERAL_NAMES(GENERAL_NAMES *in, uint8_t **outp); + +// OTHERNAME_new returns a new, empty |OTHERNAME|, or NULL on error. +OPENSSL_EXPORT OTHERNAME *OTHERNAME_new(void); + +// OTHERNAME_free releases memory associated with |name|. +OPENSSL_EXPORT void OTHERNAME_free(OTHERNAME *name); + +// EDIPARTYNAME_new returns a new, empty |EDIPARTYNAME|, or NULL on error. +// EDIPartyName is rarely used in practice, so callers are unlikely to need this +// function. +OPENSSL_EXPORT EDIPARTYNAME *EDIPARTYNAME_new(void); + +// EDIPARTYNAME_free releases memory associated with |name|. EDIPartyName is +// rarely used in practice, so callers are unlikely to need this function. +OPENSSL_EXPORT void EDIPARTYNAME_free(EDIPARTYNAME *name); + +// GENERAL_NAME_set0_value set |gen|'s type and value to |type| and |value|. +// |type| must be a |GEN_*| constant and |value| must be an object of the +// corresponding type. |gen| takes ownership of |value|, so |value| must have +// been an allocated object. +// +// WARNING: |gen| must be empty (typically as returned from |GENERAL_NAME_new|) +// before calling this function. If |gen| already contained a value, the +// previous contents will be leaked. +OPENSSL_EXPORT void GENERAL_NAME_set0_value(GENERAL_NAME *gen, int type, + void *value); + +// GENERAL_NAME_get0_value returns the in-memory representation of |gen|'s +// contents and, |out_type| is not NULL, sets |*out_type| to the type of |gen|, +// which will be a |GEN_*| constant. If |gen| is incomplete, the return value +// will be NULL and the type will be -1. +// +// WARNING: Casting the result of this function to the wrong type is a +// potentially exploitable memory error. Callers must check |gen|'s type, either +// via |*out_type| or checking |gen->type| directly, before inspecting the +// result. +// +// WARNING: This function is not const-correct. The return value should be +// const. Callers shoudl not mutate the returned object. +OPENSSL_EXPORT void *GENERAL_NAME_get0_value(const GENERAL_NAME *gen, + int *out_type); + +// GENERAL_NAME_set0_othername sets |gen| to be an OtherName with type |oid| and +// value |value|. On success, it returns one and takes ownership of |oid| and +// |value|, which must be created in a way compatible with |ASN1_OBJECT_free| +// and |ASN1_TYPE_free|, respectively. On allocation failure, it returns zero. +// In the failure case, the caller retains ownership of |oid| and |value| and +// must release them when done. +// +// WARNING: |gen| must be empty (typically as returned from |GENERAL_NAME_new|) +// before calling this function. If |gen| already contained a value, the +// previously contents will be leaked. +OPENSSL_EXPORT int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, + ASN1_TYPE *value); + +// GENERAL_NAME_get0_otherName, if |gen| is an OtherName, sets |*out_oid| and +// |*out_value| to the OtherName's type-id and value, respectively, and returns +// one. If |gen| is not an OtherName, it returns zero and leaves |*out_oid| and +// |*out_value| unmodified. Either of |out_oid| or |out_value| may be NULL to +// ignore the value. +// +// WARNING: This function is not const-correct. |out_oid| and |out_value| are +// not const, but callers should not mutate the resulting objects. +OPENSSL_EXPORT int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, + ASN1_OBJECT **out_oid, + ASN1_TYPE **out_value); + + // Algorithm identifiers. // // An |X509_ALGOR| represents an AlgorithmIdentifier structure, used in X.509 @@ -3105,7 +3278,6 @@ struct X509_algor_st { // the end of the certificate itself DECLARE_STACK_OF(DIST_POINT) -DECLARE_STACK_OF(GENERAL_NAME) // This is used for a table of trust checking functions @@ -3781,49 +3953,6 @@ struct BASIC_CONSTRAINTS_st { ASN1_INTEGER *pathlen; }; - -typedef struct otherName_st { - ASN1_OBJECT *type_id; - ASN1_TYPE *value; -} OTHERNAME; - -typedef struct EDIPartyName_st { - ASN1_STRING *nameAssigner; - ASN1_STRING *partyName; -} EDIPARTYNAME; - -struct GENERAL_NAME_st { -#define GEN_OTHERNAME 0 -#define GEN_EMAIL 1 -#define GEN_DNS 2 -#define GEN_X400 3 -#define GEN_DIRNAME 4 -#define GEN_EDIPARTY 5 -#define GEN_URI 6 -#define GEN_IPADD 7 -#define GEN_RID 8 - - int type; - union { - char *ptr; - OTHERNAME *otherName; // otherName - ASN1_IA5STRING *rfc822Name; - ASN1_IA5STRING *dNSName; - ASN1_STRING *x400Address; - X509_NAME *directoryName; - EDIPARTYNAME *ediPartyName; - ASN1_IA5STRING *uniformResourceIdentifier; - ASN1_OCTET_STRING *iPAddress; - ASN1_OBJECT *registeredID; - - // Old names - ASN1_OCTET_STRING *ip; // iPAddress - X509_NAME *dirn; // dirn - ASN1_IA5STRING *ia5; // rfc822Name, dNSName, uniformResourceIdentifier - ASN1_OBJECT *rid; // registeredID - } d; -} /* GENERAL_NAME */; - typedef struct ACCESS_DESCRIPTION_st { ASN1_OBJECT *method; GENERAL_NAME *location; @@ -3983,27 +4112,6 @@ DECLARE_ASN1_FUNCTIONS_const(BASIC_CONSTRAINTS) // an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) -// TODO(https://crbug.com/boringssl/407): This is not const because it contains -// an |X509_NAME|. -DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) -OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); - -// TODO(https://crbug.com/boringssl/407): This is not const because it contains -// an |X509_NAME|. -DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) - -DECLARE_ASN1_FUNCTIONS_const(OTHERNAME) -DECLARE_ASN1_FUNCTIONS_const(EDIPARTYNAME) -OPENSSL_EXPORT void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, - void *value); -OPENSSL_EXPORT void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype); -OPENSSL_EXPORT int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, - ASN1_OBJECT *oid, - ASN1_TYPE *value); -OPENSSL_EXPORT int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, - ASN1_OBJECT **poid, - ASN1_TYPE **pvalue); - DECLARE_ASN1_FUNCTIONS_const(EXTENDED_KEY_USAGE) DECLARE_ASN1_FUNCTIONS_const(CERTIFICATEPOLICIES) diff --git a/src/pki/path_builder.cc b/src/pki/path_builder.cc index c629550c7..f89576e5e 100644 --- a/src/pki/path_builder.cc +++ b/src/pki/path_builder.cc @@ -818,6 +818,12 @@ CertPathBuilder::Result CertPathBuilder::Run() { result_path->errors.GetOtherErrors()->AddError( cert_errors::kInternalError); } + + // Allow the delegate to do any processing or logging of the partial + // path. (This is for symmetry for the other CheckPathAfterVerification + // which also gets called on partial paths.) + delegate_->CheckPathAfterVerification(*this, result_path.get()); + AddResultPath(std::move(result_path)); } out_result_.iteration_count = iteration_count; @@ -840,11 +846,6 @@ CertPathBuilder::Result CertPathBuilder::Run() { &result_path->user_constrained_policy_set, &result_path->errors); } - if (delegate_->IsDebugLogEnabled()) { - delegate_->DebugLog("CertPathBuilder VerifyCertificateChain errors:\n" + - result_path->errors.ToDebugString(result_path->certs)); - } - // Give the delegate a chance to add errors to the path. delegate_->CheckPathAfterVerification(*this, result_path.get()); diff --git a/src/pki/path_builder.h b/src/pki/path_builder.h index 59cfc2462..325477b00 100644 --- a/src/pki/path_builder.h +++ b/src/pki/path_builder.h @@ -88,10 +88,13 @@ struct OPENSSL_EXPORT CertPathBuilderResultPath { class OPENSSL_EXPORT CertPathBuilderDelegate : public VerifyCertificateChainDelegate { public: - // This is called during path building on candidate paths which have already - // been run through RFC 5280 verification. |path| may already have errors - // and warnings set on it. Delegates can "reject" a candidate path from path - // building by adding high severity errors. + // This is called during path building on candidate paths. These are either + // paths which have already been run through RFC 5280 verification, or + // partial paths that the path builder cannot continue either due to not + // finding a matching issuer or reaching a configured pathbuilding limit. + // |path| may already have errors and warnings set on it. Delegates can + // "reject" a candidate path from path building by adding high severity + // errors. virtual void CheckPathAfterVerification(const CertPathBuilder &path_builder, CertPathBuilderResultPath *path) = 0; diff --git a/src/pki/path_builder_unittest.cc b/src/pki/path_builder_unittest.cc index 2c0781c27..c76670d1b 100644 --- a/src/pki/path_builder_unittest.cc +++ b/src/pki/path_builder_unittest.cc @@ -60,6 +60,24 @@ class TestPathBuilderDelegate : public SimplePathBuilderDelegate { MockSignatureVerifyCache cache_; }; +class CertPathBuilderDelegateBase : public SimplePathBuilderDelegate { + public: + CertPathBuilderDelegateBase() + : SimplePathBuilderDelegate( + 1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1) {} + void CheckPathAfterVerification(const CertPathBuilder &path_builder, + CertPathBuilderResultPath *path) override { + ADD_FAILURE() << "Tests must override this"; + } +}; + +class MockPathBuilderDelegate : public CertPathBuilderDelegateBase { + public: + MOCK_METHOD2(CheckPathAfterVerification, + void(const CertPathBuilder &path_builder, + CertPathBuilderResultPath *path)); +}; + // AsyncCertIssuerSourceStatic always returns its certs asynchronously. class AsyncCertIssuerSourceStatic : public CertIssuerSource { public: @@ -628,8 +646,13 @@ TEST_F(PathBuilderMultiRootTest, TestIterationLimit) { for (const bool insufficient_limit : {true, false}) { SCOPED_TRACE(insufficient_limit); + StrictMock mock_delegate; + // The CheckPathAfterVerification delegate should be called regardless if + // the iteration limit is reached. + EXPECT_CALL(mock_delegate, CheckPathAfterVerification(_, _)); + CertPathBuilder path_builder( - a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU, + a_by_b_, &trust_store, &mock_delegate, time_, KeyPurpose::ANY_EKU, initial_explicit_policy_, user_initial_policy_set_, initial_policy_mapping_inhibit_, initial_any_policy_inhibit_); path_builder.AddCertIssuerSource(&sync_certs); @@ -1872,24 +1895,6 @@ TEST_F(PathBuilderDistrustTest, TargetIntermediateRoot) { class PathBuilderCheckPathAfterVerificationTest : public PathBuilderSimpleChainTest {}; -class CertPathBuilderDelegateBase : public SimplePathBuilderDelegate { - public: - CertPathBuilderDelegateBase() - : SimplePathBuilderDelegate( - 1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1) {} - void CheckPathAfterVerification(const CertPathBuilder &path_builder, - CertPathBuilderResultPath *path) override { - ADD_FAILURE() << "Tests must override this"; - } -}; - -class MockPathBuilderDelegate : public CertPathBuilderDelegateBase { - public: - MOCK_METHOD2(CheckPathAfterVerification, - void(const CertPathBuilder &path_builder, - CertPathBuilderResultPath *path)); -}; - TEST_F(PathBuilderCheckPathAfterVerificationTest, NoOpToValidPath) { StrictMock delegate; // Just verify that the hook is called.