15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/certificate_viewer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cryptuiapi.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma comment(lib, "cryptui.lib") 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/message_loop/message_loop.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/x509_certificate.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_AURA) 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/root_window.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShowCertificateViewerImpl(content::WebContents* web_contents, 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HWND parent, 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::X509Certificate* cert) { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a new cert context and store containing just the certificate 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and its intermediate certificates. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PCCERT_CONTEXT cert_list = cert->CreateOSCertChainForCert(); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(cert_list); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CRYPTUI_VIEWCERTIFICATE_STRUCT view_info = { 0 }; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_info.dwSize = sizeof(view_info); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We set our parent to the tab window. This makes the cert dialog created 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in CryptUIDlgViewCertificate modal to the browser. 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_info.hwndParent = parent; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_info.dwFlags = CRYPTUI_DISABLE_EDITPROPERTIES | 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CRYPTUI_DISABLE_ADDTOSTORE; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_info.pCertContext = cert_list; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HCERTSTORE cert_store = cert_list->hCertStore; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_info.cStores = 1; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) view_info.rghStores = &cert_store; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BOOL properties_changed; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // We must allow nested tasks to dispatch so that, e.g. gpu tasks are 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // processed for painting. This allows a second window to continue painting 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // while the the certificate dialog is open. 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::MessageLoop::ScopedNestableTaskAllower allow( 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::MessageLoop::current()); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This next call blocks but keeps processing windows messages, making it 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // modal to the browser window. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BOOL rv = ::CryptUIDlgViewCertificate(&view_info, &properties_changed); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CertFreeCertificateContext(cert_list); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_AURA) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShowCertificateViewer(content::WebContents* web_contents, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::NativeWindow parent, 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::X509Certificate* cert) { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (chrome::GetHostDesktopTypeForNativeWindow(parent) != 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HOST_DESKTOP_TYPE_ASH) { 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShowCertificateViewerImpl( 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) web_contents, 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) parent->GetDispatcher()->host()->GetAcceleratedWidget(), cert); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTIMPLEMENTED(); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ShowCertificateViewer(content::WebContents* web_contents, 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::NativeWindow parent, 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::X509Certificate* cert) { 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShowCertificateViewerImpl(web_contents, parent, cert); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 78