blob: 12376b9c55d4db612ebe4c38f8ea45ad511c0e3e [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
17void AppendLinesWithIndentation(const std::string& text,
18 const std::string& indentation,
19 std::string* out) {
20 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
32CertError::CertError(Severity in_severity,
33 CertErrorId in_id,
34 std::unique_ptr<CertErrorParams> in_params)
35 : severity(in_severity), id(in_id), params(std::move(in_params)) {}
36
37CertError::CertError(CertError&& other) = default;
38
39CertError& CertError::operator=(CertError&&) = default;
40
41CertError::~CertError() = default;
42
43std::string CertError::ToDebugString() const {
44 std::string result;
45 switch (severity) {
46 case SEVERITY_WARNING:
47 result += "WARNING: ";
48 break;
49 case SEVERITY_HIGH:
50 result += "ERROR: ";
51 break;
52 }
53 result += CertErrorIdToDebugString(id);
54 result += +"\n";
55
56 if (params)
57 AppendLinesWithIndentation(params->ToDebugString(), " ", &result);
58
59 return result;
60}
61
62CertErrors::CertErrors() = default;
63CertErrors::CertErrors(CertErrors&& other) = default;
64CertErrors& CertErrors::operator=(CertErrors&&) = default;
65CertErrors::~CertErrors() = default;
66
67void CertErrors::Add(CertError::Severity severity,
68 CertErrorId id,
69 std::unique_ptr<CertErrorParams> params) {
70 nodes_.emplace_back(severity, id, std::move(params));
71}
72
73void CertErrors::AddError(CertErrorId id,
74 std::unique_ptr<CertErrorParams> params) {
75 Add(CertError::SEVERITY_HIGH, id, std::move(params));
76}
77
78void CertErrors::AddError(CertErrorId id) {
79 AddError(id, nullptr);
80}
81
82void CertErrors::AddWarning(CertErrorId id,
83 std::unique_ptr<CertErrorParams> params) {
84 Add(CertError::SEVERITY_WARNING, id, std::move(params));
85}
86
87void CertErrors::AddWarning(CertErrorId id) {
88 AddWarning(id, nullptr);
89}
90
91std::string CertErrors::ToDebugString() const {
92 std::string result;
93 for (const CertError& node : nodes_)
94 result += node.ToDebugString();
95
96 return result;
97}
98
99bool CertErrors::ContainsError(CertErrorId id) const {
100 for (const CertError& node : nodes_) {
101 if (node.id == id)
102 return true;
103 }
104 return false;
105}
106
107bool CertErrors::ContainsAnyErrorWithSeverity(
108 CertError::Severity severity) const {
109 for (const CertError& node : nodes_) {
110 if (node.severity == severity)
111 return true;
112 }
113 return false;
114}
115
116CertPathErrors::CertPathErrors() = default;
117
118CertPathErrors::CertPathErrors(CertPathErrors&& other) = default;
119CertPathErrors& CertPathErrors::operator=(CertPathErrors&&) = default;
120
121CertPathErrors::~CertPathErrors() = default;
122
123CertErrors* CertPathErrors::GetErrorsForCert(size_t cert_index) {
124 if (cert_index >= cert_errors_.size())
125 cert_errors_.resize(cert_index + 1);
126 return &cert_errors_[cert_index];
127}
128
129const CertErrors* CertPathErrors::GetErrorsForCert(size_t cert_index) const {
130 if (cert_index >= cert_errors_.size())
131 return nullptr;
132 return &cert_errors_[cert_index];
133}
134
135CertErrors* CertPathErrors::GetOtherErrors() {
136 return &other_errors_;
137}
138
139bool CertPathErrors::ContainsError(CertErrorId id) const {
140 for (const CertErrors& errors : cert_errors_) {
141 if (errors.ContainsError(id))
142 return true;
143 }
144
145 if (other_errors_.ContainsError(id))
146 return true;
147
148 return false;
149}
150
151bool CertPathErrors::ContainsAnyErrorWithSeverity(
152 CertError::Severity severity) const {
153 for (const CertErrors& errors : cert_errors_) {
154 if (errors.ContainsAnyErrorWithSeverity(severity))
155 return true;
156 }
157
158 if (other_errors_.ContainsAnyErrorWithSeverity(severity))
159 return true;
160
161 return false;
162}
163
164std::string CertPathErrors::ToDebugString(
165 const ParsedCertificateList& certs) const {
166 std::ostringstream result;
167
168 for (size_t i = 0; i < cert_errors_.size(); ++i) {
169 // Pretty print the current CertErrors. If there were no errors/warnings,
170 // then continue.
171 const CertErrors& errors = cert_errors_[i];
172 std::string cert_errors_string = errors.ToDebugString();
173 if (cert_errors_string.empty())
174 continue;
175
176 // Add a header that identifies which certificate this CertErrors pertains
177 // to.
178 std::string cert_name_debug_str;
179 if (i < certs.size() && certs[i]) {
180 RDNSequence subject;
181 if (ParseName(certs[i]->tbs().subject_tlv, &subject) &&
182 ConvertToRFC2253(subject, &cert_name_debug_str)) {
183 cert_name_debug_str = " (" + cert_name_debug_str + ")";
184 }
185 }
186 result << "----- Certificate i=" << i << cert_name_debug_str << " -----\n";
187 result << cert_errors_string << "\n";
188 }
189
190 // Print any other errors that aren't associated with a particular certificate
191 // in the chain.
192 std::string other_errors = other_errors_.ToDebugString();
193 if (!other_errors.empty()) {
194 result << "----- Other errors (not certificate specific) -----\n";
195 result << other_errors << "\n";
196 }
197
198 return result.str();
199}
200
201} // namespace net