security/manager/ssl/src/nsKeyModule.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:70d292b02067
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 }

mercurial