blob: da350607f8e7a161f2203ad081e3dbf7102cc432 [file] [log] [blame]
Bob Beckbc97b7a2023-04-18 08:35:15 -06001// 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// ----------------------------
Bob Beckbc97b7a2023-04-18 08:35:15 -06008//
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
Bob Beck3cd30cc2023-11-22 16:59:00 -070052#include <openssl/base.h>
Bob Beckbc97b7a2023-04-18 08:35:15 -060053
54#include "cert_error_id.h"
55#include "parsed_certificate.h"
56
57namespace bssl {
58
59class CertErrorParams;
60
61// CertError represents either an error or a warning.
62struct OPENSSL_EXPORT CertError {
63 enum Severity {
64 SEVERITY_HIGH,
65 SEVERITY_WARNING,
66 };
67
68 CertError();
Bob Beck5c7a2a02023-11-20 17:28:21 -070069 CertError(Severity severity, CertErrorId id,
Bob Beckbc97b7a2023-04-18 08:35:15 -060070 std::unique_ptr<CertErrorParams> params);
Bob Beck5c7a2a02023-11-20 17:28:21 -070071 CertError(CertError &&other);
72 CertError &operator=(CertError &&);
Bob Beckbc97b7a2023-04-18 08:35:15 -060073 ~CertError();
74
75 // Pretty-prints the error and its parameters.
76 std::string ToDebugString() const;
77
78 Severity severity;
79 CertErrorId id;
80 std::unique_ptr<CertErrorParams> params;
81};
82
83// CertErrors is a collection of CertError, along with convenience methods to
84// add and inspect errors.
85class OPENSSL_EXPORT CertErrors {
86 public:
87 CertErrors();
Bob Beck5c7a2a02023-11-20 17:28:21 -070088 CertErrors(CertErrors &&other);
89 CertErrors &operator=(CertErrors &&);
Bob Beckbc97b7a2023-04-18 08:35:15 -060090 ~CertErrors();
91
92 // Adds an error/warning. |params| may be null.
Bob Beck5c7a2a02023-11-20 17:28:21 -070093 void Add(CertError::Severity severity, CertErrorId id,
Bob Beckbc97b7a2023-04-18 08:35:15 -060094 std::unique_ptr<CertErrorParams> params);
95
96 // Adds a high severity error.
97 void AddError(CertErrorId id, std::unique_ptr<CertErrorParams> params);
98 void AddError(CertErrorId id);
99
100 // Adds a low severity error.
101 void AddWarning(CertErrorId id, std::unique_ptr<CertErrorParams> params);
102 void AddWarning(CertErrorId id);
103
104 // Dumps a textual representation of the errors for debugging purposes.
105 std::string ToDebugString() const;
106
Bob Beck58a318e2024-02-13 22:54:29 +0000107 // Returns true if the error |id| was added to this CertErrors at
108 // severity |severity|
109 bool ContainsErrorWithSeverity(CertErrorId id,
110 CertError::Severity severity) const;
111
112 // Returns true if the error |id| was added to this CertErrors at
113 // high serverity.
Bob Beckbc97b7a2023-04-18 08:35:15 -0600114 bool ContainsError(CertErrorId id) const;
115
116 // Returns true if this contains any errors of the given severity level.
117 bool ContainsAnyErrorWithSeverity(CertError::Severity severity) const;
118
119 private:
120 std::vector<CertError> nodes_;
121};
122
123// CertPathErrors is a collection of CertErrors, to group errors into different
124// buckets for different certificates. The "index" should correspond with that
125// of the certificate relative to its chain.
126class OPENSSL_EXPORT CertPathErrors {
127 public:
128 CertPathErrors();
Bob Beck5c7a2a02023-11-20 17:28:21 -0700129 CertPathErrors(CertPathErrors &&other);
130 CertPathErrors &operator=(CertPathErrors &&);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600131 ~CertPathErrors();
132
133 // Gets a bucket to put errors in for |cert_index|. This will lookup and
134 // return the existing error bucket if one exists, or create a new one for the
135 // specified index. It is expected that |cert_index| is the corresponding
136 // index in a certificate chain (with 0 being the target).
Bob Beck5c7a2a02023-11-20 17:28:21 -0700137 CertErrors *GetErrorsForCert(size_t cert_index);
Bob Beckbc97b7a2023-04-18 08:35:15 -0600138
139 // Const version of the above, with the difference that if there is no
140 // existing bucket for |cert_index| returns nullptr rather than lazyily
141 // creating one.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700142 const CertErrors *GetErrorsForCert(size_t cert_index) const;
Bob Beckbc97b7a2023-04-18 08:35:15 -0600143
144 // Returns a bucket to put errors that are not associated with a particular
145 // certificate.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700146 CertErrors *GetOtherErrors();
Bob Beckbc97b7a2023-04-18 08:35:15 -0600147
148 // Returns true if CertPathErrors contains the specified error (of any
149 // severity).
150 bool ContainsError(CertErrorId id) const;
151
152 // Returns true if this contains any errors of the given severity level.
153 bool ContainsAnyErrorWithSeverity(CertError::Severity severity) const;
154
155 // Shortcut for ContainsAnyErrorWithSeverity(CertError::SEVERITY_HIGH).
156 bool ContainsHighSeverityErrors() const {
157 return ContainsAnyErrorWithSeverity(CertError::SEVERITY_HIGH);
158 }
159
160 // Pretty-prints all the errors in the CertPathErrors. If there were no
161 // errors/warnings, returns an empty string.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700162 std::string ToDebugString(const ParsedCertificateList &certs) const;
Bob Beckbc97b7a2023-04-18 08:35:15 -0600163
164 private:
165 std::vector<CertErrors> cert_errors_;
166 CertErrors other_errors_;
167};
168
Bob Beck5c7a2a02023-11-20 17:28:21 -0700169} // namespace bssl
Bob Beckbc97b7a2023-04-18 08:35:15 -0600170
171#endif // BSSL_PKI_CERT_ERRORS_H_