Index: chrome/browser/ui/cocoa/certificate_viewer.mm |
diff --git a/chrome/browser/ui/cocoa/certificate_viewer.mm b/chrome/browser/ui/cocoa/certificate_viewer.mm |
index 8c5a9545dc075aafb18db35b6cb6b71d41e1f9dc..918835378e6fa021881701b553fe7bf229fb76f5 100644 |
--- a/chrome/browser/ui/cocoa/certificate_viewer.mm |
+++ b/chrome/browser/ui/cocoa/certificate_viewer.mm |
@@ -34,12 +34,50 @@ void ShowCertificateViewer(gfx::NativeWindow parent, |
for (size_t i = 0; i < ca_certs.size(); ++i) |
CFArrayAppendValue(certificates, ca_certs[i]); |
- [[[SFCertificatePanel alloc] init] |
- beginSheetForWindow:parent |
- modalDelegate:nil |
- didEndSelector:NULL |
- contextInfo:NULL |
- certificates:reinterpret_cast<NSArray*>(certificates.get()) |
- showGroup:YES]; |
+ // Explicitly disable revocation checking, regardless of user preferences |
+ // or system settings. The behaviour of SFCertificatePanel is to call |
+ // SecTrustEvaluate on the certificate(s) supplied, effectively |
+ // duplicating the behaviour of net::X509Certificate::Verify(). However, |
+ // this call stalls the UI if revocation checking is enabled in the |
+ // Keychain preferences or if the cert may be an EV cert. By disabling |
+ // revocation checking, the stall is limited to the time taken for path |
+ // building and verification, which should be minimized due to the path |
+ // being provided in |certificates|. This does not affect normal |
+ // revocation checking from happening, which is controlled by |
+ // net::X509Certificate::Verify() and user preferences, but will prevent |
+ // the certificate viewer UI from displaying which certificate is revoked. |
+ // This is acceptable, as certificate revocation will still be shown in |
+ // the page info bubble if a certificate in the chain is actually revoked. |
+ base::mac::ScopedCFTypeRef<CFMutableArrayRef> policies( |
+ CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); |
+ if (!policies.get()) { |
+ NOTREACHED(); |
+ return; |
+ } |
+ // Add a basic X.509 policy, in order to match the behaviour of |
+ // SFCertificatePanel when no policies are specified. |
+ SecPolicyRef basic_policy = NULL; |
+ OSStatus status = net::X509Certificate::CreateBasicX509Policy(&basic_policy); |
+ if (status != noErr) { |
+ NOTREACHED(); |
+ return; |
+ } |
+ CFArrayAppendValue(policies, basic_policy); |
+ CFRelease(basic_policy); |
+ |
+ status = net::X509Certificate::CreateRevocationPolicies(false, policies); |
+ if (status != noErr) { |
+ NOTREACHED(); |
+ return; |
+ } |
+ |
+ SFCertificatePanel* panel = [[SFCertificatePanel alloc] init]; |
+ [panel setPolicies:(id)policies.get()]; |
+ [panel beginSheetForWindow:parent |
+ modalDelegate:nil |
+ didEndSelector:NULL |
+ contextInfo:NULL |
+ certificates:reinterpret_cast<NSArray*>(certificates.get()) |
+ showGroup:YES]; |
// The SFCertificatePanel releases itself when the sheet is dismissed. |
} |