OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // ---------------------------- | 5 // ---------------------------- |
6 // Overview of error design | 6 // Overview of error design |
7 // ---------------------------- | 7 // ---------------------------- |
8 // | 8 // |
9 // Certificate path validation/parsing may emit a sequence of | 9 // Certificate path building/validation/parsing may emit a sequence of errors |
10 // errors/warnings/context. These are represented by a tree of CertErrorNodes. | 10 // and warnings. |
11 // Each node is comprised of: | 11 // |
12 // Each individual error/warning entry (CertError) is comprised of: | |
12 // | 13 // |
13 // * A unique identifier. | 14 // * A unique identifier. |
14 // | 15 // |
15 // This serves similarly to an error code, and is useful for querying if a | 16 // This serves similarly to an error code, and is used to query if a |
16 // particular error occurred. | 17 // particular error/warning occurred. |
17 // | 18 // |
18 // * [optional] A parameters object. | 19 // * [optional] A parameters object. |
19 // | 20 // |
20 // Nodes may attach a heap-allocated subclass of CertErrorParams, to carry | 21 // Nodes may attach a heap-allocated subclass of CertErrorParams to carry |
21 // extra information that is useful when reporting the error. For instance | 22 // extra information that is used when reporting the error. For instance |
22 // a parsing error may want to describe where in the DER the failure | 23 // a parsing error may describe where in the DER the failure happened, or |
23 // happened, or what the unexpected value was. | 24 // what the unexpected value was. |
24 // | 25 // |
25 // * [optional] Child nodes. | 26 // A collection of errors is represented by the CertErrors object. This may be |
27 // used to group errors that have a common context, such as all the | |
28 // errors/warnings that apply to a specific certificate. | |
26 // | 29 // |
27 // Error nodes are arranged in a tree. The parent/child hierarchy is used to | 30 // Lastly, CertPathErrors composes multiple CertErrors -- one for each |
28 // group errors that share some common state. | 31 // certfificate in the verified chain. |
mattm
2017/03/23 00:32:05
certificate
eroman
2017/03/23 01:32:12
Done.
| |
29 // For instance during path processing it is useful to group the | |
30 // errors/warnings that happened while processing certificate "i" as | |
31 // children of a shared "context" node. The context node in this case | |
32 // doesn't describe a particular error, but rather some shared event and | |
33 // its parameters. | |
34 // | |
35 // ---------------------------- | |
36 // Using errors in other APIs | |
37 // ---------------------------- | |
38 // | |
39 // The top level object used in APIs is CertErrors. A pointer to a CertErrors | |
40 // object is typically given as an out-parameter for code that may generate | |
41 // errors. | |
42 // | |
43 // Note that CertErrors gives a non-hiearhical interface for emitting errors. | |
44 // In other words, it doesn't let you create parent/child relationships | |
45 // directly. | |
46 // | |
47 // To change the parent node for subsequently emitted errors in the CertErrors | |
48 // object, one constructs a CertErrorScoper on the stack. | |
49 // | 32 // |
50 // ---------------------------- | 33 // ---------------------------- |
51 // Defining new errors | 34 // Defining new errors |
52 // ---------------------------- | 35 // ---------------------------- |
53 // | 36 // |
54 // The error IDs are extensible and do not need to be centrally defined. | 37 // The error IDs are extensible and do not need to be centrally defined. |
55 // | 38 // |
56 // To define a new error use the macro DEFINE_CERT_ERROR_ID() in a .cc file. | 39 // To define a new error use the macro DEFINE_CERT_ERROR_ID() in a .cc file. |
57 // If consumers are to be able to query for this error then the symbol should | 40 // If consumers are to be able to query for this error then the symbol should |
58 // also be exposed in a header file. | 41 // also be exposed in a header file. |
59 // | 42 // |
60 // Error IDs are in truth string literals, whose pointer value will be unique | 43 // Error IDs are in truth string literals, whose pointer value will be unique |
61 // per process. | 44 // per process. |
62 | 45 |
63 #ifndef NET_CERT_INTERNAL_CERT_ERRORS_H_ | 46 #ifndef NET_CERT_INTERNAL_CERT_ERRORS_H_ |
64 #define NET_CERT_INTERNAL_CERT_ERRORS_H_ | 47 #define NET_CERT_INTERNAL_CERT_ERRORS_H_ |
65 | 48 |
66 #include <memory> | 49 #include <memory> |
67 #include <vector> | 50 #include <vector> |
68 | 51 |
69 #include "base/compiler_specific.h" | 52 #include "base/compiler_specific.h" |
70 #include "base/macros.h" | 53 #include "base/macros.h" |
71 #include "net/base/net_export.h" | 54 #include "net/base/net_export.h" |
72 #include "net/cert/internal/cert_error_id.h" | 55 #include "net/cert/internal/cert_error_id.h" |
56 #include "net/cert/internal/parsed_certificate.h" | |
73 | 57 |
74 namespace net { | 58 namespace net { |
75 | 59 |
76 class CertErrorParams; | 60 class CertErrorParams; |
77 class CertErrorScoper; | |
78 | 61 |
79 // The type of a particular CertErrorNode. | 62 // CertError represents either an error or a warning. |
80 enum class CertErrorNodeType { | 63 struct NET_EXPORT CertError { |
81 // Note the TYPE_ prefix is to avoid compile errors. Because ERROR() is a | 64 enum Severity { |
82 // commonly used macro name. | 65 SEVERITY_HIGH, |
66 SEVERITY_WARNING, | |
67 }; | |
83 | 68 |
84 // Node that represents a single error. | 69 CertError(); |
85 TYPE_ERROR, | 70 CertError(Severity severity, |
71 CertErrorId id, | |
72 std::unique_ptr<CertErrorParams> params); | |
73 CertError(CertError&& other); | |
74 CertError& operator=(CertError&&); | |
75 ~CertError(); | |
86 | 76 |
87 // Node that represents a single non-fatal error. | 77 // Pretty-prints the error and its parameters. |
88 TYPE_WARNING, | 78 std::string ToDebugString() const; |
89 | 79 |
90 // Parent node for other errors/warnings. | 80 Severity severity; |
91 TYPE_CONTEXT, | 81 CertErrorId id; |
82 std::unique_ptr<CertErrorParams> params; | |
92 }; | 83 }; |
93 | 84 |
94 struct CertErrorNode; | 85 // CertErrors is a collection of CertError, along with convenience methods to |
95 using CertErrorNodes = std::vector<std::unique_ptr<CertErrorNode>>; | 86 // add and inspect errors. |
96 | |
97 // CertErrorNode represents a node in the error tree. This could be an error, | |
98 // warning, or simply contextual parent node. See the error design overview for | |
99 // a better description of how this is used. | |
100 struct NET_EXPORT CertErrorNode { | |
101 CertErrorNode(CertErrorNodeType node_type, | |
102 CertErrorId id, | |
103 std::unique_ptr<CertErrorParams> params); | |
104 ~CertErrorNode(); | |
105 | |
106 void AddChild(std::unique_ptr<CertErrorNode> child); | |
107 | |
108 CertErrorNodeType node_type; | |
109 CertErrorId id; | |
110 std::unique_ptr<CertErrorParams> params; | |
111 CertErrorNodes children; | |
112 }; | |
113 | |
114 // CertErrors is the main object for emitting errors and internally builds up | |
115 // the error tree. | |
116 class NET_EXPORT CertErrors { | 87 class NET_EXPORT CertErrors { |
117 public: | 88 public: |
118 CertErrors(); | 89 CertErrors(); |
90 CertErrors(CertErrors&& other); | |
91 CertErrors& operator=(CertErrors&&); | |
119 ~CertErrors(); | 92 ~CertErrors(); |
120 | 93 |
121 // Adds a node to the current insertion point in the error tree. |params| may | 94 // Adds an error/warning. |params| may be null. |
122 // be null. | 95 void Add(CertError::Severity severity, |
123 void Add(CertErrorNodeType node_type, | |
124 CertErrorId id, | 96 CertErrorId id, |
125 std::unique_ptr<CertErrorParams> params); | 97 std::unique_ptr<CertErrorParams> params); |
126 | 98 |
99 // Adds a high severity error. | |
127 void AddError(CertErrorId id, std::unique_ptr<CertErrorParams> params); | 100 void AddError(CertErrorId id, std::unique_ptr<CertErrorParams> params); |
128 void AddError(CertErrorId id); | 101 void AddError(CertErrorId id); |
129 | 102 |
103 // Adds a low severity error. | |
130 void AddWarning(CertErrorId id, std::unique_ptr<CertErrorParams> params); | 104 void AddWarning(CertErrorId id, std::unique_ptr<CertErrorParams> params); |
131 void AddWarning(CertErrorId id); | 105 void AddWarning(CertErrorId id); |
132 | 106 |
133 // Returns true if the tree is empty. Note that emptiness of the error tree | |
134 // is NOT equivalent to success for some call, and vice versa. (For instance | |
135 // consumers may forget to emit errors on failures, or some errors may be | |
136 // non-fatal warnings). | |
137 bool empty() const; | |
138 | |
139 // Dumps a textual representation of the errors for debugging purposes. | 107 // Dumps a textual representation of the errors for debugging purposes. |
140 std::string ToDebugString() const; | 108 std::string ToDebugString() const; |
141 | 109 |
142 // Returns true the error |id| was added to this CertErrors (at any depth). | 110 // Returns true if the error |id| was added to this CertErrors. |
143 bool ContainsError(CertErrorId id) const; | 111 bool ContainsError(CertErrorId id) const; |
144 | 112 |
113 // Returns true if this contains any high severity errors (does not consider | |
114 // warnings). | |
115 bool HasErrors() const; | |
116 | |
145 private: | 117 private: |
146 // CertErrorScoper manipulates the CertErrors object. | 118 std::vector<CertError> nodes_; |
147 friend class CertErrorScoper; | 119 }; |
148 | 120 |
149 void AddNode(std::unique_ptr<CertErrorNode> node); | 121 // CertPathErrors is a collection of CertErrors, to group errors into different |
122 // buckets for different certificates. The "index" should correspond with that | |
123 // of the certificate relative to its chain. | |
124 class NET_EXPORT CertPathErrors { | |
125 public: | |
126 CertPathErrors(); | |
127 CertPathErrors(CertPathErrors&& other); | |
128 CertPathErrors& operator=(CertPathErrors&&); | |
129 ~CertPathErrors(); | |
150 | 130 |
151 // Used by CertErrorScoper to register itself as the top-level scoper. | 131 // Gets a bucket to put errors in for |cert_index|. This will lookup and |
152 // Returns the previously set scoper, or nullptr if there was none. | 132 // return the existing error bucket if one exists, or create a new one for the |
153 CertErrorScoper* SetScoper(CertErrorScoper* scoper); | 133 // specified index. It is expected that |cert_index| is the corresponding |
134 // index in a certificate chain (with 0 being the target). | |
135 CertErrors* GetErrorsForCert(size_t cert_index); | |
154 | 136 |
155 CertErrorNodes nodes_; | 137 // Returns a bucket to put errors that are not associated with a particular |
138 // certificate. | |
139 CertErrors* GetOtherErrors(); | |
156 | 140 |
157 // The top-most CertErrorScoper that is currently in scope (and which affects | 141 // Returns true if CertPathErrors contains the specified error (of any |
158 // the parent node for newly added errors). | 142 // severity). |
159 CertErrorScoper* current_scoper_ = nullptr; | 143 bool ContainsError(CertErrorId id) const; |
160 | 144 |
161 DISALLOW_COPY_AND_ASSIGN(CertErrors); | 145 // Returns true if this contains any high severity errors (does not consider |
146 // warnings). | |
147 bool HasErrors() const; | |
148 | |
149 std::string ToDebugString(const ParsedCertificateList& certs) const; | |
mattm
2017/03/23 00:32:05
comment? (like that it will be an empty string if
eroman
2017/03/23 01:32:12
Done.
| |
150 | |
151 private: | |
152 std::vector<CertErrors> cert_errors_; | |
153 CertErrors other_errors_; | |
162 }; | 154 }; |
163 | 155 |
164 } // namespace net | 156 } // namespace net |
165 | 157 |
166 #endif // NET_CERT_INTERNAL_CERT_ERRORS_H_ | 158 #endif // NET_CERT_INTERNAL_CERT_ERRORS_H_ |
OLD | NEW |