1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/ssl/ssl_add_cert_handler.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host_delegate.h"
9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host_notification_task.h"
10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/resource_dispatcher_host.h"
11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/cert_database.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/x509_certificate.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenSSLAddCertHandler::SSLAddCertHandler(net::URLRequest* request,
183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     net::X509Certificate* cert,
193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     int render_process_host_id,
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     int render_view_id)
213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : cert_(cert),
223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      render_process_host_id_(render_process_host_id),
233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      render_view_id_(render_view_id) {
243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ResourceDispatcherHostRequestInfo* info =
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ResourceDispatcherHost::InfoForRequest(request);
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  network_request_id_ = info->request_id();
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Stay alive until the process completes and Finished() is called.
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddRef();
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Delay adding the certificate until the next mainloop iteration.
30731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::IO, FROM_HERE,
323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NewRunnableMethod(this, &SSLAddCertHandler::Run));
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickSSLAddCertHandler::~SSLAddCertHandler() {}
36731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SSLAddCertHandler::Run() {
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int cert_error;
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    net::CertDatabase db;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    cert_error = db.CheckUserCert(cert_);
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (cert_error != net::OK) {
443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    CallRenderViewHostSSLDelegate(
453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        render_process_host_id_, render_view_id_,
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        &RenderViewHostDelegate::SSL::OnVerifyClientCertificateError,
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        scoped_refptr<SSLAddCertHandler>(this), cert_error);
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Finished(false);
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // TODO(davidben): Move the existing certificate dialog elsewhere, make
523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // AskToAddCert send a message to the RenderViewHostDelegate, and ask when we
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // cannot completely verify the certificate for whatever reason.
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // AskToAddCert();
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Finished(true);
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if !defined(OS_MACOSX)
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLAddCertHandler::AskToAddCert() {
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(snej): Someone should add Windows and GTK implementations with UI.
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Finished(true);
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLAddCertHandler::Finished(bool add_cert) {
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (add_cert) {
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    net::CertDatabase db;
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int cert_error = db.AddUserCert(cert_);
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (cert_error != net::OK) {
713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      CallRenderViewHostSSLDelegate(
723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          render_process_host_id_, render_view_id_,
733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          &RenderViewHostDelegate::SSL::OnAddClientCertificateError,
743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          scoped_refptr<SSLAddCertHandler>(this), cert_error);
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    } else {
763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      CallRenderViewHostSSLDelegate(
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          render_process_host_id_, render_view_id_,
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          &RenderViewHostDelegate::SSL::OnAddClientCertificateSuccess,
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          scoped_refptr<SSLAddCertHandler>(this));
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Inform the RVH that we're finished
833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CallRenderViewHostSSLDelegate(
843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      render_process_host_id_, render_view_id_,
853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      &RenderViewHostDelegate::SSL::OnAddClientCertificateFinished,
863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      scoped_refptr<SSLAddCertHandler>(this));
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Release();
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
90