Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(251)

Side by Side Diff: net/cert/x509_certificate_openssl.cc

Issue 2761333002: Add a DevTools warning for a missing subjectAltName (Closed)
Patch Set: iOS & NSS fix Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName, 86 x509_util::ParsePrincipalValueByNID(x509_name, NID_commonName,
87 &principal->common_name); 87 &principal->common_name);
88 x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName, 88 x509_util::ParsePrincipalValueByNID(x509_name, NID_localityName,
89 &principal->locality_name); 89 &principal->locality_name);
90 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName, 90 x509_util::ParsePrincipalValueByNID(x509_name, NID_stateOrProvinceName,
91 &principal->state_or_province_name); 91 &principal->state_or_province_name);
92 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName, 92 x509_util::ParsePrincipalValueByNID(x509_name, NID_countryName,
93 &principal->country_name); 93 &principal->country_name);
94 } 94 }
95 95
96 void ParseSubjectAltName(X509Certificate::OSCertHandle cert, 96 bool ParseSubjectAltName(X509Certificate::OSCertHandle cert,
97 std::vector<std::string>* dns_names, 97 std::vector<std::string>* dns_names,
98 std::vector<std::string>* ip_addresses) { 98 std::vector<std::string>* ip_addresses) {
99 DCHECK(dns_names || ip_addresses);
100 int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1); 99 int index = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
101 X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index); 100 X509_EXTENSION* alt_name_ext = X509_get_ext(cert, index);
102 if (!alt_name_ext) 101 if (!alt_name_ext)
103 return; 102 return false;
104 103
105 bssl::UniquePtr<GENERAL_NAMES> alt_names( 104 bssl::UniquePtr<GENERAL_NAMES> alt_names(
106 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext))); 105 reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(alt_name_ext)));
107 if (!alt_names.get()) 106 if (!alt_names.get())
108 return; 107 return false;
109 108
109 bool has_san = false;
110 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) { 110 for (size_t i = 0; i < sk_GENERAL_NAME_num(alt_names.get()); ++i) {
111 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i); 111 const GENERAL_NAME* name = sk_GENERAL_NAME_value(alt_names.get(), i);
112 if (name->type == GEN_DNS && dns_names) { 112 if (name->type == GEN_DNS) {
113 const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName); 113 has_san = true;
114 if (!dns_name) 114 if (dns_names) {
115 continue; 115 const unsigned char* dns_name = ASN1_STRING_data(name->d.dNSName);
116 int dns_name_len = ASN1_STRING_length(name->d.dNSName); 116 if (!dns_name)
117 dns_names->push_back( 117 continue;
eroman 2017/03/21 21:09:54 Same comments as with the ios one (which this vers
118 std::string(reinterpret_cast<const char*>(dns_name), dns_name_len)); 118 int dns_name_len = ASN1_STRING_length(name->d.dNSName);
119 } else if (name->type == GEN_IPADD && ip_addresses) { 119 dns_names->push_back(
120 const unsigned char* ip_addr = name->d.iPAddress->data; 120 std::string(reinterpret_cast<const char*>(dns_name), dns_name_len));
121 if (!ip_addr)
122 continue;
123 int ip_addr_len = name->d.iPAddress->length;
124 if (ip_addr_len != static_cast<int>(IPAddress::kIPv4AddressSize) &&
125 ip_addr_len != static_cast<int>(IPAddress::kIPv6AddressSize)) {
126 // http://www.ietf.org/rfc/rfc3280.txt requires subjectAltName iPAddress
127 // to have 4 or 16 bytes, whereas in a name constraint it includes a
128 // net mask hence 8 or 32 bytes. Logging to help diagnose any mixup.
129 LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len;
130 continue;
131 } 121 }
132 ip_addresses->push_back( 122 } else if (name->type == GEN_IPADD) {
133 std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len)); 123 has_san = true;
124 if (ip_addresses) {
125 const unsigned char* ip_addr = name->d.iPAddress->data;
126 if (!ip_addr)
127 continue;
128 int ip_addr_len = name->d.iPAddress->length;
129 if (ip_addr_len != static_cast<int>(IPAddress::kIPv4AddressSize) &&
130 ip_addr_len != static_cast<int>(IPAddress::kIPv6AddressSize)) {
131 // http://www.ietf.org/rfc/rfc3280.txt requires subjectAltName
132 // iPAddress to have 4 or 16 bytes, whereas in a name constraint it
133 // includes a net mask hence 8 or 32 bytes. Logging to help diagnose
134 // any mixup.
135 LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len;
136 continue;
137 }
138 ip_addresses->push_back(
139 std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len));
140 }
134 } 141 }
142 // Fast path: Found at least one subjectAltName and the caller doesn't
143 // need the actual values.
144 if (has_san && !ip_addresses && !dns_names)
145 return true;
135 } 146 }
147 return has_san;
136 } 148 }
137 149
138 class X509InitSingleton { 150 class X509InitSingleton {
139 public: 151 public:
140 static X509InitSingleton* GetInstance() { 152 static X509InitSingleton* GetInstance() {
141 // We allow the X509 store to leak, because it is used from a non-joinable 153 // We allow the X509 store to leak, because it is used from a non-joinable
142 // worker that is not stopped on shutdown, hence may still be using 154 // worker that is not stopped on shutdown, hence may still be using
143 // OpenSSL library after the AtExit runner has completed. 155 // OpenSSL library after the AtExit runner has completed.
144 return base::Singleton<X509InitSingleton, base::LeakySingletonTraits< 156 return base::Singleton<X509InitSingleton, base::LeakySingletonTraits<
145 X509InitSingleton>>::get(); 157 X509InitSingleton>>::get();
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 } 291 }
280 292
281 void X509Certificate::GetSubjectAltName( 293 void X509Certificate::GetSubjectAltName(
282 std::vector<std::string>* dns_names, 294 std::vector<std::string>* dns_names,
283 std::vector<std::string>* ip_addrs) const { 295 std::vector<std::string>* ip_addrs) const {
284 if (dns_names) 296 if (dns_names)
285 dns_names->clear(); 297 dns_names->clear();
286 if (ip_addrs) 298 if (ip_addrs)
287 ip_addrs->clear(); 299 ip_addrs->clear();
288 300
289 ParseSubjectAltName(cert_handle_, dns_names, ip_addrs); 301 return ParseSubjectAltName(cert_handle_, dns_names, ip_addrs);
290 } 302 }
291 303
292 // static 304 // static
293 X509_STORE* X509Certificate::cert_store() { 305 X509_STORE* X509Certificate::cert_store() {
294 return X509InitSingleton::GetInstance()->store(); 306 return X509InitSingleton::GetInstance()->store();
295 } 307 }
296 308
297 // static 309 // static
298 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, 310 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle,
299 std::string* encoded) { 311 std::string* encoded) {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) { 442 bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) {
431 bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert_handle)); 443 bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert_handle));
432 if (!scoped_key) 444 if (!scoped_key)
433 return false; 445 return false;
434 if (!X509_verify(cert_handle, scoped_key.get())) 446 if (!X509_verify(cert_handle, scoped_key.get()))
435 return false; 447 return false;
436 return X509_check_issued(cert_handle, cert_handle) == X509_V_OK; 448 return X509_check_issued(cert_handle, cert_handle) == X509_V_OK;
437 } 449 }
438 450
439 } // namespace net 451 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698