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

Side by Side Diff: net/cert/x509_certificate_ios.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) 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
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 if (!dns_name)
127 dns_names->push_back( 127 continue;
eroman 2017/03/21 21:09:54 Is it expected that this code-path sets |has_san =
128 std::string(reinterpret_cast<const char*>(dns_name), dns_name_len)); 128 int dns_name_len = ASN1_STRING_length(name->d.dNSName);
129 } else if (name->type == GEN_IPADD && ip_addresses) { 129 dns_names->push_back(
130 const unsigned char* ip_addr = name->d.iPAddress->data; 130 std::string(reinterpret_cast<const char*>(dns_name), dns_name_len));
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_addrs) {
135 const unsigned char* ip_addr = name->d.iPAddress->data;
136 if (!ip_addr)
137 continue;
eroman 2017/03/21 21:09:54 Same here and other continue.
138 int ip_addr_len = name->d.iPAddress->length;
139 if (ip_addr_len != static_cast<int>(IPAddress::kIPv4AddressSize) &&
140 ip_addr_len != static_cast<int>(IPAddress::kIPv6AddressSize)) {
141 // http://www.ietf.org/rfc/rfc3280.txt requires subjectAltName
142 // iPAddress to have 4 or 16 bytes, whereas in a name constraint it
143 // includes a net mask hence 8 or 32 bytes. Logging to help diagnose
144 // any mixup.
145 LOG(WARNING) << "Bad sized IP Address in cert: " << ip_addr_len;
146 continue;
147 }
148 ip_addresses->push_back(
149 std::string(reinterpret_cast<const char*>(ip_addr), ip_addr_len));
150 }
144 } 151 }
152 // Fast path: Found at least one subjectAltName and the caller doesn't
153 // need the actual values.
154 if (has_san && !ip_addresses && !dns_names)
155 return true;
145 } 156 }
157
158 return has_san;
146 } 159 }
147 160
148 } // namespace 161 } // namespace
149 162
150 // static 163 // static
151 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( 164 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
152 OSCertHandle handle) { 165 OSCertHandle handle) {
153 if (!handle) 166 if (!handle)
154 return nullptr; 167 return nullptr;
155 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle))); 168 return reinterpret_cast<OSCertHandle>(const_cast<void*>(CFRetain(handle)));
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 } 277 }
265 default: { 278 default: {
266 NOTREACHED() << "Certificate format " << format << " unimplemented"; 279 NOTREACHED() << "Certificate format " << format << " unimplemented";
267 break; 280 break;
268 } 281 }
269 } 282 }
270 283
271 return results; 284 return results;
272 } 285 }
273 286
274 void X509Certificate::GetSubjectAltName( 287 bool X509Certificate::GetSubjectAltName(
275 std::vector<std::string>* dns_names, 288 std::vector<std::string>* dns_names,
276 std::vector<std::string>* ip_addrs) const { 289 std::vector<std::string>* ip_addrs) const {
277 if (dns_names) 290 if (dns_names)
278 dns_names->clear(); 291 dns_names->clear();
279 if (ip_addrs) 292 if (ip_addrs)
280 ip_addrs->clear(); 293 ip_addrs->clear();
281 294
282 ParseSubjectAltName(cert_handle_, dns_names, ip_addrs); 295 return ParseSubjectAltName(cert_handle_, dns_names, ip_addrs);
283 } 296 }
284 297
285 // static 298 // static
286 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, 299 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle,
287 std::string* encoded) { 300 std::string* encoded) {
288 base::StringPiece der; 301 base::StringPiece der;
289 if (!cert_handle) 302 if (!cert_handle)
290 return false; 303 return false;
291 ScopedCFTypeRef<CFDataRef> der_data(SecCertificateCopyData(cert_handle)); 304 ScopedCFTypeRef<CFDataRef> der_data(SecCertificateCopyData(cert_handle));
292 if (!der_data) 305 if (!der_data)
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 return false; 446 return false;
434 bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert.get())); 447 bssl::UniquePtr<EVP_PKEY> scoped_key(X509_get_pubkey(cert.get()));
435 if (!scoped_key) 448 if (!scoped_key)
436 return false; 449 return false;
437 if (!X509_verify(cert.get(), scoped_key.get())) 450 if (!X509_verify(cert.get(), scoped_key.get()))
438 return false; 451 return false;
439 return X509_check_issued(cert.get(), cert.get()) == X509_V_OK; 452 return X509_check_issued(cert.get(), cert.get()) == X509_V_OK;
440 } 453 }
441 454
442 } // namespace net 455 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698