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)) |
| 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 |