|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 #include "nsComponentManagerUtils.h" |
|
6 #include "nsCOMPtr.h" |
|
7 #include "nsKeyModule.h" |
|
8 #include "nsString.h" |
|
9 #include "ScopedNSSTypes.h" |
|
10 |
|
11 using namespace mozilla; |
|
12 using namespace mozilla::psm; |
|
13 |
|
14 NS_IMPL_ISUPPORTS(nsKeyObject, nsIKeyObject) |
|
15 |
|
16 nsKeyObject::nsKeyObject() |
|
17 : mKeyType(0), mSymKey(nullptr), mPrivateKey(nullptr), |
|
18 mPublicKey(nullptr) |
|
19 { |
|
20 } |
|
21 |
|
22 nsKeyObject::~nsKeyObject() |
|
23 { |
|
24 CleanUp(); |
|
25 } |
|
26 |
|
27 void |
|
28 nsKeyObject::CleanUp() |
|
29 { |
|
30 switch (mKeyType) { |
|
31 case nsIKeyObject::SYM_KEY: |
|
32 PK11_FreeSymKey(mSymKey); |
|
33 break; |
|
34 |
|
35 case nsIKeyObject::PRIVATE_KEY: |
|
36 PK11_DeleteTokenPrivateKey(mPrivateKey, true /* force */); |
|
37 break; |
|
38 |
|
39 case nsIKeyObject::PUBLIC_KEY: |
|
40 PK11_DeleteTokenPublicKey(mPublicKey); |
|
41 break; |
|
42 |
|
43 default: |
|
44 // probably not initialized, do nothing |
|
45 break; |
|
46 } |
|
47 mKeyType = 0; |
|
48 } |
|
49 |
|
50 ////////////////////////////////////////////////////////////////////////////// |
|
51 // nsIKeyObject |
|
52 |
|
53 /* [noscript] void initKey (in short aKeyType, in voidPtr aKey); */ |
|
54 NS_IMETHODIMP |
|
55 nsKeyObject::InitKey(int16_t aAlgorithm, void * aKey) |
|
56 { |
|
57 // Clear previous key data if it exists |
|
58 CleanUp(); |
|
59 |
|
60 switch (aAlgorithm) { |
|
61 case nsIKeyObject::RC4: |
|
62 case nsIKeyObject::HMAC: |
|
63 mSymKey = reinterpret_cast<PK11SymKey*>(aKey); |
|
64 |
|
65 if (!mSymKey) { |
|
66 NS_ERROR("no symkey"); |
|
67 break; |
|
68 } |
|
69 mKeyType = nsIKeyObject::SYM_KEY; |
|
70 break; |
|
71 |
|
72 case nsIKeyObject::AES_CBC: |
|
73 return NS_ERROR_NOT_IMPLEMENTED; |
|
74 |
|
75 default: |
|
76 return NS_ERROR_INVALID_ARG; |
|
77 } |
|
78 |
|
79 // One of these should have been created |
|
80 if (!mSymKey && !mPrivateKey && !mPublicKey) |
|
81 return NS_ERROR_FAILURE; |
|
82 |
|
83 return NS_OK; |
|
84 } |
|
85 |
|
86 /* [noscript] voidPtr getKeyObj (); */ |
|
87 NS_IMETHODIMP |
|
88 nsKeyObject::GetKeyObj(void * *_retval) |
|
89 { |
|
90 if (mKeyType == 0) |
|
91 return NS_ERROR_NOT_INITIALIZED; |
|
92 |
|
93 switch (mKeyType) { |
|
94 case nsIKeyObject::SYM_KEY: |
|
95 *_retval = (void*)mSymKey; |
|
96 break; |
|
97 |
|
98 case nsIKeyObject::PRIVATE_KEY: |
|
99 *_retval = (void*)mPublicKey; |
|
100 break; |
|
101 |
|
102 case nsIKeyObject::PUBLIC_KEY: |
|
103 *_retval = (void*)mPrivateKey; |
|
104 break; |
|
105 |
|
106 default: |
|
107 // unknown key type? How did that happen? |
|
108 return NS_ERROR_FAILURE; |
|
109 } |
|
110 return NS_OK; |
|
111 } |
|
112 |
|
113 /* short getType (); */ |
|
114 NS_IMETHODIMP |
|
115 nsKeyObject::GetType(int16_t *_retval) |
|
116 { |
|
117 if (mKeyType == 0) |
|
118 return NS_ERROR_NOT_INITIALIZED; |
|
119 |
|
120 *_retval = mKeyType; |
|
121 return NS_OK; |
|
122 } |
|
123 |
|
124 ////////////////////////////////////////////////////////////////////////////// |
|
125 // nsIKeyObjectFactory |
|
126 |
|
127 NS_IMPL_ISUPPORTS(nsKeyObjectFactory, nsIKeyObjectFactory) |
|
128 |
|
129 nsKeyObjectFactory::nsKeyObjectFactory() |
|
130 { |
|
131 } |
|
132 |
|
133 /* nsIKeyObject lookupKeyByName (in ACString aName); */ |
|
134 NS_IMETHODIMP |
|
135 nsKeyObjectFactory::LookupKeyByName(const nsACString & aName, |
|
136 nsIKeyObject **_retval) |
|
137 { |
|
138 return NS_ERROR_NOT_IMPLEMENTED; |
|
139 } |
|
140 |
|
141 NS_IMETHODIMP |
|
142 nsKeyObjectFactory::UnwrapKey(int16_t aAlgorithm, const uint8_t *aWrappedKey, |
|
143 uint32_t aWrappedKeyLen, nsIKeyObject **_retval) |
|
144 { |
|
145 return NS_ERROR_NOT_IMPLEMENTED; |
|
146 } |
|
147 |
|
148 NS_IMETHODIMP |
|
149 nsKeyObjectFactory::KeyFromString(int16_t aAlgorithm, const nsACString & aKey, |
|
150 nsIKeyObject **_retval) |
|
151 { |
|
152 CK_MECHANISM_TYPE cipherMech; |
|
153 CK_ATTRIBUTE_TYPE cipherOperation; |
|
154 switch (aAlgorithm) |
|
155 { |
|
156 case nsIKeyObject::HMAC: |
|
157 cipherMech = CKM_GENERIC_SECRET_KEY_GEN; |
|
158 cipherOperation = CKA_SIGN; |
|
159 break; |
|
160 |
|
161 case nsIKeyObject::RC4: |
|
162 cipherMech = CKM_RC4; |
|
163 cipherOperation = CKA_ENCRYPT; |
|
164 break; |
|
165 |
|
166 default: |
|
167 return NS_ERROR_INVALID_ARG; |
|
168 } |
|
169 |
|
170 nsresult rv; |
|
171 nsCOMPtr<nsIKeyObject> key = |
|
172 do_CreateInstance(NS_KEYMODULEOBJECT_CONTRACTID, &rv); |
|
173 NS_ENSURE_SUCCESS(rv, rv); |
|
174 |
|
175 // Convert the raw string into a SECItem |
|
176 const nsCString& flatKey = PromiseFlatCString(aKey); |
|
177 SECItem keyItem; |
|
178 keyItem.data = (unsigned char*)flatKey.get(); |
|
179 keyItem.len = flatKey.Length(); |
|
180 |
|
181 ScopedPK11SlotInfo slot(PK11_GetBestSlot(cipherMech, nullptr)); |
|
182 if (!slot) { |
|
183 NS_ERROR("no slot"); |
|
184 return NS_ERROR_FAILURE; |
|
185 } |
|
186 |
|
187 PK11SymKey* symKey = PK11_ImportSymKey(slot, cipherMech, PK11_OriginUnwrap, |
|
188 cipherOperation, &keyItem, nullptr); |
|
189 if (!symKey) { |
|
190 return NS_ERROR_FAILURE; |
|
191 } |
|
192 |
|
193 rv = key->InitKey(aAlgorithm, (void*)symKey); |
|
194 NS_ENSURE_SUCCESS(rv, rv); |
|
195 |
|
196 key.swap(*_retval); |
|
197 return NS_OK; |
|
198 } |