| Index: net/cert/x509_certificate_ios.cc
|
| diff --git a/net/cert/x509_certificate_ios.cc b/net/cert/x509_certificate_ios.cc
|
| index ce93f90dd7918a90a12d62904f468bf5cbb70484..fd1b351e7cf7d9657ece31865c00fd17d9119da4 100644
|
| --- a/net/cert/x509_certificate_ios.cc
|
| +++ b/net/cert/x509_certificate_ios.cc
|
| @@ -100,49 +100,53 @@ void ParsePrincipal(X509Certificate::OSCertHandle os_cert,
|
| &principal->country_name);
|
| }
|
|
|
| -void ParseSubjectAltName(X509Certificate::OSCertHandle os_cert,
|
| +bool ParseSubjectAltName(X509Certificate::OSCertHandle os_cert,
|
| std::vector<std::string>* dns_names,
|
| std::vector<std::string>* ip_addresses) {
|
| - DCHECK(dns_names || ip_addresses);
|
| bssl::UniquePtr<X509> cert = OSCertHandleToOpenSSL(os_cert);
|
| if (!cert.get())
|
| - return;
|
| + return false;
|
| int index = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1);
|
| X509_EXTENSION* alt_name_ext = X509_get_ext(cert.get(), index);
|
| if (!alt_name_ext)
|
| - return;
|
| + return false;
|
|
|
| bssl::UniquePtr<GENERAL_NAMES> alt_names(
|
| reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext)));
|
| if (!alt_names.get())
|
| - return;
|
| + return false;
|
|
|
| + bool has_san = false;
|
| for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) {
|
| const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i);
|
| - if (name->type == GEN_DNS && dns_names) {
|
| - const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName);
|
| - if (!dns_name)
|
| - continue;
|
| - int dns_name_len = ASN1_STRING_length(name->d.dNSName);
|
| - dns_names->push_back(
|
| - std::string(reinterpret_cast<const char*>(dns_name), dns_name_len));
|
| - } else if (name->type == GEN_IPADD && ip_addresses) {
|
| - const unsigned char* ip_addr = name->d.iPAddress->data;
|
| - if (!ip_addr)
|
| - continue;
|
| - int ip_addr_len = name->d.iPAddress->length;
|
| - if (ip_addr_len != static_cast<int>(IPAddress::kIPv4AddressSize) &&
|
| - ip_addr_len != static_cast<int>(IPAddress::kIPv6AddressSize)) {
|
| - // http://www.ietf.org/rfc/rfc3280.txt requires subjectAltName iPAddress
|
| - // to have 4 or 16 bytes, whereas in a name constraint it includes a
|
| - // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup.
|
| - LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len;
|
| - continue;
|
| + if (name->type == GEN_DNS) {
|
| + has_san = true;
|
| + if (dns_names) {
|
| + const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName);
|
| + int dns_name_len = ASN1_STRING_length(name->d.dNSName);
|
| + dns_names->push_back(
|
| + base::StringPiece(reinterpret_cast<const char*>(dns_name),
|
| + dns_name_len)
|
| + .as_string());
|
| + }
|
| + } else if (name->type == GEN_IPADD) {
|
| + has_san = true;
|
| + if (ip_addresses) {
|
| + const unsigned char* ip_addr = name->d.iPAddress->data;
|
| + int ip_addr_len = name->d.iPAddress->length;
|
| + ip_addresses->push_back(
|
| + base::StringPiece(reinterpret_cast<const char*>(ip_addr),
|
| + ip_addr_len)
|
| + .as_string());
|
| }
|
| - ip_addresses->push_back(
|
| - std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len));
|
| }
|
| + // Fast path: Found at least one subjectAltName and the caller doesn't
|
| + // need the actual values.
|
| + if (has_san && !ip_addresses && !dns_names)
|
| + return true;
|
| }
|
| +
|
| + return has_san;
|
| }
|
|
|
| } // namespace
|
| @@ -271,7 +275,7 @@ X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
|
| return results;
|
| }
|
|
|
| -void X509Certificate::GetSubjectAltName(
|
| +bool X509Certificate::GetSubjectAltName(
|
| std::vector<std::string>* dns_names,
|
| std::vector<std::string>* ip_addrs) const {
|
| if (dns_names)
|
| @@ -279,7 +283,7 @@ void X509Certificate::GetSubjectAltName(
|
| if (ip_addrs)
|
| ip_addrs->clear();
|
|
|
| - ParseSubjectAltName(cert_handle_, dns_names, ip_addrs);
|
| + return ParseSubjectAltName(cert_handle_, dns_names, ip_addrs);
|
| }
|
|
|
| // static
|
|
|