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

Side by Side Diff: net/base/x509_certificate_mac.cc

Issue 11016004: Force crypto::AppleKeychain access to be guarded by a Big Global Lock (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comment update Created 8 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « net/base/cert_verify_proc_mac.cc ('k') | no next file » | 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/base/x509_certificate.h" 5 #include "net/base/x509_certificate.h"
6 6
7 #include <CommonCrypto/CommonDigest.h> 7 #include <CommonCrypto/CommonDigest.h>
8 #include <CoreServices/CoreServices.h> 8 #include <CoreServices/CoreServices.h>
9 #include <Security/Security.h> 9 #include <Security/Security.h>
10 #include <time.h> 10 #include <time.h>
11 11
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/lazy_instance.h" 14 #include "base/lazy_instance.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/mac/mac_logging.h" 16 #include "base/mac/mac_logging.h"
17 #include "base/mac/scoped_cftyperef.h" 17 #include "base/mac/scoped_cftyperef.h"
18 #include "base/memory/singleton.h" 18 #include "base/memory/singleton.h"
19 #include "base/pickle.h" 19 #include "base/pickle.h"
20 #include "base/sha1.h" 20 #include "base/sha1.h"
21 #include "base/synchronization/lock.h"
21 #include "base/sys_string_conversions.h" 22 #include "base/sys_string_conversions.h"
22 #include "crypto/cssm_init.h" 23 #include "crypto/cssm_init.h"
24 #include "crypto/mac_security_services_lock.h"
23 #include "crypto/nss_util.h" 25 #include "crypto/nss_util.h"
24 #include "crypto/rsa_private_key.h" 26 #include "crypto/rsa_private_key.h"
25 #include "net/base/x509_util_mac.h" 27 #include "net/base/x509_util_mac.h"
26 #include "third_party/nss/mozilla/security/nss/lib/certdb/cert.h" 28 #include "third_party/nss/mozilla/security/nss/lib/certdb/cert.h"
27 29
28 using base::mac::ScopedCFTypeRef; 30 using base::mac::ScopedCFTypeRef;
29 using base::Time; 31 using base::Time;
30 32
31 namespace net { 33 namespace net {
32 34
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 88
87 // Gets the issuer for a given cert, starting with the cert itself and 89 // Gets the issuer for a given cert, starting with the cert itself and
88 // including the intermediate and finally root certificates (if any). 90 // including the intermediate and finally root certificates (if any).
89 // This function calls SecTrust but doesn't actually pay attention to the trust 91 // This function calls SecTrust but doesn't actually pay attention to the trust
90 // result: it shouldn't be used to determine trust, just to traverse the chain. 92 // result: it shouldn't be used to determine trust, just to traverse the chain.
91 // Caller is responsible for releasing the value stored into *out_cert_chain. 93 // Caller is responsible for releasing the value stored into *out_cert_chain.
92 OSStatus CopyCertChain(SecCertificateRef cert_handle, 94 OSStatus CopyCertChain(SecCertificateRef cert_handle,
93 CFArrayRef* out_cert_chain) { 95 CFArrayRef* out_cert_chain) {
94 DCHECK(cert_handle); 96 DCHECK(cert_handle);
95 DCHECK(out_cert_chain); 97 DCHECK(out_cert_chain);
98
96 // Create an SSL policy ref configured for client cert evaluation. 99 // Create an SSL policy ref configured for client cert evaluation.
97 SecPolicyRef ssl_policy; 100 SecPolicyRef ssl_policy;
98 OSStatus result = x509_util::CreateSSLClientPolicy(&ssl_policy); 101 OSStatus result = x509_util::CreateSSLClientPolicy(&ssl_policy);
99 if (result) 102 if (result)
100 return result; 103 return result;
101 ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy); 104 ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy);
102 105
103 // Create a SecTrustRef. 106 // Create a SecTrustRef.
104 ScopedCFTypeRef<CFArrayRef> input_certs(CFArrayCreate( 107 ScopedCFTypeRef<CFArrayRef> input_certs(CFArrayCreate(
105 NULL, const_cast<const void**>(reinterpret_cast<void**>(&cert_handle)), 108 NULL, const_cast<const void**>(reinterpret_cast<void**>(&cert_handle)),
106 1, &kCFTypeArrayCallBacks)); 109 1, &kCFTypeArrayCallBacks));
107 SecTrustRef trust_ref = NULL; 110 SecTrustRef trust_ref = NULL;
108 result = SecTrustCreateWithCertificates(input_certs, ssl_policy, &trust_ref); 111 {
112 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
113 result = SecTrustCreateWithCertificates(input_certs, ssl_policy,
114 &trust_ref);
115 }
109 if (result) 116 if (result)
110 return result; 117 return result;
111 ScopedCFTypeRef<SecTrustRef> trust(trust_ref); 118 ScopedCFTypeRef<SecTrustRef> trust(trust_ref);
112 119
113 // Evaluate trust, which creates the cert chain. 120 // Evaluate trust, which creates the cert chain.
114 SecTrustResultType status; 121 SecTrustResultType status;
115 CSSM_TP_APPLE_EVIDENCE_INFO* status_chain; 122 CSSM_TP_APPLE_EVIDENCE_INFO* status_chain;
116 result = SecTrustEvaluate(trust, &status); 123 {
124 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
125 result = SecTrustEvaluate(trust, &status);
126 }
117 if (result) 127 if (result)
118 return result; 128 return result;
119 return SecTrustGetResult(trust, &status, out_cert_chain, &status_chain); 129 {
130 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
131 result = SecTrustGetResult(trust, &status, out_cert_chain, &status_chain);
132 }
133 return result;
120 } 134 }
121 135
122 // Returns true if |purpose| is listed as allowed in |usage|. This 136 // Returns true if |purpose| is listed as allowed in |usage|. This
123 // function also considers the "Any" purpose. If the attribute is 137 // function also considers the "Any" purpose. If the attribute is
124 // present and empty, we return false. 138 // present and empty, we return false.
125 bool ExtendedKeyUsageAllows(const CE_ExtendedKeyUsage* usage, 139 bool ExtendedKeyUsageAllows(const CE_ExtendedKeyUsage* usage,
126 const CSSM_OID* purpose) { 140 const CSSM_OID* purpose) {
127 for (unsigned p = 0; p < usage->numPurposes; ++p) { 141 for (unsigned p = 0; p < usage->numPurposes; ++p) {
128 if (CSSMOIDEqual(&usage->purposes[p], purpose)) 142 if (CSSMOIDEqual(&usage->purposes[p], purpose))
129 return true; 143 return true;
(...skipping 25 matching lines...) Expand all
155 // within are stored into |output|. 169 // within are stored into |output|.
156 void AddCertificatesFromBytes(const char* data, size_t length, 170 void AddCertificatesFromBytes(const char* data, size_t length,
157 SecExternalFormat format, 171 SecExternalFormat format,
158 X509Certificate::OSCertHandles* output) { 172 X509Certificate::OSCertHandles* output) {
159 SecExternalFormat input_format = format; 173 SecExternalFormat input_format = format;
160 ScopedCFTypeRef<CFDataRef> local_data(CFDataCreateWithBytesNoCopy( 174 ScopedCFTypeRef<CFDataRef> local_data(CFDataCreateWithBytesNoCopy(
161 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data), length, 175 kCFAllocatorDefault, reinterpret_cast<const UInt8*>(data), length,
162 kCFAllocatorNull)); 176 kCFAllocatorNull));
163 177
164 CFArrayRef items = NULL; 178 CFArrayRef items = NULL;
165 OSStatus status = SecKeychainItemImport(local_data, NULL, &input_format, 179 OSStatus status;
166 NULL, 0, NULL, NULL, &items); 180 {
181 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
182 status = SecKeychainItemImport(local_data, NULL, &input_format,
183 NULL, 0, NULL, NULL, &items);
184 }
185
167 if (status) { 186 if (status) {
168 OSSTATUS_DLOG(WARNING, status) 187 OSSTATUS_DLOG(WARNING, status)
169 << "Unable to import items from data of length " << length; 188 << "Unable to import items from data of length " << length;
170 return; 189 return;
171 } 190 }
172 191
173 ScopedCFTypeRef<CFArrayRef> scoped_items(items); 192 ScopedCFTypeRef<CFArrayRef> scoped_items(items);
174 CFTypeID cert_type_id = SecCertificateGetTypeID(); 193 CFTypeID cert_type_id = SecCertificateGetTypeID();
175 194
176 for (CFIndex i = 0; i < CFArrayGetCount(items); ++i) { 195 for (CFIndex i = 0; i < CFArrayGetCount(items); ++i) {
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 if (!server_domain.empty()) { 705 if (!server_domain.empty()) {
687 // See if there's an identity preference for this domain: 706 // See if there's an identity preference for this domain:
688 ScopedCFTypeRef<CFStringRef> domain_str( 707 ScopedCFTypeRef<CFStringRef> domain_str(
689 base::SysUTF8ToCFStringRef("https://" + server_domain)); 708 base::SysUTF8ToCFStringRef("https://" + server_domain));
690 SecIdentityRef identity = NULL; 709 SecIdentityRef identity = NULL;
691 // While SecIdentityCopyPreferences appears to take a list of CA issuers 710 // While SecIdentityCopyPreferences appears to take a list of CA issuers
692 // to restrict the identity search to, within Security.framework the 711 // to restrict the identity search to, within Security.framework the
693 // argument is ignored and filtering unimplemented. See 712 // argument is ignored and filtering unimplemented. See
694 // SecIdentity.cpp in libsecurity_keychain, specifically 713 // SecIdentity.cpp in libsecurity_keychain, specifically
695 // _SecIdentityCopyPreferenceMatchingName(). 714 // _SecIdentityCopyPreferenceMatchingName().
696 if (SecIdentityCopyPreference(domain_str, 0, NULL, &identity) == noErr) 715 {
697 preferred_identity.reset(identity); 716 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
717 if (SecIdentityCopyPreference(domain_str, 0, NULL, &identity) == noErr)
718 preferred_identity.reset(identity);
719 }
698 } 720 }
699 721
700 // Now enumerate the identities in the available keychains. 722 // Now enumerate the identities in the available keychains.
701 SecIdentitySearchRef search = nil; 723 SecIdentitySearchRef search = NULL;
702 OSStatus err = SecIdentitySearchCreate(NULL, CSSM_KEYUSE_SIGN, &search); 724 OSStatus err;
725 {
726 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
727 err = SecIdentitySearchCreate(NULL, CSSM_KEYUSE_SIGN, &search);
728 }
729 if (err)
730 return false;
703 ScopedCFTypeRef<SecIdentitySearchRef> scoped_search(search); 731 ScopedCFTypeRef<SecIdentitySearchRef> scoped_search(search);
704 while (!err) { 732 while (!err) {
705 SecIdentityRef identity = NULL; 733 SecIdentityRef identity = NULL;
706 err = SecIdentitySearchCopyNext(search, &identity); 734 {
735 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
736 err = SecIdentitySearchCopyNext(search, &identity);
737 }
707 if (err) 738 if (err)
708 break; 739 break;
709 ScopedCFTypeRef<SecIdentityRef> scoped_identity(identity); 740 ScopedCFTypeRef<SecIdentityRef> scoped_identity(identity);
710 741
711 SecCertificateRef cert_handle; 742 SecCertificateRef cert_handle;
712 err = SecIdentityCopyCertificate(identity, &cert_handle); 743 err = SecIdentityCopyCertificate(identity, &cert_handle);
713 if (err != noErr) 744 if (err != noErr)
714 continue; 745 continue;
715 ScopedCFTypeRef<SecCertificateRef> scoped_cert_handle(cert_handle); 746 ScopedCFTypeRef<SecCertificateRef> scoped_cert_handle(cert_handle);
716 747
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 if (err != errSecItemNotFound) { 779 if (err != errSecItemNotFound) {
749 OSSTATUS_LOG(ERROR, err) << "SecIdentitySearch error"; 780 OSSTATUS_LOG(ERROR, err) << "SecIdentitySearch error";
750 return false; 781 return false;
751 } 782 }
752 return true; 783 return true;
753 } 784 }
754 785
755 CFArrayRef X509Certificate::CreateClientCertificateChain() const { 786 CFArrayRef X509Certificate::CreateClientCertificateChain() const {
756 // Initialize the result array with just the IdentityRef of the receiver: 787 // Initialize the result array with just the IdentityRef of the receiver:
757 SecIdentityRef identity; 788 SecIdentityRef identity;
758 OSStatus result = 789 OSStatus result;
759 SecIdentityCreateWithCertificate(NULL, cert_handle_, &identity); 790 {
791 base::AutoLock lock(crypto::GetMacSecurityServicesLock());
792 result = SecIdentityCreateWithCertificate(NULL, cert_handle_, &identity);
793 }
760 if (result) { 794 if (result) {
761 OSSTATUS_LOG(ERROR, result) << "SecIdentityCreateWithCertificate error"; 795 OSSTATUS_LOG(ERROR, result) << "SecIdentityCreateWithCertificate error";
762 return NULL; 796 return NULL;
763 } 797 }
764 ScopedCFTypeRef<CFMutableArrayRef> chain( 798 ScopedCFTypeRef<CFMutableArrayRef> chain(
765 CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)); 799 CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));
766 CFArrayAppendValue(chain, identity); 800 CFArrayAppendValue(chain, identity);
767 801
768 CFArrayRef cert_chain = NULL; 802 CFArrayRef cert_chain = NULL;
769 result = CopyCertChain(cert_handle_, &cert_chain); 803 result = CopyCertChain(cert_handle_, &cert_chain);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 *type = kPublicKeyTypeDH; 896 *type = kPublicKeyTypeDH;
863 break; 897 break;
864 default: 898 default:
865 *type = kPublicKeyTypeUnknown; 899 *type = kPublicKeyTypeUnknown;
866 *size_bits = 0; 900 *size_bits = 0;
867 break; 901 break;
868 } 902 }
869 } 903 }
870 904
871 } // namespace net 905 } // namespace net
OLDNEW
« no previous file with comments | « net/base/cert_verify_proc_mac.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698