1 // Copyright 2013 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/crypto_module_delegate_nss.h" 6 7 #include "base/basictypes.h" 8 #include "base/bind.h" 9 #include "chrome/browser/net/nss_context.h" 10 #include "content/public/browser/browser_thread.h" 11 12 using content::BrowserThread; 13 14 ChromeNSSCryptoModuleDelegate::ChromeNSSCryptoModuleDelegate( 15 chrome::CryptoModulePasswordReason reason, 16 const std::string& server) 17 : reason_(reason), 18 server_(server), 19 event_(false, false), 20 cancelled_(false) {} 21 22 ChromeNSSCryptoModuleDelegate::~ChromeNSSCryptoModuleDelegate() {} 23 24 bool ChromeNSSCryptoModuleDelegate::InitializeSlot( 25 content::ResourceContext* context, 26 const base::Closure& initialization_complete_callback) { 27 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 28 base::Callback<void(crypto::ScopedPK11Slot)> get_slot_callback; 29 if (!initialization_complete_callback.is_null()) 30 get_slot_callback = base::Bind(&ChromeNSSCryptoModuleDelegate::DidGetSlot, 31 // Caller is responsible for keeping |this| 32 // alive until the callback is run. 33 base::Unretained(this), 34 initialization_complete_callback); 35 36 slot_ = GetPrivateNSSKeySlotForResourceContext(context, get_slot_callback); 37 return slot_.get() != NULL; 38 } 39 40 // TODO(mattm): allow choosing which slot to generate and store the key. 41 crypto::ScopedPK11Slot ChromeNSSCryptoModuleDelegate::RequestSlot() { 42 return slot_.Pass(); 43 } 44 45 std::string ChromeNSSCryptoModuleDelegate::RequestPassword( 46 const std::string& slot_name, 47 bool retry, 48 bool* cancelled) { 49 DCHECK(!event_.IsSignaled()); 50 event_.Reset(); 51 52 if (BrowserThread::PostTask( 53 BrowserThread::UI, 54 FROM_HERE, 55 base::Bind(&ChromeNSSCryptoModuleDelegate::ShowDialog, 56 // This method blocks on |event_| until the task completes, 57 // so there's no need to ref-count. 58 base::Unretained(this), 59 slot_name, 60 retry))) { 61 event_.Wait(); 62 } 63 *cancelled = cancelled_; 64 return password_; 65 } 66 67 void ChromeNSSCryptoModuleDelegate::ShowDialog(const std::string& slot_name, 68 bool retry) { 69 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 70 ShowCryptoModulePasswordDialog( 71 slot_name, 72 retry, 73 reason_, 74 server_, 75 NULL, // TODO(mattm): Supply parent window. 76 base::Bind(&ChromeNSSCryptoModuleDelegate::GotPassword, 77 // RequestPassword is blocked on |event_| until GotPassword is 78 // called, so there's no need to ref-count. 79 base::Unretained(this))); 80 } 81 82 void ChromeNSSCryptoModuleDelegate::GotPassword(const std::string& password) { 83 if (!password.empty()) 84 password_ = password; 85 else 86 cancelled_ = true; 87 event_.Signal(); 88 } 89 90 void ChromeNSSCryptoModuleDelegate::DidGetSlot(const base::Closure& callback, 91 crypto::ScopedPK11Slot slot) { 92 slot_ = slot.Pass(); 93 callback.Run(); 94 } 95 96 crypto::CryptoModuleBlockingPasswordDelegate* 97 CreateCryptoModuleBlockingPasswordDelegate( 98 chrome::CryptoModulePasswordReason reason, 99 const std::string& server) { 100 // Returns a ChromeNSSCryptoModuleDelegate without calling InitializeSlot. 101 // Since it is only being used as a CreateCryptoModuleBlockingDialogDelegate, 102 // initializing the slot handle is unnecessary. 103 return new ChromeNSSCryptoModuleDelegate(reason, server); 104 } 105