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 #ifndef CHROME_BROWSER_SSL_SSL_CLIENT_AUTH_HANDLER_H_ 6 #define CHROME_BROWSER_SSL_SSL_CLIENT_AUTH_HANDLER_H_ 7 #pragma once 8 9 #include "base/basictypes.h" 10 #include "base/memory/ref_counted.h" 11 #include "content/browser/browser_thread.h" 12 #include "content/common/notification_observer.h" 13 #include "content/common/notification_registrar.h" 14 #include "net/base/ssl_cert_request_info.h" 15 16 namespace net { 17 class URLRequest; 18 class X509Certificate; 19 } // namespace net 20 21 // This class handles the approval and selection of a certificate for SSL client 22 // authentication by the user. 23 // It is self-owned and deletes itself when the UI reports the user selection or 24 // when the net::URLRequest is cancelled. 25 class SSLClientAuthHandler 26 : public base::RefCountedThreadSafe<SSLClientAuthHandler, 27 BrowserThread::DeleteOnIOThread> { 28 public: 29 SSLClientAuthHandler(net::URLRequest* request, 30 net::SSLCertRequestInfo* cert_request_info); 31 32 // Asks the user to select a certificate and resumes the URL request with that 33 // certificate. 34 // Should only be called on the IO thread. 35 void SelectCertificate(); 36 37 // Invoked when the request associated with this handler is cancelled. 38 // Should only be called on the IO thread. 39 void OnRequestCancelled(); 40 41 // Calls DoCertificateSelected on the I/O thread. 42 // Called on the UI thread after the user has made a selection (which may 43 // be long after DoSelectCertificate returns, if the UI is modeless/async.) 44 void CertificateSelected(net::X509Certificate* cert); 45 46 // Like CertificateSelected, but does not send SSL_CLIENT_AUTH_CERT_SELECTED 47 // notification. Used to avoid notification re-spamming when other 48 // certificate selectors act on a notification matching the same host. 49 void CertificateSelectedNoNotify(net::X509Certificate* cert); 50 51 // Returns the SSLCertRequestInfo for this handler. cert_request_info()52 net::SSLCertRequestInfo* cert_request_info() { return cert_request_info_; } 53 54 private: 55 friend class BrowserThread; 56 friend class DeleteTask<SSLClientAuthHandler>; 57 58 virtual ~SSLClientAuthHandler(); 59 60 // Notifies that the user has selected a cert. 61 // Called on the IO thread. 62 void DoCertificateSelected(net::X509Certificate* cert); 63 64 // The net::URLRequest that triggered this client auth. 65 net::URLRequest* request_; 66 67 // The certs to choose from. 68 scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; 69 70 DISALLOW_COPY_AND_ASSIGN(SSLClientAuthHandler); 71 }; 72 73 class SSLClientAuthObserver : public NotificationObserver { 74 public: 75 SSLClientAuthObserver(net::SSLCertRequestInfo* cert_request_info, 76 SSLClientAuthHandler* handler); 77 virtual ~SSLClientAuthObserver(); 78 79 // UI should implement this to close the dialog. 80 virtual void OnCertSelectedByNotification() = 0; 81 82 // NotificationObserver implementation: 83 virtual void Observe(NotificationType type, 84 const NotificationSource& source, 85 const NotificationDetails& details); 86 87 // Begins observing notifications from other SSLClientAuthHandler instances. 88 // If another instance chooses a cert for a matching SSLCertRequestInfo, we 89 // will also use the same cert and OnCertSelectedByNotification will be called 90 // so that the cert selection UI can be closed. 91 void StartObserving(); 92 93 // Stops observing notifications. We will no longer act on client auth 94 // notifications. 95 void StopObserving(); 96 97 private: 98 scoped_refptr<net::SSLCertRequestInfo> cert_request_info_; 99 100 scoped_refptr<SSLClientAuthHandler> handler_; 101 102 NotificationRegistrar notification_registrar_; 103 104 DISALLOW_COPY_AND_ASSIGN(SSLClientAuthObserver); 105 }; 106 107 #endif // CHROME_BROWSER_SSL_SSL_CLIENT_AUTH_HANDLER_H_ 108