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

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

Issue 2770713002: Add a DevTools warning for a missing subjectAltName (Closed)
Patch Set: 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
« no previous file with comments | « net/cert/x509_certificate_nss.cc ('k') | net/cert/x509_certificate_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « net/cert/x509_certificate_nss.cc ('k') | net/cert/x509_certificate_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698