blob: 3f5a77f781879adade9cccece4123eab76b6a1e3 [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#include "cert_errors.h"
6
7#include "cert_error_params.h"
8#include "parse_name.h"
9#include "parsed_certificate.h"
10
11#include <sstream>
12
13namespace bssl {
14
15namespace {
16
Bob Beck5c7a2a02023-11-20 17:28:21 -070017void AppendLinesWithIndentation(const std::string &text,
18 const std::string &indentation,
19 std::string *out) {
Bob Beckbc97b7a2023-04-18 08:35:15 -060020 std::istringstream stream(text);
21 for (std::string line; std::getline(stream, line, '\n');) {
22 out->append(indentation);
23 out->append(line);
24 out->append("\n");
25 }
26}
27
28} // namespace
29
30CertError::CertError() = default;
31
Bob Beck5c7a2a02023-11-20 17:28:21 -070032CertError::CertError(Severity in_severity, CertErrorId in_id,
Bob Beckbc97b7a2023-04-18 08:35:15 -060033 std::unique_ptr<CertErrorParams> in_params)
34 : severity(in_severity), id(in_id), params(std::move(in_params)) {}
35
Bob Beck5c7a2a02023-11-20 17:28:21 -070036CertError::CertError(CertError &&other) = default;
Bob Beckbc97b7a2023-04-18 08:35:15 -060037
Bob Beck5c7a2a02023-11-20 17:28:21 -070038CertError &CertError::operator=(CertError &&) = default;
Bob Beckbc97b7a2023-04-18 08:35:15 -060039
40CertError::~CertError() = default;
41
42std::string CertError::ToDebugString() const {
43 std::string result;
44 switch (severity) {
45 case SEVERITY_WARNING:
46 result += "WARNING: ";
47 break;
48 case SEVERITY_HIGH:
49 result += "ERROR: ";
50 break;
51 }
52 result += CertErrorIdToDebugString(id);
53 result += +"\n";
54
Bob Beck6beabf32023-11-21 09:43:52 -070055 if (params) {
Bob Beckbc97b7a2023-04-18 08:35:15 -060056 AppendLinesWithIndentation(params->ToDebugString(), " ", &result);
Bob Beck6beabf32023-11-21 09:43:52 -070057 }
Bob Beckbc97b7a2023-04-18 08:35:15 -060058
59 return result;
60}
61
62CertErrors::CertErrors() = default;
Bob Beck5c7a2a02023-11-20 17:28:21 -070063CertErrors::CertErrors(CertErrors &&other) = default;
64CertErrors &CertErrors::operator=(CertErrors &&) = default;
Bob Beckbc97b7a2023-04-18 08:35:15 -060065CertErrors::~CertErrors() = default;
66
Bob Beck5c7a2a02023-11-20 17:28:21 -070067void CertErrors::Add(CertError::Severity severity, CertErrorId id,
Bob Beckbc97b7a2023-04-18 08:35:15 -060068 std::unique_ptr<CertErrorParams> params) {
69 nodes_.emplace_back(severity, id, std::move(params));
70}
71
72void CertErrors::AddError(CertErrorId id,
73 std::unique_ptr<CertErrorParams> params) {
74 Add(CertError::SEVERITY_HIGH, id, std::move(params));
75}
76
Bob Beck5c7a2a02023-11-20 17:28:21 -070077void CertErrors::AddError(CertErrorId id) { AddError(id, nullptr); }
Bob Beckbc97b7a2023-04-18 08:35:15 -060078
79void CertErrors::AddWarning(CertErrorId id,
80 std::unique_ptr<CertErrorParams> params) {
81 Add(CertError::SEVERITY_WARNING, id, std::move(params));
82}
83
Bob Beck5c7a2a02023-11-20 17:28:21 -070084void CertErrors::AddWarning(CertErrorId id) { AddWarning(id, nullptr); }
Bob Beckbc97b7a2023-04-18 08:35:15 -060085
86std::string CertErrors::ToDebugString() const {
87 std::string result;
Bob Beck6beabf32023-11-21 09:43:52 -070088 for (const CertError &node : nodes_) {
Bob Beckbc97b7a2023-04-18 08:35:15 -060089 result += node.ToDebugString();
Bob Beck6beabf32023-11-21 09:43:52 -070090 }
Bob Beckbc97b7a2023-04-18 08:35:15 -060091
92 return result;
93}
94
Bob Beck58a318e2024-02-13 22:54:29 +000095bool CertErrors::ContainsErrorWithSeverity(CertErrorId id,
96 CertError::Severity severity) const {
Bob Beck5c7a2a02023-11-20 17:28:21 -070097 for (const CertError &node : nodes_) {
Bob Beck58a318e2024-02-13 22:54:29 +000098 if (node.id == id && node.severity == severity) {
Bob Beckbc97b7a2023-04-18 08:35:15 -060099 return true;
Bob Beck6beabf32023-11-21 09:43:52 -0700100 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600101 }
102 return false;
103}
104
Bob Beck58a318e2024-02-13 22:54:29 +0000105bool CertErrors::ContainsError(CertErrorId id) const {
106 return ContainsErrorWithSeverity(id, CertError::SEVERITY_HIGH);
107}
108
Bob Beckbc97b7a2023-04-18 08:35:15 -0600109bool CertErrors::ContainsAnyErrorWithSeverity(
110 CertError::Severity severity) const {
Bob Beck5c7a2a02023-11-20 17:28:21 -0700111 for (const CertError &node : nodes_) {
Bob Beck6beabf32023-11-21 09:43:52 -0700112 if (node.severity == severity) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600113 return true;
Bob Beck6beabf32023-11-21 09:43:52 -0700114 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600115 }
116 return false;
117}
118
119CertPathErrors::CertPathErrors() = default;
120
Bob Beck5c7a2a02023-11-20 17:28:21 -0700121CertPathErrors::CertPathErrors(CertPathErrors &&other) = default;
122CertPathErrors &CertPathErrors::operator=(CertPathErrors &&) = default;
Bob Beckbc97b7a2023-04-18 08:35:15 -0600123
124CertPathErrors::~CertPathErrors() = default;
125
Bob Beck5c7a2a02023-11-20 17:28:21 -0700126CertErrors *CertPathErrors::GetErrorsForCert(size_t cert_index) {
Bob Beck6beabf32023-11-21 09:43:52 -0700127 if (cert_index >= cert_errors_.size()) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600128 cert_errors_.resize(cert_index + 1);
Bob Beck6beabf32023-11-21 09:43:52 -0700129 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600130 return &cert_errors_[cert_index];
131}
132
Bob Beck5c7a2a02023-11-20 17:28:21 -0700133const CertErrors *CertPathErrors::GetErrorsForCert(size_t cert_index) const {
Bob Beck6beabf32023-11-21 09:43:52 -0700134 if (cert_index >= cert_errors_.size()) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600135 return nullptr;
Bob Beck6beabf32023-11-21 09:43:52 -0700136 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600137 return &cert_errors_[cert_index];
138}
139
Bob Beck5c7a2a02023-11-20 17:28:21 -0700140CertErrors *CertPathErrors::GetOtherErrors() { return &other_errors_; }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600141
142bool CertPathErrors::ContainsError(CertErrorId id) const {
Bob Beck5c7a2a02023-11-20 17:28:21 -0700143 for (const CertErrors &errors : cert_errors_) {
Bob Beck6beabf32023-11-21 09:43:52 -0700144 if (errors.ContainsError(id)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600145 return true;
Bob Beck6beabf32023-11-21 09:43:52 -0700146 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600147 }
148
Bob Beck6beabf32023-11-21 09:43:52 -0700149 if (other_errors_.ContainsError(id)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600150 return true;
Bob Beck6beabf32023-11-21 09:43:52 -0700151 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600152
153 return false;
154}
155
156bool CertPathErrors::ContainsAnyErrorWithSeverity(
157 CertError::Severity severity) const {
Bob Beck5c7a2a02023-11-20 17:28:21 -0700158 for (const CertErrors &errors : cert_errors_) {
Bob Beck6beabf32023-11-21 09:43:52 -0700159 if (errors.ContainsAnyErrorWithSeverity(severity)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600160 return true;
Bob Beck6beabf32023-11-21 09:43:52 -0700161 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600162 }
163
Bob Beck6beabf32023-11-21 09:43:52 -0700164 if (other_errors_.ContainsAnyErrorWithSeverity(severity)) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600165 return true;
Bob Beck6beabf32023-11-21 09:43:52 -0700166 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600167
168 return false;
169}
170
171std::string CertPathErrors::ToDebugString(
Bob Beck5c7a2a02023-11-20 17:28:21 -0700172 const ParsedCertificateList &certs) const {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600173 std::ostringstream result;
174
175 for (size_t i = 0; i < cert_errors_.size(); ++i) {
176 // Pretty print the current CertErrors. If there were no errors/warnings,
177 // then continue.
Bob Beck5c7a2a02023-11-20 17:28:21 -0700178 const CertErrors &errors = cert_errors_[i];
Bob Beckbc97b7a2023-04-18 08:35:15 -0600179 std::string cert_errors_string = errors.ToDebugString();
Bob Beck6beabf32023-11-21 09:43:52 -0700180 if (cert_errors_string.empty()) {
Bob Beckbc97b7a2023-04-18 08:35:15 -0600181 continue;
Bob Beck6beabf32023-11-21 09:43:52 -0700182 }
Bob Beckbc97b7a2023-04-18 08:35:15 -0600183
184 // Add a header that identifies which certificate this CertErrors pertains
185 // to.
186 std::string cert_name_debug_str;
187 if (i < certs.size() && certs[i]) {
188 RDNSequence subject;
189 if (ParseName(certs[i]->tbs().subject_tlv, &subject) &&
190 ConvertToRFC2253(subject, &cert_name_debug_str)) {
191 cert_name_debug_str = " (" + cert_name_debug_str + ")";
192 }
193 }
194 result << "----- Certificate i=" << i << cert_name_debug_str << " -----\n";
195 result << cert_errors_string << "\n";
196 }
197
198 // Print any other errors that aren't associated with a particular certificate
199 // in the chain.
200 std::string other_errors = other_errors_.ToDebugString();
201 if (!other_errors.empty()) {
202 result << "----- Other errors (not certificate specific) -----\n";
203 result << other_errors << "\n";
204 }
205
206 return result.str();
207}
208
Bob Beck5c7a2a02023-11-20 17:28:21 -0700209} // namespace bssl