1 // Copyright (c) 2011 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 "chrome/browser/certificate_viewer.h" 6 7 #include <windows.h> 8 #include <cryptuiapi.h> 9 #pragma comment(lib, "cryptui.lib") 10 11 #include "base/logging.h" 12 #include "base/message_loop/message_loop.h" 13 #include "chrome/browser/ui/host_desktop.h" 14 #include "net/cert/x509_certificate.h" 15 #include "ui/aura/window.h" 16 #include "ui/aura/window_tree_host.h" 17 18 namespace { 19 20 void ShowCertificateViewerImpl(content::WebContents* web_contents, 21 HWND parent, 22 net::X509Certificate* cert) { 23 // Create a new cert context and store containing just the certificate 24 // and its intermediate certificates. 25 PCCERT_CONTEXT cert_list = cert->CreateOSCertChainForCert(); 26 CHECK(cert_list); 27 28 CRYPTUI_VIEWCERTIFICATE_STRUCT view_info = { 0 }; 29 view_info.dwSize = sizeof(view_info); 30 // We set our parent to the tab window. This makes the cert dialog created 31 // in CryptUIDlgViewCertificate modal to the browser. 32 view_info.hwndParent = parent; 33 view_info.dwFlags = CRYPTUI_DISABLE_EDITPROPERTIES | 34 CRYPTUI_DISABLE_ADDTOSTORE; 35 view_info.pCertContext = cert_list; 36 HCERTSTORE cert_store = cert_list->hCertStore; 37 view_info.cStores = 1; 38 view_info.rghStores = &cert_store; 39 BOOL properties_changed; 40 41 // We must allow nested tasks to dispatch so that, e.g. gpu tasks are 42 // processed for painting. This allows a second window to continue painting 43 // while the the certificate dialog is open. 44 base::MessageLoop::ScopedNestableTaskAllower allow( 45 base::MessageLoop::current()); 46 // This next call blocks but keeps processing windows messages, making it 47 // modal to the browser window. 48 BOOL rv = ::CryptUIDlgViewCertificate(&view_info, &properties_changed); 49 50 CertFreeCertificateContext(cert_list); 51 } 52 53 } // namespace 54 55 void ShowCertificateViewer(content::WebContents* web_contents, 56 gfx::NativeWindow parent, 57 net::X509Certificate* cert) { 58 if (chrome::GetHostDesktopTypeForNativeWindow(parent) != 59 chrome::HOST_DESKTOP_TYPE_ASH) { 60 ShowCertificateViewerImpl( 61 web_contents, 62 parent->GetHost()->GetAcceleratedWidget(), cert); 63 } else { 64 NOTIMPLEMENTED(); 65 } 66 } 67