| Index: net/cert/internal/cert_errors.h
|
| diff --git a/net/cert/internal/cert_errors.h b/net/cert/internal/cert_errors.h
|
| index f12133b06350b232630172eed538bc0f5929c26c..f7b78206ca1e16a353051ab9fed0393fe1e1cc05 100644
|
| --- a/net/cert/internal/cert_errors.h
|
| +++ b/net/cert/internal/cert_errors.h
|
| @@ -6,24 +6,59 @@
|
| // Overview of error design
|
| // ----------------------------
|
| //
|
| -// Certificate path validation may emit a sequence of errors/warnings. These
|
| -// are represented by |CertErrors|.
|
| +// Certificate path validation/parsing may emit a sequence of
|
| +// errors/warnings/context. These are represented by a tree of CertErrorNodes.
|
| +// Each node is comprised of:
|
| //
|
| -// |CertErrors| is basically just a sequence of errors. The order of the errors
|
| -// reflects when they were added.
|
| +// * A unique identifier.
|
| //
|
| -// Each |CertError| has three parts:
|
| +// This serves similarly to an error code, and is useful for querying if a
|
| +// particular error occurred.
|
| //
|
| -// * A unique identifier for the error/warning
|
| -// - essentially an error code
|
| +// * [optional] A parameters object.
|
| //
|
| -// * Optional parameters specific to this error type
|
| -// - May identify relevant DER or OIDs in the certificate
|
| +// Nodes may attach a heap-allocated subclass of CertErrorParams, to carry
|
| +// extra information that is useful when reporting the error. For instance
|
| +// a parsing error may want to describe where in the DER the failure
|
| +// happened, or what the unexpected value was.
|
| //
|
| -// * Optional context that describes where the error happened
|
| -// - Which certificate or trust anchor were we processing when the error
|
| -// was encountered?
|
| +// * [optional] Child nodes.
|
| //
|
| +// Error nodes are arranged in a tree. The parent/child hiearchy is used to
|
| +// group errors that share some common state.
|
| +// For instance during path processing it is useful to group the
|
| +// errors/warnings that happened while processing certificate "i" as
|
| +// children of a shared "context" node. The context node in this case
|
| +// doesn't describe a particular error, but rather some shared event and
|
| +// its parameters.
|
| +//
|
| +// ----------------------------
|
| +// Using errors in other APIs
|
| +// ----------------------------
|
| +//
|
| +// The top level object used in APIs is CertErrors. A pointer to a CertErrors
|
| +// object is typically given as an out-parameter for code that may generate
|
| +// errors.
|
| +//
|
| +// Note that CertErrors gives a non-hiearhical interface for emitting errors.
|
| +// In other words, it doesn't let you create parent/child relationships
|
| +// directly.
|
| +//
|
| +// To change the parent node for subsequently emitted errors in the CertErrors
|
| +// object, one constructs a CertErrorScoper on the stack.
|
| +//
|
| +// ----------------------------
|
| +// Defining new errors
|
| +// ----------------------------
|
| +//
|
| +// The error IDs are extensible and do not need to be centrally defined.
|
| +//
|
| +// To define a new error use the macro DEFINE_CERT_ERROR_ID() in a .cc file.
|
| +// If consumers are to be able to query for this error then the symbol should
|
| +// also be exposed in a header file.
|
| +//
|
| +// Error IDs are in truth string literals, whose pointer value will be unique
|
| +// per process.
|
|
|
| #ifndef NET_CERT_INTERNAL_CERT_ERRORS_H_
|
| #define NET_CERT_INTERNAL_CERT_ERRORS_H_
|
| @@ -32,152 +67,100 @@
|
| #include <vector>
|
|
|
| #include "base/compiler_specific.h"
|
| -#include "base/memory/ref_counted.h"
|
| +#include "base/macros.h"
|
| #include "net/base/net_export.h"
|
| -#include "net/der/input.h"
|
| -
|
| -namespace base {
|
| -class Value;
|
| -}
|
| +#include "net/cert/internal/cert_error_id.h"
|
|
|
| namespace net {
|
|
|
| +class CertErrorParams;
|
| +class CertErrorScoper;
|
| class ParsedCertificate;
|
| -class TrustAnchor;
|
| -
|
| -// Certificate error types are identified by null-terminated C-strings, with
|
| -// unique pointer values.
|
| -//
|
| -// Equality of CertErrorType is done using (pointer) equality and not string
|
| -// comparison.
|
| -//
|
| -// To ensure uniqueness define errors using the macro DEFINE_CERT_ERROR_TYPE().
|
| -using CertErrorType = const char*;
|
| -
|
| -// TODO(crbug.com/634443): Implement this -- add magic to ensure that storage
|
| -// of identical strings isn't pool.
|
| -#define DEFINE_CERT_ERROR_TYPE(name, c_str_literal) \
|
| - CertErrorType name = c_str_literal
|
|
|
| -// CertErrorParams is a base class for describing parameters for a particular
|
| -// CertErrorType.
|
| -//
|
| -// Parameters may be used to associate extra information with an error. An
|
| -// example use for parameters is to identify the OID for an unconsumed critical
|
| -// extension.
|
| -class NET_EXPORT CertErrorParams {
|
| - public:
|
| - CertErrorParams();
|
| - virtual ~CertErrorParams();
|
| +// The type of a particular CertErrorNode.
|
| +enum class CertErrorNodeType {
|
| + // Note the TYPE_ prefix is to avoid compile errors. Because ERROR() is a
|
| + // commonly used macro name.
|
|
|
| - // Creates a representation of this parameter as a base::Value, which may be
|
| - // used for pretty printing the error.
|
| - virtual std::unique_ptr<base::Value> ToValue() const = 0;
|
| + // Node that represents a single error.
|
| + TYPE_ERROR,
|
|
|
| - // TODO(crbug.com/634443): Add methods access the underlying structure.
|
| - // ToValue() alone is not a great way to get at the data.
|
| + // Node that represents a single non-fatal error.
|
| + TYPE_WARNING,
|
|
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(CertErrorParams);
|
| + // Parent node for other errors/warnings.
|
| + TYPE_CONTEXT,
|
| };
|
|
|
| -// CertError represents a single error during path validation.
|
| -struct NET_EXPORT CertError {
|
| - CertError();
|
| - CertError(CertError&& other);
|
| - ~CertError();
|
| +struct CertErrorNode;
|
| +using CertErrorNodes = std::vector<std::unique_ptr<CertErrorNode>>;
|
|
|
| - // The "type" of the error. This describes the error class -- what is
|
| - // typically done using an integer error code.
|
| - CertErrorType type = nullptr;
|
| +// CertErrorNode represents a node in the error tree. This could be an error,
|
| +// warning, or simply contextual parent node. See the error design overview for
|
| +// a better description of how this is used.
|
| +struct NET_EXPORT CertErrorNode {
|
| + CertErrorNode(CertErrorNodeType node_type,
|
| + CertErrorId id,
|
| + std::unique_ptr<CertErrorParams> params);
|
| + ~CertErrorNode();
|
|
|
| - // This describes any parameter relevant to the error.
|
| - std::unique_ptr<CertErrorParams> params;
|
| + void AddChild(std::unique_ptr<CertErrorNode> child);
|
|
|
| - // TODO(crbug.com/634443): Add context (i.e. associated certificate/trust
|
| - // anchor).
|
| + CertErrorNodeType node_type;
|
| + CertErrorId id;
|
| + std::unique_ptr<CertErrorParams> params;
|
| + CertErrorNodes children;
|
| };
|
|
|
| +// CertErrors is the main object for emitting errors and internally builds up
|
| +// the error tree.
|
| class NET_EXPORT CertErrors {
|
| public:
|
| CertErrors();
|
| ~CertErrors();
|
|
|
| - void Add(CertErrorType type);
|
| + // Adds a node to the current insertion point in the error tree. |params| may
|
| + // be null.
|
| + void Add(CertErrorNodeType node_type,
|
| + CertErrorId id,
|
| + std::unique_ptr<CertErrorParams> params);
|
| +
|
| + // TODO(crbug.com/634443): Eliminate this and use AddError() instead (which
|
| + // is less ambiguous).
|
| + void Add(CertErrorId id);
|
|
|
| - void AddWithParam(CertErrorType type,
|
| - std::unique_ptr<CertErrorParams> params);
|
| + void AddError(CertErrorId id, std::unique_ptr<CertErrorParams> params);
|
| + void AddError(CertErrorId id);
|
|
|
| - void AddWith1DerParam(CertErrorType type, const der::Input& der1);
|
| - void AddWith2DerParams(CertErrorType type,
|
| - const der::Input& der1,
|
| - const der::Input& der2);
|
| + void AddWarning(CertErrorId id, std::unique_ptr<CertErrorParams> params);
|
| + void AddWarning(CertErrorId id);
|
|
|
| - const std::vector<CertError>& errors() const { return errors_; }
|
| + // Returns true if the tree is empty. Note that emptiness of the error tree
|
| + // is NOT equivalent to success for some call, and vice versa. (For instance
|
| + // consumers may forget to emit errors on failures, or some errors may be
|
| + // non-fatal warnings).
|
| + bool empty() const;
|
|
|
| // Dumps a textual representation of the errors for debugging purposes.
|
| std::string ToDebugString() const;
|
|
|
| private:
|
| - std::vector<CertError> errors_;
|
| + // CertErrorScoper manipulates the CertErrors object.
|
| + friend class CertErrorScoper;
|
|
|
| - DISALLOW_COPY_AND_ASSIGN(CertErrors);
|
| -};
|
| -
|
| -// --------------------------
|
| -// Context scopers
|
| -// --------------------------
|
| -
|
| -// TODO(crbug.com/634443): Implement.
|
| -class NET_EXPORT ScopedCertErrorsCertContext {
|
| - public:
|
| - ScopedCertErrorsCertContext(CertErrors* parent,
|
| - const ParsedCertificate* cert,
|
| - size_t i);
|
| - ~ScopedCertErrorsCertContext();
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(ScopedCertErrorsCertContext);
|
| -};
|
| -
|
| -// TODO(crbug.com/634443): Implement.
|
| -class NET_EXPORT ScopedCertErrorsTrustAnchorContext {
|
| - public:
|
| - ScopedCertErrorsTrustAnchorContext(CertErrors* parent,
|
| - const TrustAnchor* trust_anchor);
|
| - ~ScopedCertErrorsTrustAnchorContext();
|
| + void AddNode(std::unique_ptr<CertErrorNode> node);
|
|
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(ScopedCertErrorsTrustAnchorContext);
|
| -};
|
| + // Used by CertErrorScoper to register itself as the top-level scoper.
|
| + // Returns the previously set scoper, or nullptr if there was none.
|
| + CertErrorScoper* SetScoper(CertErrorScoper* scoper);
|
|
|
| -// --------------------------
|
| -// Error parameters
|
| -// --------------------------
|
| + CertErrorNodes nodes_;
|
|
|
| -class NET_EXPORT CertErrorParamsDer1 : public CertErrorParams {
|
| - public:
|
| - explicit CertErrorParamsDer1(const der::Input& der1);
|
| + // The top-most CertErrorScoper that is currently in scope (and which affects
|
| + // the parent node for newly added errors).
|
| + CertErrorScoper* current_scoper_ = nullptr;
|
|
|
| - std::unique_ptr<base::Value> ToValue() const override;
|
| -
|
| - private:
|
| - const std::string der1_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(CertErrorParamsDer1);
|
| -};
|
| -
|
| -class NET_EXPORT CertErrorParamsDer2 : public CertErrorParams {
|
| - public:
|
| - CertErrorParamsDer2(const der::Input& der1, const der::Input& der2);
|
| -
|
| - std::unique_ptr<base::Value> ToValue() const override;
|
| -
|
| - private:
|
| - const std::string der1_;
|
| - const std::string der2_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(CertErrorParamsDer2);
|
| + DISALLOW_COPY_AND_ASSIGN(CertErrors);
|
| };
|
|
|
| } // namespace net
|
|
|