OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2010 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/ui/pk11_password_dialog.h" |
| 6 |
| 7 #include <pk11pub.h> |
| 8 |
| 9 #include "base/logging.h" |
| 10 #include "chrome/browser/browser_thread.h" |
| 11 #include "net/base/crypto_module.h" |
| 12 #include "net/base/x509_certificate.h" |
| 13 |
| 14 namespace { |
| 15 |
| 16 // Basically an asynchronous implementation of NSS's PK11_DoPassword. |
| 17 // Note: This currently handles only the simple case. See the TODOs in |
| 18 // GotPassword for what is yet unimplemented. |
| 19 class SlotUnlocker { |
| 20 public: |
| 21 SlotUnlocker(net::CryptoModule* module, |
| 22 browser::PK11PasswordReason reason, |
| 23 const std::string& host, |
| 24 Callback0::Type* callback); |
| 25 |
| 26 void Start(); |
| 27 |
| 28 private: |
| 29 void GotPassword(const char* password); |
| 30 void Done(); |
| 31 |
| 32 scoped_refptr<net::CryptoModule> module_; |
| 33 browser::PK11PasswordReason reason_; |
| 34 std::string host_; |
| 35 Callback0::Type* callback_; |
| 36 PRBool retry_; |
| 37 }; |
| 38 |
| 39 SlotUnlocker::SlotUnlocker(net::CryptoModule* module, |
| 40 browser::PK11PasswordReason reason, |
| 41 const std::string& host, |
| 42 Callback0::Type* callback) |
| 43 : module_(module), |
| 44 reason_(reason), |
| 45 host_(host), |
| 46 callback_(callback), |
| 47 retry_(PR_FALSE) { |
| 48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 49 } |
| 50 |
| 51 void SlotUnlocker::Start() { |
| 52 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 53 |
| 54 ShowPK11PasswordDialog( |
| 55 module_->GetTokenName(), |
| 56 retry_, |
| 57 reason_, |
| 58 host_, |
| 59 NewCallback(this, &SlotUnlocker::GotPassword)); |
| 60 } |
| 61 |
| 62 void SlotUnlocker::GotPassword(const char* password) { |
| 63 // TODO(mattm): PK11_DoPassword has something about PK11_Global.verifyPass. |
| 64 // Do we need it? |
| 65 // http://mxr.mozilla.org/mozilla/source/security/nss/lib/pk11wrap/pk11auth.c#
577 |
| 66 |
| 67 if (!password) { |
| 68 // User cancelled entering password. Oh well. |
| 69 Done(); |
| 70 return; |
| 71 } |
| 72 |
| 73 // TODO(mattm): handle protectedAuthPath |
| 74 SECStatus rv = PK11_CheckUserPassword(module_->os_module_handle(), |
| 75 password); |
| 76 if (rv == SECWouldBlock) { |
| 77 // Incorrect password. Try again. |
| 78 retry_ = PR_TRUE; |
| 79 Start(); |
| 80 return; |
| 81 } |
| 82 |
| 83 // TODO(mattm): PK11_DoPassword calls nssTrustDomain_UpdateCachedTokenCerts on |
| 84 // non-friendly slots. How important is that? |
| 85 |
| 86 // Correct password (SECSuccess) or too many attempts/other failure |
| 87 // (SECFailure). Either way we're done. |
| 88 Done(); |
| 89 } |
| 90 |
| 91 void SlotUnlocker::Done() { |
| 92 callback_->Run(); |
| 93 delete this; |
| 94 } |
| 95 |
| 96 } // namespace |
| 97 |
| 98 namespace browser { |
| 99 |
| 100 void UnlockSlotIfNecessary(net::CryptoModule* module, |
| 101 browser::PK11PasswordReason reason, |
| 102 const std::string& host, |
| 103 Callback0::Type* callback) { |
| 104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 105 // The wincx arg is unused since we don't call PK11_SetIsLoggedInFunc. |
| 106 if (PK11_NeedLogin(module->os_module_handle()) && |
| 107 !PK11_IsLoggedIn(module->os_module_handle(), NULL /* wincx */)) { |
| 108 (new SlotUnlocker(module, reason, host, callback))->Start(); |
| 109 } else { |
| 110 callback->Run(); |
| 111 } |
| 112 } |
| 113 |
| 114 void UnlockCertSlotIfNecessary(net::X509Certificate* cert, |
| 115 browser::PK11PasswordReason reason, |
| 116 const std::string& host, |
| 117 Callback0::Type* callback) { |
| 118 scoped_refptr<net::CryptoModule> module(net::CryptoModule::CreateFromHandle( |
| 119 cert->os_cert_handle()->slot)); |
| 120 UnlockSlotIfNecessary(module.get(), reason, host, callback); |
| 121 } |
| 122 |
| 123 } // namespace browser |
OLD | NEW |