OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/base/test_root_certs.h" | |
6 | |
7 #include <Security/Security.h> | |
8 | |
9 #include "base/logging.h" | |
10 #include "base/mac/scoped_cftyperef.h" | |
11 #include "net/base/x509_certificate.h" | |
12 | |
13 namespace net { | |
14 | |
15 namespace { | |
16 | |
17 #if !defined(MAC_OS_X_VERSION_10_6) || \ | |
18 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 | |
19 // Declared in <Security/SecBase.h> of the 10.6 SDK. | |
20 enum { | |
21 errSecUnimplemented = -4, | |
22 }; | |
23 #endif | |
24 | |
25 typedef OSStatus (*SecTrustSetAnchorCertificatesOnlyFuncPtr)(SecTrustRef, | |
26 Boolean); | |
27 | |
28 Boolean OurSecCertificateEqual(const void* value1, const void* value2) { | |
29 if (CFGetTypeID(value1) != SecCertificateGetTypeID() || | |
30 CFGetTypeID(value2) != SecCertificateGetTypeID()) | |
31 return CFEqual(value1, value2); | |
32 return X509Certificate::IsSameOSCert( | |
33 reinterpret_cast<SecCertificateRef>(const_cast<void*>(value1)), | |
34 reinterpret_cast<SecCertificateRef>(const_cast<void*>(value2))); | |
35 } | |
36 | |
37 const void* RetainWrapper(CFAllocatorRef unused, const void* value) { | |
38 return CFRetain(value); | |
39 } | |
40 | |
41 void ReleaseWrapper(CFAllocatorRef unused, const void* value) { | |
42 CFRelease(value); | |
43 } | |
44 | |
45 // CFEqual prior to 10.6 only performed pointer checks on SecCertificateRefs, | |
46 // rather than checking if they were the same (logical) certificate, so a | |
47 // custom structure is used for the array callbacks. | |
48 const CFArrayCallBacks kCertArrayCallbacks = { | |
49 0, // version | |
50 RetainWrapper, | |
51 ReleaseWrapper, | |
52 CFCopyDescription, | |
53 OurSecCertificateEqual | |
bulach
2010/11/17 17:17:30
append ,
| |
54 }; | |
55 | |
56 } // namespace | |
57 | |
58 bool TestRootCerts::Add(X509Certificate* certificate) { | |
59 if (CFArrayContainsValue(temporary_roots_, | |
60 CFRangeMake(0, CFArrayGetCount(temporary_roots_)), | |
61 certificate->os_cert_handle())) | |
62 return true; | |
63 CFArrayAppendValue(temporary_roots_, certificate->os_cert_handle()); | |
64 return true; | |
65 } | |
66 | |
67 void TestRootCerts::Clear() { | |
68 CFArrayRemoveAllValues(temporary_roots_); | |
69 } | |
70 | |
71 bool TestRootCerts::IsEmpty() const { | |
72 return CFArrayGetCount(temporary_roots_) == 0; | |
73 } | |
74 | |
75 OSStatus TestRootCerts::SetAnchorCertificates(SecTrustRef trust_ref) const { | |
76 if (IsEmpty()) | |
77 return noErr; | |
78 | |
79 CFBundleRef bundle = | |
80 CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security")); | |
81 SecTrustSetAnchorCertificatesOnlyFuncPtr set_anchor_certificates_only = NULL; | |
82 if (bundle) { | |
83 set_anchor_certificates_only = | |
84 reinterpret_cast<SecTrustSetAnchorCertificatesOnlyFuncPtr>( | |
85 CFBundleGetFunctionPointerForName(bundle, | |
86 CFSTR("SecTrustSetAnchorCertificatesOnly"))); | |
87 } | |
88 | |
89 OSStatus status = noErr; | |
90 if (set_anchor_certificates_only) { | |
91 // OS X 10.6 includes a function where the system trusts can be | |
92 // preserved while appending application trusts. This is preferable, | |
93 // because it preserves any user trust settings (explicit distrust), | |
94 // which the naive copy in 10.5 does not. Unfortunately, though the | |
95 // function pointer may be available, it is not always implemented. If it | |
96 // returns errSecUnimplemented, fall through to the 10.5 behaviour. | |
97 status = SecTrustSetAnchorCertificates(trust_ref, temporary_roots_); | |
98 if (status) | |
99 return status; | |
100 status = set_anchor_certificates_only(trust_ref, false); | |
101 if (status != errSecUnimplemented) | |
102 return status; | |
103 | |
104 // Restore the original settings before falling back. | |
105 status = SecTrustSetAnchorCertificates(trust_ref, NULL); | |
106 if (status) | |
107 return status; | |
108 } | |
109 | |
110 // On 10.5, the system certificates have to be copied and merged into | |
111 // the application trusts, and may override any user trust settings. | |
112 CFArrayRef system_roots = NULL; | |
113 status = SecTrustCopyAnchorCertificates(&system_roots); | |
114 if (status) | |
115 return status; | |
116 | |
117 base::mac::ScopedCFTypeRef<CFArrayRef> scoped_system_roots(system_roots); | |
118 base::mac::ScopedCFTypeRef<CFMutableArrayRef> scoped_roots( | |
119 CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, | |
120 scoped_system_roots)); | |
121 DCHECK(scoped_roots.get()); | |
122 | |
123 CFArrayAppendArray(scoped_roots, temporary_roots_, | |
124 CFRangeMake(0, CFArrayGetCount(temporary_roots_))); | |
125 return SecTrustSetAnchorCertificates(trust_ref, scoped_roots); | |
126 } | |
127 | |
128 TestRootCerts::TestRootCerts() { | |
129 temporary_roots_.reset(CFArrayCreateMutable(kCFAllocatorDefault, 0, | |
130 &kCertArrayCallbacks)); | |
131 } | |
132 | |
133 TestRootCerts::~TestRootCerts() { | |
134 } | |
135 | |
136 } // namespace net | |
OLD | NEW |