Index: net/base/x509_certificate_mac.cc |
diff --git a/net/base/x509_certificate_mac.cc b/net/base/x509_certificate_mac.cc |
index a2a0eeaa676b1b43c254185c83c64f87563ed076..744cec7d5f70ef0f6ebdec000f7aedf625409389 100644 |
--- a/net/base/x509_certificate_mac.cc |
+++ b/net/base/x509_certificate_mac.cc |
@@ -15,72 +15,19 @@ |
#include "net/base/cert_status_flags.h" |
#include "net/base/cert_verify_result.h" |
#include "net/base/net_errors.h" |
+#include "net/base/temporary_root_certs.h" |
using base::mac::ScopedCFTypeRef; |
using base::Time; |
namespace net { |
-class MacTrustedCertificates { |
- public: |
- // Sets the trusted root certificate used by tests. Call with |cert| set |
- // to NULL to clear the test certificate. |
- void SetTestCertificate(X509Certificate* cert) { |
- AutoLock lock(lock_); |
- test_certificate_ = cert; |
- } |
- |
- // Returns an array containing the trusted certificates for use with |
- // SecTrustSetAnchorCertificates(). Returns NULL if the system-supplied |
- // list of trust anchors is acceptable (that is, there is not test |
- // certificate available). Ownership follows the Create Rule (caller |
- // is responsible for calling CFRelease on the non-NULL result). |
- CFArrayRef CopyTrustedCertificateArray() { |
- AutoLock lock(lock_); |
- |
- if (!test_certificate_) |
- return NULL; |
- |
- // Failure to copy the anchor certificates or add the test certificate |
- // is non-fatal; SecTrustEvaluate() will use the system anchors instead. |
- CFArrayRef anchor_array; |
- OSStatus status = SecTrustCopyAnchorCertificates(&anchor_array); |
- if (status) |
- return NULL; |
- ScopedCFTypeRef<CFArrayRef> scoped_anchor_array(anchor_array); |
- CFMutableArrayRef merged_array = CFArrayCreateMutableCopy( |
- kCFAllocatorDefault, 0, anchor_array); |
- if (!merged_array) |
- return NULL; |
- CFArrayAppendValue(merged_array, test_certificate_->os_cert_handle()); |
- |
- return merged_array; |
- } |
- private: |
- friend struct DefaultSingletonTraits<MacTrustedCertificates>; |
- |
- // Obtain an instance of MacTrustedCertificates via the singleton |
- // interface. |
- MacTrustedCertificates() : test_certificate_(NULL) { } |
- |
- // An X509Certificate object that may be appended to the list of |
- // system trusted anchors. |
- scoped_refptr<X509Certificate> test_certificate_; |
- |
- // The trusted cache may be accessed from multiple threads. |
- mutable Lock lock_; |
- |
- DISALLOW_COPY_AND_ASSIGN(MacTrustedCertificates); |
-}; |
- |
-void SetMacTestCertificate(X509Certificate* cert) { |
- Singleton<MacTrustedCertificates>::get()->SetTestCertificate(cert); |
-} |
- |
namespace { |
typedef OSStatus (*SecTrustCopyExtendedResultFuncPtr)(SecTrustRef, |
CFDictionaryRef*); |
+typedef OSStatus (*SecTrustSetAnchorCertificatesOnlyFuncPtr)(SecTrustRef, |
+ Boolean); |
int NetErrorFromOSStatus(OSStatus status) { |
switch (status) { |
@@ -542,15 +489,50 @@ int X509Certificate::Verify(const std::string& hostname, int flags, |
return NetErrorFromOSStatus(status); |
ScopedCFTypeRef<SecTrustRef> scoped_trust_ref(trust_ref); |
- // Set the trusted anchor certificates for the SecTrustRef by merging the |
- // system trust anchors and the test root certificate. |
- CFArrayRef anchor_array = |
- Singleton<MacTrustedCertificates>::get()->CopyTrustedCertificateArray(); |
- ScopedCFTypeRef<CFArrayRef> scoped_anchor_array(anchor_array); |
- if (anchor_array) { |
- status = SecTrustSetAnchorCertificates(trust_ref, anchor_array); |
- if (status) |
- return NetErrorFromOSStatus(status); |
+ TemporaryRootCerts* root_certs = TemporaryRootCerts::GetInstance(); |
+ if (!root_certs->IsEmpty()) { |
+ CFBundleRef bundle = |
+ CFBundleGetBundleWithIdentifier(CFSTR("com.apple.security")); |
+ SecTrustSetAnchorCertificatesOnlyFuncPtr set_anchor_certificates_only = |
+ NULL; |
+ if (bundle) |
+ set_anchor_certificates_only = |
+ reinterpret_cast<SecTrustSetAnchorCertificatesOnlyFuncPtr>( |
+ CFBundleGetFunctionPointerForName(bundle, |
+ CFSTR("SecTrustSetAnchorCertificatesOnly"))); |
+ |
+ if (set_anchor_certificates_only) { |
+ // OS X 10.6 includes a function where the system trusts can be |
+ // preserved while appending application trusts. This is preferable, |
+ // because it preserves any user trust settings (explicit distrust), |
+ // which the naive copy of 10.5 does not. |
+ status = SecTrustSetAnchorCertificates(trust_ref, |
+ root_certs->temporary_roots()); |
+ if (status) |
+ return NetErrorFromOSStatus(status); |
+ status = set_anchor_certificates_only(trust_ref, false); |
+ } else { |
+ // On 10.5, the system certificates have to be copied and merged into |
+ // the application trusts. |
+ CFArrayRef system_trusts = NULL; |
+ status = SecTrustCopyAnchorCertificates(&system_trusts); |
+ if (status) |
+ return NetErrorFromOSStatus(status); |
+ |
+ ScopedCFTypeRef<CFArrayRef> scoped_system_trusts(system_trusts); |
+ ScopedCFTypeRef<CFMutableArrayRef> scoped_trusts( |
+ CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, |
+ scoped_system_trusts)); |
+ if (!scoped_trusts) |
+ return ERR_FAILED; |
+ |
+ CFArrayAppendArray( |
+ scoped_trusts, root_certs->temporary_roots(), |
+ CFRangeMake(0, CFArrayGetCount(root_certs->temporary_roots()))); |
+ status = SecTrustSetAnchorCertificates(trust_ref, scoped_trusts); |
+ if (status) |
+ return NetErrorFromOSStatus(status); |
+ } |
bulach
2010/11/09 16:21:09
could we move 494-534 to something like
status T
|
} |
if (flags & VERIFY_REV_CHECKING_ENABLED) { |