| OLD | NEW |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 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 <CommonCrypto/CommonDigest.h> | 7 #include <CommonCrypto/CommonDigest.h> |
| 8 #include <Security/Security.h> | 8 #include <Security/Security.h> |
| 9 | 9 |
| 10 #include "base/mac/scoped_cftyperef.h" | 10 #include "base/mac/scoped_cftyperef.h" |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName, | 93 x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName, |
| 94 &principal->common_name); | 94 &principal->common_name); |
| 95 x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName, | 95 x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName, |
| 96 &principal->locality_name); | 96 &principal->locality_name); |
| 97 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName, | 97 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName, |
| 98 &principal->state_or_province_name); | 98 &principal->state_or_province_name); |
| 99 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName, | 99 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName, |
| 100 &principal->country_name); | 100 &principal->country_name); |
| 101 } | 101 } |
| 102 | 102 |
| 103 void ParseSubjectAltName(X509Certificate::OSCertHandle os_cert, | 103 bool ParseSubjectAltName(X509Certificate::OSCertHandle os_cert, |
| 104 std::vector<std::string>* dns_names, | 104 std::vector<std::string>* dns_names, |
| 105 std::vector<std::string>* ip_addresses) { | 105 std::vector<std::string>* ip_addresses) { |
| 106 DCHECK(dns_names || ip_addresses); | |
| 107 bssl::UniquePtr<X509> cert = OSCertHandleToOpenSSL(os_cert); | 106 bssl::UniquePtr<X509> cert = OSCertHandleToOpenSSL(os_cert); |
| 108 if (!cert.get()) | 107 if (!cert.get()) |
| 109 return; | 108 return false; |
| 110 int index = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1); | 109 int index = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1); |
| 111 X509_EXTENSION* alt_name_ext = X509_get_ext(cert.get(), index); | 110 X509_EXTENSION* alt_name_ext = X509_get_ext(cert.get(), index); |
| 112 if (!alt_name_ext) | 111 if (!alt_name_ext) |
| 113 return; | 112 return false; |
| 114 | 113 |
| 115 bssl::UniquePtr<GENERAL_NAMES> alt_names( | 114 bssl::UniquePtr<GENERAL_NAMES> alt_names( |
| 116 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); | 115 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); |
| 117 if (!alt_names.get()) | 116 if (!alt_names.get()) |
| 118 return; | 117 return false; |
| 119 | 118 |
| 119 bool has_san = false; |
| 120 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { | 120 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { |
| 121 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); | 121 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); |
| 122 if (name->type == GEN_DNS && dns_names) { | 122 if (name->type == GEN_DNS) { |
| 123 const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName); | 123 has_san = true; |
| 124 if (!dns_name) | 124 if (dns_names) { |
| 125 continue; | 125 const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName); |
| 126 int dns_name_len = ASN1_STRING_length(name->d.dNSName); | 126 int dns_name_len = ASN1_STRING_length(name->d.dNSName); |
| 127 dns_names->push_back( | 127 dns_names->push_back( |
| 128 std::string(reinterpret_cast<const char*>(dns_name), dns_name_len)); | 128 base::StringPiece(reinterpret_cast<const char*>(dns_name), |
| 129 } else if (name->type == GEN_IPADD && ip_addresses) { | 129 dns_name_len) |
| 130 const unsigned char* ip_addr = name->d.iPAddress->data; | 130 .as_string()); |
| 131 if (!ip_addr) | |
| 132 continue; | |
| 133 int ip_addr_len = name->d.iPAddress->length; | |
| 134 if (ip_addr_len != static_cast<int>(IPAddress::kIPv4AddressSize) && | |
| 135 ip_addr_len != static_cast<int>(IPAddress::kIPv6AddressSize)) { | |
| 136 // http://www.ietf.org/rfc/rfc3280.txt requires subjectAltName iPAddress | |
| 137 // to have 4 or 16 bytes, whereas in a name constraint it includes a | |
| 138 // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup. | |
| 139 LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len; | |
| 140 continue; | |
| 141 } | 131 } |
| 142 ip_addresses->push_back( | 132 } else if (name->type == GEN_IPADD) { |
| 143 std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len)); | 133 has_san = true; |
| 134 if (ip_addresses) { |
| 135 const unsigned char* ip_addr = name->d.iPAddress->data; |
| 136 int ip_addr_len = name->d.iPAddress->length; |
| 137 ip_addresses->push_back( |
| 138 base::StringPiece(reinterpret_cast<const char*>(ip_addr), |
| 139 ip_addr_len) |
| 140 .as_string()); |
| 141 } |
| 144 } | 142 } |
| 143 // Fast path: Found at least one subjectAltName and the caller doesn't |
| 144 // need the actual values. |
| 145 if (has_san && !ip_addresses && !dns_names) |
| 146 return true; |
| 145 } | 147 } |
| 148 |
| 149 return has_san; |
| 146 } | 150 } |
| 147 | 151 |
| 148 } // namespace | 152 } // namespace |
| 149 | 153 |
| 150 // static | 154 // static |
| 151 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( | 155 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( |
| 152 OSCertHandle handle) { | 156 OSCertHandle handle) { |
| 153 if (!handle) | 157 if (!handle) |
| 154 return nullptr; | 158 return nullptr; |
| 155 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle))); | 159 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle))); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 } | 268 } |
| 265 default: { | 269 default: { |
| 266 NOTREACHED() << "Certificate format " << format << " unimplemented"; | 270 NOTREACHED() << "Certificate format " << format << " unimplemented"; |
| 267 break; | 271 break; |
| 268 } | 272 } |
| 269 } | 273 } |
| 270 | 274 |
| 271 return results; | 275 return results; |
| 272 } | 276 } |
| 273 | 277 |
| 274 void X509Certificate::GetSubjectAltName( | 278 bool X509Certificate::GetSubjectAltName( |
| 275 std::vector<std::string>* dns_names, | 279 std::vector<std::string>* dns_names, |
| 276 std::vector<std::string>* ip_addrs) const { | 280 std::vector<std::string>* ip_addrs) const { |
| 277 if (dns_names) | 281 if (dns_names) |
| 278 dns_names->clear(); | 282 dns_names->clear(); |
| 279 if (ip_addrs) | 283 if (ip_addrs) |
| 280 ip_addrs->clear(); | 284 ip_addrs->clear(); |
| 281 | 285 |
| 282 ParseSubjectAltName(cert_handle_, dns_names, ip_addrs); | 286 return ParseSubjectAltName(cert_handle_, dns_names, ip_addrs); |
| 283 } | 287 } |
| 284 | 288 |
| 285 // static | 289 // static |
| 286 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, | 290 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, |
| 287 std::string* encoded) { | 291 std::string* encoded) { |
| 288 base::StringPiece der; | 292 base::StringPiece der; |
| 289 if (!cert_handle) | 293 if (!cert_handle) |
| 290 return false; | 294 return false; |
| 291 ScopedCFTypeRef<CFDataRef> der_data(SecCertificateCopyData(cert_handle)); | 295 ScopedCFTypeRef<CFDataRef> der_data(SecCertificateCopyData(cert_handle)); |
| 292 if (!der_data) | 296 if (!der_data) |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 return false; | 437 return false; |
| 434 bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert.get())); | 438 bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert.get())); |
| 435 if (!scoped_key) | 439 if (!scoped_key) |
| 436 return false; | 440 return false; |
| 437 if (!X509_verify(cert.get(), scoped_key.get())) | 441 if (!X509_verify(cert.get(), scoped_key.get())) |
| 438 return false; | 442 return false; |
| 439 return X509_check_issued(cert.get(), cert.get()) == X509_V_OK; | 443 return X509_check_issued(cert.get(), cert.get()) == X509_V_OK; |
| 440 } | 444 } |
| 441 | 445 |
| 442 } // namespace net | 446 } // namespace net |
| OLD | NEW |