Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/ssl/client_cert_store_mac.h" | 5 #include "net/ssl/client_cert_store_mac.h" |
| 6 | 6 |
| 7 #include <CommonCrypto/CommonDigest.h> | 7 #include <CommonCrypto/CommonDigest.h> |
| 8 #include <CoreFoundation/CFArray.h> | 8 #include <CoreFoundation/CFArray.h> |
| 9 #include <CoreServices/CoreServices.h> | 9 #include <CoreServices/CoreServices.h> |
| 10 #include <Security/SecBase.h> | 10 #include <Security/SecBase.h> |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 | 84 |
| 85 // Returns true if |*cert| is issued by an authority in |valid_issuers| | 85 // Returns true if |*cert| is issued by an authority in |valid_issuers| |
| 86 // according to Keychain Services, rather than using |cert|'s intermediate | 86 // according to Keychain Services, rather than using |cert|'s intermediate |
| 87 // certificates. If it is, |*cert| is updated to point to the completed | 87 // certificates. If it is, |*cert| is updated to point to the completed |
| 88 // certificate | 88 // certificate |
| 89 bool IsIssuedByInKeychain(const std::vector<std::string>& valid_issuers, | 89 bool IsIssuedByInKeychain(const std::vector<std::string>& valid_issuers, |
| 90 scoped_refptr<X509Certificate>* cert) { | 90 scoped_refptr<X509Certificate>* cert) { |
| 91 DCHECK(cert); | 91 DCHECK(cert); |
| 92 DCHECK(cert->get()); | 92 DCHECK(cert->get()); |
| 93 | 93 |
| 94 X509Certificate::OSCertHandle cert_handle = (*cert)->os_cert_handle(); | 94 base::ScopedCFTypeRef<SecCertificateRef> os_cert( |
| 95 x509_util::CreateSecCertificateFromX509Certificate(cert->get())); | |
| 96 if (!os_cert) | |
| 97 return false; | |
| 95 CFArrayRef cert_chain = NULL; | 98 CFArrayRef cert_chain = NULL; |
| 96 OSStatus result = CopyCertChain(cert_handle, &cert_chain); | 99 OSStatus result = CopyCertChain(os_cert.get(), &cert_chain); |
| 97 if (result) { | 100 if (result) { |
| 98 OSSTATUS_LOG(ERROR, result) << "CopyCertChain error"; | 101 OSSTATUS_LOG(ERROR, result) << "CopyCertChain error"; |
| 99 return false; | 102 return false; |
| 100 } | 103 } |
| 101 | 104 |
| 102 if (!cert_chain) | 105 if (!cert_chain) |
| 103 return false; | 106 return false; |
| 104 | 107 |
| 105 X509Certificate::OSCertHandles intermediates; | 108 std::vector<SecCertificateRef> intermediates; |
| 106 for (CFIndex i = 1, chain_count = CFArrayGetCount(cert_chain); | 109 for (CFIndex i = 1, chain_count = CFArrayGetCount(cert_chain); |
| 107 i < chain_count; ++i) { | 110 i < chain_count; ++i) { |
| 108 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>( | 111 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>( |
| 109 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i))); | 112 const_cast<void*>(CFArrayGetValueAtIndex(cert_chain, i))); |
| 110 intermediates.push_back(cert); | 113 intermediates.push_back(cert); |
| 111 } | 114 } |
| 112 | 115 |
| 113 scoped_refptr<X509Certificate> new_cert(X509Certificate::CreateFromHandle( | 116 scoped_refptr<X509Certificate> new_cert( |
| 114 cert_handle, intermediates)); | 117 x509_util::CreateX509CertificateFromSecCertificate(os_cert.get(), |
| 118 intermediates)); | |
| 115 CFRelease(cert_chain); // Also frees |intermediates|. | 119 CFRelease(cert_chain); // Also frees |intermediates|. |
| 116 | 120 |
| 117 if (!new_cert || !new_cert->IsIssuedByEncoded(valid_issuers)) | 121 if (!new_cert || !new_cert->IsIssuedByEncoded(valid_issuers)) |
| 118 return false; | 122 return false; |
| 119 | 123 |
| 120 cert->swap(new_cert); | 124 cert->swap(new_cert); |
| 121 return true; | 125 return true; |
| 122 } | 126 } |
| 123 | 127 |
| 124 // Returns true if |purpose| is listed as allowed in |usage|. This | 128 // Returns true if |purpose| is listed as allowed in |usage|. This |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 186 CertificateList* selected_certs) { | 190 CertificateList* selected_certs) { |
| 187 CertificateList preliminary_list; | 191 CertificateList preliminary_list; |
| 188 if (preferred_cert.get()) | 192 if (preferred_cert.get()) |
| 189 preliminary_list.push_back(preferred_cert); | 193 preliminary_list.push_back(preferred_cert); |
| 190 preliminary_list.insert(preliminary_list.end(), regular_certs.begin(), | 194 preliminary_list.insert(preliminary_list.end(), regular_certs.begin(), |
| 191 regular_certs.end()); | 195 regular_certs.end()); |
| 192 | 196 |
| 193 selected_certs->clear(); | 197 selected_certs->clear(); |
| 194 for (size_t i = 0; i < preliminary_list.size(); ++i) { | 198 for (size_t i = 0; i < preliminary_list.size(); ++i) { |
| 195 scoped_refptr<X509Certificate>& cert = preliminary_list[i]; | 199 scoped_refptr<X509Certificate>& cert = preliminary_list[i]; |
| 196 if (cert->HasExpired() || !SupportsSSLClientAuth(cert->os_cert_handle())) | 200 if (cert->HasExpired()) |
| 197 continue; | 201 continue; |
| 198 | 202 |
| 199 // Skip duplicates (a cert may be in multiple keychains). | 203 // Skip duplicates (a cert may be in multiple keychains). |
| 200 auto cert_iter = std::find_if( | 204 auto cert_iter = std::find_if( |
| 201 selected_certs->begin(), selected_certs->end(), | 205 selected_certs->begin(), selected_certs->end(), |
| 202 [&cert](const scoped_refptr<X509Certificate>& other_cert) { | 206 [&cert](const scoped_refptr<X509Certificate>& other_cert) { |
| 203 return X509Certificate::IsSameOSCert(cert->os_cert_handle(), | 207 return X509Certificate::IsSameOSCert(cert->os_cert_handle(), |
| 204 other_cert->os_cert_handle()); | 208 other_cert->os_cert_handle()); |
| 205 }); | 209 }); |
| 206 if (cert_iter != selected_certs->end()) | 210 if (cert_iter != selected_certs->end()) |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 280 if (err) | 284 if (err) |
| 281 break; | 285 break; |
| 282 ScopedCFTypeRef<SecIdentityRef> scoped_identity(identity); | 286 ScopedCFTypeRef<SecIdentityRef> scoped_identity(identity); |
| 283 | 287 |
| 284 SecCertificateRef cert_handle; | 288 SecCertificateRef cert_handle; |
| 285 err = SecIdentityCopyCertificate(identity, &cert_handle); | 289 err = SecIdentityCopyCertificate(identity, &cert_handle); |
| 286 if (err != noErr) | 290 if (err != noErr) |
| 287 continue; | 291 continue; |
| 288 ScopedCFTypeRef<SecCertificateRef> scoped_cert_handle(cert_handle); | 292 ScopedCFTypeRef<SecCertificateRef> scoped_cert_handle(cert_handle); |
| 289 | 293 |
| 294 if (!SupportsSSLClientAuth(cert_handle)) | |
|
eroman
2017/03/29 23:06:55
Can you explain this line? Was this a check that w
mattm
2017/03/30 04:38:10
This is moved from GetClientCertsImpl (the previou
| |
| 295 continue; | |
| 296 | |
| 290 scoped_refptr<X509Certificate> cert( | 297 scoped_refptr<X509Certificate> cert( |
| 291 X509Certificate::CreateFromHandle(cert_handle, | 298 x509_util::CreateX509CertificateFromSecCertificate( |
| 292 X509Certificate::OSCertHandles())); | 299 cert_handle, std::vector<SecCertificateRef>())); |
| 293 if (!cert) | 300 if (!cert) |
| 294 continue; | 301 continue; |
| 295 | 302 |
| 296 if (preferred_identity && CFEqual(preferred_identity, identity)) { | 303 if (preferred_identity && CFEqual(preferred_identity, identity)) { |
| 297 // Only one certificate should match. | 304 // Only one certificate should match. |
| 298 DCHECK(!preferred_cert.get()); | 305 DCHECK(!preferred_cert.get()); |
| 299 preferred_cert = cert; | 306 preferred_cert = cert; |
| 300 } else { | 307 } else { |
| 301 regular_certs.push_back(cert); | 308 regular_certs.push_back(cert); |
| 302 } | 309 } |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 328 const SSLCertRequestInfo& request, | 335 const SSLCertRequestInfo& request, |
| 329 CertificateList* selected_certs) { | 336 CertificateList* selected_certs) { |
| 330 GetClientCertsImpl( | 337 GetClientCertsImpl( |
| 331 preferred_cert, regular_certs, request, false, selected_certs); | 338 preferred_cert, regular_certs, request, false, selected_certs); |
| 332 return true; | 339 return true; |
| 333 } | 340 } |
| 334 | 341 |
| 335 #pragma clang diagnostic pop // "-Wdeprecated-declarations" | 342 #pragma clang diagnostic pop // "-Wdeprecated-declarations" |
| 336 | 343 |
| 337 } // namespace net | 344 } // namespace net |
| OLD | NEW |