| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/cert/x509_certificate.h" | 5 #include "net/cert/x509_certificate.h" |
| 6 | 6 |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/memory/singleton.h" | 8 #include "base/memory/singleton.h" |
| 9 #include "base/numerics/safe_conversions.h" | 9 #include "base/numerics/safe_conversions.h" |
| 10 #include "base/pickle.h" | 10 #include "base/pickle.h" |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName, | 85 x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName, |
| 86 &principal->common_name); | 86 &principal->common_name); |
| 87 x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName, | 87 x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName, |
| 88 &principal->locality_name); | 88 &principal->locality_name); |
| 89 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName, | 89 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName, |
| 90 &principal->state_or_province_name); | 90 &principal->state_or_province_name); |
| 91 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName, | 91 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName, |
| 92 &principal->country_name); | 92 &principal->country_name); |
| 93 } | 93 } |
| 94 | 94 |
| 95 void ParseSubjectAltName(X509Certificate::OSCertHandle cert, | 95 bool ParseSubjectAltName(X509Certificate::OSCertHandle cert, |
| 96 std::vector<std::string>* dns_names, | 96 std::vector<std::string>* dns_names, |
| 97 std::vector<std::string>* ip_addresses) { | 97 std::vector<std::string>* ip_addresses) { |
| 98 DCHECK(dns_names || ip_addresses); | |
| 99 int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); | 98 int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); |
| 100 X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index); | 99 X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index); |
| 101 if (!alt_name_ext) | 100 if (!alt_name_ext) |
| 102 return; | 101 return false; |
| 103 | 102 |
| 104 bssl::UniquePtr<GENERAL_NAMES> alt_names( | 103 bssl::UniquePtr<GENERAL_NAMES> alt_names( |
| 105 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); | 104 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); |
| 106 if (!alt_names.get()) | 105 if (!alt_names.get()) |
| 107 return; | 106 return false; |
| 108 | 107 |
| 108 bool has_san = false; |
| 109 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { | 109 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { |
| 110 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); | 110 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); |
| 111 if (name->type == GEN_DNS && dns_names) { | 111 if (name->type == GEN_DNS) { |
| 112 const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName); | 112 has_san = true; |
| 113 if (!dns_name) | 113 if (dns_names) { |
| 114 continue; | 114 const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName); |
| 115 int dns_name_len = ASN1_STRING_length(name->d.dNSName); | 115 int dns_name_len = ASN1_STRING_length(name->d.dNSName); |
| 116 dns_names->push_back( | 116 dns_names->push_back( |
| 117 std::string(reinterpret_cast<const char*>(dns_name), dns_name_len)); | 117 base::StringPiece(reinterpret_cast<const char*>(dns_name), |
| 118 } else if (name->type == GEN_IPADD && ip_addresses) { | 118 dns_name_len) |
| 119 const unsigned char* ip_addr = name->d.iPAddress->data; | 119 .as_string()); |
| 120 if (!ip_addr) | |
| 121 continue; | |
| 122 int ip_addr_len = name->d.iPAddress->length; | |
| 123 if (ip_addr_len != static_cast<int>(IPAddress::kIPv4AddressSize) && | |
| 124 ip_addr_len != static_cast<int>(IPAddress::kIPv6AddressSize)) { | |
| 125 // http://www.ietf.org/rfc/rfc3280.txt requires subjectAltName iPAddress | |
| 126 // to have 4 or 16 bytes, whereas in a name constraint it includes a | |
| 127 // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup. | |
| 128 LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len; | |
| 129 continue; | |
| 130 } | 120 } |
| 131 ip_addresses->push_back( | 121 } else if (name->type == GEN_IPADD) { |
| 132 std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len)); | 122 has_san = true; |
| 123 if (ip_addresses) { |
| 124 const unsigned char* ip_addr = name->d.iPAddress->data; |
| 125 int ip_addr_len = name->d.iPAddress->length; |
| 126 ip_addresses->push_back( |
| 127 base::StringPiece(reinterpret_cast<const char*>(ip_addr), |
| 128 ip_addr_len) |
| 129 .as_string()); |
| 130 } |
| 133 } | 131 } |
| 132 // Fast path: Found at least one subjectAltName and the caller doesn't |
| 133 // need the actual values. |
| 134 if (has_san && !ip_addresses && !dns_names) |
| 135 return true; |
| 134 } | 136 } |
| 137 return has_san; |
| 135 } | 138 } |
| 136 | 139 |
| 137 class X509InitSingleton { | 140 class X509InitSingleton { |
| 138 public: | 141 public: |
| 139 static X509InitSingleton* GetInstance() { | 142 static X509InitSingleton* GetInstance() { |
| 140 // We allow the X509 store to leak, because it is used from a non-joinable | 143 // We allow the X509 store to leak, because it is used from a non-joinable |
| 141 // worker that is not stopped on shutdown, hence may still be using | 144 // worker that is not stopped on shutdown, hence may still be using |
| 142 // OpenSSL library after the AtExit runner has completed. | 145 // OpenSSL library after the AtExit runner has completed. |
| 143 return base::Singleton<X509InitSingleton, base::LeakySingletonTraits< | 146 return base::Singleton<X509InitSingleton, base::LeakySingletonTraits< |
| 144 X509InitSingleton>>::get(); | 147 X509InitSingleton>>::get(); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 } | 276 } |
| 274 default: { | 277 default: { |
| 275 NOTREACHED() << "Certificate format " << format << " unimplemented"; | 278 NOTREACHED() << "Certificate format " << format << " unimplemented"; |
| 276 break; | 279 break; |
| 277 } | 280 } |
| 278 } | 281 } |
| 279 | 282 |
| 280 return results; | 283 return results; |
| 281 } | 284 } |
| 282 | 285 |
| 283 void X509Certificate::GetSubjectAltName( | 286 bool X509Certificate::GetSubjectAltName( |
| 284 std::vector<std::string>* dns_names, | 287 std::vector<std::string>* dns_names, |
| 285 std::vector<std::string>* ip_addrs) const { | 288 std::vector<std::string>* ip_addrs) const { |
| 286 if (dns_names) | 289 if (dns_names) |
| 287 dns_names->clear(); | 290 dns_names->clear(); |
| 288 if (ip_addrs) | 291 if (ip_addrs) |
| 289 ip_addrs->clear(); | 292 ip_addrs->clear(); |
| 290 | 293 |
| 291 ParseSubjectAltName(cert_handle_, dns_names, ip_addrs); | 294 return ParseSubjectAltName(cert_handle_, dns_names, ip_addrs); |
| 292 } | 295 } |
| 293 | 296 |
| 294 // static | 297 // static |
| 295 X509_STORE* X509Certificate::cert_store() { | 298 X509_STORE* X509Certificate::cert_store() { |
| 296 return X509InitSingleton::GetInstance()->store(); | 299 return X509InitSingleton::GetInstance()->store(); |
| 297 } | 300 } |
| 298 | 301 |
| 299 // static | 302 // static |
| 300 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, | 303 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, |
| 301 std::string* encoded) { | 304 std::string* encoded) { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) { | 435 bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) { |
| 433 bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert_handle)); | 436 bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert_handle)); |
| 434 if (!scoped_key) | 437 if (!scoped_key) |
| 435 return false; | 438 return false; |
| 436 if (!X509_verify(cert_handle, scoped_key.get())) | 439 if (!X509_verify(cert_handle, scoped_key.get())) |
| 437 return false; | 440 return false; |
| 438 return X509_check_issued(cert_handle, cert_handle) == X509_V_OK; | 441 return X509_check_issued(cert_handle, cert_handle) == X509_V_OK; |
| 439 } | 442 } |
| 440 | 443 |
| 441 } // namespace net | 444 } // namespace net |
| OLD | NEW |