1 : /* ***** BEGIN LICENSE BLOCK *****
2 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 : *
4 : * The contents of this file are subject to the Mozilla Public License Version
5 : * 1.1 (the "License"); you may not use this file except in compliance with
6 : * the License. You may obtain a copy of the License at
7 : * http://www.mozilla.org/MPL/
8 : *
9 : * Software distributed under the License is distributed on an "AS IS" basis,
10 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 : * for the specific language governing rights and limitations under the
12 : * License.
13 : *
14 : * The Original Code is mozilla.org code.
15 : *
16 : * The Initial Developer of the Original Code is Google Inc.
17 : * Portions created by the Initial Developer are Copyright (C) 2006
18 : * the Initial Developer. All Rights Reserved.
19 : *
20 : * Contributor(s):
21 : * Tony Chang <tc@google.com>
22 : *
23 : * Alternatively, the contents of this file may be used under the terms of
24 : * either the GNU General Public License Version 2 or later (the "GPL"), or
25 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 : * in which case the provisions of the GPL or the LGPL are applicable instead
27 : * of those above. If you wish to allow use of your version of this file only
28 : * under the terms of either the GPL or the LGPL, and not to allow others to
29 : * use your version of this file under the terms of the MPL, indicate your
30 : * decision by deleting the provisions above and replace them with the notice
31 : * and other provisions required by the GPL or the LGPL. If you do not delete
32 : * the provisions above, a recipient may use your version of this file under
33 : * the terms of any one of the MPL, the GPL or the LGPL.
34 : *
35 : * ***** END LICENSE BLOCK ***** */
36 :
37 : #include "nsComponentManagerUtils.h"
38 : #include "nsCOMPtr.h"
39 : #include "nsKeyModule.h"
40 : #include "nsString.h"
41 :
42 39847 : NS_IMPL_ISUPPORTS1(nsKeyObject, nsIKeyObject)
43 :
44 1676 : nsKeyObject::nsKeyObject()
45 : : mKeyType(0), mSymKey(nsnull), mPrivateKey(nsnull),
46 1676 : mPublicKey(nsnull)
47 : {
48 1676 : }
49 :
50 1676 : nsKeyObject::~nsKeyObject()
51 : {
52 1676 : CleanUp();
53 1676 : }
54 :
55 : void
56 3352 : nsKeyObject::CleanUp()
57 : {
58 3352 : switch (mKeyType) {
59 : case nsIKeyObject::SYM_KEY:
60 1676 : PK11_FreeSymKey(mSymKey);
61 1676 : break;
62 :
63 : case nsIKeyObject::PRIVATE_KEY:
64 0 : PK11_DeleteTokenPrivateKey(mPrivateKey, true /* force */);
65 0 : break;
66 :
67 : case nsIKeyObject::PUBLIC_KEY:
68 0 : PK11_DeleteTokenPublicKey(mPublicKey);
69 0 : break;
70 :
71 : default:
72 : // probably not initialized, do nothing
73 1676 : break;
74 : }
75 3352 : mKeyType = 0;
76 3352 : }
77 :
78 : //////////////////////////////////////////////////////////////////////////////
79 : // nsIKeyObject
80 :
81 : /* [noscript] void initKey (in short aKeyType, in voidPtr aKey); */
82 : NS_IMETHODIMP
83 1676 : nsKeyObject::InitKey(PRInt16 aAlgorithm, void * aKey)
84 : {
85 : // Clear previous key data if it exists
86 1676 : CleanUp();
87 :
88 1676 : switch (aAlgorithm) {
89 : case nsIKeyObject::RC4:
90 : case nsIKeyObject::HMAC:
91 1676 : mSymKey = reinterpret_cast<PK11SymKey*>(aKey);
92 :
93 1676 : if (!mSymKey) {
94 0 : NS_ERROR("no symkey");
95 0 : break;
96 : }
97 1676 : mKeyType = nsIKeyObject::SYM_KEY;
98 1676 : break;
99 :
100 : case nsIKeyObject::AES_CBC:
101 0 : return NS_ERROR_NOT_IMPLEMENTED;
102 :
103 : default:
104 0 : return NS_ERROR_INVALID_ARG;
105 : }
106 :
107 : // One of these should have been created
108 1676 : if (!mSymKey && !mPrivateKey && !mPublicKey)
109 0 : return NS_ERROR_FAILURE;
110 :
111 1676 : return NS_OK;
112 : }
113 :
114 : /* [noscript] voidPtr getKeyObj (); */
115 : NS_IMETHODIMP
116 1558 : nsKeyObject::GetKeyObj(void * *_retval)
117 : {
118 1558 : if (mKeyType == 0)
119 0 : return NS_ERROR_NOT_INITIALIZED;
120 :
121 1558 : switch (mKeyType) {
122 : case nsIKeyObject::SYM_KEY:
123 1558 : *_retval = (void*)mSymKey;
124 1558 : break;
125 :
126 : case nsIKeyObject::PRIVATE_KEY:
127 0 : *_retval = (void*)mPublicKey;
128 0 : break;
129 :
130 : case nsIKeyObject::PUBLIC_KEY:
131 0 : *_retval = (void*)mPrivateKey;
132 0 : break;
133 :
134 : default:
135 : // unknown key type? How did that happen?
136 0 : return NS_ERROR_FAILURE;
137 : }
138 1558 : return NS_OK;
139 : }
140 :
141 : /* short getType (); */
142 : NS_IMETHODIMP
143 1558 : nsKeyObject::GetType(PRInt16 *_retval)
144 : {
145 1558 : if (mKeyType == 0)
146 0 : return NS_ERROR_NOT_INITIALIZED;
147 :
148 1558 : *_retval = mKeyType;
149 1558 : return NS_OK;
150 : }
151 :
152 : //////////////////////////////////////////////////////////////////////////////
153 : // nsIKeyObjectFactory
154 :
155 1903 : NS_IMPL_THREADSAFE_ISUPPORTS1(nsKeyObjectFactory, nsIKeyObjectFactory)
156 :
157 38 : nsKeyObjectFactory::nsKeyObjectFactory()
158 : {
159 38 : }
160 :
161 : /* nsIKeyObject lookupKeyByName (in ACString aName); */
162 : NS_IMETHODIMP
163 0 : nsKeyObjectFactory::LookupKeyByName(const nsACString & aName,
164 : nsIKeyObject **_retval)
165 : {
166 0 : return NS_ERROR_NOT_IMPLEMENTED;
167 : }
168 :
169 : NS_IMETHODIMP
170 0 : nsKeyObjectFactory::UnwrapKey(PRInt16 aAlgorithm, const PRUint8 *aWrappedKey,
171 : PRUint32 aWrappedKeyLen, nsIKeyObject **_retval)
172 : {
173 0 : return NS_ERROR_NOT_IMPLEMENTED;
174 : }
175 :
176 : NS_IMETHODIMP
177 1676 : nsKeyObjectFactory::KeyFromString(PRInt16 aAlgorithm, const nsACString & aKey,
178 : nsIKeyObject **_retval)
179 : {
180 : CK_MECHANISM_TYPE cipherMech;
181 : CK_ATTRIBUTE_TYPE cipherOperation;
182 1676 : switch (aAlgorithm)
183 : {
184 : case nsIKeyObject::HMAC:
185 1676 : cipherMech = CKM_GENERIC_SECRET_KEY_GEN;
186 1676 : cipherOperation = CKA_SIGN;
187 1676 : break;
188 :
189 : case nsIKeyObject::RC4:
190 0 : cipherMech = CKM_RC4;
191 0 : cipherOperation = CKA_ENCRYPT;
192 0 : break;
193 :
194 : default:
195 0 : return NS_ERROR_INVALID_ARG;
196 : }
197 :
198 : nsresult rv;
199 : nsCOMPtr<nsIKeyObject> key =
200 3352 : do_CreateInstance(NS_KEYMODULEOBJECT_CONTRACTID, &rv);
201 1676 : NS_ENSURE_SUCCESS(rv, rv);
202 :
203 : // Convert the raw string into a SECItem
204 3352 : const nsCString& flatKey = PromiseFlatCString(aKey);
205 : SECItem keyItem;
206 1676 : keyItem.data = (unsigned char*)flatKey.get();
207 1676 : keyItem.len = flatKey.Length();
208 :
209 1676 : PK11SlotInfo *slot = nsnull;
210 1676 : slot = PK11_GetBestSlot(cipherMech, nsnull);
211 1676 : if (!slot) {
212 0 : NS_ERROR("no slot");
213 0 : return NS_ERROR_FAILURE;
214 : }
215 :
216 : PK11SymKey* symKey = PK11_ImportSymKey(slot, cipherMech, PK11_OriginUnwrap,
217 1676 : cipherOperation, &keyItem, nsnull);
218 : // cleanup code
219 1676 : if (slot)
220 1676 : PK11_FreeSlot(slot);
221 :
222 1676 : if (!symKey) {
223 0 : return NS_ERROR_FAILURE;
224 : }
225 :
226 1676 : rv = key->InitKey(aAlgorithm, (void*)symKey);
227 1676 : NS_ENSURE_SUCCESS(rv, rv);
228 :
229 1676 : key.swap(*_retval);
230 1676 : return NS_OK;
231 : }
|