xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/pki/cert_errors.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // ----------------------------
6 // Overview of error design
7 // ----------------------------
8 //
9 // Certificate path building/validation/parsing may emit a sequence of errors
10 // and warnings.
11 //
12 // Each individual error/warning entry (CertError) is comprised of:
13 //
14 //   * A unique identifier.
15 //
16 //     This serves similarly to an error code, and is used to query if a
17 //     particular error/warning occurred.
18 //
19 //   * [optional] A parameters object.
20 //
21 //     Nodes may attach a heap-allocated subclass of CertErrorParams to carry
22 //     extra information that is used when reporting the error. For instance
23 //     a parsing error may describe where in the DER the failure happened, or
24 //     what the unexpected value was.
25 //
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.
29 //
30 // Lastly, CertPathErrors composes multiple CertErrors -- one for each
31 // certificate in the verified chain.
32 //
33 // ----------------------------
34 // Defining new errors
35 // ----------------------------
36 //
37 // The error IDs are extensible and do not need to be centrally defined.
38 //
39 // To define a new error use the macro DEFINE_CERT_ERROR_ID() in a .cc file.
40 // If consumers are to be able to query for this error then the symbol should
41 // also be exposed in a header file.
42 //
43 // Error IDs are in truth string literals, whose pointer value will be unique
44 // per process.
45 
46 #ifndef BSSL_PKI_CERT_ERRORS_H_
47 #define BSSL_PKI_CERT_ERRORS_H_
48 
49 #include <memory>
50 #include <vector>
51 
52 #include <openssl/base.h>
53 
54 #include "cert_error_id.h"
55 #include "parsed_certificate.h"
56 
57 namespace bssl {
58 
59 class CertErrorParams;
60 class CertPathErrors;
61 
62 // CertError represents either an error or a warning.
63 struct OPENSSL_EXPORT CertError {
64   enum Severity {
65     SEVERITY_HIGH,
66     SEVERITY_WARNING,
67   };
68 
69   CertError();
70   CertError(Severity severity, CertErrorId id,
71             std::unique_ptr<CertErrorParams> params);
72   CertError(CertError &&other);
73   CertError &operator=(CertError &&);
74   ~CertError();
75 
76   // Pretty-prints the error and its parameters.
77   std::string ToDebugString() const;
78 
79   Severity severity;
80   CertErrorId id;
81   std::unique_ptr<CertErrorParams> params;
82 };
83 
84 // CertErrors is a collection of CertError, along with convenience methods to
85 // add and inspect errors.
86 class OPENSSL_EXPORT CertErrors {
87  public:
88   CertErrors();
89   CertErrors(CertErrors &&other);
90   CertErrors &operator=(CertErrors &&);
91   ~CertErrors();
92 
93   // Adds an error/warning. |params| may be null.
94   void Add(CertError::Severity severity, CertErrorId id,
95            std::unique_ptr<CertErrorParams> params);
96 
97   // Adds a high severity error.
98   void AddError(CertErrorId id, std::unique_ptr<CertErrorParams> params);
99   void AddError(CertErrorId id);
100 
101   // Adds a low severity error.
102   void AddWarning(CertErrorId id, std::unique_ptr<CertErrorParams> params);
103   void AddWarning(CertErrorId id);
104 
105   // Dumps a textual representation of the errors for debugging purposes.
106   std::string ToDebugString() const;
107 
108   // Returns true if the error |id| was added to this CertErrors at
109   // severity |severity|
110   bool ContainsErrorWithSeverity(CertErrorId id,
111                                  CertError::Severity severity) const;
112 
113   // Returns true if the error |id| was added to this CertErrors at
114   // high serverity.
115   bool ContainsError(CertErrorId id) const;
116 
117   // Returns true if this contains any errors of the given severity level.
118   bool ContainsAnyErrorWithSeverity(CertError::Severity severity) const;
119 
120  private:
121  friend CertPathErrors;
122   std::vector<CertError> nodes_;
123 };
124 
125 // CertPathErrors is a collection of CertErrors, to group errors into different
126 // buckets for different certificates. The "index" should correspond with that
127 // of the certificate relative to its chain.
128 class OPENSSL_EXPORT CertPathErrors {
129  public:
130   CertPathErrors();
131   CertPathErrors(CertPathErrors &&other);
132   CertPathErrors &operator=(CertPathErrors &&);
133   ~CertPathErrors();
134 
135   // Gets a bucket to put errors in for |cert_index|. This will lookup and
136   // return the existing error bucket if one exists, or create a new one for the
137   // specified index. It is expected that |cert_index| is the corresponding
138   // index in a certificate chain (with 0 being the target).
139   CertErrors *GetErrorsForCert(size_t cert_index);
140 
141   // Const version of the above, with the difference that if there is no
142   // existing bucket for |cert_index| returns nullptr rather than lazyily
143   // creating one.
144   const CertErrors *GetErrorsForCert(size_t cert_index) const;
145 
146   // Returns a bucket to put errors that are not associated with a particular
147   // certificate.
148   CertErrors *GetOtherErrors();
149   const CertErrors *GetOtherErrors() const;
150 
151   // Returns true if CertPathErrors contains the specified error (of any
152   // severity).
153   bool ContainsError(CertErrorId id) const;
154 
155   // Returns true if this contains any errors of the given severity level.
156   bool ContainsAnyErrorWithSeverity(CertError::Severity severity) const;
157 
158   // If the path contains only one unique high severity error, return the
159   // error id and sets |out_depth| to the depth at which the error was
160   // first seen. A depth of -1 means the error is not associated with
161   // a single certificate of the path.
162   std::optional<CertErrorId> FindSingleHighSeverityError(
163       ptrdiff_t &out_depth) const;
164 
165   // Shortcut for ContainsAnyErrorWithSeverity(CertError::SEVERITY_HIGH).
ContainsHighSeverityErrors()166   bool ContainsHighSeverityErrors() const {
167     return ContainsAnyErrorWithSeverity(CertError::SEVERITY_HIGH);
168   }
169 
170   // Pretty-prints all the errors in the CertPathErrors. If there were no
171   // errors/warnings, returns an empty string.
172   std::string ToDebugString(const ParsedCertificateList &certs) const;
173 
174  private:
175   std::vector<CertErrors> cert_errors_;
176   CertErrors other_errors_;
177 };
178 
179 }  // namespace bssl
180 
181 #endif  // BSSL_PKI_CERT_ERRORS_H_
182