| OLD | NEW |
| 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/ssl/client_cert_store_impl.h" | 5 #include "net/ssl/client_cert_store_impl.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> |
| 11 #include <Security/Security.h> | 11 #include <Security/Security.h> |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <string> | 14 #include <string> |
| 15 | 15 |
| 16 #include "base/callback.h" |
| 16 #include "base/logging.h" | 17 #include "base/logging.h" |
| 17 #include "base/mac/mac_logging.h" | 18 #include "base/mac/mac_logging.h" |
| 18 #include "base/mac/scoped_cftyperef.h" | 19 #include "base/mac/scoped_cftyperef.h" |
| 19 #include "base/strings/sys_string_conversions.h" | 20 #include "base/strings/sys_string_conversions.h" |
| 20 #include "base/synchronization/lock.h" | 21 #include "base/synchronization/lock.h" |
| 21 #include "crypto/mac_security_services_lock.h" | 22 #include "crypto/mac_security_services_lock.h" |
| 22 #include "net/base/host_port_pair.h" | 23 #include "net/base/host_port_pair.h" |
| 23 #include "net/cert/x509_util.h" | 24 #include "net/cert/x509_util.h" |
| 24 #include "net/cert/x509_util_mac.h" | 25 #include "net/cert/x509_util_mac.h" |
| 25 | 26 |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 if (preferred_cert.get() && sort_begin != sort_end && | 166 if (preferred_cert.get() && sort_begin != sort_end && |
| 166 sort_begin->get() == preferred_cert.get()) { | 167 sort_begin->get() == preferred_cert.get()) { |
| 167 ++sort_begin; | 168 ++sort_begin; |
| 168 } | 169 } |
| 169 sort(sort_begin, sort_end, x509_util::ClientCertSorter()); | 170 sort(sort_begin, sort_end, x509_util::ClientCertSorter()); |
| 170 return true; | 171 return true; |
| 171 } | 172 } |
| 172 | 173 |
| 173 } // namespace | 174 } // namespace |
| 174 | 175 |
| 175 bool ClientCertStoreImpl::GetClientCerts(const SSLCertRequestInfo& request, | 176 void ClientCertStoreImpl::GetClientCerts(const SSLCertRequestInfo& request, |
| 176 CertificateList* selected_certs) { | 177 CertificateList* selected_certs, |
| 178 const base::Closure& callback) { |
| 177 std::string server_domain = | 179 std::string server_domain = |
| 178 HostPortPair::FromString(request.host_and_port).host(); | 180 HostPortPair::FromString(request.host_and_port).host(); |
| 179 | 181 |
| 180 ScopedCFTypeRef<SecIdentityRef> preferred_identity; | 182 ScopedCFTypeRef<SecIdentityRef> preferred_identity; |
| 181 if (!server_domain.empty()) { | 183 if (!server_domain.empty()) { |
| 182 // See if there's an identity preference for this domain: | 184 // See if there's an identity preference for this domain: |
| 183 ScopedCFTypeRef<CFStringRef> domain_str( | 185 ScopedCFTypeRef<CFStringRef> domain_str( |
| 184 base::SysUTF8ToCFStringRef("https://" + server_domain)); | 186 base::SysUTF8ToCFStringRef("https://" + server_domain)); |
| 185 SecIdentityRef identity = NULL; | 187 SecIdentityRef identity = NULL; |
| 186 // While SecIdentityCopyPreferences appears to take a list of CA issuers | 188 // While SecIdentityCopyPreferences appears to take a list of CA issuers |
| (...skipping 11 matching lines...) Expand all Loading... |
| 198 // Now enumerate the identities in the available keychains. | 200 // Now enumerate the identities in the available keychains. |
| 199 scoped_refptr<X509Certificate> preferred_cert = NULL; | 201 scoped_refptr<X509Certificate> preferred_cert = NULL; |
| 200 CertificateList regular_certs; | 202 CertificateList regular_certs; |
| 201 | 203 |
| 202 SecIdentitySearchRef search = NULL; | 204 SecIdentitySearchRef search = NULL; |
| 203 OSStatus err; | 205 OSStatus err; |
| 204 { | 206 { |
| 205 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); | 207 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); |
| 206 err = SecIdentitySearchCreate(NULL, CSSM_KEYUSE_SIGN, &search); | 208 err = SecIdentitySearchCreate(NULL, CSSM_KEYUSE_SIGN, &search); |
| 207 } | 209 } |
| 208 if (err) | 210 if (err) { |
| 209 return false; | 211 callback.Run(); |
| 212 return; |
| 213 } |
| 210 ScopedCFTypeRef<SecIdentitySearchRef> scoped_search(search); | 214 ScopedCFTypeRef<SecIdentitySearchRef> scoped_search(search); |
| 211 while (!err) { | 215 while (!err) { |
| 212 SecIdentityRef identity = NULL; | 216 SecIdentityRef identity = NULL; |
| 213 { | 217 { |
| 214 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); | 218 base::AutoLock lock(crypto::GetMacSecurityServicesLock()); |
| 215 err = SecIdentitySearchCopyNext(search, &identity); | 219 err = SecIdentitySearchCopyNext(search, &identity); |
| 216 } | 220 } |
| 217 if (err) | 221 if (err) |
| 218 break; | 222 break; |
| 219 ScopedCFTypeRef<SecIdentityRef> scoped_identity(identity); | 223 ScopedCFTypeRef<SecIdentityRef> scoped_identity(identity); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 232 // Only one certificate should match. | 236 // Only one certificate should match. |
| 233 DCHECK(!preferred_cert.get()); | 237 DCHECK(!preferred_cert.get()); |
| 234 preferred_cert = cert; | 238 preferred_cert = cert; |
| 235 } else { | 239 } else { |
| 236 regular_certs.push_back(cert); | 240 regular_certs.push_back(cert); |
| 237 } | 241 } |
| 238 } | 242 } |
| 239 | 243 |
| 240 if (err != errSecItemNotFound) { | 244 if (err != errSecItemNotFound) { |
| 241 OSSTATUS_LOG(ERROR, err) << "SecIdentitySearch error"; | 245 OSSTATUS_LOG(ERROR, err) << "SecIdentitySearch error"; |
| 242 return false; | 246 callback.Run(); |
| 247 return; |
| 243 } | 248 } |
| 244 | 249 |
| 245 return GetClientCertsImpl(preferred_cert, regular_certs, request, true, | 250 GetClientCertsImpl(preferred_cert, regular_certs, request, true, |
| 246 selected_certs); | 251 selected_certs); |
| 252 callback.Run(); |
| 247 } | 253 } |
| 248 | 254 |
| 249 bool ClientCertStoreImpl::SelectClientCertsForTesting( | 255 bool ClientCertStoreImpl::SelectClientCertsForTesting( |
| 250 const CertificateList& input_certs, | 256 const CertificateList& input_certs, |
| 251 const SSLCertRequestInfo& request, | 257 const SSLCertRequestInfo& request, |
| 252 CertificateList* selected_certs) { | 258 CertificateList* selected_certs) { |
| 253 return GetClientCertsImpl(NULL, input_certs, request, false, | 259 return GetClientCertsImpl(NULL, input_certs, request, false, |
| 254 selected_certs); | 260 selected_certs); |
| 255 } | 261 } |
| 256 | 262 |
| 257 #if !defined(OS_IOS) | 263 #if !defined(OS_IOS) |
| 258 bool ClientCertStoreImpl::SelectClientCertsGivenPreferredForTesting( | 264 bool ClientCertStoreImpl::SelectClientCertsGivenPreferredForTesting( |
| 259 const scoped_refptr<X509Certificate>& preferred_cert, | 265 const scoped_refptr<X509Certificate>& preferred_cert, |
| 260 const CertificateList& regular_certs, | 266 const CertificateList& regular_certs, |
| 261 const SSLCertRequestInfo& request, | 267 const SSLCertRequestInfo& request, |
| 262 CertificateList* selected_certs) { | 268 CertificateList* selected_certs) { |
| 263 return GetClientCertsImpl(preferred_cert, regular_certs, request, false, | 269 return GetClientCertsImpl(preferred_cert, regular_certs, request, false, |
| 264 selected_certs); | 270 selected_certs); |
| 265 } | 271 } |
| 266 #endif | 272 #endif |
| 267 | 273 |
| 268 } // namespace net | 274 } // namespace net |
| OLD | NEW |