Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(932)

Unified Diff: net/cert/internal/parsed_certificate.cc

Issue 1976433002: Add new ParsedCertificate class, move TrustStore to own file. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cert-parsing-remove-old-parsedcertificate
Patch Set: . Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/cert/internal/parsed_certificate.cc
diff --git a/net/cert/internal/parsed_certificate.cc b/net/cert/internal/parsed_certificate.cc
new file mode 100644
index 0000000000000000000000000000000000000000..53bb044e6510f42e338b58afbfe115f92d0b9243
--- /dev/null
+++ b/net/cert/internal/parsed_certificate.cc
@@ -0,0 +1,135 @@
+// 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/parsed_certificate.h"
+
+#include "net/cert/internal/name_constraints.h"
+#include "net/cert/internal/signature_algorithm.h"
+#include "net/cert/internal/verify_name_match.h"
+#include "net/der/parser.h"
+
+namespace net {
+
+namespace {
+
+WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv,
+ der::Input* value) {
+ der::Parser parser(tlv);
+ return parser.ReadTag(der::kSequence, value) && !parser.HasMore();
+}
+
+} // namespace
+
+ParsedCertificate::ParsedCertificate() {}
+ParsedCertificate::~ParsedCertificate() {}
+
+scoped_refptr<ParsedCertificate> ParsedCertificate::CreateFromCertificateData(
+ const uint8_t* data,
+ size_t length,
+ DataSource source) {
+ scoped_refptr<ParsedCertificate> result(new ParsedCertificate);
+
+ switch (source) {
+ case DataSource::INTERNAL_COPY:
+ result->cert_data_.assign(data, data + length);
+ result->cert_ =
+ der::Input(result->cert_data_.data(), result->cert_data_.size());
+ break;
+ case DataSource::EXTERNAL_REFERENCE:
+ result->cert_ = der::Input(data, length);
+ break;
+ }
+
+ if (!ParseCertificate(result->cert_, &result->tbs_certificate_tlv_,
+ &result->signature_algorithm_tlv_,
+ &result->signature_value_))
+ return nullptr;
eroman 2016/05/12 18:12:29 nit: curly braces?
mattm 2016/05/13 02:17:36 Done.
+
+ if (!ParseTbsCertificate(result->tbs_certificate_tlv_, &result->parsed_tbs_))
+ return nullptr;
+
+ // Attempt to parse the signature algorithm contained in the Certificate.
+ // Do not give up on failure here, since SignatureAlgorithm::CreateFromDer
+ // will fail on valid but unsupported signature algorithms.
eroman 2016/05/12 18:12:29 What current consumer is this allowance made for?
mattm 2016/05/13 02:17:36 There are several in tests (PKITS and ours), they
+ // TODO(mattm): should distinguish between unsupported algorithms and parsing
+ // errors.
+ result->signature_algorithm_ =
+ SignatureAlgorithm::CreateFromDer(result->signature_algorithm_tlv_);
+
+ der::Input subject_value;
+ if (!GetSequenceValue(result->parsed_tbs_.subject_tlv, &subject_value) ||
+ !NormalizeName(subject_value, &result->normalized_subject_))
+ return nullptr;
+ der::Input issuer_value;
+ if (!GetSequenceValue(result->parsed_tbs_.issuer_tlv, &issuer_value) ||
+ !NormalizeName(issuer_value, &result->normalized_issuer_))
+ return nullptr;
eroman 2016/05/12 18:12:29 Same question throughout -- if we consider these m
mattm 2016/05/13 02:17:36 yeah, I always forget that. done.
+
+ // Parse the standard X.509 extensions and remove them from
+ // |unconsumed_extensions|.
+ if (result->parsed_tbs_.has_extensions) {
+ // ParseExtensions() ensures there are no duplicates, and maps the (unique)
+ // OID to the extension value.
+ if (!ParseExtensions(result->parsed_tbs_.extensions_tlv,
+ &result->unconsumed_extensions_))
+ return nullptr;
+
+ ParsedExtension extension;
+
+ // Basic constraints.
+ if (ConsumeExtension(BasicConstraintsOid(), &result->unconsumed_extensions_,
+ &extension)) {
+ result->has_basic_constraints_ = true;
+ if (!ParseBasicConstraints(extension.value, &result->basic_constraints_))
+ return nullptr;
+ }
+
+ // KeyUsage.
+ if (ConsumeExtension(KeyUsageOid(), &result->unconsumed_extensions_,
+ &extension)) {
+ result->has_key_usage_ = true;
+ if (!ParseKeyUsage(extension.value, &result->key_usage_))
+ return nullptr;
+ }
+
+ // Subject alternative name.
+ if (ConsumeExtension(SubjectAltNameOid(), &result->unconsumed_extensions_,
+ &result->subject_alt_names_extension_)) {
+ // RFC 5280 section 4.2.1.6:
+ // SubjectAltName ::= GeneralNames
+ result->subject_alt_names_ = GeneralNames::CreateFromDer(
+ result->subject_alt_names_extension_.value);
+ if (!result->subject_alt_names_)
+ return nullptr;
+ // RFC 5280 section 4.1.2.6:
+ // If subject naming information is present only in the subjectAltName
+ // extension (e.g., a key bound only to an email address or URI), then the
+ // subject name MUST be an empty sequence and the subjectAltName extension
+ // MUST be critical.
+ if (subject_value.Length() == 0 &&
+ !result->subject_alt_names_extension_.critical)
+ return nullptr;
+ }
+
+ // Name constraints.
+ if (ConsumeExtension(NameConstraintsOid(), &result->unconsumed_extensions_,
+ &extension)) {
+ result->name_constraints_ =
+ NameConstraints::CreateFromDer(extension.value, extension.critical);
+ if (!result->name_constraints_)
+ return nullptr;
+ }
+ }
+
+ return result;
+}
+
+scoped_refptr<ParsedCertificate> ParsedCertificate::CreateFromCertificateCopy(
+ const base::StringPiece& data) {
+ return ParsedCertificate::CreateFromCertificateData(
+ reinterpret_cast<const uint8_t*>(data.data()), data.size(),
+ DataSource::INTERNAL_COPY);
+}
+
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698