OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 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/x509_certificate.h" |
| 6 |
| 7 #include "base/numerics/safe_conversions.h" |
| 8 #include "base/pickle.h" |
| 9 #include "crypto/openssl_util.h" |
| 10 #include "net/base/ip_address.h" |
| 11 #include "net/cert/asn1_util.h" |
| 12 #include "net/cert/internal/cert_errors.h" |
| 13 #include "net/cert/internal/name_constraints.h" |
| 14 #include "net/cert/internal/parse_name.h" |
| 15 #include "net/cert/internal/parsed_certificate.h" |
| 16 #include "net/cert/internal/signature_policy.h" |
| 17 #include "net/cert/internal/verify_name_match.h" |
| 18 #include "net/cert/internal/verify_signed_data.h" |
| 19 #include "net/cert/x509_util.h" |
| 20 #include "net/cert/x509_util_openssl.h" |
| 21 #include "net/der/parser.h" |
| 22 #include "third_party/boringssl/src/include/openssl/evp.h" |
| 23 #include "third_party/boringssl/src/include/openssl/pool.h" |
| 24 #include "third_party/boringssl/src/include/openssl/sha.h" |
| 25 |
| 26 namespace net { |
| 27 |
| 28 namespace { |
| 29 |
| 30 // Converts a GeneralizedTime struct to a base::Time, returning true on success |
| 31 // or false if |generalized| was invalid or cannot be represented by |
| 32 // base::Time. |
| 33 bool GeneralizedTimeToBaseTime(const der::GeneralizedTime& generalized, |
| 34 base::Time* result) { |
| 35 base::Time::Exploded exploded = {0}; |
| 36 exploded.year = generalized.year; |
| 37 exploded.month = generalized.month; |
| 38 exploded.day_of_month = generalized.day; |
| 39 exploded.hour = generalized.hours; |
| 40 exploded.minute = generalized.minutes; |
| 41 exploded.second = generalized.seconds; |
| 42 return base::Time::FromUTCExploded(exploded, result); |
| 43 } |
| 44 |
| 45 // Sets |value| to the Value from a DER Sequence Tag-Length-Value and return |
| 46 // true, or return false if the TLV was not a valid DER Sequence. |
| 47 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv, |
| 48 der::Input* value) { |
| 49 der::Parser parser(tlv); |
| 50 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); |
| 51 } |
| 52 |
| 53 // Normalize |cert|'s Issuer and store it in |out_normalized_issuer|, returning |
| 54 // true on success or false if there was a parsing error. |
| 55 bool GetNormalizedCertIssuer(CRYPTO_BUFFER* cert, |
| 56 std::string* out_normalized_issuer) { |
| 57 der::Input tbs_certificate_tlv; |
| 58 der::Input signature_algorithm_tlv; |
| 59 der::BitString signature_value; |
| 60 if (!ParseCertificate( |
| 61 der::Input(CRYPTO_BUFFER_data(cert), CRYPTO_BUFFER_len(cert)), |
| 62 &tbs_certificate_tlv, &signature_algorithm_tlv, &signature_value, |
| 63 nullptr)) { |
| 64 return false; |
| 65 } |
| 66 ParsedTbsCertificate tbs; |
| 67 if (!ParseTbsCertificate(tbs_certificate_tlv, {}, &tbs, nullptr)) |
| 68 return false; |
| 69 |
| 70 der::Input issuer_value; |
| 71 if (!GetSequenceValue(tbs.issuer_tlv, &issuer_value)) |
| 72 return false; |
| 73 |
| 74 return NormalizeName(issuer_value, out_normalized_issuer); |
| 75 } |
| 76 |
| 77 // Fills |principal| from the DER encoded |name_tlv|, returning true on success |
| 78 // or false if parsing failed or some of the values could not be converted to |
| 79 // UTF-8. |
| 80 bool ParsePrincipal(const der::Input& name_tlv, CertPrincipal* principal) { |
| 81 RDNSequence rdns; |
| 82 if (!ParseName(name_tlv, &rdns)) |
| 83 return false; |
| 84 |
| 85 for (const RelativeDistinguishedName& rdn : rdns) { |
| 86 for (const X509NameAttribute& name_attribute : rdn) { |
| 87 if (name_attribute.type == TypeCommonNameOid()) { |
| 88 if (principal->common_name.empty() && |
| 89 !name_attribute.ValueAsString(&principal->common_name)) { |
| 90 return false; |
| 91 } |
| 92 } else if (name_attribute.type == TypeLocalityNameOid()) { |
| 93 if (principal->locality_name.empty() && |
| 94 !name_attribute.ValueAsString(&principal->locality_name)) { |
| 95 return false; |
| 96 } |
| 97 } else if (name_attribute.type == TypeStateOrProvinceNameOid()) { |
| 98 if (principal->state_or_province_name.empty() && |
| 99 !name_attribute.ValueAsString(&principal->state_or_province_name)) { |
| 100 return false; |
| 101 } |
| 102 } else if (name_attribute.type == TypeCountryNameOid()) { |
| 103 if (principal->country_name.empty() && |
| 104 !name_attribute.ValueAsString(&principal->country_name)) { |
| 105 return false; |
| 106 } |
| 107 } else if (name_attribute.type == TypeStreetAddressOid()) { |
| 108 std::string s; |
| 109 if (!name_attribute.ValueAsString(&s)) |
| 110 return false; |
| 111 principal->street_addresses.push_back(s); |
| 112 } else if (name_attribute.type == TypeOrganizationNameOid()) { |
| 113 std::string s; |
| 114 if (!name_attribute.ValueAsString(&s)) |
| 115 return false; |
| 116 principal->organization_names.push_back(s); |
| 117 } else if (name_attribute.type == TypeOrganizationUnitNameOid()) { |
| 118 std::string s; |
| 119 if (!name_attribute.ValueAsString(&s)) |
| 120 return false; |
| 121 principal->organization_unit_names.push_back(s); |
| 122 } else if (name_attribute.type == TypeDomainComponentOid()) { |
| 123 std::string s; |
| 124 if (!name_attribute.ValueAsString(&s)) |
| 125 return false; |
| 126 principal->domain_components.push_back(s); |
| 127 } |
| 128 } |
| 129 } |
| 130 return true; |
| 131 } |
| 132 |
| 133 // Parses certificates from a PKCS#7 SignedData structure, appending them to |
| 134 // |handles|. |
| 135 void CreateOSCertHandlesFromPKCS7Bytes( |
| 136 const char* data, |
| 137 size_t length, |
| 138 X509Certificate::OSCertHandles* handles) { |
| 139 crypto::EnsureOpenSSLInit(); |
| 140 crypto::OpenSSLErrStackTracer err_cleaner(FROM_HERE); |
| 141 |
| 142 CBS der_data; |
| 143 CBS_init(&der_data, reinterpret_cast<const uint8_t*>(data), length); |
| 144 STACK_OF(X509)* certs = sk_X509_new_null(); |
| 145 |
| 146 if (PKCS7_get_certificates(certs, &der_data)) { |
| 147 for (size_t i = 0; i < sk_X509_num(certs); ++i) { |
| 148 base::StringPiece stringpiece; |
| 149 x509_util::GetDER(sk_X509_value(certs, i), &stringpiece); |
| 150 handles->push_back(x509_util::CreateCryptoBuffer(stringpiece).release()); |
| 151 } |
| 152 } |
| 153 sk_X509_pop_free(certs, X509_free); |
| 154 } |
| 155 |
| 156 } // namespace |
| 157 |
| 158 bool X509Certificate::Initialize() { |
| 159 der::Input tbs_certificate_tlv; |
| 160 der::Input signature_algorithm_tlv; |
| 161 der::BitString signature_value; |
| 162 |
| 163 if (!ParseCertificate(der::Input(CRYPTO_BUFFER_data(cert_handle_), |
| 164 CRYPTO_BUFFER_len(cert_handle_)), |
| 165 &tbs_certificate_tlv, &signature_algorithm_tlv, |
| 166 &signature_value, nullptr)) { |
| 167 return false; |
| 168 } |
| 169 |
| 170 ParsedTbsCertificate tbs; |
| 171 if (!ParseTbsCertificate(tbs_certificate_tlv, {}, &tbs, nullptr)) |
| 172 return false; |
| 173 |
| 174 if (!ParsePrincipal(tbs.subject_tlv, &subject_) || |
| 175 !ParsePrincipal(tbs.issuer_tlv, &issuer_)) { |
| 176 return false; |
| 177 } |
| 178 |
| 179 if (!GeneralizedTimeToBaseTime(tbs.validity_not_before, &valid_start_) || |
| 180 !GeneralizedTimeToBaseTime(tbs.validity_not_after, &valid_expiry_)) { |
| 181 return false; |
| 182 } |
| 183 serial_number_ = tbs.serial_number.AsString(); |
| 184 return true; |
| 185 } |
| 186 |
| 187 bool X509Certificate::GetSubjectAltName( |
| 188 std::vector<std::string>* dns_names, |
| 189 std::vector<std::string>* ip_addrs) const { |
| 190 if (dns_names) |
| 191 dns_names->clear(); |
| 192 if (ip_addrs) |
| 193 ip_addrs->clear(); |
| 194 |
| 195 der::Input tbs_certificate_tlv; |
| 196 der::Input signature_algorithm_tlv; |
| 197 der::BitString signature_value; |
| 198 if (!ParseCertificate(der::Input(CRYPTO_BUFFER_data(cert_handle_), |
| 199 CRYPTO_BUFFER_len(cert_handle_)), |
| 200 &tbs_certificate_tlv, &signature_algorithm_tlv, |
| 201 &signature_value, nullptr)) { |
| 202 return false; |
| 203 } |
| 204 |
| 205 ParsedTbsCertificate tbs; |
| 206 if (!ParseTbsCertificate(tbs_certificate_tlv, {}, &tbs, nullptr)) |
| 207 return false; |
| 208 if (!tbs.has_extensions) |
| 209 return false; |
| 210 |
| 211 std::map<der::Input, ParsedExtension> extensions; |
| 212 if (!ParseExtensions(tbs.extensions_tlv, &extensions)) |
| 213 return false; |
| 214 |
| 215 ParsedExtension subject_alt_names_extension; |
| 216 if (!ConsumeExtension(SubjectAltNameOid(), &extensions, |
| 217 &subject_alt_names_extension)) { |
| 218 return false; |
| 219 } |
| 220 |
| 221 std::unique_ptr<GeneralNames> subject_alt_names = |
| 222 GeneralNames::Create(subject_alt_names_extension.value); |
| 223 if (!subject_alt_names) |
| 224 return false; |
| 225 |
| 226 if (dns_names) |
| 227 *dns_names = subject_alt_names->dns_names; |
| 228 if (ip_addrs) { |
| 229 for (const IPAddress& addr : subject_alt_names->ip_addresses) { |
| 230 ip_addrs->push_back( |
| 231 std::string(reinterpret_cast<const char*>(addr.bytes().data()), |
| 232 addr.bytes().size())); |
| 233 } |
| 234 } |
| 235 |
| 236 return !subject_alt_names->dns_names.empty() || |
| 237 !subject_alt_names->ip_addresses.empty(); |
| 238 } |
| 239 |
| 240 bool X509Certificate::IsIssuedByEncoded( |
| 241 const std::vector<std::string>& valid_issuers) { |
| 242 std::vector<std::string> normalized_issuers; |
| 243 for (const auto& raw_issuer : valid_issuers) { |
| 244 der::Input issuer_value; |
| 245 std::string normalized_issuer; |
| 246 if (!GetSequenceValue(der::Input(&raw_issuer), &issuer_value) || |
| 247 !NormalizeName(issuer_value, &normalized_issuer)) { |
| 248 continue; |
| 249 } |
| 250 normalized_issuers.push_back(std::move(normalized_issuer)); |
| 251 } |
| 252 |
| 253 std::string normalized_cert_issuer; |
| 254 if (!GetNormalizedCertIssuer(cert_handle_, &normalized_cert_issuer)) |
| 255 return false; |
| 256 if (std::find(normalized_issuers.begin(), normalized_issuers.end(), |
| 257 normalized_cert_issuer) != normalized_issuers.end()) |
| 258 return true; |
| 259 |
| 260 for (CRYPTO_BUFFER* intermediate : intermediate_ca_certs_) { |
| 261 if (!GetNormalizedCertIssuer(intermediate, &normalized_cert_issuer)) |
| 262 return false; |
| 263 if (std::find(normalized_issuers.begin(), normalized_issuers.end(), |
| 264 normalized_cert_issuer) != normalized_issuers.end()) |
| 265 return true; |
| 266 } |
| 267 return false; |
| 268 } |
| 269 |
| 270 // static |
| 271 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, |
| 272 std::string* encoded) { |
| 273 if (!cert_handle) |
| 274 return false; |
| 275 encoded->assign( |
| 276 reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert_handle)), |
| 277 CRYPTO_BUFFER_len(cert_handle)); |
| 278 return true; |
| 279 } |
| 280 |
| 281 // static |
| 282 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, |
| 283 size_t* size_bits, |
| 284 PublicKeyType* type) { |
| 285 *type = kPublicKeyTypeUnknown; |
| 286 *size_bits = 0; |
| 287 |
| 288 base::StringPiece spki; |
| 289 if (!asn1::ExtractSPKIFromDERCert( |
| 290 base::StringPiece( |
| 291 reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert_handle)), |
| 292 CRYPTO_BUFFER_len(cert_handle)), |
| 293 &spki)) { |
| 294 return; |
| 295 } |
| 296 |
| 297 bssl::UniquePtr<EVP_PKEY> pkey; |
| 298 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 299 CBS cbs; |
| 300 CBS_init(&cbs, reinterpret_cast<const uint8_t*>(spki.data()), spki.size()); |
| 301 pkey.reset(EVP_parse_public_key(&cbs)); |
| 302 if (!pkey) |
| 303 return; |
| 304 |
| 305 switch (pkey->type) { |
| 306 case EVP_PKEY_RSA: |
| 307 *type = kPublicKeyTypeRSA; |
| 308 break; |
| 309 case EVP_PKEY_DSA: |
| 310 *type = kPublicKeyTypeDSA; |
| 311 break; |
| 312 case EVP_PKEY_EC: |
| 313 *type = kPublicKeyTypeECDSA; |
| 314 break; |
| 315 case EVP_PKEY_DH: |
| 316 *type = kPublicKeyTypeDH; |
| 317 break; |
| 318 } |
| 319 *size_bits = base::saturated_cast<size_t>(EVP_PKEY_bits(pkey.get())); |
| 320 } |
| 321 |
| 322 // static |
| 323 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a, |
| 324 X509Certificate::OSCertHandle b) { |
| 325 DCHECK(a && b); |
| 326 if (a == b) |
| 327 return true; |
| 328 return CRYPTO_BUFFER_len(a) == CRYPTO_BUFFER_len(b) && |
| 329 memcmp(CRYPTO_BUFFER_data(a), CRYPTO_BUFFER_data(b), |
| 330 CRYPTO_BUFFER_len(a)) == 0; |
| 331 } |
| 332 |
| 333 // static |
| 334 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes( |
| 335 const char* data, |
| 336 size_t length) { |
| 337 der::Input tbs_certificate_tlv; |
| 338 der::Input signature_algorithm_tlv; |
| 339 der::BitString signature_value; |
| 340 // Do a bare minimum of DER parsing here to make sure the input is not |
| 341 // completely crazy. (This is required for at least |
| 342 // CreateCertificateListFromBytes with FORMAT_AUTO, if not more.) |
| 343 if (!ParseCertificate( |
| 344 der::Input(reinterpret_cast<const uint8_t*>(data), length), |
| 345 &tbs_certificate_tlv, &signature_algorithm_tlv, &signature_value, |
| 346 nullptr)) { |
| 347 return nullptr; |
| 348 } |
| 349 |
| 350 return CRYPTO_BUFFER_new(reinterpret_cast<const uint8_t*>(data), length, |
| 351 x509_util::GetBufferPool()); |
| 352 } |
| 353 |
| 354 // static |
| 355 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( |
| 356 const char* data, |
| 357 size_t length, |
| 358 Format format) { |
| 359 OSCertHandles results; |
| 360 |
| 361 switch (format) { |
| 362 case FORMAT_SINGLE_CERTIFICATE: { |
| 363 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length); |
| 364 if (handle) |
| 365 results.push_back(handle); |
| 366 break; |
| 367 } |
| 368 case FORMAT_PKCS7: { |
| 369 CreateOSCertHandlesFromPKCS7Bytes(data, length, &results); |
| 370 break; |
| 371 } |
| 372 default: { |
| 373 NOTREACHED() << "Certificate format " << format << " unimplemented"; |
| 374 break; |
| 375 } |
| 376 } |
| 377 |
| 378 return results; |
| 379 } |
| 380 |
| 381 // static |
| 382 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( |
| 383 OSCertHandle cert_handle) { |
| 384 CRYPTO_BUFFER_up_ref(cert_handle); |
| 385 return cert_handle; |
| 386 } |
| 387 |
| 388 // static |
| 389 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { |
| 390 CRYPTO_BUFFER_free(cert_handle); |
| 391 } |
| 392 |
| 393 // static |
| 394 SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) { |
| 395 SHA256HashValue sha256; |
| 396 |
| 397 SHA256(CRYPTO_BUFFER_data(cert), CRYPTO_BUFFER_len(cert), sha256.data); |
| 398 return sha256; |
| 399 } |
| 400 |
| 401 // static |
| 402 SHA256HashValue X509Certificate::CalculateCAFingerprint256( |
| 403 const OSCertHandles& intermediates) { |
| 404 SHA256HashValue sha256; |
| 405 memset(sha256.data, 0, sizeof(sha256.data)); |
| 406 |
| 407 SHA256_CTX sha256_ctx; |
| 408 SHA256_Init(&sha256_ctx); |
| 409 for (CRYPTO_BUFFER* cert : intermediates) { |
| 410 SHA256_Update(&sha256_ctx, CRYPTO_BUFFER_data(cert), |
| 411 CRYPTO_BUFFER_len(cert)); |
| 412 } |
| 413 SHA256_Final(sha256.data, &sha256_ctx); |
| 414 |
| 415 return sha256; |
| 416 } |
| 417 |
| 418 // static |
| 419 bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) { |
| 420 der::Input tbs_certificate_tlv; |
| 421 der::Input signature_algorithm_tlv; |
| 422 der::BitString signature_value; |
| 423 if (!ParseCertificate(der::Input(CRYPTO_BUFFER_data(cert_handle), |
| 424 CRYPTO_BUFFER_len(cert_handle)), |
| 425 &tbs_certificate_tlv, &signature_algorithm_tlv, |
| 426 &signature_value, nullptr)) { |
| 427 return false; |
| 428 } |
| 429 ParsedTbsCertificate tbs; |
| 430 if (!ParseTbsCertificate(tbs_certificate_tlv, {}, &tbs, nullptr)) { |
| 431 return false; |
| 432 } |
| 433 |
| 434 der::Input subject_value; |
| 435 std::string normalized_subject; |
| 436 if (!GetSequenceValue(tbs.subject_tlv, &subject_value) || |
| 437 !NormalizeName(subject_value, &normalized_subject)) { |
| 438 return false; |
| 439 } |
| 440 der::Input issuer_value; |
| 441 std::string normalized_issuer; |
| 442 if (!GetSequenceValue(tbs.issuer_tlv, &issuer_value) || |
| 443 !NormalizeName(issuer_value, &normalized_issuer)) { |
| 444 return false; |
| 445 } |
| 446 |
| 447 if (normalized_subject != normalized_issuer) |
| 448 return false; |
| 449 |
| 450 std::unique_ptr<SignatureAlgorithm> signature_algorithm = |
| 451 SignatureAlgorithm::Create(signature_algorithm_tlv, nullptr /* errors */); |
| 452 if (!signature_algorithm) |
| 453 return false; |
| 454 |
| 455 SimpleSignaturePolicy signature_policy(1024); |
| 456 CertErrors unused_errors; |
| 457 return VerifySignedData(*signature_algorithm, tbs_certificate_tlv, |
| 458 signature_value, tbs.spki_tlv, &signature_policy, |
| 459 &unused_errors); |
| 460 } |
| 461 |
| 462 // static |
| 463 X509Certificate::OSCertHandle X509Certificate::ReadOSCertHandleFromPickle( |
| 464 base::PickleIterator* pickle_iter) { |
| 465 const char* data; |
| 466 int length; |
| 467 if (!pickle_iter->ReadData(&data, &length)) |
| 468 return NULL; |
| 469 |
| 470 return CreateOSCertHandleFromBytes(data, length); |
| 471 } |
| 472 |
| 473 // static |
| 474 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, |
| 475 base::Pickle* pickle) { |
| 476 return pickle->WriteData( |
| 477 reinterpret_cast<const char*>(CRYPTO_BUFFER_data(cert_handle)), |
| 478 CRYPTO_BUFFER_len(cert_handle)); |
| 479 } |
| 480 |
| 481 } // namespace net |
OLD | NEW |