| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/cert/internal/cert_errors.h" |
| |
| #include "base/logging.h" |
| #include "base/strings/string_split.h" |
| #include "base/strings/stringprintf.h" |
| #include "net/cert/internal/cert_error_params.h" |
| #include "net/cert/internal/parse_name.h" |
| #include "net/cert/internal/parsed_certificate.h" |
| |
| namespace net { |
| |
| namespace { |
| |
| void AppendLinesWithIndentation(const std::string& text, |
| const std::string& indentation, |
| std::string* out) { |
| std::vector<base::StringPiece> lines = base::SplitStringPieceUsingSubstr( |
| text, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); |
| |
| for (const auto& line : lines) { |
| *out += indentation; |
| line.AppendToString(out); |
| *out += "\n"; |
| } |
| } |
| |
| } // namespace |
| |
| CertError::CertError() = default; |
| |
| CertError::CertError(Severity severity, |
| CertErrorId id, |
| std::unique_ptr<CertErrorParams> params) |
| : severity(severity), id(id), params(std::move(params)) {} |
| |
| CertError::CertError(CertError&& other) = default; |
| |
| CertError& CertError::operator=(CertError&&) = default; |
| |
| CertError::~CertError() = default; |
| |
| std::string CertError::ToDebugString() const { |
| std::string result; |
| switch (severity) { |
| case SEVERITY_WARNING: |
| result += "WARNING: "; |
| break; |
| case SEVERITY_HIGH: |
| result += "ERROR: "; |
| break; |
| } |
| result += CertErrorIdToDebugString(id); |
| result += +"\n"; |
| |
| if (params) |
| AppendLinesWithIndentation(params->ToDebugString(), " ", &result); |
| |
| return result; |
| } |
| |
| CertErrors::CertErrors() = default; |
| CertErrors::CertErrors(CertErrors&& other) = default; |
| CertErrors& CertErrors::operator=(CertErrors&&) = default; |
| CertErrors::~CertErrors() = default; |
| |
| void CertErrors::Add(CertError::Severity severity, |
| CertErrorId id, |
| std::unique_ptr<CertErrorParams> params) { |
| nodes_.push_back(CertError(severity, id, std::move(params))); |
| } |
| |
| void CertErrors::AddError(CertErrorId id, |
| std::unique_ptr<CertErrorParams> params) { |
| Add(CertError::SEVERITY_HIGH, id, std::move(params)); |
| } |
| |
| void CertErrors::AddError(CertErrorId id) { |
| AddError(id, nullptr); |
| } |
| |
| void CertErrors::AddWarning(CertErrorId id, |
| std::unique_ptr<CertErrorParams> params) { |
| Add(CertError::SEVERITY_WARNING, id, std::move(params)); |
| } |
| |
| void CertErrors::AddWarning(CertErrorId id) { |
| AddWarning(id, nullptr); |
| } |
| |
| std::string CertErrors::ToDebugString() const { |
| std::string result; |
| for (const CertError& node : nodes_) |
| result += node.ToDebugString(); |
| |
| return result; |
| } |
| |
| bool CertErrors::ContainsError(CertErrorId id) const { |
| for (const CertError& node : nodes_) { |
| if (node.id == id) |
| return true; |
| } |
| return false; |
| } |
| |
| bool CertErrors::ContainsAnyErrorWithSeverity( |
| CertError::Severity severity) const { |
| for (const CertError& node : nodes_) { |
| if (node.severity == severity) |
| return true; |
| } |
| return false; |
| } |
| |
| CertPathErrors::CertPathErrors() = default; |
| |
| CertPathErrors::CertPathErrors(CertPathErrors&& other) = default; |
| CertPathErrors& CertPathErrors::operator=(CertPathErrors&&) = default; |
| |
| CertPathErrors::~CertPathErrors() = default; |
| |
| CertErrors* CertPathErrors::GetErrorsForCert(size_t cert_index) { |
| if (cert_index >= cert_errors_.size()) |
| cert_errors_.resize(cert_index + 1); |
| return &cert_errors_[cert_index]; |
| } |
| |
| const CertErrors* CertPathErrors::GetErrorsForCert(size_t cert_index) const { |
| if (cert_index >= cert_errors_.size()) |
| return nullptr; |
| return &cert_errors_[cert_index]; |
| } |
| |
| CertErrors* CertPathErrors::GetOtherErrors() { |
| return &other_errors_; |
| } |
| |
| bool CertPathErrors::ContainsError(CertErrorId id) const { |
| for (const CertErrors& errors : cert_errors_) { |
| if (errors.ContainsError(id)) |
| return true; |
| } |
| |
| if (other_errors_.ContainsError(id)) |
| return true; |
| |
| return false; |
| } |
| |
| bool CertPathErrors::ContainsAnyErrorWithSeverity( |
| CertError::Severity severity) const { |
| for (const CertErrors& errors : cert_errors_) { |
| if (errors.ContainsAnyErrorWithSeverity(severity)) |
| return true; |
| } |
| |
| if (other_errors_.ContainsAnyErrorWithSeverity(severity)) |
| return true; |
| |
| return false; |
| } |
| |
| std::string CertPathErrors::ToDebugString( |
| const ParsedCertificateList& certs) const { |
| std::string result; |
| |
| for (size_t i = 0; i < cert_errors_.size(); ++i) { |
| // Pretty print the current CertErrors. If there were no errors/warnings, |
| // then continue. |
| const CertErrors& errors = cert_errors_[i]; |
| std::string cert_errors_string = errors.ToDebugString(); |
| if (cert_errors_string.empty()) |
| continue; |
| |
| // Add a header that identifies which certificate this CertErrors pertains |
| // to. |
| std::string cert_name_debug_str; |
| if (i < certs.size() && certs[i]) { |
| RDNSequence subject; |
| if (ParseName(certs[i]->tbs().subject_tlv, &subject) && |
| ConvertToRFC2253(subject, &cert_name_debug_str)) { |
| cert_name_debug_str = " (" + cert_name_debug_str + ")"; |
| } |
| } |
| |
| result += |
| base::StringPrintf("----- Certificate i=%d%s -----\n", |
| static_cast<int>(i), cert_name_debug_str.c_str()); |
| |
| result += cert_errors_string; |
| result += "\n"; |
| } |
| |
| // Print any other errors that aren't associated with a particular certificate |
| // in the chain. |
| std::string other_errors = other_errors_.ToDebugString(); |
| if (!other_errors.empty()) { |
| result += "----- Other errors (not certificate specific) -----\n"; |
| result += other_errors; |
| result += "\n"; |
| } |
| |
| return result; |
| } |
| |
| } // namespace net |