1 // Copyright (c) 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.
5 #include "chrome/browser/net/nss_context.h"
7 #include "base/memory/weak_ptr.h"
8 #include "base/supports_user_data.h"
9 #include "chrome/browser/profiles/profile_io_data.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "crypto/nss_util_internal.h"
12 #include "net/cert/nss_cert_database_chromeos.h"
16 void* kDatabaseManagerKey
= &kDatabaseManagerKey
;
18 class NSSCertDatabaseChromeOSManager
: public base::SupportsUserData::Data
{
20 typedef base::Callback
<void(net::NSSCertDatabaseChromeOS
*)>
21 GetNSSCertDatabaseCallback
;
22 explicit NSSCertDatabaseChromeOSManager(const std::string
& username_hash
)
23 : username_hash_(username_hash
), weak_ptr_factory_(this) {
24 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
25 crypto::ScopedPK11Slot
private_slot(crypto::GetPrivateSlotForChromeOSUser(
27 base::Bind(&NSSCertDatabaseChromeOSManager::DidGetPrivateSlot
,
28 weak_ptr_factory_
.GetWeakPtr())));
30 DidGetPrivateSlot(private_slot
.Pass());
33 ~NSSCertDatabaseChromeOSManager() override
{
34 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
37 net::NSSCertDatabaseChromeOS
* GetNSSCertDatabase(
38 const GetNSSCertDatabaseCallback
& callback
) {
39 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
41 if (nss_cert_database_
)
42 return nss_cert_database_
.get();
44 ready_callback_list_
.push_back(callback
);
49 typedef std::vector
<GetNSSCertDatabaseCallback
> ReadyCallbackList
;
51 void DidGetPrivateSlot(crypto::ScopedPK11Slot private_slot
) {
52 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
53 nss_cert_database_
.reset(new net::NSSCertDatabaseChromeOS(
54 crypto::GetPublicSlotForChromeOSUser(username_hash_
),
55 private_slot
.Pass()));
57 ReadyCallbackList callback_list
;
58 callback_list
.swap(ready_callback_list_
);
59 for (ReadyCallbackList::iterator i
= callback_list
.begin();
60 i
!= callback_list
.end();
62 (*i
).Run(nss_cert_database_
.get());
66 std::string username_hash_
;
67 scoped_ptr
<net::NSSCertDatabaseChromeOS
> nss_cert_database_
;
68 ReadyCallbackList ready_callback_list_
;
69 base::WeakPtrFactory
<NSSCertDatabaseChromeOSManager
> weak_ptr_factory_
;
71 DISALLOW_COPY_AND_ASSIGN(NSSCertDatabaseChromeOSManager
);
74 std::string
GetUsername(content::ResourceContext
* context
) {
75 return ProfileIOData::FromResourceContext(context
)->username_hash();
78 net::NSSCertDatabaseChromeOS
* GetNSSCertDatabaseChromeOS(
79 content::ResourceContext
* context
,
80 const NSSCertDatabaseChromeOSManager::GetNSSCertDatabaseCallback
&
82 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
83 NSSCertDatabaseChromeOSManager
* manager
=
84 static_cast<NSSCertDatabaseChromeOSManager
*>(
85 context
->GetUserData(kDatabaseManagerKey
));
87 manager
= new NSSCertDatabaseChromeOSManager(GetUsername(context
));
88 context
->SetUserData(kDatabaseManagerKey
, manager
);
90 return manager
->GetNSSCertDatabase(callback
);
93 void CallWithNSSCertDatabase(
94 const base::Callback
<void(net::NSSCertDatabase
*)>& callback
,
95 net::NSSCertDatabaseChromeOS
* db
) {
99 void SetSystemSlot(crypto::ScopedPK11Slot system_slot
,
100 net::NSSCertDatabaseChromeOS
* db
) {
101 db
->SetSystemSlot(system_slot
.Pass());
104 void SetSystemSlotOfDBForResourceContext(content::ResourceContext
* context
,
105 crypto::ScopedPK11Slot system_slot
) {
106 base::Callback
<void(net::NSSCertDatabaseChromeOS
*)> callback
=
107 base::Bind(&SetSystemSlot
, base::Passed(&system_slot
));
109 net::NSSCertDatabaseChromeOS
* db
=
110 GetNSSCertDatabaseChromeOS(context
, callback
);
117 crypto::ScopedPK11Slot
GetPublicNSSKeySlotForResourceContext(
118 content::ResourceContext
* context
) {
119 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
120 return crypto::GetPublicSlotForChromeOSUser(GetUsername(context
));
123 crypto::ScopedPK11Slot
GetPrivateNSSKeySlotForResourceContext(
124 content::ResourceContext
* context
,
125 const base::Callback
<void(crypto::ScopedPK11Slot
)>& callback
) {
126 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
127 return crypto::GetPrivateSlotForChromeOSUser(GetUsername(context
), callback
);
130 net::NSSCertDatabase
* GetNSSCertDatabaseForResourceContext(
131 content::ResourceContext
* context
,
132 const base::Callback
<void(net::NSSCertDatabase
*)>& callback
) {
133 return GetNSSCertDatabaseChromeOS(
134 context
, base::Bind(&CallWithNSSCertDatabase
, callback
));
137 void EnableNSSSystemKeySlotForResourceContext(
138 content::ResourceContext
* context
) {
139 DCHECK_CURRENTLY_ON(content::BrowserThread::IO
);
140 base::Callback
<void(crypto::ScopedPK11Slot
)> callback
=
141 base::Bind(&SetSystemSlotOfDBForResourceContext
, context
);
142 crypto::ScopedPK11Slot system_slot
= crypto::GetSystemNSSKeySlot(callback
);
144 callback
.Run(system_slot
.Pass());