Home | History | Annotate | Download | only in views
      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