crypto_module_delegate_nss.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/crypto_module_delegate_nss.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/basictypes.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/net/nss_context.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using content::BrowserThread; 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ChromeNSSCryptoModuleDelegate::ChromeNSSCryptoModuleDelegate( 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::CryptoModulePasswordReason reason, 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const net::HostPortPair& server) 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : reason_(reason), 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) server_(server), 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event_(false, false), 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cancelled_(false) {} 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ChromeNSSCryptoModuleDelegate::~ChromeNSSCryptoModuleDelegate() {} 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ChromeNSSCryptoModuleDelegate::InitializeSlot( 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) content::ResourceContext* context, 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Closure& initialization_complete_callback) { 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!slot_); 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Callback<void(crypto::ScopedPK11Slot)> get_slot_callback; 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!initialization_complete_callback.is_null()) 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) get_slot_callback = base::Bind(&ChromeNSSCryptoModuleDelegate::DidGetSlot, 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Caller is responsible for keeping |this| 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // alive until the callback is run. 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this), 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) initialization_complete_callback); 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) slot_ = GetPrivateNSSKeySlotForResourceContext(context, get_slot_callback); 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return slot_.get() != NULL; 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(mattm): allow choosing which slot to generate and store the key. 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)crypto::ScopedPK11Slot ChromeNSSCryptoModuleDelegate::RequestSlot() { 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return slot_.Pass(); 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string ChromeNSSCryptoModuleDelegate::RequestPassword( 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& slot_name, 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool retry, 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool* cancelled) { 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!event_.IsSignaled()); 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event_.Reset(); 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (BrowserThread::PostTask( 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::UI, 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&ChromeNSSCryptoModuleDelegate::ShowDialog, 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This method blocks on |event_| until the task completes, 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // so there's no need to ref-count. 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this), 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) slot_name, 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) retry))) { 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event_.Wait(); 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *cancelled = cancelled_; 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return password_; 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeNSSCryptoModuleDelegate::ShowDialog(const std::string& slot_name, 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool retry) { 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShowCryptoModulePasswordDialog( 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) slot_name, 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) retry, 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) reason_, 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) server_.host(), 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NULL, // TODO(mattm): Supply parent window. 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&ChromeNSSCryptoModuleDelegate::GotPassword, 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // RequestPassword is blocked on |event_| until GotPassword is 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // called, so there's no need to ref-count. 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this))); 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeNSSCryptoModuleDelegate::GotPassword(const std::string& password) { 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!password.empty()) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) password_ = password; 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cancelled_ = true; 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event_.Signal(); 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ChromeNSSCryptoModuleDelegate::DidGetSlot(const base::Closure& callback, 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crypto::ScopedPK11Slot slot) { 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!slot_); 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) slot_ = slot.Pass(); 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback.Run(); 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)crypto::CryptoModuleBlockingPasswordDelegate* 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CreateCryptoModuleBlockingPasswordDelegate( 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) chrome::CryptoModulePasswordReason reason, 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const net::HostPortPair& server) { 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Returns a ChromeNSSCryptoModuleDelegate without calling InitializeSlot. 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Since it is only being used as a CreateCryptoModuleBlockingDialogDelegate, 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // initializing the slot handle is unnecessary. 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return new ChromeNSSCryptoModuleDelegate(reason, server); 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 107