OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 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 "net/cert/internal/parsed_certificate.h" |
| 6 |
| 7 #include "net/cert/internal/name_constraints.h" |
| 8 #include "net/cert/internal/signature_algorithm.h" |
| 9 #include "net/cert/internal/verify_name_match.h" |
| 10 #include "net/der/parser.h" |
| 11 |
| 12 namespace net { |
| 13 |
| 14 namespace { |
| 15 |
| 16 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv, |
| 17 der::Input* value) { |
| 18 der::Parser parser(tlv); |
| 19 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); |
| 20 } |
| 21 |
| 22 } // namespace |
| 23 |
| 24 ParsedCertificate::ParsedCertificate() {} |
| 25 ParsedCertificate::~ParsedCertificate() {} |
| 26 |
| 27 scoped_refptr<ParsedCertificate> ParsedCertificate::CreateFromCertificateData( |
| 28 const uint8_t* data, |
| 29 size_t length, |
| 30 DataSource source) { |
| 31 scoped_refptr<ParsedCertificate> result(new ParsedCertificate); |
| 32 |
| 33 switch (source) { |
| 34 case DataSource::INTERNAL_COPY: |
| 35 result->cert_data_.assign(data, data + length); |
| 36 result->cert_ = |
| 37 der::Input(result->cert_data_.data(), result->cert_data_.size()); |
| 38 break; |
| 39 case DataSource::EXTERNAL_REFERENCE: |
| 40 result->cert_ = der::Input(data, length); |
| 41 break; |
| 42 } |
| 43 |
| 44 if (!ParseCertificate(result->cert_, &result->tbs_certificate_tlv_, |
| 45 &result->signature_algorithm_tlv_, |
| 46 &result->signature_value_)) { |
| 47 return nullptr; |
| 48 } |
| 49 |
| 50 if (!ParseTbsCertificate(result->tbs_certificate_tlv_, &result->tbs_)) |
| 51 return nullptr; |
| 52 |
| 53 // Attempt to parse the signature algorithm contained in the Certificate. |
| 54 // Do not give up on failure here, since SignatureAlgorithm::CreateFromDer |
| 55 // will fail on valid but unsupported signature algorithms. |
| 56 // TODO(mattm): should distinguish between unsupported algorithms and parsing |
| 57 // errors. |
| 58 result->signature_algorithm_ = |
| 59 SignatureAlgorithm::CreateFromDer(result->signature_algorithm_tlv_); |
| 60 |
| 61 der::Input subject_value; |
| 62 if (!GetSequenceValue(result->tbs_.subject_tlv, &subject_value) || |
| 63 !NormalizeName(subject_value, &result->normalized_subject_)) { |
| 64 return nullptr; |
| 65 } |
| 66 der::Input issuer_value; |
| 67 if (!GetSequenceValue(result->tbs_.issuer_tlv, &issuer_value) || |
| 68 !NormalizeName(issuer_value, &result->normalized_issuer_)) { |
| 69 return nullptr; |
| 70 } |
| 71 |
| 72 // Parse the standard X.509 extensions and remove them from |
| 73 // |unparsed_extensions|. |
| 74 if (result->tbs_.has_extensions) { |
| 75 // ParseExtensions() ensures there are no duplicates, and maps the (unique) |
| 76 // OID to the extension value. |
| 77 if (!ParseExtensions(result->tbs_.extensions_tlv, |
| 78 &result->unparsed_extensions_)) { |
| 79 return nullptr; |
| 80 } |
| 81 |
| 82 ParsedExtension extension; |
| 83 |
| 84 // Basic constraints. |
| 85 if (ConsumeExtension(BasicConstraintsOid(), &result->unparsed_extensions_, |
| 86 &extension)) { |
| 87 result->has_basic_constraints_ = true; |
| 88 if (!ParseBasicConstraints(extension.value, &result->basic_constraints_)) |
| 89 return nullptr; |
| 90 } |
| 91 |
| 92 // KeyUsage. |
| 93 if (ConsumeExtension(KeyUsageOid(), &result->unparsed_extensions_, |
| 94 &extension)) { |
| 95 result->has_key_usage_ = true; |
| 96 if (!ParseKeyUsage(extension.value, &result->key_usage_)) |
| 97 return nullptr; |
| 98 } |
| 99 |
| 100 // Subject alternative name. |
| 101 if (ConsumeExtension(SubjectAltNameOid(), &result->unparsed_extensions_, |
| 102 &result->subject_alt_names_extension_)) { |
| 103 // RFC 5280 section 4.2.1.6: |
| 104 // SubjectAltName ::= GeneralNames |
| 105 result->subject_alt_names_ = GeneralNames::CreateFromDer( |
| 106 result->subject_alt_names_extension_.value); |
| 107 if (!result->subject_alt_names_) |
| 108 return nullptr; |
| 109 // RFC 5280 section 4.1.2.6: |
| 110 // If subject naming information is present only in the subjectAltName |
| 111 // extension (e.g., a key bound only to an email address or URI), then the |
| 112 // subject name MUST be an empty sequence and the subjectAltName extension |
| 113 // MUST be critical. |
| 114 if (subject_value.Length() == 0 && |
| 115 !result->subject_alt_names_extension_.critical) { |
| 116 return nullptr; |
| 117 } |
| 118 } |
| 119 |
| 120 // Name constraints. |
| 121 if (ConsumeExtension(NameConstraintsOid(), &result->unparsed_extensions_, |
| 122 &extension)) { |
| 123 result->name_constraints_ = |
| 124 NameConstraints::CreateFromDer(extension.value, extension.critical); |
| 125 if (!result->name_constraints_) |
| 126 return nullptr; |
| 127 } |
| 128 |
| 129 // NOTE: if additional extensions are consumed here, the verification code |
| 130 // must be updated to process those extensions, since the |
| 131 // VerifyNoUnconsumedCriticalExtensions uses the unparsed_extensions_ |
| 132 // variable to tell which extensions were processed. |
| 133 } |
| 134 |
| 135 return result; |
| 136 } |
| 137 |
| 138 scoped_refptr<ParsedCertificate> ParsedCertificate::CreateFromCertificateCopy( |
| 139 const base::StringPiece& data) { |
| 140 return ParsedCertificate::CreateFromCertificateData( |
| 141 reinterpret_cast<const uint8_t*>(data.data()), data.size(), |
| 142 DataSource::INTERNAL_COPY); |
| 143 } |
| 144 |
| 145 bool ParsedCertificate::CreateAndAddToVector( |
| 146 const uint8_t* data, |
| 147 size_t length, |
| 148 DataSource source, |
| 149 std::vector<scoped_refptr<ParsedCertificate>>* chain) { |
| 150 scoped_refptr<ParsedCertificate> cert( |
| 151 CreateFromCertificateData(data, length, source)); |
| 152 if (!cert) |
| 153 return false; |
| 154 chain->push_back(std::move(cert)); |
| 155 return true; |
| 156 } |
| 157 |
| 158 } // namespace net |
OLD | NEW |