blob: cf5ec1640e61452db6a60504a737f87a2124db65 [file] [log] [blame]
// Copyright 2019 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 "chromeos/network/onc/onc_certificate_pattern.h"
#include <stddef.h>
#include <utility>
#include "base/logging.h"
#include "base/values.h"
#include "components/onc/onc_constants.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util_nss.h"
namespace chromeos {
namespace {
bool GetAsListOfStrings(const base::Value& value,
std::vector<std::string>* result) {
if (!value.is_list())
return false;
result->clear();
result->reserve(value.GetList().size());
for (const auto& entry : value.GetList()) {
if (!entry.is_string())
return false;
result->push_back(entry.GetString());
}
return true;
}
} // namespace
////////////////////////////////////////////////////////////////////////////////
// OncCertificatePattern
OncCertificatePattern::OncCertificatePattern() = default;
OncCertificatePattern::OncCertificatePattern(
const OncCertificatePattern& other) = default;
OncCertificatePattern::OncCertificatePattern(OncCertificatePattern&& other) =
default;
OncCertificatePattern::~OncCertificatePattern() = default;
OncCertificatePattern& OncCertificatePattern::operator=(
const OncCertificatePattern& rhs) = default;
OncCertificatePattern& OncCertificatePattern::operator=(
OncCertificatePattern&& rhs) = default;
bool OncCertificatePattern::Empty() const {
return pem_encoded_issuer_cas_.empty() && issuer_pattern_.Empty() &&
subject_pattern_.Empty();
}
bool OncCertificatePattern::Matches(
const net::X509Certificate& certificate,
const std::string& pem_encoded_issuer_ca) const {
if (!issuer_pattern_.Empty() || !subject_pattern_.Empty()) {
if (!issuer_pattern_.Empty() &&
!issuer_pattern_.Matches(certificate.issuer()))
return false;
if (!subject_pattern_.Empty() &&
!subject_pattern_.Matches(certificate.subject()))
return false;
}
if (!pem_encoded_issuer_cas_.empty() &&
!base::ContainsValue(pem_encoded_issuer_cas_, pem_encoded_issuer_ca)) {
return false;
}
return true;
}
// static
base::Optional<OncCertificatePattern>
OncCertificatePattern::ReadFromONCDictionary(const base::Value& dict) {
// All of these are optional.
const base::Value* pem_encoded_issuer_cas_value = dict.FindKeyOfType(
onc::client_cert::kIssuerCAPEMs, base::Value::Type::LIST);
std::vector<std::string> pem_encoded_issuer_cas;
if (pem_encoded_issuer_cas_value &&
!GetAsListOfStrings(*pem_encoded_issuer_cas_value,
&pem_encoded_issuer_cas)) {
return base::nullopt;
}
const base::Value* enrollment_uri_list_value = dict.FindKeyOfType(
onc::client_cert::kEnrollmentURI, base::Value::Type::LIST);
std::vector<std::string> enrollment_uri_list;
if (enrollment_uri_list_value &&
!GetAsListOfStrings(*enrollment_uri_list_value, &enrollment_uri_list)) {
return base::nullopt;
}
auto issuer_pattern =
certificate_matching::CertificatePrincipalPattern::ParseFromOptionalDict(
dict.FindKeyOfType(onc::client_cert::kIssuer,
base::Value::Type::DICTIONARY),
onc::client_cert::kCommonName, onc::client_cert::kLocality,
onc::client_cert::kOrganization,
onc::client_cert::kOrganizationalUnit);
auto subject_pattern =
certificate_matching::CertificatePrincipalPattern::ParseFromOptionalDict(
dict.FindKeyOfType(onc::client_cert::kSubject,
base::Value::Type::DICTIONARY),
onc::client_cert::kCommonName, onc::client_cert::kLocality,
onc::client_cert::kOrganization,
onc::client_cert::kOrganizationalUnit);
return OncCertificatePattern(pem_encoded_issuer_cas, issuer_pattern,
subject_pattern, enrollment_uri_list);
}
OncCertificatePattern::OncCertificatePattern(
std::vector<std::string> pem_encoded_issuer_cas,
certificate_matching::CertificatePrincipalPattern issuer_pattern,
certificate_matching::CertificatePrincipalPattern subject_pattern,
std::vector<std::string> enrollment_uri_list)
: pem_encoded_issuer_cas_(std::move(pem_encoded_issuer_cas)),
issuer_pattern_(std::move(issuer_pattern)),
subject_pattern_(std::move(subject_pattern)),
enrollment_uri_list_(std::move(enrollment_uri_list)) {}
} // namespace chromeos