File: | s/lib/softoken/legacydb/lgattr.c |
Warning: | line 718, column 13 Value stored to 'keyType' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | * Internal PKCS #11 functions. Should only be called by pkcs11.c |
6 | */ |
7 | #include "pkcs11.h" |
8 | #include "lgdb.h" |
9 | |
10 | #include "pcertt.h" |
11 | #include "lowkeyi.h" |
12 | #include "pcert.h" |
13 | #include "blapi.h" |
14 | #include "secerr.h" |
15 | #include "secasn1.h" |
16 | |
17 | /* |
18 | * Cache the object we are working on during Set's and Get's |
19 | */ |
20 | typedef struct LGObjectCacheStr { |
21 | CK_OBJECT_CLASS objclass; |
22 | CK_OBJECT_HANDLE handle; |
23 | SDB *sdb; |
24 | void *objectInfo; |
25 | LGFreeFunc infoFree; |
26 | SECItem dbKey; |
27 | } LGObjectCache; |
28 | |
29 | static const CK_OBJECT_HANDLE lg_classArray[] = { |
30 | 0, CKO_PRIVATE_KEY0x00000003UL, CKO_PUBLIC_KEY0x00000002UL, CKO_SECRET_KEY0x00000004UL, |
31 | CKO_NSS_TRUST((0x80000000UL | 0x4E534350) + 3), CKO_NSS_CRL((0x80000000UL | 0x4E534350) + 1), CKO_NSS_SMIME((0x80000000UL | 0x4E534350) + 2), |
32 | CKO_CERTIFICATE0x00000001UL |
33 | }; |
34 | |
35 | #define handleToClass(handle)lg_classArray[((handle & 0x38000000L)) >> 27] \ |
36 | lg_classArray[((handle & LG_TOKEN_TYPE_MASK0x38000000L)) >> LG_TOKEN_TYPE_SHIFT27] |
37 | |
38 | static void lg_DestroyObjectCache(LGObjectCache *obj); |
39 | |
40 | static LGObjectCache * |
41 | lg_NewObjectCache(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE handle) |
42 | { |
43 | LGObjectCache *obj = NULL((void*)0); |
44 | SECStatus rv; |
45 | |
46 | obj = PORT_New(LGObjectCache)(LGObjectCache *)PORT_Alloc_Util(sizeof(LGObjectCache)); |
47 | if (obj == NULL((void*)0)) { |
48 | return NULL((void*)0); |
49 | } |
50 | |
51 | obj->objclass = handleToClass(handle)lg_classArray[((handle & 0x38000000L)) >> 27]; |
52 | obj->handle = handle; |
53 | obj->sdb = sdb; |
54 | obj->objectInfo = NULL((void*)0); |
55 | obj->infoFree = NULL((void*)0); |
56 | obj->dbKey.data = NULL((void*)0); |
57 | obj->dbKey.len = 0; |
58 | lg_DBLock(sdb); |
59 | if (dbKey == NULL((void*)0)) { |
60 | dbKey = lg_lookupTokenKeyByHandle(sdb, handle); |
61 | } |
62 | if (dbKey == NULL((void*)0)) { |
63 | lg_DBUnlock(sdb); |
64 | goto loser; |
65 | } |
66 | rv = SECITEM_CopyItemSECITEM_CopyItem_Util(NULL((void*)0), &obj->dbKey, dbKey); |
67 | lg_DBUnlock(sdb); |
68 | if (rv != SECSuccess) { |
69 | goto loser; |
70 | } |
71 | |
72 | return obj; |
73 | loser: |
74 | (void)lg_DestroyObjectCache(obj); |
75 | return NULL((void*)0); |
76 | } |
77 | |
78 | /* |
79 | * free all the data associated with an object. Object reference count must |
80 | * be 'zero'. |
81 | */ |
82 | static void |
83 | lg_DestroyObjectCache(LGObjectCache *obj) |
84 | { |
85 | if (obj->dbKey.data) { |
86 | PORT_FreePORT_Free_Util(obj->dbKey.data); |
87 | obj->dbKey.data = NULL((void*)0); |
88 | } |
89 | if (obj->objectInfo) { |
90 | (*obj->infoFree)(obj->objectInfo); |
91 | obj->objectInfo = NULL((void*)0); |
92 | obj->infoFree = NULL((void*)0); |
93 | } |
94 | PORT_FreePORT_Free_Util(obj); |
95 | } |
96 | /* |
97 | * ******************** Attribute Utilities ******************************* |
98 | */ |
99 | |
100 | static CK_RV |
101 | lg_ULongAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, CK_ULONG value) |
102 | { |
103 | unsigned char *data; |
104 | int i; |
105 | |
106 | if (attr->pValue == NULL((void*)0)) { |
107 | attr->ulValueLen = 4; |
108 | return CKR_OK0x00000000UL; |
109 | } |
110 | if (attr->ulValueLen < 4) { |
111 | attr->ulValueLen = (CK_ULONG)-1; |
112 | return CKR_BUFFER_TOO_SMALL0x00000150UL; |
113 | } |
114 | |
115 | data = (unsigned char *)attr->pValue; |
116 | for (i = 0; i < 4; i++) { |
117 | data[i] = (value >> ((3 - i) * 8)) & 0xff; |
118 | } |
119 | attr->ulValueLen = 4; |
120 | return CKR_OK0x00000000UL; |
121 | } |
122 | |
123 | static CK_RV |
124 | lg_CopyAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, |
125 | CK_VOID_PTR value, CK_ULONG len) |
126 | { |
127 | |
128 | if (attr->pValue == NULL((void*)0)) { |
129 | attr->ulValueLen = len; |
130 | return CKR_OK0x00000000UL; |
131 | } |
132 | if (attr->ulValueLen < len) { |
133 | attr->ulValueLen = (CK_ULONG)-1; |
134 | return CKR_BUFFER_TOO_SMALL0x00000150UL; |
135 | } |
136 | if (len > 0 && value != NULL((void*)0)) { |
137 | PORT_Memcpymemcpy(attr->pValue, value, len); |
138 | } |
139 | attr->ulValueLen = len; |
140 | return CKR_OK0x00000000UL; |
141 | } |
142 | |
143 | static CK_RV |
144 | lg_CopyAttributeSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type, |
145 | void *value, CK_ULONG len) |
146 | { |
147 | unsigned char *dval = (unsigned char *)value; |
148 | if (*dval == 0) { |
149 | dval++; |
150 | len--; |
151 | } |
152 | return lg_CopyAttribute(attribute, type, dval, len); |
153 | } |
154 | |
155 | static CK_RV |
156 | lg_CopyPrivAttribute(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type, |
157 | void *value, CK_ULONG len, SDB *sdbpw) |
158 | { |
159 | SECItem plainText, *cipherText = NULL((void*)0); |
160 | CK_RV crv = CKR_USER_NOT_LOGGED_IN0x00000101UL; |
161 | SECStatus rv; |
162 | |
163 | plainText.data = value; |
164 | plainText.len = len; |
165 | rv = lg_util_encrypt(NULL((void*)0), sdbpw, &plainText, &cipherText); |
166 | if (rv != SECSuccess) { |
167 | goto loser; |
168 | } |
169 | crv = lg_CopyAttribute(attribute, type, cipherText->data, cipherText->len); |
170 | loser: |
171 | if (cipherText) { |
172 | SECITEM_FreeItemSECITEM_FreeItem_Util(cipherText, PR_TRUE1); |
173 | } |
174 | return crv; |
175 | } |
176 | |
177 | static CK_RV |
178 | lg_CopyPrivAttrSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type, |
179 | void *value, CK_ULONG len, SDB *sdbpw) |
180 | { |
181 | unsigned char *dval = (unsigned char *)value; |
182 | |
183 | if (*dval == 0) { |
184 | dval++; |
185 | len--; |
186 | } |
187 | return lg_CopyPrivAttribute(attribute, type, dval, len, sdbpw); |
188 | } |
189 | |
190 | static CK_RV |
191 | lg_invalidAttribute(CK_ATTRIBUTE *attr) |
192 | { |
193 | attr->ulValueLen = (CK_ULONG)-1; |
194 | return CKR_ATTRIBUTE_TYPE_INVALID0x00000012UL; |
195 | } |
196 | |
197 | #define LG_DEF_ATTRIBUTE(value, len){ 0, value, len } \ |
198 | { \ |
199 | 0, value, len \ |
200 | } |
201 | |
202 | #define LG_CLONE_ATTR(attribute, type, staticAttr)lg_CopyAttribute(attribute, type, staticAttr.pValue, staticAttr .ulValueLen) \ |
203 | lg_CopyAttribute(attribute, type, staticAttr.pValue, staticAttr.ulValueLen) |
204 | |
205 | CK_BBOOL lg_staticTrueValue = CK_TRUE1; |
206 | CK_BBOOL lg_staticFalseValue = CK_FALSE0; |
207 | static const CK_ATTRIBUTE lg_StaticTrueAttr = |
208 | LG_DEF_ATTRIBUTE(&lg_staticTrueValue, sizeof(lg_staticTrueValue)){ 0, &lg_staticTrueValue, sizeof(lg_staticTrueValue) }; |
209 | static const CK_ATTRIBUTE lg_StaticFalseAttr = |
210 | LG_DEF_ATTRIBUTE(&lg_staticFalseValue, sizeof(lg_staticFalseValue)){ 0, &lg_staticFalseValue, sizeof(lg_staticFalseValue) }; |
211 | static const CK_ATTRIBUTE lg_StaticNullAttr = LG_DEF_ATTRIBUTE(NULL, 0){ 0, ((void*)0), 0 }; |
212 | char lg_StaticOneValue = 1; |
213 | |
214 | /* |
215 | * helper functions which get the database and call the underlying |
216 | * low level database function. |
217 | */ |
218 | static char * |
219 | lg_FindKeyNicknameByPublicKey(SDB *sdb, SECItem *dbKey) |
220 | { |
221 | NSSLOWKEYDBHandle *keyHandle; |
222 | char *label; |
223 | |
224 | keyHandle = lg_getKeyDB(sdb); |
225 | if (!keyHandle) { |
226 | return NULL((void*)0); |
227 | } |
228 | |
229 | label = nsslowkey_FindKeyNicknameByPublicKey(keyHandle, dbKey, |
230 | sdb); |
231 | return label; |
232 | } |
233 | |
234 | NSSLOWKEYPrivateKey * |
235 | lg_FindKeyByPublicKey(SDB *sdb, SECItem *dbKey) |
236 | { |
237 | NSSLOWKEYPrivateKey *privKey; |
238 | NSSLOWKEYDBHandle *keyHandle; |
239 | |
240 | keyHandle = lg_getKeyDB(sdb); |
241 | if (keyHandle == NULL((void*)0)) { |
242 | return NULL((void*)0); |
243 | } |
244 | privKey = nsslowkey_FindKeyByPublicKey(keyHandle, dbKey, sdb); |
245 | if (privKey == NULL((void*)0)) { |
246 | return NULL((void*)0); |
247 | } |
248 | return privKey; |
249 | } |
250 | |
251 | static certDBEntrySMime * |
252 | lg_getSMime(LGObjectCache *obj) |
253 | { |
254 | certDBEntrySMime *entry; |
255 | NSSLOWCERTCertDBHandle *certHandle; |
256 | |
257 | if (obj->objclass != CKO_NSS_SMIME((0x80000000UL | 0x4E534350) + 2)) { |
258 | return NULL((void*)0); |
259 | } |
260 | if (obj->objectInfo) { |
261 | return (certDBEntrySMime *)obj->objectInfo; |
262 | } |
263 | |
264 | certHandle = lg_getCertDB(obj->sdb); |
265 | if (!certHandle) { |
266 | return NULL((void*)0); |
267 | } |
268 | entry = nsslowcert_ReadDBSMimeEntry(certHandle, (char *)obj->dbKey.data); |
269 | obj->objectInfo = (void *)entry; |
270 | obj->infoFree = (LGFreeFunc)nsslowcert_DestroyDBEntry; |
271 | return entry; |
272 | } |
273 | |
274 | static certDBEntryRevocation * |
275 | lg_getCrl(LGObjectCache *obj) |
276 | { |
277 | certDBEntryRevocation *crl; |
278 | PRBool isKrl; |
279 | NSSLOWCERTCertDBHandle *certHandle; |
280 | |
281 | if (obj->objclass != CKO_NSS_CRL((0x80000000UL | 0x4E534350) + 1)) { |
282 | return NULL((void*)0); |
283 | } |
284 | if (obj->objectInfo) { |
285 | return (certDBEntryRevocation *)obj->objectInfo; |
286 | } |
287 | |
288 | isKrl = (PRBool)(obj->handle == LG_TOKEN_KRL_HANDLE(0x28000000L | 1)); |
289 | certHandle = lg_getCertDB(obj->sdb); |
290 | if (!certHandle) { |
291 | return NULL((void*)0); |
292 | } |
293 | |
294 | crl = nsslowcert_FindCrlByKey(certHandle, &obj->dbKey, isKrl); |
295 | obj->objectInfo = (void *)crl; |
296 | obj->infoFree = (LGFreeFunc)nsslowcert_DestroyDBEntry; |
297 | return crl; |
298 | } |
299 | |
300 | static NSSLOWCERTCertificate * |
301 | lg_getCert(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle) |
302 | { |
303 | NSSLOWCERTCertificate *cert; |
304 | CK_OBJECT_CLASS objClass = obj->objclass; |
305 | |
306 | if ((objClass != CKO_CERTIFICATE0x00000001UL) && (objClass != CKO_NSS_TRUST((0x80000000UL | 0x4E534350) + 3))) { |
307 | return NULL((void*)0); |
308 | } |
309 | if (objClass == CKO_CERTIFICATE0x00000001UL && obj->objectInfo) { |
310 | return (NSSLOWCERTCertificate *)obj->objectInfo; |
311 | } |
312 | cert = nsslowcert_FindCertByKey(certHandle, &obj->dbKey); |
313 | if (objClass == CKO_CERTIFICATE0x00000001UL) { |
314 | obj->objectInfo = (void *)cert; |
315 | obj->infoFree = (LGFreeFunc)nsslowcert_DestroyCertificate; |
316 | } |
317 | return cert; |
318 | } |
319 | |
320 | static NSSLOWCERTTrust * |
321 | lg_getTrust(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle) |
322 | { |
323 | NSSLOWCERTTrust *trust; |
324 | |
325 | if (obj->objclass != CKO_NSS_TRUST((0x80000000UL | 0x4E534350) + 3)) { |
326 | return NULL((void*)0); |
327 | } |
328 | if (obj->objectInfo) { |
329 | return (NSSLOWCERTTrust *)obj->objectInfo; |
330 | } |
331 | trust = nsslowcert_FindTrustByKey(certHandle, &obj->dbKey); |
332 | obj->objectInfo = (void *)trust; |
333 | obj->infoFree = (LGFreeFunc)nsslowcert_DestroyTrust; |
334 | return trust; |
335 | } |
336 | |
337 | static NSSLOWKEYPublicKey * |
338 | lg_GetPublicKey(LGObjectCache *obj) |
339 | { |
340 | NSSLOWKEYPublicKey *pubKey; |
341 | NSSLOWKEYPrivateKey *privKey; |
342 | |
343 | if (obj->objclass != CKO_PUBLIC_KEY0x00000002UL) { |
344 | return NULL((void*)0); |
345 | } |
346 | if (obj->objectInfo) { |
347 | return (NSSLOWKEYPublicKey *)obj->objectInfo; |
348 | } |
349 | privKey = lg_FindKeyByPublicKey(obj->sdb, &obj->dbKey); |
350 | if (privKey == NULL((void*)0)) { |
351 | return NULL((void*)0); |
352 | } |
353 | pubKey = lg_nsslowkey_ConvertToPublicKey(privKey); |
354 | lg_nsslowkey_DestroyPrivateKey(privKey); |
355 | obj->objectInfo = (void *)pubKey; |
356 | obj->infoFree = (LGFreeFunc)lg_nsslowkey_DestroyPublicKey; |
357 | return pubKey; |
358 | } |
359 | |
360 | /* |
361 | * we need two versions of lg_GetPrivateKey. One version that takes the |
362 | * DB handle so we can pass the handle we have already acquired in, |
363 | * rather than going through the 'getKeyDB' code again, |
364 | * which may fail the second time and another which just aquires |
365 | * the key handle from the sdb (where we don't already have a key handle. |
366 | * This version does the former. |
367 | */ |
368 | static NSSLOWKEYPrivateKey * |
369 | lg_GetPrivateKeyWithDB(LGObjectCache *obj, NSSLOWKEYDBHandle *keyHandle) |
370 | { |
371 | NSSLOWKEYPrivateKey *privKey; |
372 | |
373 | if ((obj->objclass != CKO_PRIVATE_KEY0x00000003UL) && |
374 | (obj->objclass != CKO_SECRET_KEY0x00000004UL)) { |
375 | return NULL((void*)0); |
376 | } |
377 | if (obj->objectInfo) { |
378 | return (NSSLOWKEYPrivateKey *)obj->objectInfo; |
379 | } |
380 | privKey = nsslowkey_FindKeyByPublicKey(keyHandle, &obj->dbKey, obj->sdb); |
381 | if (privKey == NULL((void*)0)) { |
382 | return NULL((void*)0); |
383 | } |
384 | obj->objectInfo = (void *)privKey; |
385 | obj->infoFree = (LGFreeFunc)lg_nsslowkey_DestroyPrivateKey; |
386 | return privKey; |
387 | } |
388 | |
389 | /* this version does the latter */ |
390 | static NSSLOWKEYPrivateKey * |
391 | lg_GetPrivateKey(LGObjectCache *obj) |
392 | { |
393 | NSSLOWKEYDBHandle *keyHandle; |
394 | NSSLOWKEYPrivateKey *privKey; |
395 | |
396 | keyHandle = lg_getKeyDB(obj->sdb); |
397 | if (!keyHandle) { |
398 | return NULL((void*)0); |
399 | } |
400 | privKey = lg_GetPrivateKeyWithDB(obj, keyHandle); |
401 | return privKey; |
402 | } |
403 | |
404 | /* lg_GetPubItem returns data associated with the public key. |
405 | * one only needs to free the public key. This comment is here |
406 | * because this sematic would be non-obvious otherwise. All callers |
407 | * should include this comment. |
408 | */ |
409 | static SECItem * |
410 | lg_GetPubItem(NSSLOWKEYPublicKey *pubKey) |
411 | { |
412 | SECItem *pubItem = NULL((void*)0); |
413 | /* get value to compare from the cert's public key */ |
414 | switch (pubKey->keyType) { |
415 | case NSSLOWKEYRSAKey: |
416 | pubItem = &pubKey->u.rsa.modulus; |
417 | break; |
418 | case NSSLOWKEYDSAKey: |
419 | pubItem = &pubKey->u.dsa.publicValue; |
420 | break; |
421 | case NSSLOWKEYDHKey: |
422 | pubItem = &pubKey->u.dh.publicValue; |
423 | break; |
424 | case NSSLOWKEYECKey: |
425 | pubItem = &pubKey->u.ec.publicValue; |
426 | break; |
427 | default: |
428 | break; |
429 | } |
430 | return pubItem; |
431 | } |
432 | |
433 | static CK_RV |
434 | lg_FindRSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, |
435 | CK_ATTRIBUTE *attribute) |
436 | { |
437 | unsigned char hash[SHA1_LENGTH20]; |
438 | CK_KEY_TYPE keyType = CKK_RSA0x00000000UL; |
439 | |
440 | switch (type) { |
441 | case CKA_KEY_TYPE0x00000100UL: |
442 | return lg_ULongAttribute(attribute, type, keyType); |
443 | case CKA_ID0x00000102UL: |
444 | SHA1_HashBuf(hash, key->u.rsa.modulus.data, key->u.rsa.modulus.len); |
445 | return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH20); |
446 | case CKA_DERIVE0x0000010CUL: |
447 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
448 | case CKA_ENCRYPT0x00000104UL: |
449 | case CKA_VERIFY0x0000010AUL: |
450 | case CKA_VERIFY_RECOVER0x0000010BUL: |
451 | case CKA_WRAP0x00000106UL: |
452 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
453 | case CKA_MODULUS0x00000120UL: |
454 | return lg_CopyAttributeSigned(attribute, type, key->u.rsa.modulus.data, |
455 | key->u.rsa.modulus.len); |
456 | case CKA_PUBLIC_EXPONENT0x00000122UL: |
457 | return lg_CopyAttributeSigned(attribute, type, |
458 | key->u.rsa.publicExponent.data, |
459 | key->u.rsa.publicExponent.len); |
460 | default: |
461 | break; |
462 | } |
463 | return lg_invalidAttribute(attribute); |
464 | } |
465 | |
466 | static CK_RV |
467 | lg_FindDSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, |
468 | CK_ATTRIBUTE *attribute) |
469 | { |
470 | unsigned char hash[SHA1_LENGTH20]; |
471 | CK_KEY_TYPE keyType = CKK_DSA0x00000001UL; |
472 | |
473 | switch (type) { |
474 | case CKA_KEY_TYPE0x00000100UL: |
475 | return lg_ULongAttribute(attribute, type, keyType); |
476 | case CKA_ID0x00000102UL: |
477 | SHA1_HashBuf(hash, key->u.dsa.publicValue.data, |
478 | key->u.dsa.publicValue.len); |
479 | return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH20); |
480 | case CKA_DERIVE0x0000010CUL: |
481 | case CKA_ENCRYPT0x00000104UL: |
482 | case CKA_VERIFY_RECOVER0x0000010BUL: |
483 | case CKA_WRAP0x00000106UL: |
484 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
485 | case CKA_VERIFY0x0000010AUL: |
486 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
487 | case CKA_VALUE0x00000011UL: |
488 | return lg_CopyAttributeSigned(attribute, type, |
489 | key->u.dsa.publicValue.data, |
490 | key->u.dsa.publicValue.len); |
491 | case CKA_PRIME0x00000130UL: |
492 | return lg_CopyAttributeSigned(attribute, type, |
493 | key->u.dsa.params.prime.data, |
494 | key->u.dsa.params.prime.len); |
495 | case CKA_SUBPRIME0x00000131UL: |
496 | return lg_CopyAttributeSigned(attribute, type, |
497 | key->u.dsa.params.subPrime.data, |
498 | key->u.dsa.params.subPrime.len); |
499 | case CKA_BASE0x00000132UL: |
500 | return lg_CopyAttributeSigned(attribute, type, |
501 | key->u.dsa.params.base.data, |
502 | key->u.dsa.params.base.len); |
503 | default: |
504 | break; |
505 | } |
506 | return lg_invalidAttribute(attribute); |
507 | } |
508 | |
509 | static CK_RV |
510 | lg_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, |
511 | CK_ATTRIBUTE *attribute) |
512 | { |
513 | unsigned char hash[SHA1_LENGTH20]; |
514 | CK_KEY_TYPE keyType = CKK_DH0x00000002UL; |
515 | |
516 | switch (type) { |
517 | case CKA_KEY_TYPE0x00000100UL: |
518 | return lg_ULongAttribute(attribute, type, keyType); |
519 | case CKA_ID0x00000102UL: |
520 | SHA1_HashBuf(hash, key->u.dh.publicValue.data, key->u.dh.publicValue.len); |
521 | return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH20); |
522 | case CKA_DERIVE0x0000010CUL: |
523 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
524 | case CKA_ENCRYPT0x00000104UL: |
525 | case CKA_VERIFY0x0000010AUL: |
526 | case CKA_VERIFY_RECOVER0x0000010BUL: |
527 | case CKA_WRAP0x00000106UL: |
528 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
529 | case CKA_VALUE0x00000011UL: |
530 | return lg_CopyAttributeSigned(attribute, type, |
531 | key->u.dh.publicValue.data, |
532 | key->u.dh.publicValue.len); |
533 | case CKA_PRIME0x00000130UL: |
534 | return lg_CopyAttributeSigned(attribute, type, key->u.dh.prime.data, |
535 | key->u.dh.prime.len); |
536 | case CKA_BASE0x00000132UL: |
537 | return lg_CopyAttributeSigned(attribute, type, key->u.dh.base.data, |
538 | key->u.dh.base.len); |
539 | default: |
540 | break; |
541 | } |
542 | return lg_invalidAttribute(attribute); |
543 | } |
544 | |
545 | static CK_RV |
546 | lg_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, |
547 | CK_ATTRIBUTE *attribute) |
548 | { |
549 | unsigned char hash[SHA1_LENGTH20]; |
550 | CK_KEY_TYPE keyType = CKK_EC0x00000003UL; |
551 | |
552 | switch (type) { |
553 | case CKA_KEY_TYPE0x00000100UL: |
554 | return lg_ULongAttribute(attribute, type, keyType); |
555 | case CKA_ID0x00000102UL: |
556 | SHA1_HashBuf(hash, key->u.ec.publicValue.data, |
557 | key->u.ec.publicValue.len); |
558 | return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH20); |
559 | case CKA_DERIVE0x0000010CUL: |
560 | case CKA_VERIFY0x0000010AUL: |
561 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
562 | case CKA_ENCRYPT0x00000104UL: |
563 | case CKA_VERIFY_RECOVER0x0000010BUL: |
564 | case CKA_WRAP0x00000106UL: |
565 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
566 | case CKA_EC_PARAMS0x00000180UL: |
567 | return lg_CopyAttributeSigned(attribute, type, |
568 | key->u.ec.ecParams.DEREncoding.data, |
569 | key->u.ec.ecParams.DEREncoding.len); |
570 | case CKA_EC_POINT0x00000181UL: |
571 | if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT")) { |
572 | return lg_CopyAttributeSigned(attribute, type, |
573 | key->u.ec.publicValue.data, |
574 | key->u.ec.publicValue.len); |
575 | } else { |
576 | SECItem *pubValue = SEC_ASN1EncodeItemSEC_ASN1EncodeItem_Util(NULL((void*)0), NULL((void*)0), |
577 | &(key->u.ec.publicValue), |
578 | SEC_ASN1_GET(SEC_OctetStringTemplate)SEC_OctetStringTemplate_Util); |
579 | CK_RV crv; |
580 | if (!pubValue) { |
581 | return CKR_HOST_MEMORY0x00000002UL; |
582 | } |
583 | crv = lg_CopyAttributeSigned(attribute, type, |
584 | pubValue->data, |
585 | pubValue->len); |
586 | SECITEM_FreeItemSECITEM_FreeItem_Util(pubValue, PR_TRUE1); |
587 | return crv; |
588 | } |
589 | default: |
590 | break; |
591 | } |
592 | return lg_invalidAttribute(attribute); |
593 | } |
594 | |
595 | static CK_RV |
596 | lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, |
597 | CK_ATTRIBUTE *attribute) |
598 | { |
599 | NSSLOWKEYPublicKey *key; |
600 | CK_RV crv; |
601 | char *label; |
602 | |
603 | switch (type) { |
604 | case CKA_PRIVATE0x00000002UL: |
605 | case CKA_SENSITIVE0x00000103UL: |
606 | case CKA_ALWAYS_SENSITIVE0x00000165UL: |
607 | case CKA_NEVER_EXTRACTABLE0x00000164UL: |
608 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
609 | case CKA_MODIFIABLE0x00000170UL: |
610 | case CKA_EXTRACTABLE0x00000162UL: |
611 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
612 | case CKA_SUBJECT0x00000101UL: |
613 | return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
614 | case CKA_START_DATE0x00000110UL: |
615 | case CKA_END_DATE0x00000111UL: |
616 | return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
617 | case CKA_LABEL0x00000003UL: |
618 | label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey); |
619 | if (label == NULL((void*)0)) { |
620 | return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
621 | } |
622 | crv = lg_CopyAttribute(attribute, type, label, PORT_Strlen(label)strlen(label)); |
623 | PORT_FreePORT_Free_Util(label); |
624 | return crv; |
625 | default: |
626 | break; |
627 | } |
628 | |
629 | key = lg_GetPublicKey(obj); |
630 | if (key == NULL((void*)0)) { |
631 | if (type == CKA_ID0x00000102UL) { |
632 | return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
633 | } |
634 | return CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
635 | } |
636 | |
637 | switch (key->keyType) { |
638 | case NSSLOWKEYRSAKey: |
639 | return lg_FindRSAPublicKeyAttribute(key, type, attribute); |
640 | case NSSLOWKEYDSAKey: |
641 | return lg_FindDSAPublicKeyAttribute(key, type, attribute); |
642 | case NSSLOWKEYDHKey: |
643 | return lg_FindDHPublicKeyAttribute(key, type, attribute); |
644 | case NSSLOWKEYECKey: |
645 | return lg_FindECPublicKeyAttribute(key, type, attribute); |
646 | default: |
647 | break; |
648 | } |
649 | |
650 | return lg_invalidAttribute(attribute); |
651 | } |
652 | |
653 | static CK_RV |
654 | lg_FindSecretKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, |
655 | CK_ATTRIBUTE *attribute) |
656 | { |
657 | NSSLOWKEYPrivateKey *key; |
658 | char *label; |
659 | unsigned char *keyString; |
660 | CK_RV crv; |
661 | int keyTypeLen; |
662 | CK_ULONG keyLen; |
663 | CK_KEY_TYPE keyType; |
664 | PRUint32 keyTypeStorage; |
665 | |
666 | switch (type) { |
667 | case CKA_PRIVATE0x00000002UL: |
668 | case CKA_SENSITIVE0x00000103UL: |
669 | case CKA_ALWAYS_SENSITIVE0x00000165UL: |
670 | case CKA_EXTRACTABLE0x00000162UL: |
671 | case CKA_DERIVE0x0000010CUL: |
672 | case CKA_ENCRYPT0x00000104UL: |
673 | case CKA_DECRYPT0x00000105UL: |
674 | case CKA_SIGN0x00000108UL: |
675 | case CKA_VERIFY0x0000010AUL: |
676 | case CKA_WRAP0x00000106UL: |
677 | case CKA_UNWRAP0x00000107UL: |
678 | case CKA_MODIFIABLE0x00000170UL: |
679 | case CKA_LOCAL0x00000163UL: |
680 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
681 | case CKA_NEVER_EXTRACTABLE0x00000164UL: |
682 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
683 | case CKA_START_DATE0x00000110UL: |
684 | case CKA_END_DATE0x00000111UL: |
685 | return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
686 | case CKA_LABEL0x00000003UL: |
687 | label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey); |
688 | if (label == NULL((void*)0)) { |
689 | return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
690 | } |
691 | crv = lg_CopyAttribute(attribute, type, label, PORT_Strlen(label)strlen(label)); |
692 | PORT_FreePORT_Free_Util(label); |
693 | return crv; |
694 | case CKA_ID0x00000102UL: |
695 | return lg_CopyAttribute(attribute, type, obj->dbKey.data, |
696 | obj->dbKey.len); |
697 | case CKA_KEY_TYPE0x00000100UL: |
698 | case CKA_VALUE_LEN0x00000161UL: |
699 | case CKA_VALUE0x00000011UL: |
700 | break; |
701 | default: |
702 | return lg_invalidAttribute(attribute); |
703 | } |
704 | |
705 | key = lg_GetPrivateKey(obj); |
706 | if (key == NULL((void*)0)) { |
707 | return CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
708 | } |
709 | switch (type) { |
710 | case CKA_KEY_TYPE0x00000100UL: |
711 | /* handle legacy databases. In legacy databases key_type was stored |
712 | * in host order, with any leading zeros stripped off. Only key types |
713 | * under 0x1f (AES) were stored. We assume that any values which are |
714 | * either 1 byte long (big endian), or have byte[0] between 0 and |
715 | * 0x7f and bytes[1]-bytes[3] equal to '0' (little endian). All other |
716 | * values are assumed to be from the new database, which is always 4 |
717 | * bytes in network order */ |
718 | keyType = 0; |
Value stored to 'keyType' is never read | |
719 | keyString = key->u.rsa.coefficient.data; |
720 | keyTypeLen = key->u.rsa.coefficient.len; |
721 | |
722 | /* |
723 | * Because of various endian and word lengths The database may have |
724 | * stored the keyType value in one of the following formats: |
725 | * (kt) <= 0x1f |
726 | * length data |
727 | * Big Endian, pre-3.9, all lengths: 1 (kt) |
728 | * Little Endian, pre-3.9, 32 bits: 4 (kt) 0 0 0 |
729 | * Little Endian, pre-3.9, 64 bits: 8 (kt) 0 0 0 0 0 0 0 |
730 | * All platforms, 3.9, 32 bits: 4 0 0 0 (kt) |
731 | * Big Endian, 3.9, 64 bits: 8 0 0 0 (kt) 0 0 0 0 |
732 | * Little Endian, 3.9, 64 bits: 8 0 0 0 0 0 0 0 (kt) |
733 | * All platforms, >= 3.9.1, all lengths: 4 (a) k1 k2 k3 |
734 | * where (a) is 0 or >= 0x80. currently (a) can only be 0. |
735 | */ |
736 | /* |
737 | * this key was written on a 64 bit platform with a using NSS 3.9 |
738 | * or earlier. Reduce the 64 bit possibilities above. When we are |
739 | * through, we will only have: |
740 | * |
741 | * Big Endian, pre-3.9, all lengths: 1 (kt) |
742 | * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0 |
743 | * All platforms, 3.9, all lengths: 4 0 0 0 (kt) |
744 | * All platforms, => 3.9.1, all lengths: 4 (a) k1 k2 k3 |
745 | */ |
746 | if (keyTypeLen == 8) { |
747 | keyTypeStorage = *(PRUint32 *)keyString; |
748 | if (keyTypeStorage == 0) { |
749 | keyString += sizeof(PRUint32); |
750 | } |
751 | keyTypeLen = 4; |
752 | } |
753 | /* |
754 | * Now Handle: |
755 | * |
756 | * All platforms, 3.9, all lengths: 4 0 0 0 (kt) |
757 | * All platforms, => 3.9.1, all lengths: 4 (a) k1 k2 k3 |
758 | * |
759 | * NOTE: if kt == 0 or ak1k2k3 == 0, the test fails and |
760 | * we handle it as: |
761 | * |
762 | * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0 |
763 | */ |
764 | if (keyTypeLen == sizeof(keyTypeStorage) && |
765 | (((keyString[0] & 0x80) == 0x80) || |
766 | !((keyString[1] == 0) && (keyString[2] == 0) && (keyString[3] == 0)))) { |
767 | PORT_Memcpymemcpy(&keyTypeStorage, keyString, sizeof(keyTypeStorage)); |
768 | keyType = (CK_KEY_TYPE)PR_ntohl(keyTypeStorage); |
769 | } else { |
770 | /* |
771 | * Now Handle: |
772 | * |
773 | * Big Endian, pre-3.9, all lengths: 1 (kt) |
774 | * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0 |
775 | * -- KeyType == 0 all other cases ---: 4 0 0 0 0 |
776 | */ |
777 | keyType = (CK_KEY_TYPE)keyString[0]; |
778 | } |
779 | return lg_ULongAttribute(attribute, type, keyType); |
780 | case CKA_VALUE0x00000011UL: |
781 | return lg_CopyPrivAttribute(attribute, type, key->u.rsa.privateExponent.data, |
782 | key->u.rsa.privateExponent.len, obj->sdb); |
783 | case CKA_VALUE_LEN0x00000161UL: |
784 | keyLen = key->u.rsa.privateExponent.len; |
785 | return lg_ULongAttribute(attribute, type, keyLen); |
786 | } |
787 | return lg_invalidAttribute(attribute); |
788 | } |
789 | |
790 | static CK_RV |
791 | lg_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, |
792 | CK_ATTRIBUTE *attribute, SDB *sdbpw) |
793 | { |
794 | unsigned char hash[SHA1_LENGTH20]; |
795 | CK_KEY_TYPE keyType = CKK_RSA0x00000000UL; |
796 | |
797 | switch (type) { |
798 | case CKA_KEY_TYPE0x00000100UL: |
799 | return lg_ULongAttribute(attribute, type, keyType); |
800 | case CKA_ID0x00000102UL: |
801 | SHA1_HashBuf(hash, key->u.rsa.modulus.data, key->u.rsa.modulus.len); |
802 | return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH20); |
803 | case CKA_DERIVE0x0000010CUL: |
804 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
805 | case CKA_DECRYPT0x00000105UL: |
806 | case CKA_SIGN0x00000108UL: |
807 | case CKA_SIGN_RECOVER0x00000109UL: |
808 | case CKA_UNWRAP0x00000107UL: |
809 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
810 | case CKA_MODULUS0x00000120UL: |
811 | return lg_CopyAttributeSigned(attribute, type, key->u.rsa.modulus.data, |
812 | key->u.rsa.modulus.len); |
813 | case CKA_PUBLIC_EXPONENT0x00000122UL: |
814 | return lg_CopyAttributeSigned(attribute, type, |
815 | key->u.rsa.publicExponent.data, |
816 | key->u.rsa.publicExponent.len); |
817 | case CKA_PRIVATE_EXPONENT0x00000123UL: |
818 | return lg_CopyPrivAttrSigned(attribute, type, |
819 | key->u.rsa.privateExponent.data, |
820 | key->u.rsa.privateExponent.len, sdbpw); |
821 | case CKA_PRIME_10x00000124UL: |
822 | return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime1.data, |
823 | key->u.rsa.prime1.len, sdbpw); |
824 | case CKA_PRIME_20x00000125UL: |
825 | return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime2.data, |
826 | key->u.rsa.prime2.len, sdbpw); |
827 | case CKA_EXPONENT_10x00000126UL: |
828 | return lg_CopyPrivAttrSigned(attribute, type, |
829 | key->u.rsa.exponent1.data, |
830 | key->u.rsa.exponent1.len, sdbpw); |
831 | case CKA_EXPONENT_20x00000127UL: |
832 | return lg_CopyPrivAttrSigned(attribute, type, |
833 | key->u.rsa.exponent2.data, |
834 | key->u.rsa.exponent2.len, sdbpw); |
835 | case CKA_COEFFICIENT0x00000128UL: |
836 | return lg_CopyPrivAttrSigned(attribute, type, |
837 | key->u.rsa.coefficient.data, |
838 | key->u.rsa.coefficient.len, sdbpw); |
839 | default: |
840 | break; |
841 | } |
842 | return lg_invalidAttribute(attribute); |
843 | } |
844 | |
845 | static CK_RV |
846 | lg_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, |
847 | CK_ATTRIBUTE *attribute, SDB *sdbpw) |
848 | { |
849 | unsigned char hash[SHA1_LENGTH20]; |
850 | CK_KEY_TYPE keyType = CKK_DSA0x00000001UL; |
851 | |
852 | switch (type) { |
853 | case CKA_KEY_TYPE0x00000100UL: |
854 | return lg_ULongAttribute(attribute, type, keyType); |
855 | case CKA_ID0x00000102UL: |
856 | SHA1_HashBuf(hash, key->u.dsa.publicValue.data, |
857 | key->u.dsa.publicValue.len); |
858 | return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH20); |
859 | case CKA_DERIVE0x0000010CUL: |
860 | case CKA_DECRYPT0x00000105UL: |
861 | case CKA_SIGN_RECOVER0x00000109UL: |
862 | case CKA_UNWRAP0x00000107UL: |
863 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
864 | case CKA_SIGN0x00000108UL: |
865 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
866 | case CKA_VALUE0x00000011UL: |
867 | return lg_CopyPrivAttrSigned(attribute, type, |
868 | key->u.dsa.privateValue.data, |
869 | key->u.dsa.privateValue.len, sdbpw); |
870 | case CKA_PRIME0x00000130UL: |
871 | return lg_CopyAttributeSigned(attribute, type, |
872 | key->u.dsa.params.prime.data, |
873 | key->u.dsa.params.prime.len); |
874 | case CKA_SUBPRIME0x00000131UL: |
875 | return lg_CopyAttributeSigned(attribute, type, |
876 | key->u.dsa.params.subPrime.data, |
877 | key->u.dsa.params.subPrime.len); |
878 | case CKA_BASE0x00000132UL: |
879 | return lg_CopyAttributeSigned(attribute, type, |
880 | key->u.dsa.params.base.data, |
881 | key->u.dsa.params.base.len); |
882 | case CKA_NSS_DB0xD5A0DB00L: |
883 | return lg_CopyAttributeSigned(attribute, type, |
884 | key->u.dsa.publicValue.data, |
885 | key->u.dsa.publicValue.len); |
886 | default: |
887 | break; |
888 | } |
889 | return lg_invalidAttribute(attribute); |
890 | } |
891 | |
892 | static CK_RV |
893 | lg_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, |
894 | CK_ATTRIBUTE *attribute, SDB *sdbpw) |
895 | { |
896 | unsigned char hash[SHA1_LENGTH20]; |
897 | CK_KEY_TYPE keyType = CKK_DH0x00000002UL; |
898 | |
899 | switch (type) { |
900 | case CKA_KEY_TYPE0x00000100UL: |
901 | return lg_ULongAttribute(attribute, type, keyType); |
902 | case CKA_ID0x00000102UL: |
903 | SHA1_HashBuf(hash, key->u.dh.publicValue.data, key->u.dh.publicValue.len); |
904 | return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH20); |
905 | case CKA_DERIVE0x0000010CUL: |
906 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
907 | case CKA_DECRYPT0x00000105UL: |
908 | case CKA_SIGN0x00000108UL: |
909 | case CKA_SIGN_RECOVER0x00000109UL: |
910 | case CKA_UNWRAP0x00000107UL: |
911 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
912 | case CKA_VALUE0x00000011UL: |
913 | return lg_CopyPrivAttrSigned(attribute, type, |
914 | key->u.dh.privateValue.data, |
915 | key->u.dh.privateValue.len, sdbpw); |
916 | case CKA_PRIME0x00000130UL: |
917 | return lg_CopyAttributeSigned(attribute, type, key->u.dh.prime.data, |
918 | key->u.dh.prime.len); |
919 | case CKA_BASE0x00000132UL: |
920 | return lg_CopyAttributeSigned(attribute, type, key->u.dh.base.data, |
921 | key->u.dh.base.len); |
922 | case CKA_NSS_DB0xD5A0DB00L: |
923 | return lg_CopyAttributeSigned(attribute, type, |
924 | key->u.dh.publicValue.data, |
925 | key->u.dh.publicValue.len); |
926 | default: |
927 | break; |
928 | } |
929 | return lg_invalidAttribute(attribute); |
930 | } |
931 | |
932 | static CK_RV |
933 | lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, |
934 | CK_ATTRIBUTE *attribute, SDB *sdbpw) |
935 | { |
936 | unsigned char hash[SHA1_LENGTH20]; |
937 | CK_KEY_TYPE keyType = CKK_EC0x00000003UL; |
938 | |
939 | switch (type) { |
940 | case CKA_KEY_TYPE0x00000100UL: |
941 | return lg_ULongAttribute(attribute, type, keyType); |
942 | case CKA_ID0x00000102UL: |
943 | SHA1_HashBuf(hash, key->u.ec.publicValue.data, key->u.ec.publicValue.len); |
944 | return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH20); |
945 | case CKA_DERIVE0x0000010CUL: |
946 | case CKA_SIGN0x00000108UL: |
947 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
948 | case CKA_DECRYPT0x00000105UL: |
949 | case CKA_SIGN_RECOVER0x00000109UL: |
950 | case CKA_UNWRAP0x00000107UL: |
951 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
952 | case CKA_VALUE0x00000011UL: |
953 | return lg_CopyPrivAttribute(attribute, type, |
954 | key->u.ec.privateValue.data, |
955 | key->u.ec.privateValue.len, sdbpw); |
956 | case CKA_EC_PARAMS0x00000180UL: |
957 | return lg_CopyAttributeSigned(attribute, type, |
958 | key->u.ec.ecParams.DEREncoding.data, |
959 | key->u.ec.ecParams.DEREncoding.len); |
960 | case CKA_NSS_DB0xD5A0DB00L: |
961 | return lg_CopyAttributeSigned(attribute, type, |
962 | key->u.ec.publicValue.data, |
963 | key->u.ec.publicValue.len); |
964 | default: |
965 | break; |
966 | } |
967 | return lg_invalidAttribute(attribute); |
968 | } |
969 | |
970 | static CK_RV |
971 | lg_FindPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, |
972 | CK_ATTRIBUTE *attribute) |
973 | { |
974 | NSSLOWKEYPrivateKey *key; |
975 | char *label; |
976 | CK_RV crv; |
977 | |
978 | switch (type) { |
979 | case CKA_PRIVATE0x00000002UL: |
980 | case CKA_SENSITIVE0x00000103UL: |
981 | case CKA_ALWAYS_SENSITIVE0x00000165UL: |
982 | case CKA_EXTRACTABLE0x00000162UL: |
983 | case CKA_MODIFIABLE0x00000170UL: |
984 | case CKA_LOCAL0x00000163UL: |
985 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
986 | case CKA_NEVER_EXTRACTABLE0x00000164UL: |
987 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
988 | case CKA_SUBJECT0x00000101UL: |
989 | return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
990 | case CKA_START_DATE0x00000110UL: |
991 | case CKA_END_DATE0x00000111UL: |
992 | return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
993 | case CKA_LABEL0x00000003UL: |
994 | label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey); |
995 | if (label == NULL((void*)0)) { |
996 | return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
997 | } |
998 | crv = lg_CopyAttribute(attribute, type, label, PORT_Strlen(label)strlen(label)); |
999 | PORT_FreePORT_Free_Util(label); |
1000 | return crv; |
1001 | default: |
1002 | break; |
1003 | } |
1004 | key = lg_GetPrivateKey(obj); |
1005 | if (key == NULL((void*)0)) { |
1006 | return CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
1007 | } |
1008 | switch (key->keyType) { |
1009 | case NSSLOWKEYRSAKey: |
1010 | return lg_FindRSAPrivateKeyAttribute(key, type, attribute, obj->sdb); |
1011 | case NSSLOWKEYDSAKey: |
1012 | return lg_FindDSAPrivateKeyAttribute(key, type, attribute, obj->sdb); |
1013 | case NSSLOWKEYDHKey: |
1014 | return lg_FindDHPrivateKeyAttribute(key, type, attribute, obj->sdb); |
1015 | case NSSLOWKEYECKey: |
1016 | return lg_FindECPrivateKeyAttribute(key, type, attribute, obj->sdb); |
1017 | default: |
1018 | break; |
1019 | } |
1020 | |
1021 | return lg_invalidAttribute(attribute); |
1022 | } |
1023 | |
1024 | static CK_RV |
1025 | lg_FindSMIMEAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, |
1026 | CK_ATTRIBUTE *attribute) |
1027 | { |
1028 | certDBEntrySMime *entry; |
1029 | switch (type) { |
1030 | case CKA_PRIVATE0x00000002UL: |
1031 | case CKA_MODIFIABLE0x00000170UL: |
1032 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
1033 | case CKA_NSS_EMAIL((0x80000000UL | 0x4E534350) + 2): |
1034 | return lg_CopyAttribute(attribute, type, obj->dbKey.data, |
1035 | obj->dbKey.len - 1); |
1036 | case CKA_NSS_SMIME_TIMESTAMP((0x80000000UL | 0x4E534350) + 4): |
1037 | case CKA_SUBJECT0x00000101UL: |
1038 | case CKA_VALUE0x00000011UL: |
1039 | break; |
1040 | default: |
1041 | return lg_invalidAttribute(attribute); |
1042 | } |
1043 | entry = lg_getSMime(obj); |
1044 | if (entry == NULL((void*)0)) { |
1045 | return CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
1046 | } |
1047 | switch (type) { |
1048 | case CKA_NSS_SMIME_TIMESTAMP((0x80000000UL | 0x4E534350) + 4): |
1049 | return lg_CopyAttribute(attribute, type, entry->optionsDate.data, |
1050 | entry->optionsDate.len); |
1051 | case CKA_SUBJECT0x00000101UL: |
1052 | return lg_CopyAttribute(attribute, type, entry->subjectName.data, |
1053 | entry->subjectName.len); |
1054 | case CKA_VALUE0x00000011UL: |
1055 | return lg_CopyAttribute(attribute, type, entry->smimeOptions.data, |
1056 | entry->smimeOptions.len); |
1057 | default: |
1058 | break; |
1059 | } |
1060 | return lg_invalidAttribute(attribute); |
1061 | } |
1062 | |
1063 | static CK_RV |
1064 | lg_FindTrustAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, |
1065 | CK_ATTRIBUTE *attribute) |
1066 | { |
1067 | NSSLOWCERTTrust *trust; |
1068 | NSSLOWCERTCertDBHandle *certHandle; |
1069 | NSSLOWCERTCertificate *cert; |
1070 | unsigned char hash[SHA1_LENGTH20]; |
1071 | unsigned int trustFlags; |
1072 | CK_RV crv = CKR_CANCEL0x00000001UL; |
1073 | |
1074 | switch (type) { |
1075 | case CKA_PRIVATE0x00000002UL: |
1076 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
1077 | case CKA_MODIFIABLE0x00000170UL: |
1078 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
1079 | case CKA_CERT_SHA1_HASH(((0x80000000UL | 0x4E534350) + 0x2000) + 100): |
1080 | case CKA_CERT_MD5_HASH(((0x80000000UL | 0x4E534350) + 0x2000) + 101): |
1081 | case CKA_TRUST_CLIENT_AUTH(((0x80000000UL | 0x4E534350) + 0x2000) + 9): |
1082 | case CKA_TRUST_SERVER_AUTH(((0x80000000UL | 0x4E534350) + 0x2000) + 8): |
1083 | case CKA_TRUST_EMAIL_PROTECTION(((0x80000000UL | 0x4E534350) + 0x2000) + 11): |
1084 | case CKA_TRUST_CODE_SIGNING(((0x80000000UL | 0x4E534350) + 0x2000) + 10): |
1085 | case CKA_TRUST_STEP_UP_APPROVED(((0x80000000UL | 0x4E534350) + 0x2000) + 16): |
1086 | case CKA_ISSUER0x00000081UL: |
1087 | case CKA_SERIAL_NUMBER0x00000082UL: |
1088 | break; |
1089 | default: |
1090 | return lg_invalidAttribute(attribute); |
1091 | } |
1092 | certHandle = lg_getCertDB(obj->sdb); |
1093 | if (!certHandle) { |
1094 | return CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
1095 | } |
1096 | trust = lg_getTrust(obj, certHandle); |
1097 | if (trust == NULL((void*)0)) { |
1098 | return CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
1099 | } |
1100 | switch (type) { |
1101 | case CKA_CERT_SHA1_HASH(((0x80000000UL | 0x4E534350) + 0x2000) + 100): |
1102 | SHA1_HashBuf(hash, trust->derCert->data, trust->derCert->len); |
1103 | return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH20); |
1104 | case CKA_CERT_MD5_HASH(((0x80000000UL | 0x4E534350) + 0x2000) + 101): |
1105 | MD5_HashBuf(hash, trust->derCert->data, trust->derCert->len); |
1106 | return lg_CopyAttribute(attribute, type, hash, MD5_LENGTH16); |
1107 | case CKA_TRUST_CLIENT_AUTH(((0x80000000UL | 0x4E534350) + 0x2000) + 9): |
1108 | trustFlags = trust->trust->sslFlags & |
1109 | CERTDB_TRUSTED_CLIENT_CA(1u << 7) |
1110 | ? trust->trust->sslFlags | CERTDB_TRUSTED_CA(1u << 4) |
1111 | : 0; |
1112 | goto trust; |
1113 | case CKA_TRUST_SERVER_AUTH(((0x80000000UL | 0x4E534350) + 0x2000) + 8): |
1114 | trustFlags = trust->trust->sslFlags; |
1115 | goto trust; |
1116 | case CKA_TRUST_EMAIL_PROTECTION(((0x80000000UL | 0x4E534350) + 0x2000) + 11): |
1117 | trustFlags = trust->trust->emailFlags; |
1118 | goto trust; |
1119 | case CKA_TRUST_CODE_SIGNING(((0x80000000UL | 0x4E534350) + 0x2000) + 10): |
1120 | trustFlags = trust->trust->objectSigningFlags; |
1121 | trust: |
1122 | if (trustFlags & CERTDB_TRUSTED_CA(1u << 4)) { |
1123 | return lg_ULongAttribute(attribute, type, |
1124 | CKT_NSS_TRUSTED_DELEGATOR((0x80000000 | 0x4E534350) + 2)); |
1125 | } |
1126 | if (trustFlags & CERTDB_TRUSTED(1u << 1)) { |
1127 | return lg_ULongAttribute(attribute, type, CKT_NSS_TRUSTED((0x80000000 | 0x4E534350) + 1)); |
1128 | } |
1129 | if (trustFlags & CERTDB_MUST_VERIFY(1u << 10)) { |
1130 | return lg_ULongAttribute(attribute, type, |
1131 | CKT_NSS_MUST_VERIFY_TRUST((0x80000000 | 0x4E534350) + 3)); |
1132 | } |
1133 | if (trustFlags & CERTDB_TRUSTED_UNKNOWN(1u << 11)) { |
1134 | return lg_ULongAttribute(attribute, type, CKT_NSS_TRUST_UNKNOWN((0x80000000 | 0x4E534350) + 5)); |
1135 | } |
1136 | if (trustFlags & CERTDB_VALID_CA(1u << 3)) { |
1137 | return lg_ULongAttribute(attribute, type, CKT_NSS_VALID_DELEGATOR((0x80000000 | 0x4E534350) + 11)); |
1138 | } |
1139 | if (trustFlags & CERTDB_TERMINAL_RECORD(1u << 0)) { |
1140 | return lg_ULongAttribute(attribute, type, CKT_NSS_NOT_TRUSTED((0x80000000 | 0x4E534350) + 10)); |
1141 | } |
1142 | return lg_ULongAttribute(attribute, type, CKT_NSS_TRUST_UNKNOWN((0x80000000 | 0x4E534350) + 5)); |
1143 | case CKA_TRUST_STEP_UP_APPROVED(((0x80000000UL | 0x4E534350) + 0x2000) + 16): |
1144 | if (trust->trust->sslFlags & CERTDB_GOVT_APPROVED_CA(1u << 9)) { |
1145 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
1146 | } else { |
1147 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
1148 | } |
1149 | default: |
1150 | break; |
1151 | } |
1152 | |
1153 | switch (type) { |
1154 | case CKA_ISSUER0x00000081UL: |
1155 | cert = lg_getCert(obj, certHandle); |
1156 | if (cert == NULL((void*)0)) |
1157 | break; |
1158 | crv = lg_CopyAttribute(attribute, type, cert->derIssuer.data, |
1159 | cert->derIssuer.len); |
1160 | break; |
1161 | case CKA_SERIAL_NUMBER0x00000082UL: |
1162 | cert = lg_getCert(obj, certHandle); |
1163 | if (cert == NULL((void*)0)) |
1164 | break; |
1165 | crv = lg_CopyAttribute(attribute, type, cert->derSN.data, |
1166 | cert->derSN.len); |
1167 | break; |
1168 | default: |
1169 | cert = NULL((void*)0); |
1170 | break; |
1171 | } |
1172 | if (cert) { |
1173 | nsslowcert_DestroyCertificate(cert); |
1174 | return crv; |
1175 | } |
1176 | return lg_invalidAttribute(attribute); |
1177 | } |
1178 | |
1179 | static CK_RV |
1180 | lg_FindCrlAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, |
1181 | CK_ATTRIBUTE *attribute) |
1182 | { |
1183 | certDBEntryRevocation *crl; |
1184 | |
1185 | switch (type) { |
1186 | case CKA_PRIVATE0x00000002UL: |
1187 | case CKA_MODIFIABLE0x00000170UL: |
1188 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
1189 | case CKA_NSS_KRL((0x80000000UL | 0x4E534350) + 8): |
1190 | return ((obj->handle == LG_TOKEN_KRL_HANDLE(0x28000000L | 1)) |
1191 | ? LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen) |
1192 | : LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen)); |
1193 | case CKA_SUBJECT0x00000101UL: |
1194 | return lg_CopyAttribute(attribute, type, obj->dbKey.data, |
1195 | obj->dbKey.len); |
1196 | case CKA_NSS_URL((0x80000000UL | 0x4E534350) + 1): |
1197 | case CKA_VALUE0x00000011UL: |
1198 | break; |
1199 | default: |
1200 | return lg_invalidAttribute(attribute); |
1201 | } |
1202 | crl = lg_getCrl(obj); |
1203 | if (!crl) { |
1204 | return CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
1205 | } |
1206 | switch (type) { |
1207 | case CKA_NSS_URL((0x80000000UL | 0x4E534350) + 1): |
1208 | if (crl->url == NULL((void*)0)) { |
1209 | return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
1210 | } |
1211 | return lg_CopyAttribute(attribute, type, crl->url, |
1212 | PORT_Strlen(crl->url)strlen(crl->url) + 1); |
1213 | case CKA_VALUE0x00000011UL: |
1214 | return lg_CopyAttribute(attribute, type, crl->derCrl.data, |
1215 | crl->derCrl.len); |
1216 | default: |
1217 | break; |
1218 | } |
1219 | return lg_invalidAttribute(attribute); |
1220 | } |
1221 | |
1222 | static CK_RV |
1223 | lg_FindCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, |
1224 | CK_ATTRIBUTE *attribute) |
1225 | { |
1226 | NSSLOWCERTCertificate *cert; |
1227 | NSSLOWCERTCertDBHandle *certHandle; |
1228 | NSSLOWKEYPublicKey *pubKey; |
1229 | unsigned char hash[SHA1_LENGTH20]; |
1230 | SECItem *item; |
1231 | |
1232 | switch (type) { |
1233 | case CKA_PRIVATE0x00000002UL: |
1234 | return LG_CLONE_ATTR(attribute, type, lg_StaticFalseAttr)lg_CopyAttribute(attribute, type, lg_StaticFalseAttr.pValue, lg_StaticFalseAttr .ulValueLen); |
1235 | case CKA_MODIFIABLE0x00000170UL: |
1236 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
1237 | case CKA_CERTIFICATE_TYPE0x00000080UL: |
1238 | /* hardcoding X.509 into here */ |
1239 | return lg_ULongAttribute(attribute, type, CKC_X_5090x00000000UL); |
1240 | case CKA_VALUE0x00000011UL: |
1241 | case CKA_ID0x00000102UL: |
1242 | case CKA_LABEL0x00000003UL: |
1243 | case CKA_SUBJECT0x00000101UL: |
1244 | case CKA_ISSUER0x00000081UL: |
1245 | case CKA_SERIAL_NUMBER0x00000082UL: |
1246 | case CKA_NSS_EMAIL((0x80000000UL | 0x4E534350) + 2): |
1247 | break; |
1248 | default: |
1249 | return lg_invalidAttribute(attribute); |
1250 | } |
1251 | |
1252 | certHandle = lg_getCertDB(obj->sdb); |
1253 | if (certHandle == NULL((void*)0)) { |
1254 | return CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
1255 | } |
1256 | |
1257 | cert = lg_getCert(obj, certHandle); |
1258 | if (cert == NULL((void*)0)) { |
1259 | return CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
1260 | } |
1261 | switch (type) { |
1262 | case CKA_VALUE0x00000011UL: |
1263 | return lg_CopyAttribute(attribute, type, cert->derCert.data, |
1264 | cert->derCert.len); |
1265 | case CKA_ID0x00000102UL: |
1266 | if (((cert->trust->sslFlags & CERTDB_USER(1u << 6)) == 0) && |
1267 | ((cert->trust->emailFlags & CERTDB_USER(1u << 6)) == 0) && |
1268 | ((cert->trust->objectSigningFlags & CERTDB_USER(1u << 6)) == 0)) { |
1269 | return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
1270 | } |
1271 | pubKey = nsslowcert_ExtractPublicKey(cert); |
1272 | if (pubKey == NULL((void*)0)) |
1273 | break; |
1274 | item = lg_GetPubItem(pubKey); |
1275 | if (item == NULL((void*)0)) { |
1276 | lg_nsslowkey_DestroyPublicKey(pubKey); |
1277 | break; |
1278 | } |
1279 | SHA1_HashBuf(hash, item->data, item->len); |
1280 | /* item is imbedded in pubKey, just free the key */ |
1281 | lg_nsslowkey_DestroyPublicKey(pubKey); |
1282 | return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH20); |
1283 | case CKA_LABEL0x00000003UL: |
1284 | return cert->nickname |
1285 | ? lg_CopyAttribute(attribute, type, cert->nickname, |
1286 | PORT_Strlen(cert->nickname)strlen(cert->nickname)) |
1287 | : LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
1288 | case CKA_SUBJECT0x00000101UL: |
1289 | return lg_CopyAttribute(attribute, type, cert->derSubject.data, |
1290 | cert->derSubject.len); |
1291 | case CKA_ISSUER0x00000081UL: |
1292 | return lg_CopyAttribute(attribute, type, cert->derIssuer.data, |
1293 | cert->derIssuer.len); |
1294 | case CKA_SERIAL_NUMBER0x00000082UL: |
1295 | return lg_CopyAttribute(attribute, type, cert->derSN.data, |
1296 | cert->derSN.len); |
1297 | case CKA_NSS_EMAIL((0x80000000UL | 0x4E534350) + 2): |
1298 | return (cert->emailAddr && cert->emailAddr[0]) |
1299 | ? lg_CopyAttribute(attribute, type, cert->emailAddr, |
1300 | PORT_Strlen(cert->emailAddr)strlen(cert->emailAddr)) |
1301 | : LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
1302 | default: |
1303 | break; |
1304 | } |
1305 | return lg_invalidAttribute(attribute); |
1306 | } |
1307 | |
1308 | CK_RV |
1309 | lg_GetSingleAttribute(LGObjectCache *obj, CK_ATTRIBUTE *attribute) |
1310 | { |
1311 | /* handle the common ones */ |
1312 | CK_ATTRIBUTE_TYPE type = attribute->type; |
1313 | switch (type) { |
1314 | case CKA_CLASS0x00000000UL: |
1315 | return lg_ULongAttribute(attribute, type, obj->objclass); |
1316 | case CKA_TOKEN0x00000001UL: |
1317 | return LG_CLONE_ATTR(attribute, type, lg_StaticTrueAttr)lg_CopyAttribute(attribute, type, lg_StaticTrueAttr.pValue, lg_StaticTrueAttr .ulValueLen); |
1318 | case CKA_LABEL0x00000003UL: |
1319 | if ((obj->objclass == CKO_CERTIFICATE0x00000001UL) || |
1320 | (obj->objclass == CKO_PRIVATE_KEY0x00000003UL) || |
1321 | (obj->objclass == CKO_PUBLIC_KEY0x00000002UL) || |
1322 | (obj->objclass == CKO_SECRET_KEY0x00000004UL)) { |
1323 | break; |
1324 | } |
1325 | return LG_CLONE_ATTR(attribute, type, lg_StaticNullAttr)lg_CopyAttribute(attribute, type, lg_StaticNullAttr.pValue, lg_StaticNullAttr .ulValueLen); |
1326 | default: |
1327 | break; |
1328 | } |
1329 | switch (obj->objclass) { |
1330 | case CKO_CERTIFICATE0x00000001UL: |
1331 | return lg_FindCertAttribute(obj, type, attribute); |
1332 | case CKO_NSS_CRL((0x80000000UL | 0x4E534350) + 1): |
1333 | return lg_FindCrlAttribute(obj, type, attribute); |
1334 | case CKO_NSS_TRUST((0x80000000UL | 0x4E534350) + 3): |
1335 | return lg_FindTrustAttribute(obj, type, attribute); |
1336 | case CKO_NSS_SMIME((0x80000000UL | 0x4E534350) + 2): |
1337 | return lg_FindSMIMEAttribute(obj, type, attribute); |
1338 | case CKO_PUBLIC_KEY0x00000002UL: |
1339 | return lg_FindPublicKeyAttribute(obj, type, attribute); |
1340 | case CKO_PRIVATE_KEY0x00000003UL: |
1341 | return lg_FindPrivateKeyAttribute(obj, type, attribute); |
1342 | case CKO_SECRET_KEY0x00000004UL: |
1343 | return lg_FindSecretKeyAttribute(obj, type, attribute); |
1344 | default: |
1345 | break; |
1346 | } |
1347 | return lg_invalidAttribute(attribute); |
1348 | } |
1349 | |
1350 | /* |
1351 | * Fill in the attribute template based on the data in the database. |
1352 | */ |
1353 | CK_RV |
1354 | lg_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE *templ, |
1355 | CK_ULONG count) |
1356 | { |
1357 | LGObjectCache *obj = lg_NewObjectCache(sdb, NULL((void*)0), handle & ~LG_TOKEN_MASK0xc0000000L); |
1358 | CK_RV crv, crvCollect = CKR_OK0x00000000UL; |
1359 | unsigned int i; |
1360 | |
1361 | if (obj == NULL((void*)0)) { |
1362 | return CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
1363 | } |
1364 | |
1365 | for (i = 0; i < count; i++) { |
1366 | crv = lg_GetSingleAttribute(obj, &templ[i]); |
1367 | if (crvCollect == CKR_OK0x00000000UL) |
1368 | crvCollect = crv; |
1369 | } |
1370 | |
1371 | lg_DestroyObjectCache(obj); |
1372 | return crvCollect; |
1373 | } |
1374 | |
1375 | PRBool |
1376 | lg_cmpAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attribute) |
1377 | { |
1378 | unsigned char buf[LG_BUF_SPACE50]; |
1379 | CK_ATTRIBUTE testAttr; |
1380 | unsigned char *tempBuf = NULL((void*)0); |
1381 | PRBool match = PR_TRUE1; |
1382 | CK_RV crv; |
1383 | |
1384 | /* we're going to compare 'attribute' with the actual attribute from |
1385 | * the object. We'll use the length of 'attribute' to decide how much |
1386 | * space we need to read the test attribute. If 'attribute' doesn't give |
1387 | * enough space, then we know the values don't match and that will |
1388 | * show up as ckr != CKR_OK */ |
1389 | testAttr = *attribute; |
1390 | testAttr.pValue = buf; |
1391 | |
1392 | /* if we don't have enough space, malloc it */ |
1393 | if (attribute->ulValueLen > LG_BUF_SPACE50) { |
1394 | tempBuf = PORT_AllocPORT_Alloc_Util(attribute->ulValueLen); |
1395 | if (!tempBuf) { |
1396 | return PR_FALSE0; |
1397 | } |
1398 | testAttr.pValue = tempBuf; |
1399 | } |
1400 | |
1401 | /* get the attribute */ |
1402 | crv = lg_GetSingleAttribute(obj, &testAttr); |
1403 | /* if the attribute was read OK, compare it */ |
1404 | if ((crv != CKR_OK0x00000000UL) || |
1405 | (attribute->pValue == NULL((void*)0)) || |
1406 | (attribute->ulValueLen != testAttr.ulValueLen) || |
1407 | (PORT_Memcmpmemcmp(attribute->pValue, testAttr.pValue, testAttr.ulValueLen) != 0)) { |
1408 | /* something didn't match, this isn't the object we are looking for */ |
1409 | match = PR_FALSE0; |
1410 | } |
1411 | /* free the buffer we may have allocated */ |
1412 | if (tempBuf) { |
1413 | PORT_FreePORT_Free_Util(tempBuf); |
1414 | } |
1415 | return match; |
1416 | } |
1417 | |
1418 | PRBool |
1419 | lg_tokenMatch(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE class, |
1420 | const CK_ATTRIBUTE *templ, CK_ULONG count) |
1421 | { |
1422 | PRBool match = PR_TRUE1; |
1423 | LGObjectCache *obj = lg_NewObjectCache(sdb, dbKey, class); |
1424 | unsigned int i; |
1425 | |
1426 | if (obj == NULL((void*)0)) { |
1427 | return PR_FALSE0; |
1428 | } |
1429 | |
1430 | for (i = 0; i < count; i++) { |
1431 | match = lg_cmpAttribute(obj, &templ[i]); |
1432 | if (!match) { |
1433 | break; |
1434 | } |
1435 | } |
1436 | |
1437 | /* done looking, free up our cache */ |
1438 | lg_DestroyObjectCache(obj); |
1439 | |
1440 | /* if we get through the whole list without finding a mismatched attribute, |
1441 | * then this object fits the criteria we are matching */ |
1442 | return match; |
1443 | } |
1444 | |
1445 | static CK_RV |
1446 | lg_SetCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, |
1447 | const void *value, unsigned int len) |
1448 | { |
1449 | NSSLOWCERTCertificate *cert; |
1450 | NSSLOWCERTCertDBHandle *certHandle; |
1451 | char *nickname = NULL((void*)0); |
1452 | SECStatus rv; |
1453 | CK_RV crv; |
1454 | |
1455 | /* we can't change the EMAIL values, but let the |
1456 | * upper layers feel better about the fact we tried to set these */ |
1457 | if (type == CKA_NSS_EMAIL((0x80000000UL | 0x4E534350) + 2)) { |
1458 | return CKR_OK0x00000000UL; |
1459 | } |
1460 | |
1461 | certHandle = lg_getCertDB(obj->sdb); |
1462 | if (certHandle == NULL((void*)0)) { |
1463 | crv = CKR_TOKEN_WRITE_PROTECTED0x000000E2UL; |
1464 | goto done; |
1465 | } |
1466 | |
1467 | if ((type != CKA_LABEL0x00000003UL) && (type != CKA_ID0x00000102UL)) { |
1468 | crv = CKR_ATTRIBUTE_READ_ONLY0x00000010UL; |
1469 | goto done; |
1470 | } |
1471 | |
1472 | cert = lg_getCert(obj, certHandle); |
1473 | if (cert == NULL((void*)0)) { |
1474 | crv = CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
1475 | goto done; |
1476 | } |
1477 | |
1478 | /* if the app is trying to set CKA_ID, it's probably because it just |
1479 | * imported the key. Look to see if we need to set the CERTDB_USER bits. |
1480 | */ |
1481 | if (type == CKA_ID0x00000102UL) { |
1482 | if (((cert->trust->sslFlags & CERTDB_USER(1u << 6)) == 0) && |
1483 | ((cert->trust->emailFlags & CERTDB_USER(1u << 6)) == 0) && |
1484 | ((cert->trust->objectSigningFlags & CERTDB_USER(1u << 6)) == 0)) { |
1485 | NSSLOWKEYDBHandle *keyHandle; |
1486 | |
1487 | keyHandle = lg_getKeyDB(obj->sdb); |
1488 | if (keyHandle) { |
1489 | if (nsslowkey_KeyForCertExists(keyHandle, cert)) { |
1490 | NSSLOWCERTCertTrust trust = *cert->trust; |
1491 | trust.sslFlags |= CERTDB_USER(1u << 6); |
1492 | trust.emailFlags |= CERTDB_USER(1u << 6); |
1493 | trust.objectSigningFlags |= CERTDB_USER(1u << 6); |
1494 | nsslowcert_ChangeCertTrust(certHandle, cert, &trust); |
1495 | } |
1496 | } |
1497 | } |
1498 | crv = CKR_OK0x00000000UL; |
1499 | goto done; |
1500 | } |
1501 | |
1502 | /* must be CKA_LABEL */ |
1503 | if (value != NULL((void*)0)) { |
1504 | nickname = PORT_ZAllocPORT_ZAlloc_Util(len + 1); |
1505 | if (nickname == NULL((void*)0)) { |
1506 | crv = CKR_HOST_MEMORY0x00000002UL; |
1507 | goto done; |
1508 | } |
1509 | PORT_Memcpymemcpy(nickname, value, len); |
1510 | nickname[len] = 0; |
1511 | } |
1512 | rv = nsslowcert_AddPermNickname(certHandle, cert, nickname); |
1513 | crv = (rv == SECSuccess) ? CKR_OK0x00000000UL : CKR_DEVICE_ERROR0x00000030UL; |
1514 | |
1515 | done: |
1516 | if (nickname) { |
1517 | PORT_FreePORT_Free_Util(nickname); |
1518 | } |
1519 | return crv; |
1520 | } |
1521 | |
1522 | static CK_RV |
1523 | lg_SetPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, |
1524 | const void *value, unsigned int len, |
1525 | PRBool *writePrivate) |
1526 | { |
1527 | NSSLOWKEYPrivateKey *privKey; |
1528 | NSSLOWKEYDBHandle *keyHandle; |
1529 | char *nickname = NULL((void*)0); |
1530 | SECStatus rv; |
1531 | CK_RV crv; |
1532 | |
1533 | /* we can't change the ID and we don't store the subject, but let the |
1534 | * upper layers feel better about the fact we tried to set these */ |
1535 | if ((type == CKA_ID0x00000102UL) || (type == CKA_SUBJECT0x00000101UL) || |
1536 | (type == CKA_LOCAL0x00000163UL) || (type == CKA_NEVER_EXTRACTABLE0x00000164UL) || |
1537 | (type == CKA_ALWAYS_SENSITIVE0x00000165UL)) { |
1538 | return CKR_OK0x00000000UL; |
1539 | } |
1540 | |
1541 | keyHandle = lg_getKeyDB(obj->sdb); |
1542 | if (keyHandle == NULL((void*)0)) { |
1543 | crv = CKR_TOKEN_WRITE_PROTECTED0x000000E2UL; |
1544 | goto done; |
1545 | } |
1546 | |
1547 | privKey = lg_GetPrivateKeyWithDB(obj, keyHandle); |
1548 | if (privKey == NULL((void*)0)) { |
1549 | crv = CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
1550 | goto done; |
1551 | } |
1552 | |
1553 | crv = CKR_ATTRIBUTE_READ_ONLY0x00000010UL; |
1554 | switch (type) { |
1555 | case CKA_LABEL0x00000003UL: |
1556 | if (value != NULL((void*)0)) { |
1557 | nickname = PORT_ZAllocPORT_ZAlloc_Util(len + 1); |
1558 | if (nickname == NULL((void*)0)) { |
1559 | crv = CKR_HOST_MEMORY0x00000002UL; |
1560 | goto done; |
1561 | } |
1562 | PORT_Memcpymemcpy(nickname, value, len); |
1563 | nickname[len] = 0; |
1564 | } |
1565 | rv = nsslowkey_UpdateNickname(keyHandle, privKey, &obj->dbKey, |
1566 | nickname, obj->sdb); |
1567 | crv = (rv == SECSuccess) ? CKR_OK0x00000000UL : CKR_DEVICE_ERROR0x00000030UL; |
1568 | break; |
1569 | case CKA_UNWRAP0x00000107UL: |
1570 | case CKA_SIGN0x00000108UL: |
1571 | case CKA_DERIVE0x0000010CUL: |
1572 | case CKA_SIGN_RECOVER0x00000109UL: |
1573 | case CKA_DECRYPT0x00000105UL: |
1574 | /* ignore attempts to change restrict these. |
1575 | * legacyDB ignore these flags and always presents all of them |
1576 | * that are valid as true. |
1577 | * NOTE: We only get here if the current value and the new value do |
1578 | * not match. */ |
1579 | if (*(char *)value == 0) { |
1580 | crv = CKR_OK0x00000000UL; |
1581 | } |
1582 | break; |
1583 | case CKA_VALUE0x00000011UL: |
1584 | case CKA_PRIVATE_EXPONENT0x00000123UL: |
1585 | case CKA_PRIME_10x00000124UL: |
1586 | case CKA_PRIME_20x00000125UL: |
1587 | case CKA_EXPONENT_10x00000126UL: |
1588 | case CKA_EXPONENT_20x00000127UL: |
1589 | case CKA_COEFFICIENT0x00000128UL: |
1590 | /* We aren't really changing these values, we are just triggering |
1591 | * the database to update it's entry */ |
1592 | *writePrivate = PR_TRUE1; |
1593 | crv = CKR_OK0x00000000UL; |
1594 | break; |
1595 | default: |
1596 | crv = CKR_ATTRIBUTE_READ_ONLY0x00000010UL; |
1597 | break; |
1598 | } |
1599 | done: |
1600 | if (nickname) { |
1601 | PORT_FreePORT_Free_Util(nickname); |
1602 | } |
1603 | return crv; |
1604 | } |
1605 | |
1606 | static CK_RV |
1607 | lg_SetPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, |
1608 | const void *value, unsigned int len, |
1609 | PRBool *writePrivate) |
1610 | { |
1611 | /* we can't change the ID and we don't store the subject, but let the |
1612 | * upper layers feel better about the fact we tried to set these */ |
1613 | if ((type == CKA_ID0x00000102UL) || (type == CKA_SUBJECT0x00000101UL) || (type == CKA_LABEL0x00000003UL)) { |
1614 | return CKR_OK0x00000000UL; |
1615 | } |
1616 | return CKR_ATTRIBUTE_READ_ONLY0x00000010UL; |
1617 | } |
1618 | |
1619 | static CK_RV |
1620 | lg_SetTrustAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr) |
1621 | { |
1622 | unsigned int flags; |
1623 | CK_TRUST trust; |
1624 | NSSLOWCERTCertificate *cert = NULL((void*)0); |
1625 | NSSLOWCERTCertDBHandle *certHandle; |
1626 | NSSLOWCERTCertTrust dbTrust; |
1627 | SECStatus rv; |
1628 | CK_RV crv; |
1629 | |
1630 | if (attr->type == CKA_LABEL0x00000003UL) { |
1631 | return CKR_OK0x00000000UL; |
1632 | } |
1633 | |
1634 | crv = lg_GetULongAttribute(attr->type, attr, 1, &trust); |
1635 | if (crv != CKR_OK0x00000000UL) { |
1636 | return crv; |
1637 | } |
1638 | flags = lg_MapTrust(trust, (PRBool)(attr->type == CKA_TRUST_CLIENT_AUTH(((0x80000000UL | 0x4E534350) + 0x2000) + 9))); |
1639 | |
1640 | certHandle = lg_getCertDB(obj->sdb); |
1641 | |
1642 | if (certHandle == NULL((void*)0)) { |
1643 | crv = CKR_TOKEN_WRITE_PROTECTED0x000000E2UL; |
1644 | goto done; |
1645 | } |
1646 | |
1647 | cert = lg_getCert(obj, certHandle); |
1648 | if (cert == NULL((void*)0)) { |
1649 | crv = CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
1650 | goto done; |
1651 | } |
1652 | dbTrust = *cert->trust; |
1653 | |
1654 | switch (attr->type) { |
1655 | case CKA_TRUST_EMAIL_PROTECTION(((0x80000000UL | 0x4E534350) + 0x2000) + 11): |
1656 | dbTrust.emailFlags = flags | |
1657 | (cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS((1u << 6) | (1u << 5) | (1u << 3) | (1u << 8) | (1u << 9))); |
1658 | break; |
1659 | case CKA_TRUST_CODE_SIGNING(((0x80000000UL | 0x4E534350) + 0x2000) + 10): |
1660 | dbTrust.objectSigningFlags = flags | |
1661 | (cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS((1u << 6) | (1u << 5) | (1u << 3) | (1u << 8) | (1u << 9))); |
1662 | break; |
1663 | case CKA_TRUST_CLIENT_AUTH(((0x80000000UL | 0x4E534350) + 0x2000) + 9): |
1664 | dbTrust.sslFlags = flags | (cert->trust->sslFlags & |
1665 | (CERTDB_PRESERVE_TRUST_BITS((1u << 6) | (1u << 5) | (1u << 3) | (1u << 8) | (1u << 9)) | CERTDB_TRUSTED_CA(1u << 4))); |
1666 | break; |
1667 | case CKA_TRUST_SERVER_AUTH(((0x80000000UL | 0x4E534350) + 0x2000) + 8): |
1668 | dbTrust.sslFlags = flags | (cert->trust->sslFlags & |
1669 | (CERTDB_PRESERVE_TRUST_BITS((1u << 6) | (1u << 5) | (1u << 3) | (1u << 8) | (1u << 9)) | CERTDB_TRUSTED_CLIENT_CA(1u << 7))); |
1670 | break; |
1671 | default: |
1672 | crv = CKR_ATTRIBUTE_READ_ONLY0x00000010UL; |
1673 | goto done; |
1674 | } |
1675 | |
1676 | rv = nsslowcert_ChangeCertTrust(certHandle, cert, &dbTrust); |
1677 | crv = (rv == SECSuccess) ? CKR_OK0x00000000UL : CKR_DEVICE_ERROR0x00000030UL; |
1678 | done: |
1679 | if (cert) { |
1680 | nsslowcert_DestroyCertificate(cert); |
1681 | } |
1682 | return crv; |
1683 | } |
1684 | |
1685 | static CK_RV |
1686 | lg_SetSingleAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr, |
1687 | PRBool *writePrivate) |
1688 | { |
1689 | CK_ATTRIBUTE attribLocal; |
1690 | CK_RV crv; |
1691 | |
1692 | if ((attr->type == CKA_NSS_DB0xD5A0DB00L) && (obj->objclass == CKO_PRIVATE_KEY0x00000003UL)) { |
1693 | *writePrivate = PR_TRUE1; |
1694 | return CKR_OK0x00000000UL; |
1695 | } |
1696 | |
1697 | /* Make sure the attribute exists first */ |
1698 | attribLocal.type = attr->type; |
1699 | attribLocal.pValue = NULL((void*)0); |
1700 | attribLocal.ulValueLen = 0; |
1701 | crv = lg_GetSingleAttribute(obj, &attribLocal); |
1702 | if (crv != CKR_OK0x00000000UL) { |
1703 | return crv; |
1704 | } |
1705 | |
1706 | /* if we are just setting it to the value we already have, |
1707 | * allow it to happen. Let label setting go through so |
1708 | * we have the opportunity to repair any database corruption. */ |
1709 | if (attr->type != CKA_LABEL0x00000003UL) { |
1710 | if (lg_cmpAttribute(obj, attr)) { |
1711 | return CKR_OK0x00000000UL; |
1712 | } |
1713 | } |
1714 | |
1715 | crv = CKR_ATTRIBUTE_READ_ONLY0x00000010UL; |
1716 | switch (obj->objclass) { |
1717 | case CKO_CERTIFICATE0x00000001UL: |
1718 | /* change NICKNAME, EMAIL, */ |
1719 | crv = lg_SetCertAttribute(obj, attr->type, |
1720 | attr->pValue, attr->ulValueLen); |
1721 | break; |
1722 | case CKO_NSS_CRL((0x80000000UL | 0x4E534350) + 1): |
1723 | /* change URL */ |
1724 | break; |
1725 | case CKO_NSS_TRUST((0x80000000UL | 0x4E534350) + 3): |
1726 | crv = lg_SetTrustAttribute(obj, attr); |
1727 | break; |
1728 | case CKO_PRIVATE_KEY0x00000003UL: |
1729 | case CKO_SECRET_KEY0x00000004UL: |
1730 | crv = lg_SetPrivateKeyAttribute(obj, attr->type, |
1731 | attr->pValue, attr->ulValueLen, writePrivate); |
1732 | break; |
1733 | case CKO_PUBLIC_KEY0x00000002UL: |
1734 | crv = lg_SetPublicKeyAttribute(obj, attr->type, |
1735 | attr->pValue, attr->ulValueLen, writePrivate); |
1736 | break; |
1737 | } |
1738 | return crv; |
1739 | } |
1740 | |
1741 | /* |
1742 | * Fill in the attribute template based on the data in the database. |
1743 | */ |
1744 | CK_RV |
1745 | lg_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle, |
1746 | const CK_ATTRIBUTE *templ, CK_ULONG count) |
1747 | { |
1748 | LGObjectCache *obj = lg_NewObjectCache(sdb, NULL((void*)0), handle & ~LG_TOKEN_MASK0xc0000000L); |
1749 | CK_RV crv, crvCollect = CKR_OK0x00000000UL; |
1750 | PRBool writePrivate = PR_FALSE0; |
1751 | unsigned int i; |
1752 | |
1753 | if (obj == NULL((void*)0)) { |
1754 | return CKR_OBJECT_HANDLE_INVALID0x00000082UL; |
1755 | } |
1756 | |
1757 | for (i = 0; i < count; i++) { |
1758 | crv = lg_SetSingleAttribute(obj, &templ[i], &writePrivate); |
1759 | if (crvCollect == CKR_OK0x00000000UL) |
1760 | crvCollect = crv; |
1761 | } |
1762 | |
1763 | /* Write any collected changes out for private and secret keys. |
1764 | * don't do the write for just the label */ |
1765 | if (writePrivate) { |
1766 | NSSLOWKEYPrivateKey *privKey = lg_GetPrivateKey(obj); |
1767 | SECStatus rv = SECFailure; |
1768 | char *label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey); |
1769 | |
1770 | if (privKey) { |
1771 | rv = nsslowkey_StoreKeyByPublicKeyAlg(lg_getKeyDB(sdb), privKey, |
1772 | &obj->dbKey, label, sdb, PR_TRUE1); |
1773 | } |
1774 | if (rv != SECSuccess) { |
1775 | crv = CKR_DEVICE_ERROR0x00000030UL; |
1776 | } |
1777 | PORT_FreePORT_Free_Util(label); |
1778 | } |
1779 | |
1780 | lg_DestroyObjectCache(obj); |
1781 | return crvCollect; |
1782 | } |