blob: 8422fd5c96a7b805a925203ee001613d62fe4ffb [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_CERT_INTERNAL_TRUST_STORE_H_
#define NET_CERT_INTERNAL_TRUST_STORE_H_
#include <vector>
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "net/base/net_export.h"
#include "net/cert/internal/parsed_certificate.h"
namespace net {
namespace der {
class Input;
}
// A TrustAnchor represents a trust anchor used during RFC 5280 path validation.
//
// At its core, each trust anchor has two parts:
// * Name
// * Public Key
//
// Optionally a trust anchor may contain:
// * An associated certificate (used when pretty-printing)
// * Mandatory trust anchor constraints
//
// Relationship between ParsedCertificate and TrustAnchor:
//
// For convenience trust anchors are often described using a
// (self-signed) certificate. TrustAnchor facilitates this by allowing
// construction of a TrustAnchor given a ParsedCertificate.
//
// When constructing a TrustAnchor from a certificate there are different
// interpretations for the meaning of properties other than the Subject and
// SPKI in the certificate.
//
// * CreateFromCertificateNoConstraints() -- Extracts the Subject and SPKI from
// the source certificate. ALL other information in the certificate is
// considered irrelevant during path validation.
//
// * CreateFromCertificateWithConstraints() -- Extracts the Subject and SPKI
// from the source certificate, and additionally interprets some properties of
// the source certificate as mandatory anchor constraints.
//
// Trust anchor constraints are described in more detail by RFC 5937. This
// implementation follows that description, and fixes
// "enforceTrustAnchorConstraints" to true.
class NET_EXPORT TrustAnchor : public base::RefCountedThreadSafe<TrustAnchor> {
public:
// Creates a TrustAnchor given a certificate. The ONLY parts of the
// certificate that are relevant to the resulting trust anchor are:
//
// * Subject
// * SPKI
//
// Everything else, including the source certiticate's expiration, basic
// constraints, policy constraints, etc is not used.
//
// This is the common interpretation for a trust anchor when given as a
// certificate.
static scoped_refptr<TrustAnchor> CreateFromCertificateNoConstraints(
scoped_refptr<ParsedCertificate> cert);
// Creates a TrustAnchor given a certificate. The resulting trust anchor is
// initialized using the source certificate's subject and SPKI as usual,
// however other parts of the certificate are applied as anchor constraints.
//
// The implementation matches the properties identified by RFC 5937,
// resulting in the following hodgepodge of enforcement on the source
// certificate:
//
// * Signature: No
// * Validity (expiration): No
// * Key usage: No
// * Extended key usage: No
// * Basic constraints: Yes, but only the pathlen (CA=false is accepted)
// * Name constraints: Yes
// * Certificate policies: Not currently, TODO(crbug.com/634453)
// * inhibitAnyPolicy: Not currently, TODO(crbug.com/634453)
// * PolicyConstraints: Not currently, TODO(crbug.com/634452)
//
// The presence of any other unrecognized extension marked as critical fails
// validation.
static scoped_refptr<TrustAnchor> CreateFromCertificateWithConstraints(
scoped_refptr<ParsedCertificate> cert);
der::Input spki() const;
der::Input normalized_subject() const;
// Returns the optional certificate representing this trust anchor.
// In the current implementation it will never return nullptr...
// however clients should be prepared to handle this case.
const scoped_refptr<ParsedCertificate>& cert() const;
// Returns true if the trust anchor has attached (mandatory) trust anchor
// constraints. This returns true when the anchor was constructed using
// CreateFromCertificateWithConstraints.
bool enforces_constraints() const { return enforces_constraints_; }
private:
friend class base::RefCountedThreadSafe<TrustAnchor>;
TrustAnchor(scoped_refptr<ParsedCertificate>, bool enforces_constraints);
~TrustAnchor();
scoped_refptr<ParsedCertificate> cert_;
bool enforces_constraints_ = false;
};
using TrustAnchors = std::vector<scoped_refptr<TrustAnchor>>;
// Interface for finding trust anchors.
class NET_EXPORT TrustStore {
public:
class NET_EXPORT Request {
public:
Request();
// Destruction of the Request cancels it.
virtual ~Request();
};
TrustStore();
virtual ~TrustStore();
using TrustAnchorsCallback = base::Callback<void(TrustAnchors)>;
// Returns the trust anchors that match |cert|'s issuer name in
// |*synchronous_matches| and/or through |callback|. |cert| and
// |synchronous_matches| must not be null.
//
// If results are available synchronously, they will be appended to
// |*synchronous_matches|. |*synchronous_matches| will not be modified
// asynchronously.
//
// If |callback| is not null and results may be available asynchronously,
// |*out_req| will be filled with a Request, and |callback| will be called
// when results are available. The Request may be destroyed to cancel
// the callback if it has not occurred yet.
virtual void FindTrustAnchorsForCert(
const scoped_refptr<ParsedCertificate>& cert,
const TrustAnchorsCallback& callback,
TrustAnchors* synchronous_matches,
std::unique_ptr<Request>* out_req) const = 0;
private:
DISALLOW_COPY_AND_ASSIGN(TrustStore);
};
} // namespace net
#endif // NET_CERT_INTERNAL_TRUST_STORE_H_