Coverage Report

Created: 2026-03-19 06:22

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