• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "fillins/openssl_util.h"
9 //
10 // Certificate path building/validation/parsing may emit a sequence of errors
11 // and warnings.
12 //
13 // Each individual error/warning entry (CertError) is comprised of:
14 //
15 //   * A unique identifier.
16 //
17 //     This serves similarly to an error code, and is used to query if a
18 //     particular error/warning occurred.
19 //
20 //   * [optional] A parameters object.
21 //
22 //     Nodes may attach a heap-allocated subclass of CertErrorParams to carry
23 //     extra information that is used when reporting the error. For instance
24 //     a parsing error may describe where in the DER the failure happened, or
25 //     what the unexpected value was.
26 //
27 // A collection of errors is represented by the CertErrors object. This may be
28 // used to group errors that have a common context, such as all the
29 // errors/warnings that apply to a specific certificate.
30 //
31 // Lastly, CertPathErrors composes multiple CertErrors -- one for each
32 // certificate in the verified chain.
33 //
34 // ----------------------------
35 // Defining new errors
36 // ----------------------------
37 //
38 // The error IDs are extensible and do not need to be centrally defined.
39 //
40 // To define a new error use the macro DEFINE_CERT_ERROR_ID() in a .cc file.
41 // If consumers are to be able to query for this error then the symbol should
42 // also be exposed in a header file.
43 //
44 // Error IDs are in truth string literals, whose pointer value will be unique
45 // per process.
46 
47 #ifndef BSSL_PKI_CERT_ERRORS_H_
48 #define BSSL_PKI_CERT_ERRORS_H_
49 
50 #include <memory>
51 #include <vector>
52 
53 
54 #include "cert_error_id.h"
55 #include "parsed_certificate.h"
56 
57 namespace bssl {
58 
59 class CertErrorParams;
60 
61 // CertError represents either an error or a warning.
62 struct OPENSSL_EXPORT CertError {
63   enum Severity {
64     SEVERITY_HIGH,
65     SEVERITY_WARNING,
66   };
67 
68   CertError();
69   CertError(Severity severity,
70             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,
95            CertErrorId id,
96            std::unique_ptr<CertErrorParams> params);
97 
98   // Adds a high severity error.
99   void AddError(CertErrorId id, std::unique_ptr<CertErrorParams> params);
100   void AddError(CertErrorId id);
101 
102   // Adds a low severity error.
103   void AddWarning(CertErrorId id, std::unique_ptr<CertErrorParams> params);
104   void AddWarning(CertErrorId id);
105 
106   // Dumps a textual representation of the errors for debugging purposes.
107   std::string ToDebugString() const;
108 
109   // Returns true if the error |id| was added to this CertErrors (of any
110   // severity).
111   bool ContainsError(CertErrorId id) const;
112 
113   // Returns true if this contains any errors of the given severity level.
114   bool ContainsAnyErrorWithSeverity(CertError::Severity severity) const;
115 
116  private:
117   std::vector<CertError> nodes_;
118 };
119 
120 // CertPathErrors is a collection of CertErrors, to group errors into different
121 // buckets for different certificates. The "index" should correspond with that
122 // of the certificate relative to its chain.
123 class OPENSSL_EXPORT CertPathErrors {
124  public:
125   CertPathErrors();
126   CertPathErrors(CertPathErrors&& other);
127   CertPathErrors& operator=(CertPathErrors&&);
128   ~CertPathErrors();
129 
130   // Gets a bucket to put errors in for |cert_index|. This will lookup and
131   // return the existing error bucket if one exists, or create a new one for the
132   // specified index. It is expected that |cert_index| is the corresponding
133   // index in a certificate chain (with 0 being the target).
134   CertErrors* GetErrorsForCert(size_t cert_index);
135 
136   // Const version of the above, with the difference that if there is no
137   // existing bucket for |cert_index| returns nullptr rather than lazyily
138   // creating one.
139   const CertErrors* GetErrorsForCert(size_t cert_index) const;
140 
141   // Returns a bucket to put errors that are not associated with a particular
142   // certificate.
143   CertErrors* GetOtherErrors();
144 
145   // Returns true if CertPathErrors contains the specified error (of any
146   // severity).
147   bool ContainsError(CertErrorId id) const;
148 
149   // Returns true if this contains any errors of the given severity level.
150   bool ContainsAnyErrorWithSeverity(CertError::Severity severity) const;
151 
152   // Shortcut for ContainsAnyErrorWithSeverity(CertError::SEVERITY_HIGH).
ContainsHighSeverityErrors()153   bool ContainsHighSeverityErrors() const {
154     return ContainsAnyErrorWithSeverity(CertError::SEVERITY_HIGH);
155   }
156 
157   // Pretty-prints all the errors in the CertPathErrors. If there were no
158   // errors/warnings, returns an empty string.
159   std::string ToDebugString(const ParsedCertificateList& certs) const;
160 
161  private:
162   std::vector<CertErrors> cert_errors_;
163   CertErrors other_errors_;
164 };
165 
166 }  // namespace net
167 
168 #endif  // BSSL_PKI_CERT_ERRORS_H_
169