Bug Summary

File:s/lib/softoken/legacydb/lgattr.c
Warning:line 1775, column 13
Value stored to 'crv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name lgattr.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/softoken/legacydb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nss/lib/softoken/legacydb -resource-dir /usr/lib/llvm-18/lib/clang/18 -D HAVE_STRERROR -D LINUX -D linux -D XP_UNIX -D XP_UNIX -D SHLIB_SUFFIX="so" -D SHLIB_PREFIX="lib" -D LG_LIB_NAME="libnssdbm3.so" -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D DEBUG -U NDEBUG -D _DEFAULT_SOURCE -D _BSD_SOURCE -D _POSIX_SOURCE -D SDB_MEASURE_USE_TEMP_DIR -D _REENTRANT -D NSS_DISABLE_SSE3 -D NSS_NO_INIT_SUPPORT -D USE_UTIL_DIRECTLY -D NO_NSPR_10_SUPPORT -D SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES -I ../../../../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../../dist/public/nss -I ../../../../dist/private/nss -I ../../../../dist/public/dbm -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c lgattr.c
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 */
20typedef 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
29static 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
38static void lg_DestroyObjectCache(LGObjectCache *obj);
39
40static LGObjectCache *
41lg_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;
73loser:
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 */
82static void
83lg_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
100static CK_RV
101lg_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
123static CK_RV
124lg_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
143static CK_RV
144lg_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
155static CK_RV
156lg_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);
170loser:
171 if (cipherText) {
172 SECITEM_FreeItemSECITEM_FreeItem_Util(cipherText, PR_TRUE1);
173 }
174 return crv;
175}
176
177static CK_RV
178lg_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
190static CK_RV
191lg_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
205CK_BBOOL lg_staticTrueValue = CK_TRUE1;
206CK_BBOOL lg_staticFalseValue = CK_FALSE0;
207static const CK_ATTRIBUTE lg_StaticTrueAttr =
208 LG_DEF_ATTRIBUTE(&lg_staticTrueValue, sizeof(lg_staticTrueValue)){ 0, &lg_staticTrueValue, sizeof(lg_staticTrueValue) };
209static const CK_ATTRIBUTE lg_StaticFalseAttr =
210 LG_DEF_ATTRIBUTE(&lg_staticFalseValue, sizeof(lg_staticFalseValue)){ 0, &lg_staticFalseValue, sizeof(lg_staticFalseValue) };
211static const CK_ATTRIBUTE lg_StaticNullAttr = LG_DEF_ATTRIBUTE(NULL, 0){ 0, ((void*)0), 0 };
212char lg_StaticOneValue = 1;
213
214/*
215 * helper functions which get the database and call the underlying
216 * low level database function.
217 */
218static char *
219lg_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
234NSSLOWKEYPrivateKey *
235lg_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
251static certDBEntrySMime *
252lg_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
274static certDBEntryRevocation *
275lg_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
300static NSSLOWCERTCertificate *
301lg_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
320static NSSLOWCERTTrust *
321lg_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
337static NSSLOWKEYPublicKey *
338lg_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 */
368static NSSLOWKEYPrivateKey *
369lg_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 */
390static NSSLOWKEYPrivateKey *
391lg_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 */
409static SECItem *
410lg_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
433static CK_RV
434lg_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
466static CK_RV
467lg_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
509static CK_RV
510lg_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
545static CK_RV
546lg_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
595static CK_RV
596lg_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
653static CK_RV
654lg_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;
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
790static CK_RV
791lg_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
845static CK_RV
846lg_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
892static CK_RV
893lg_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
932static CK_RV
933lg_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
970static CK_RV
971lg_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
1024static CK_RV
1025lg_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
1063static CK_RV
1064lg_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
1179static CK_RV
1180lg_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
1222static CK_RV
1223lg_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
1308CK_RV
1309lg_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 */
1353CK_RV
1354lg_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
1375PRBool
1376lg_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
1418PRBool
1419lg_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
1445static CK_RV
1446lg_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
1515done:
1516 if (nickname) {
1517 PORT_FreePORT_Free_Util(nickname);
1518 }
1519 return crv;
1520}
1521
1522static CK_RV
1523lg_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 }
1599done:
1600 if (nickname) {
1601 PORT_FreePORT_Free_Util(nickname);
1602 }
1603 return crv;
1604}
1605
1606static CK_RV
1607lg_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
1619static CK_RV
1620lg_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;
1678done:
1679 if (cert) {
1680 nsslowcert_DestroyCertificate(cert);
1681 }
1682 return crv;
1683}
1684
1685static CK_RV
1686lg_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 */
1744CK_RV
1745lg_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;
Value stored to 'crv' is never read
1776 }
1777 PORT_FreePORT_Free_Util(label);
1778 }
1779
1780 lg_DestroyObjectCache(obj);
1781 return crvCollect;
1782}