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