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/ssl_client_certificate_selector.h"
      6 
      7 #include <windows.h>
      8 #include <cryptuiapi.h>
      9 #pragma comment(lib, "cryptui.lib")
     10 
     11 #include "base/string_util.h"
     12 #include "base/utf_string_conversions.h"
     13 #include "chrome/browser/ssl/ssl_client_auth_handler.h"
     14 #include "chrome/browser/ui/browser_list.h"
     15 #include "chrome/browser/ui/browser_window.h"
     16 #include "content/browser/tab_contents/tab_contents.h"
     17 #include "grit/generated_resources.h"
     18 #include "net/url_request/url_request.h"
     19 #include "ui/base/l10n/l10n_util.h"
     20 
     21 namespace browser {
     22 
     23 void ShowSSLClientCertificateSelector(
     24     TabContents* parent,
     25     net::SSLCertRequestInfo* cert_request_info,
     26     SSLClientAuthHandler* delegate) {
     27   // TODO(jcampan): replace this with our own cert selection dialog.
     28   // CryptUIDlgSelectCertificateFromStore is blocking (but still processes
     29   // Windows messages), which is scary.
     30   //
     31   // TODO(davidben): Make this dialog tab-modal to the
     32   // TabContents. This depends on the above TODO.
     33   HCERTSTORE client_certs = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL,
     34                                           0, NULL);
     35   BOOL ok;
     36   for (size_t i = 0; i < cert_request_info->client_certs.size(); ++i) {
     37     PCCERT_CONTEXT cc = cert_request_info->client_certs[i]->os_cert_handle();
     38     ok = CertAddCertificateContextToStore(client_certs, cc,
     39                                           CERT_STORE_ADD_ALWAYS, NULL);
     40     DCHECK(ok);
     41   }
     42 
     43   std::wstring title =
     44       UTF16ToWide(l10n_util::GetStringUTF16(IDS_CLIENT_CERT_DIALOG_TITLE));
     45   std::wstring text = UTF16ToWide(l10n_util::GetStringFUTF16(
     46       IDS_CLIENT_CERT_DIALOG_TEXT,
     47       ASCIIToUTF16(cert_request_info->host_and_port)));
     48   PCCERT_CONTEXT cert_context = CryptUIDlgSelectCertificateFromStore(
     49       client_certs, parent->GetMessageBoxRootWindow(),
     50       title.c_str(), text.c_str(), 0, 0, NULL);
     51 
     52   net::X509Certificate* cert = NULL;
     53   if (cert_context) {
     54     for (size_t i = 0; i < cert_request_info->client_certs.size(); ++i) {
     55       net::X509Certificate* client_cert = cert_request_info->client_certs[i];
     56       if (net::X509Certificate::IsSameOSCert(cert_context,
     57                                              client_cert->os_cert_handle())) {
     58         cert = client_cert;
     59         break;
     60       }
     61     }
     62     DCHECK(cert != NULL);
     63     net::X509Certificate::FreeOSCertHandle(cert_context);
     64   }
     65 
     66   ok = CertCloseStore(client_certs, CERT_CLOSE_STORE_CHECK_FLAG);
     67   DCHECK(ok);
     68 
     69   delegate->CertificateSelected(cert);
     70 }
     71 
     72 }  // namespace browser
     73