comparison nss/lib/softoken/legacydb/lgattr.c @ 3:150b72113545

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