Index: net/cert/x509_certificate_openssl.cc |
diff --git a/net/cert/x509_certificate_openssl.cc b/net/cert/x509_certificate_openssl.cc |
index 30d9598a50ae32c58b4362d54d5dcd090461fd7f..49e5ad7c979c56a6d8ba3b2aba33a687d39cb0fd 100644 |
--- a/net/cert/x509_certificate_openssl.cc |
+++ b/net/cert/x509_certificate_openssl.cc |
@@ -92,46 +92,49 @@ void ParsePrincipal(X509Certificate::OSCertHandle cert, |
&principal->country_name); |
} |
-void ParseSubjectAltName(X509Certificate::OSCertHandle cert, |
+bool ParseSubjectAltName(X509Certificate::OSCertHandle cert, |
std::vector<std::string>* dns_names, |
std::vector<std::string>* ip_addresses) { |
- DCHECK(dns_names || ip_addresses); |
int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); |
X509_EXTENSION* alt_name_ext = X509_get_ext(cert, 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; |
} |
class X509InitSingleton { |
@@ -280,7 +283,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) |
@@ -288,7 +291,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 |