1 // Copyright (c) 2012 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.
5 #include "chrome/browser/ssl/ssl_add_cert_handler.h"
8 #include "chrome/browser/ssl/ssl_tab_helper.h"
9 #include "chrome/browser/tab_contents/tab_util.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/resource_request_info.h"
12 #include "content/public/browser/web_contents.h"
13 #include "net/base/net_errors.h"
14 #include "net/cert/cert_database.h"
15 #include "net/cert/x509_certificate.h"
16 #include "net/url_request/url_request.h"
18 using content::BrowserThread
;
19 using content::WebContents
;
21 SSLAddCertHandler::SSLAddCertHandler(net::URLRequest
* request
,
22 net::X509Certificate
* cert
,
23 int render_process_host_id
,
26 render_process_host_id_(render_process_host_id
),
27 render_view_id_(render_view_id
) {
29 = content::ResourceRequestInfo::ForRequest(request
)->GetRequestID();
30 // Stay alive until the process completes and Finished() is called.
32 // Delay adding the certificate until the next mainloop iteration.
33 BrowserThread::PostTask(
34 BrowserThread::IO
, FROM_HERE
,
35 base::Bind(&SSLAddCertHandler::Run
, this));
38 SSLAddCertHandler::~SSLAddCertHandler() {}
40 void SSLAddCertHandler::Run() {
41 int cert_error
= net::CertDatabase::GetInstance()->CheckUserCert(cert_
.get());
42 if (cert_error
!= net::OK
) {
43 LOG_IF(ERROR
, cert_error
== net::ERR_NO_PRIVATE_KEY_FOR_CERT
)
44 << "No corresponding private key in store for cert: "
45 << (cert_
.get() ? cert_
->subject().GetDisplayName() : "NULL");
47 BrowserThread::PostTask(
48 BrowserThread::UI
, FROM_HERE
,
50 &SSLAddCertHandler::CallVerifyClientCertificateError
, this,
55 // TODO(davidben): Move the existing certificate dialog elsewhere, make
56 // AskToAddCert send a message to the RenderViewHostDelegate, and ask when we
57 // cannot completely verify the certificate for whatever reason.
63 #if !defined(OS_MACOSX)
64 void SSLAddCertHandler::AskToAddCert() {
65 // TODO(snej): Someone should add Windows and GTK implementations with UI.
70 void SSLAddCertHandler::Finished(bool add_cert
) {
71 int cert_error
= net::OK
;
73 cert_error
= net::CertDatabase::GetInstance()->AddUserCert(cert_
.get());
75 BrowserThread::PostTask(
76 BrowserThread::UI
, FROM_HERE
,
78 &SSLAddCertHandler::CallAddClientCertificate
, this,
79 add_cert
, cert_error
));
84 void SSLAddCertHandler::CallVerifyClientCertificateError(int cert_error
) {
85 WebContents
* tab
= tab_util::GetWebContentsByID(
86 render_process_host_id_
, render_view_id_
);
90 SSLTabHelper
* ssl_tab_helper
= SSLTabHelper::FromWebContents(tab
);
91 ssl_tab_helper
->OnVerifyClientCertificateError(this, cert_error
);
94 void SSLAddCertHandler::CallAddClientCertificate(bool add_cert
,
96 WebContents
* tab
= tab_util::GetWebContentsByID(
97 render_process_host_id_
, render_view_id_
);
101 SSLTabHelper
* ssl_tab_helper
= SSLTabHelper::FromWebContents(tab
);
103 if (cert_error
== net::OK
) {
104 ssl_tab_helper
->OnAddClientCertificateSuccess(this);
106 ssl_tab_helper
->OnAddClientCertificateError(this, cert_error
);
109 ssl_tab_helper
->OnAddClientCertificateFinished(this);