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 NET_CERT_PKI_CERT_ERRORS_H_ 47 #define NET_CERT_PKI_CERT_ERRORS_H_ 48 49 #include <memory> 50 #include <vector> 51 52 #include "net/base/net_export.h" 53 #include "net/cert/pki/cert_error_id.h" 54 #include "net/cert/pki/parsed_certificate.h" 55 56 namespace net { 57 58 class CertErrorParams; 59 60 // CertError represents either an error or a warning. 61 struct NET_EXPORT CertError { 62 enum Severity { 63 SEVERITY_HIGH, 64 SEVERITY_WARNING, 65 }; 66 67 CertError(); 68 CertError(Severity severity, 69 CertErrorId id, 70 std::unique_ptr<CertErrorParams> params); 71 CertError(CertError&& other); 72 CertError& operator=(CertError&&); 73 ~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. 85 class NET_EXPORT CertErrors { 86 public: 87 CertErrors(); 88 CertErrors(CertErrors&& other); 89 CertErrors& operator=(CertErrors&&); 90 ~CertErrors(); 91 92 // Adds an error/warning. |params| may be null. 93 void Add(CertError::Severity severity, 94 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 (of any 109 // severity). 110 bool ContainsError(CertErrorId id) const; 111 112 // Returns true if this contains any errors of the given severity level. 113 bool ContainsAnyErrorWithSeverity(CertError::Severity severity) const; 114 115 private: 116 std::vector<CertError> nodes_; 117 }; 118 119 // CertPathErrors is a collection of CertErrors, to group errors into different 120 // buckets for different certificates. The "index" should correspond with that 121 // of the certificate relative to its chain. 122 class NET_EXPORT CertPathErrors { 123 public: 124 CertPathErrors(); 125 CertPathErrors(CertPathErrors&& other); 126 CertPathErrors& operator=(CertPathErrors&&); 127 ~CertPathErrors(); 128 129 // Gets a bucket to put errors in for |cert_index|. This will lookup and 130 // return the existing error bucket if one exists, or create a new one for the 131 // specified index. It is expected that |cert_index| is the corresponding 132 // index in a certificate chain (with 0 being the target). 133 CertErrors* GetErrorsForCert(size_t cert_index); 134 135 // Const version of the above, with the difference that if there is no 136 // existing bucket for |cert_index| returns nullptr rather than lazyily 137 // creating one. 138 const CertErrors* GetErrorsForCert(size_t cert_index) const; 139 140 // Returns a bucket to put errors that are not associated with a particular 141 // certificate. 142 CertErrors* GetOtherErrors(); 143 144 // Returns true if CertPathErrors contains the specified error (of any 145 // severity). 146 bool ContainsError(CertErrorId id) const; 147 148 // Returns true if this contains any errors of the given severity level. 149 bool ContainsAnyErrorWithSeverity(CertError::Severity severity) const; 150 151 // Shortcut for ContainsAnyErrorWithSeverity(CertError::SEVERITY_HIGH). ContainsHighSeverityErrors()152 bool ContainsHighSeverityErrors() const { 153 return ContainsAnyErrorWithSeverity(CertError::SEVERITY_HIGH); 154 } 155 156 // Pretty-prints all the errors in the CertPathErrors. If there were no 157 // errors/warnings, returns an empty string. 158 std::string ToDebugString(const ParsedCertificateList& certs) const; 159 160 private: 161 std::vector<CertErrors> cert_errors_; 162 CertErrors other_errors_; 163 }; 164 165 } // namespace net 166 167 #endif // NET_CERT_PKI_CERT_ERRORS_H_ 168