15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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/ssl/ssl_client_auth_observer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/x509_certificate.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_cert_request_info.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::pair<net::SSLCertRequestInfo*, net::X509Certificate*> CertDetails; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLClientAuthObserver::SSLClientAuthObserver( 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::HttpNetworkSession* network_session, 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<net::SSLCertRequestInfo>& cert_request_info, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<void(net::X509Certificate*)>& callback) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : network_session_(network_session), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cert_request_info_(cert_request_info), 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_(callback) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SSLClientAuthObserver::~SSLClientAuthObserver() { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientAuthObserver::CertificateSelected( 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::X509Certificate* certificate) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (callback_.is_null()) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop listening right away so we don't get our own notification. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopObserving(); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CertDetails details; 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) details.first = cert_request_info_.get(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details.second = certificate; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService* service = 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service->Notify(chrome::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<net::HttpNetworkSession>(network_session_), 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<CertDetails>(&details)); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(certificate); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Reset(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientAuthObserver::Observe( 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "SSLClientAuthObserver::Observe " << this; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(type == chrome::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CertDetails* cert_details = content::Details<CertDetails>(details).ptr(); 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!cert_details->first->host_and_port.Equals( 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cert_request_info_->host_and_port)) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << this << " got matching notification and selecting cert " 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << cert_details->second; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopObserving(); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(cert_details->second); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Reset(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCertSelectedByNotification(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientAuthObserver::StartObserving() { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.Add( 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, chrome::NOTIFICATION_SSL_CLIENT_AUTH_CERT_SELECTED, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<net::HttpNetworkSession>(network_session_)); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SSLClientAuthObserver::StopObserving() { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.RemoveAll(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 86