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/. */
5
* Internal PKCS #11 functions. Should only be called by pkcs11.c
18
* Cache the object we are working on during Set's and Get's
20
typedef struct LGObjectCacheStr {
21
CK_OBJECT_CLASS objclass;
22
CK_OBJECT_HANDLE handle;
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,
34
#define handleToClass(handle) \
35
lg_classArray[((handle & LG_TOKEN_TYPE_MASK))>>LG_TOKEN_TYPE_SHIFT]
38
static void lg_DestroyObjectCache(LGObjectCache *obj);
40
static LGObjectCache *
41
lg_NewObjectCache(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE handle)
43
LGObjectCache *obj = NULL;
46
obj = PORT_New(LGObjectCache);
51
obj->objclass = handleToClass(handle);
54
obj->objectInfo = NULL;
56
obj->dbKey.data = NULL;
60
dbKey = lg_lookupTokenKeyByHandle(sdb,handle);
66
rv = SECITEM_CopyItem(NULL,&obj->dbKey,dbKey);
68
if (rv != SECSuccess) {
75
(void) lg_DestroyObjectCache(obj);
82
* free all the data associated with an object. Object reference count must
86
lg_DestroyObjectCache(LGObjectCache *obj)
88
if (obj->dbKey.data) {
89
PORT_Free(obj->dbKey.data);
90
obj->dbKey.data = NULL;
92
if (obj->objectInfo) {
93
(*obj->infoFree)(obj->objectInfo);
94
obj->objectInfo = NULL;
100
* ******************** Attribute Utilities *******************************
104
lg_ULongAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, CK_ULONG value)
109
if (attr->pValue == NULL) {
110
attr->ulValueLen = 4;
113
if (attr->ulValueLen < 4) {
114
attr->ulValueLen = (CK_ULONG) -1;
115
return CKR_BUFFER_TOO_SMALL;
118
data = (unsigned char *)attr->pValue;
119
for (i=0; i < 4; i++) {
120
data[i] = (value >> ((3-i)*8)) & 0xff;
122
attr->ulValueLen = 4;
127
lg_CopyAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type,
128
CK_VOID_PTR value, CK_ULONG len)
131
if (attr->pValue == NULL) {
132
attr->ulValueLen = len;
135
if (attr->ulValueLen < len) {
136
attr->ulValueLen = (CK_ULONG) -1;
137
return CKR_BUFFER_TOO_SMALL;
139
PORT_Memcpy(attr->pValue,value,len);
140
attr->ulValueLen = len;
145
lg_CopyAttributeSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type,
146
void *value, CK_ULONG len)
148
unsigned char * dval = (unsigned char *)value;
153
return lg_CopyAttribute(attribute,type,dval,len);
157
lg_CopyPrivAttribute(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type,
158
void *value, CK_ULONG len, SDB *sdbpw)
160
SECItem plainText, *cipherText = NULL;
161
CK_RV crv = CKR_USER_NOT_LOGGED_IN;
164
plainText.data = value;
166
rv = lg_util_encrypt(NULL, sdbpw, &plainText, &cipherText);
167
if (rv != SECSuccess) {
170
crv = lg_CopyAttribute(attribute,type,cipherText->data,cipherText->len);
173
SECITEM_FreeItem(cipherText,PR_TRUE);
179
lg_CopyPrivAttrSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type,
180
void *value, CK_ULONG len, SDB *sdbpw)
182
unsigned char * dval = (unsigned char *)value;
188
return lg_CopyPrivAttribute(attribute,type,dval,len,sdbpw);
192
lg_invalidAttribute(CK_ATTRIBUTE *attr)
194
attr->ulValueLen = (CK_ULONG) -1;
195
return CKR_ATTRIBUTE_TYPE_INVALID;
199
#define LG_DEF_ATTRIBUTE(value,len) \
202
#define LG_CLONE_ATTR(attribute, type, staticAttr) \
203
lg_CopyAttribute(attribute, type, staticAttr.pValue, staticAttr.ulValueLen)
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));
217
* helper functions which get the database and call the underlying
218
* low level database function.
221
lg_FindKeyNicknameByPublicKey(SDB *sdb, SECItem *dbKey)
223
NSSLOWKEYDBHandle *keyHandle;
226
keyHandle = lg_getKeyDB(sdb);
231
label = nsslowkey_FindKeyNicknameByPublicKey(keyHandle, dbKey,
237
NSSLOWKEYPrivateKey *
238
lg_FindKeyByPublicKey(SDB *sdb, SECItem *dbKey)
240
NSSLOWKEYPrivateKey *privKey;
241
NSSLOWKEYDBHandle *keyHandle;
243
keyHandle = lg_getKeyDB(sdb);
244
if (keyHandle == NULL) {
247
privKey = nsslowkey_FindKeyByPublicKey(keyHandle, dbKey, sdb);
248
if (privKey == NULL) {
254
static certDBEntrySMime *
255
lg_getSMime(LGObjectCache *obj)
257
certDBEntrySMime *entry;
258
NSSLOWCERTCertDBHandle *certHandle;
260
if (obj->objclass != CKO_NSS_SMIME) {
263
if (obj->objectInfo) {
264
return (certDBEntrySMime *)obj->objectInfo;
267
certHandle = lg_getCertDB(obj->sdb);
271
entry = nsslowcert_ReadDBSMimeEntry(certHandle, (char *)obj->dbKey.data);
272
obj->objectInfo = (void *)entry;
273
obj->infoFree = (LGFreeFunc) nsslowcert_DestroyDBEntry;
277
static certDBEntryRevocation *
278
lg_getCrl(LGObjectCache *obj)
280
certDBEntryRevocation *crl;
282
NSSLOWCERTCertDBHandle *certHandle;
284
if (obj->objclass != CKO_NSS_CRL) {
287
if (obj->objectInfo) {
288
return (certDBEntryRevocation *)obj->objectInfo;
291
isKrl = (PRBool) (obj->handle == LG_TOKEN_KRL_HANDLE);
292
certHandle = lg_getCertDB(obj->sdb);
297
crl = nsslowcert_FindCrlByKey(certHandle, &obj->dbKey, isKrl);
298
obj->objectInfo = (void *)crl;
299
obj->infoFree = (LGFreeFunc) nsslowcert_DestroyDBEntry;
303
static NSSLOWCERTCertificate *
304
lg_getCert(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle)
306
NSSLOWCERTCertificate *cert;
307
CK_OBJECT_CLASS objClass = obj->objclass;
309
if ((objClass != CKO_CERTIFICATE) && (objClass != CKO_NSS_TRUST)) {
312
if (objClass == CKO_CERTIFICATE && obj->objectInfo) {
313
return (NSSLOWCERTCertificate *)obj->objectInfo;
315
cert = nsslowcert_FindCertByKey(certHandle, &obj->dbKey);
316
if (objClass == CKO_CERTIFICATE) {
317
obj->objectInfo = (void *)cert;
318
obj->infoFree = (LGFreeFunc) nsslowcert_DestroyCertificate ;
323
static NSSLOWCERTTrust *
324
lg_getTrust(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle)
326
NSSLOWCERTTrust *trust;
328
if (obj->objclass != CKO_NSS_TRUST) {
331
if (obj->objectInfo) {
332
return (NSSLOWCERTTrust *)obj->objectInfo;
334
trust = nsslowcert_FindTrustByKey(certHandle, &obj->dbKey);
335
obj->objectInfo = (void *)trust;
336
obj->infoFree = (LGFreeFunc) nsslowcert_DestroyTrust ;
340
static NSSLOWKEYPublicKey *
341
lg_GetPublicKey(LGObjectCache *obj)
343
NSSLOWKEYPublicKey *pubKey;
344
NSSLOWKEYPrivateKey *privKey;
346
if (obj->objclass != CKO_PUBLIC_KEY) {
349
if (obj->objectInfo) {
350
return (NSSLOWKEYPublicKey *)obj->objectInfo;
352
privKey = lg_FindKeyByPublicKey(obj->sdb, &obj->dbKey);
353
if (privKey == NULL) {
356
pubKey = lg_nsslowkey_ConvertToPublicKey(privKey);
357
lg_nsslowkey_DestroyPrivateKey(privKey);
358
obj->objectInfo = (void *) pubKey;
359
obj->infoFree = (LGFreeFunc) lg_nsslowkey_DestroyPublicKey ;
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.
371
static NSSLOWKEYPrivateKey *
372
lg_GetPrivateKeyWithDB(LGObjectCache *obj, NSSLOWKEYDBHandle *keyHandle)
374
NSSLOWKEYPrivateKey *privKey;
376
if ((obj->objclass != CKO_PRIVATE_KEY) &&
377
(obj->objclass != CKO_SECRET_KEY)) {
380
if (obj->objectInfo) {
381
return (NSSLOWKEYPrivateKey *)obj->objectInfo;
383
privKey = nsslowkey_FindKeyByPublicKey(keyHandle, &obj->dbKey, obj->sdb);
384
if (privKey == NULL) {
387
obj->objectInfo = (void *) privKey;
388
obj->infoFree = (LGFreeFunc) lg_nsslowkey_DestroyPrivateKey ;
392
/* this version does the latter */
393
static NSSLOWKEYPrivateKey *
394
lg_GetPrivateKey(LGObjectCache *obj)
396
NSSLOWKEYDBHandle *keyHandle;
397
NSSLOWKEYPrivateKey *privKey;
399
keyHandle = lg_getKeyDB(obj->sdb);
403
privKey = lg_GetPrivateKeyWithDB(obj, keyHandle);
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.
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;
420
case NSSLOWKEYDSAKey:
421
pubItem = &pubKey->u.dsa.publicValue;
424
pubItem = &pubKey->u.dh.publicValue;
426
#ifdef NSS_ENABLE_ECC
428
pubItem = &pubKey->u.ec.publicValue;
430
#endif /* NSS_ENABLE_ECC */
437
static const SEC_ASN1Template lg_SerialTemplate[] = {
438
{ SEC_ASN1_INTEGER, offsetof(NSSLOWCERTCertificate,serialNumber) },
443
lg_FindRSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
444
CK_ATTRIBUTE *attribute)
446
unsigned char hash[SHA1_LENGTH];
447
CK_KEY_TYPE keyType = CKK_RSA;
451
return lg_ULongAttribute(attribute, type, keyType);
453
SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len);
454
return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
456
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
459
case CKA_VERIFY_RECOVER:
461
return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
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);
472
return lg_invalidAttribute(attribute);
476
lg_FindDSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
477
CK_ATTRIBUTE *attribute)
479
unsigned char hash[SHA1_LENGTH];
480
CK_KEY_TYPE keyType = CKK_DSA;
484
return lg_ULongAttribute(attribute, type, keyType);
486
SHA1_HashBuf(hash,key->u.dsa.publicValue.data,
487
key->u.dsa.publicValue.len);
488
return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
491
case CKA_VERIFY_RECOVER:
493
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
495
return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
497
return lg_CopyAttributeSigned(attribute,type,
498
key->u.dsa.publicValue.data,
499
key->u.dsa.publicValue.len);
501
return lg_CopyAttributeSigned(attribute,type,
502
key->u.dsa.params.prime.data,
503
key->u.dsa.params.prime.len);
505
return lg_CopyAttributeSigned(attribute,type,
506
key->u.dsa.params.subPrime.data,
507
key->u.dsa.params.subPrime.len);
509
return lg_CopyAttributeSigned(attribute,type,
510
key->u.dsa.params.base.data,
511
key->u.dsa.params.base.len);
515
return lg_invalidAttribute(attribute);
519
lg_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
520
CK_ATTRIBUTE *attribute)
522
unsigned char hash[SHA1_LENGTH];
523
CK_KEY_TYPE keyType = CKK_DH;
527
return lg_ULongAttribute(attribute, type, keyType);
529
SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len);
530
return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
532
return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
535
case CKA_VERIFY_RECOVER:
537
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
539
return lg_CopyAttributeSigned(attribute,type,
540
key->u.dh.publicValue.data,
541
key->u.dh.publicValue.len);
543
return lg_CopyAttributeSigned(attribute,type,key->u.dh.prime.data,
544
key->u.dh.prime.len);
546
return lg_CopyAttributeSigned(attribute,type,key->u.dh.base.data,
551
return lg_invalidAttribute(attribute);
554
#ifdef NSS_ENABLE_ECC
556
lg_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
557
CK_ATTRIBUTE *attribute)
559
unsigned char hash[SHA1_LENGTH];
560
CK_KEY_TYPE keyType = CKK_EC;
564
return lg_ULongAttribute(attribute, type, keyType);
566
SHA1_HashBuf(hash, key->u.ec.publicValue.data,
567
key->u.ec.publicValue.len);
568
return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
571
return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
573
case CKA_VERIFY_RECOVER:
575
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
577
return lg_CopyAttributeSigned(attribute,type,
578
key->u.ec.ecParams.DEREncoding.data,
579
key->u.ec.ecParams.DEREncoding.len);
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);
586
SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL,
587
&(key->u.ec.publicValue),
588
SEC_ASN1_GET(SEC_OctetStringTemplate));
591
return CKR_HOST_MEMORY;
593
crv = lg_CopyAttributeSigned(attribute, type,
596
SECITEM_FreeItem(pubValue, PR_TRUE);
602
return lg_invalidAttribute(attribute);
604
#endif /* NSS_ENABLE_ECC */
608
lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
609
CK_ATTRIBUTE *attribute)
611
NSSLOWKEYPublicKey *key;
618
case CKA_ALWAYS_SENSITIVE:
619
case CKA_NEVER_EXTRACTABLE:
620
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
622
case CKA_EXTRACTABLE:
623
return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
625
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
628
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
630
label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
632
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
634
crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label));
641
key = lg_GetPublicKey(obj);
643
if (type == CKA_ID) {
644
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
646
return CKR_OBJECT_HANDLE_INVALID;
649
switch (key->keyType) {
650
case NSSLOWKEYRSAKey:
651
return lg_FindRSAPublicKeyAttribute(key,type,attribute);
652
case NSSLOWKEYDSAKey:
653
return lg_FindDSAPublicKeyAttribute(key,type,attribute);
655
return lg_FindDHPublicKeyAttribute(key,type,attribute);
656
#ifdef NSS_ENABLE_ECC
658
return lg_FindECPublicKeyAttribute(key,type,attribute);
659
#endif /* NSS_ENABLE_ECC */
664
return lg_invalidAttribute(attribute);
668
lg_FindSecretKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
669
CK_ATTRIBUTE *attribute)
671
NSSLOWKEYPrivateKey *key;
673
unsigned char *keyString;
678
PRUint32 keyTypeStorage;
683
case CKA_ALWAYS_SENSITIVE:
684
case CKA_EXTRACTABLE:
694
return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
695
case CKA_NEVER_EXTRACTABLE:
696
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
699
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
701
label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
703
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
705
crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label));
709
return lg_CopyAttribute(attribute,type,obj->dbKey.data,
716
return lg_invalidAttribute(attribute);
719
key = lg_GetPrivateKey(obj);
721
return CKR_OBJECT_HANDLE_INVALID;
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 */
733
keyString = key->u.rsa.coefficient.data;
734
keyTypeLen = key->u.rsa.coefficient.len;
738
* Because of various endian and word lengths The database may have
739
* stored the keyType value in one of the following formats:
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.
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:
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
761
if (keyTypeLen == 8) {
762
keyTypeStorage = *(PRUint32 *) keyString;
763
if (keyTypeStorage == 0) {
764
keyString += sizeof(PRUint32);
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
774
* NOTE: if kt == 0 or ak1k2k3 == 0, the test fails and
777
* Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0
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);
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
793
keyType = (CK_KEY_TYPE) keyString[0] ;
795
return lg_ULongAttribute(attribute, type, keyType);
797
return lg_CopyPrivAttribute(attribute,type,key->u.rsa.privateExponent.data,
798
key->u.rsa.privateExponent.len, obj->sdb);
800
keyLen=key->u.rsa.privateExponent.len;
801
return lg_ULongAttribute(attribute,type, keyLen);
803
return lg_invalidAttribute(attribute);
807
lg_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
808
CK_ATTRIBUTE *attribute, SDB *sdbpw)
810
unsigned char hash[SHA1_LENGTH];
811
CK_KEY_TYPE keyType = CKK_RSA;
815
return lg_ULongAttribute(attribute, type, keyType);
817
SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len);
818
return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
820
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
823
case CKA_SIGN_RECOVER:
825
return LG_CLONE_ATTR(attribute, type,lg_StaticTrueAttr);
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);
838
return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime1.data,
839
key->u.rsa.prime1.len, sdbpw);
841
return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime2.data,
842
key->u.rsa.prime2.len, sdbpw);
844
return lg_CopyPrivAttrSigned(attribute, type,
845
key->u.rsa.exponent1.data,
846
key->u.rsa.exponent1.len, sdbpw);
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);
858
return lg_invalidAttribute(attribute);
862
lg_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
863
CK_ATTRIBUTE *attribute, SDB *sdbpw)
865
unsigned char hash[SHA1_LENGTH];
866
CK_KEY_TYPE keyType = CKK_DSA;
870
return lg_ULongAttribute(attribute, type, keyType);
872
SHA1_HashBuf(hash,key->u.dsa.publicValue.data,
873
key->u.dsa.publicValue.len);
874
return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
877
case CKA_SIGN_RECOVER:
879
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
881
return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
883
return lg_CopyPrivAttrSigned(attribute, type,
884
key->u.dsa.privateValue.data,
885
key->u.dsa.privateValue.len, sdbpw);
887
return lg_CopyAttributeSigned(attribute, type,
888
key->u.dsa.params.prime.data,
889
key->u.dsa.params.prime.len);
891
return lg_CopyAttributeSigned(attribute, type,
892
key->u.dsa.params.subPrime.data,
893
key->u.dsa.params.subPrime.len);
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);
905
return lg_invalidAttribute(attribute);
909
lg_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
910
CK_ATTRIBUTE *attribute, SDB *sdbpw)
912
unsigned char hash[SHA1_LENGTH];
913
CK_KEY_TYPE keyType = CKK_DH;
917
return lg_ULongAttribute(attribute, type, keyType);
919
SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len);
920
return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
922
return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
925
case CKA_SIGN_RECOVER:
927
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
929
return lg_CopyPrivAttrSigned(attribute, type,
930
key->u.dh.privateValue.data,
931
key->u.dh.privateValue.len, sdbpw);
933
return lg_CopyAttributeSigned(attribute, type, key->u.dh.prime.data,
934
key->u.dh.prime.len);
936
return lg_CopyAttributeSigned(attribute, type, key->u.dh.base.data,
938
case CKA_NETSCAPE_DB:
939
return lg_CopyAttributeSigned(attribute, type,
940
key->u.dh.publicValue.data,
941
key->u.dh.publicValue.len);
945
return lg_invalidAttribute(attribute);
948
#ifdef NSS_ENABLE_ECC
950
lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
951
CK_ATTRIBUTE *attribute, SDB *sdbpw)
953
unsigned char hash[SHA1_LENGTH];
954
CK_KEY_TYPE keyType = CKK_EC;
958
return lg_ULongAttribute(attribute, type, keyType);
960
SHA1_HashBuf(hash,key->u.ec.publicValue.data,key->u.ec.publicValue.len);
961
return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
964
return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
966
case CKA_SIGN_RECOVER:
968
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
970
return lg_CopyPrivAttrSigned(attribute, type,
971
key->u.ec.privateValue.data,
972
key->u.ec.privateValue.len, sdbpw);
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);
984
return lg_invalidAttribute(attribute);
986
#endif /* NSS_ENABLE_ECC */
989
lg_FindPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
990
CK_ATTRIBUTE *attribute)
992
NSSLOWKEYPrivateKey *key;
999
case CKA_ALWAYS_SENSITIVE:
1000
case CKA_EXTRACTABLE:
1001
case CKA_MODIFIABLE:
1003
return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
1004
case CKA_NEVER_EXTRACTABLE:
1005
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
1007
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
1008
case CKA_START_DATE:
1010
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
1012
label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
1013
if (label == NULL) {
1014
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
1016
crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label));
1022
key = lg_GetPrivateKey(obj);
1024
return CKR_OBJECT_HANDLE_INVALID;
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
#ifdef NSS_ENABLE_ECC
1034
case NSSLOWKEYECKey:
1035
return lg_FindECPrivateKeyAttribute(key,type,attribute,obj->sdb);
1036
#endif /* NSS_ENABLE_ECC */
1041
return lg_invalidAttribute(attribute);
1045
lg_FindSMIMEAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
1046
CK_ATTRIBUTE *attribute)
1048
certDBEntrySMime *entry;
1051
case CKA_MODIFIABLE:
1052
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
1054
return lg_CopyAttribute(attribute,type,obj->dbKey.data,
1056
case CKA_NSS_SMIME_TIMESTAMP:
1061
return lg_invalidAttribute(attribute);
1063
entry = lg_getSMime(obj);
1064
if (entry == NULL) {
1065
return CKR_OBJECT_HANDLE_INVALID;
1068
case CKA_NSS_SMIME_TIMESTAMP:
1069
return lg_CopyAttribute(attribute,type,entry->optionsDate.data,
1070
entry->optionsDate.len);
1072
return lg_CopyAttribute(attribute,type,entry->subjectName.data,
1073
entry->subjectName.len);
1075
return lg_CopyAttribute(attribute,type,entry->smimeOptions.data,
1076
entry->smimeOptions.len);
1080
return lg_invalidAttribute(attribute);
1084
lg_FindTrustAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
1085
CK_ATTRIBUTE *attribute)
1087
NSSLOWCERTTrust *trust;
1088
NSSLOWCERTCertDBHandle *certHandle;
1089
NSSLOWCERTCertificate *cert;
1090
unsigned char hash[SHA1_LENGTH];
1091
unsigned int trustFlags;
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:
1107
case CKA_SERIAL_NUMBER:
1110
return lg_invalidAttribute(attribute);
1112
certHandle = lg_getCertDB(obj->sdb);
1114
return CKR_OBJECT_HANDLE_INVALID;
1116
trust = lg_getTrust(obj, certHandle);
1117
if (trust == NULL) {
1118
return CKR_OBJECT_HANDLE_INVALID;
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 ;
1131
case CKA_TRUST_SERVER_AUTH:
1132
trustFlags = trust->trust->sslFlags;
1134
case CKA_TRUST_EMAIL_PROTECTION:
1135
trustFlags = trust->trust->emailFlags;
1137
case CKA_TRUST_CODE_SIGNING:
1138
trustFlags = trust->trust->objectSigningFlags;
1140
if (trustFlags & CERTDB_TRUSTED_CA ) {
1141
return lg_ULongAttribute(attribute, type,
1142
CKT_NSS_TRUSTED_DELEGATOR);
1144
if (trustFlags & CERTDB_TRUSTED) {
1145
return lg_ULongAttribute(attribute, type, CKT_NSS_TRUSTED);
1147
if (trustFlags & CERTDB_MUST_VERIFY) {
1148
return lg_ULongAttribute(attribute, type,
1149
CKT_NSS_MUST_VERIFY_TRUST);
1151
if (trustFlags & CERTDB_TRUSTED_UNKNOWN) {
1152
return lg_ULongAttribute(attribute, type, CKT_NSS_TRUST_UNKNOWN);
1154
if (trustFlags & CERTDB_VALID_CA) {
1155
return lg_ULongAttribute(attribute, type, CKT_NSS_VALID_DELEGATOR);
1157
if (trustFlags & CERTDB_TERMINAL_RECORD) {
1158
return lg_ULongAttribute(attribute, type, CKT_NSS_NOT_TRUSTED);
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);
1165
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
1174
cert = lg_getCert(obj, certHandle);
1175
if (cert == NULL) break;
1176
crv = lg_CopyAttribute(attribute,type,cert->derIssuer.data,
1177
cert->derIssuer.len);
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,
1190
nsslowcert_DestroyCertificate(cert);
1193
return lg_invalidAttribute(attribute);
1197
lg_FindCrlAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
1198
CK_ATTRIBUTE *attribute)
1200
certDBEntryRevocation *crl;
1204
case CKA_MODIFIABLE:
1205
return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
1207
return ((obj->handle == LG_TOKEN_KRL_HANDLE)
1208
? LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr)
1209
: LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr));
1211
return lg_CopyAttribute(attribute,type,obj->dbKey.data,
1217
return lg_invalidAttribute(attribute);
1219
crl = lg_getCrl(obj);
1221
return CKR_OBJECT_HANDLE_INVALID;
1225
if (crl->url == NULL) {
1226
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
1228
return lg_CopyAttribute(attribute, type, crl->url,
1229
PORT_Strlen(crl->url)+1);
1231
return lg_CopyAttribute(attribute, type, crl->derCrl.data,
1236
return lg_invalidAttribute(attribute);
1240
lg_FindCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
1241
CK_ATTRIBUTE *attribute)
1243
NSSLOWCERTCertificate *cert;
1244
NSSLOWCERTCertDBHandle *certHandle;
1245
NSSLOWKEYPublicKey *pubKey;
1246
unsigned char hash[SHA1_LENGTH];
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);
1262
case CKA_SERIAL_NUMBER:
1266
return lg_invalidAttribute(attribute);
1269
certHandle = lg_getCertDB(obj->sdb);
1270
if (certHandle == NULL) {
1271
return CKR_OBJECT_HANDLE_INVALID;
1274
cert = lg_getCert(obj, certHandle);
1276
return CKR_OBJECT_HANDLE_INVALID;
1280
return lg_CopyAttribute(attribute,type,cert->derCert.data,
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);
1288
pubKey = nsslowcert_ExtractPublicKey(cert);
1289
if (pubKey == NULL) break;
1290
item = lg_GetPubItem(pubKey);
1292
lg_nsslowkey_DestroyPublicKey(pubKey);
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);
1300
return cert->nickname
1301
? lg_CopyAttribute(attribute, type, cert->nickname,
1302
PORT_Strlen(cert->nickname))
1303
: LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
1305
return lg_CopyAttribute(attribute,type,cert->derSubject.data,
1306
cert->derSubject.len);
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,
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);
1321
return lg_invalidAttribute(attribute);
1325
lg_GetSingleAttribute(LGObjectCache *obj, CK_ATTRIBUTE *attribute)
1327
/* handle the common ones */
1328
CK_ATTRIBUTE_TYPE type = attribute->type;
1331
return lg_ULongAttribute(attribute,type,obj->objclass);
1333
return LG_CLONE_ATTR(attribute, type,lg_StaticTrueAttr);
1335
if ( (obj->objclass == CKO_CERTIFICATE)
1336
|| (obj->objclass == CKO_PRIVATE_KEY)
1337
|| (obj->objclass == CKO_PUBLIC_KEY)
1338
|| (obj->objclass == CKO_SECRET_KEY)) {
1341
return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
1345
switch (obj->objclass) {
1346
case CKO_CERTIFICATE:
1347
return lg_FindCertAttribute(obj,type,attribute);
1349
return lg_FindCrlAttribute(obj,type,attribute);
1351
return lg_FindTrustAttribute(obj,type,attribute);
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);
1363
return lg_invalidAttribute(attribute);
1367
* Fill in the attribute template based on the data in the database.
1370
lg_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE *templ,
1373
LGObjectCache *obj = lg_NewObjectCache(sdb, NULL, handle & ~LG_TOKEN_MASK);
1374
CK_RV crv, crvCollect = CKR_OK;
1378
return CKR_OBJECT_HANDLE_INVALID;
1381
for (i=0; i < count; i++) {
1382
crv = lg_GetSingleAttribute(obj, &templ[i]);
1383
if (crvCollect == CKR_OK) crvCollect = crv;
1386
lg_DestroyObjectCache(obj);
1391
lg_cmpAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attribute)
1393
unsigned char buf[LG_BUF_SPACE];
1394
CK_ATTRIBUTE testAttr;
1395
unsigned char *tempBuf = NULL;
1396
PRBool match = PR_TRUE;
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;
1407
/* if we don't have enough space, malloc it */
1408
if (attribute->ulValueLen > LG_BUF_SPACE) {
1409
tempBuf = PORT_Alloc(attribute->ulValueLen);
1413
testAttr.pValue = tempBuf;
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 */
1424
/* free the buffer we may have allocated */
1432
lg_tokenMatch(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE class,
1433
const CK_ATTRIBUTE *templ, CK_ULONG count)
1435
PRBool match = PR_TRUE;
1436
LGObjectCache *obj = lg_NewObjectCache(sdb, dbKey, class);
1443
for (i=0; i < count; i++) {
1444
match = lg_cmpAttribute(obj, &templ[i]);
1450
/* done looking, free up our cache */
1451
lg_DestroyObjectCache(obj);
1453
/* if we get through the whole list without finding a mismatched attribute,
1454
* then this object fits the criteria we are matching */
1459
lg_SetCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
1460
const void *value, unsigned int len)
1462
NSSLOWCERTCertificate *cert;
1463
NSSLOWCERTCertDBHandle *certHandle;
1464
char *nickname = NULL;
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) {
1474
certHandle = lg_getCertDB(obj->sdb);
1475
if (certHandle == NULL) {
1476
crv = CKR_TOKEN_WRITE_PROTECTED;
1480
if ((type != CKA_LABEL) && (type != CKA_ID)) {
1481
crv = CKR_ATTRIBUTE_READ_ONLY;
1485
cert = lg_getCert(obj, certHandle);
1487
crv = CKR_OBJECT_HANDLE_INVALID;
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.
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;
1500
keyHandle = lg_getKeyDB(obj->sdb);
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);
1515
/* must be CKA_LABEL */
1516
if (value != NULL) {
1517
nickname = PORT_ZAlloc(len+1);
1518
if (nickname == NULL) {
1519
crv = CKR_HOST_MEMORY;
1522
PORT_Memcpy(nickname,value,len);
1525
rv = nsslowcert_AddPermNickname(certHandle, cert, nickname);
1526
crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
1530
PORT_Free(nickname);
1536
lg_SetPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
1537
const void *value, unsigned int len,
1538
PRBool *writePrivate)
1540
NSSLOWKEYPrivateKey *privKey;
1541
NSSLOWKEYDBHandle *keyHandle;
1542
char *nickname = NULL;
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)) {
1554
keyHandle = lg_getKeyDB(obj->sdb);
1555
if (keyHandle == NULL) {
1556
crv = CKR_TOKEN_WRITE_PROTECTED;
1560
privKey = lg_GetPrivateKeyWithDB(obj, keyHandle);
1561
if (privKey == NULL) {
1562
crv = CKR_OBJECT_HANDLE_INVALID;
1566
crv = CKR_ATTRIBUTE_READ_ONLY;
1569
if (value != NULL) {
1570
nickname = PORT_ZAlloc(len+1);
1571
if (nickname == NULL) {
1572
crv = CKR_HOST_MEMORY;
1575
PORT_Memcpy(nickname,value,len);
1578
rv = nsslowkey_UpdateNickname(keyHandle, privKey, &obj->dbKey,
1579
nickname, obj->sdb);
1580
crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
1585
case CKA_SIGN_RECOVER:
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
1592
if (*(char *)value == 0) {
1597
case CKA_PRIVATE_EXPONENT:
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;
1609
crv = CKR_ATTRIBUTE_READ_ONLY;
1614
PORT_Free(nickname);
1620
lg_SetPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
1621
const void *value, unsigned int len,
1622
PRBool *writePrivate)
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)) {
1629
return CKR_ATTRIBUTE_READ_ONLY;
1633
lg_SetTrustAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr)
1637
NSSLOWCERTCertificate *cert;
1638
NSSLOWCERTCertDBHandle *certHandle;
1639
NSSLOWCERTCertTrust dbTrust;
1643
if (attr->type == CKA_LABEL) {
1647
crv = lg_GetULongAttribute(attr->type, attr, 1, &trust);
1648
if (crv != CKR_OK) {
1651
flags = lg_MapTrust(trust, (PRBool) (attr->type == CKA_TRUST_CLIENT_AUTH));
1653
certHandle = lg_getCertDB(obj->sdb);
1655
if (certHandle == NULL) {
1656
crv = CKR_TOKEN_WRITE_PROTECTED;
1660
cert = lg_getCert(obj, certHandle);
1662
crv = CKR_OBJECT_HANDLE_INVALID;
1665
dbTrust = *cert->trust;
1667
switch (attr->type) {
1668
case CKA_TRUST_EMAIL_PROTECTION:
1669
dbTrust.emailFlags = flags |
1670
(cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS);
1672
case CKA_TRUST_CODE_SIGNING:
1673
dbTrust.objectSigningFlags = flags |
1674
(cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS);
1676
case CKA_TRUST_CLIENT_AUTH:
1677
dbTrust.sslFlags = flags | (cert->trust->sslFlags &
1678
(CERTDB_PRESERVE_TRUST_BITS|CERTDB_TRUSTED_CA));
1680
case CKA_TRUST_SERVER_AUTH:
1681
dbTrust.sslFlags = flags | (cert->trust->sslFlags &
1682
(CERTDB_PRESERVE_TRUST_BITS|CERTDB_TRUSTED_CLIENT_CA));
1685
crv = CKR_ATTRIBUTE_READ_ONLY;
1689
rv = nsslowcert_ChangeCertTrust(certHandle, cert, &dbTrust);
1690
crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
1696
lg_SetSingleAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr,
1697
PRBool *writePrivate)
1699
CK_ATTRIBUTE attribLocal;
1702
if ((attr->type == CKA_NETSCAPE_DB) && (obj->objclass == CKO_PRIVATE_KEY)) {
1703
*writePrivate = PR_TRUE;
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) {
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)) {
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);
1736
crv = lg_SetTrustAttribute(obj,attr);
1738
case CKO_PRIVATE_KEY:
1739
case CKO_SECRET_KEY:
1740
crv = lg_SetPrivateKeyAttribute(obj,attr->type,
1741
attr->pValue,attr->ulValueLen, writePrivate);
1743
case CKO_PUBLIC_KEY:
1744
crv = lg_SetPublicKeyAttribute(obj,attr->type,
1745
attr->pValue,attr->ulValueLen, writePrivate);
1752
* Fill in the attribute template based on the data in the database.
1755
lg_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle,
1756
const CK_ATTRIBUTE *templ, CK_ULONG count)
1758
LGObjectCache *obj = lg_NewObjectCache(sdb, NULL, handle & ~LG_TOKEN_MASK);
1759
CK_RV crv, crvCollect = CKR_OK;
1760
PRBool writePrivate = PR_FALSE;
1764
return CKR_OBJECT_HANDLE_INVALID;
1767
for (i=0; i < count; i++) {
1768
crv = lg_SetSingleAttribute(obj, &templ[i], &writePrivate);
1769
if (crvCollect == CKR_OK) crvCollect = crv;
1772
/* Write any collected changes out for private and secret keys.
1773
* don't do the write for just the label */
1775
NSSLOWKEYPrivateKey *privKey = lg_GetPrivateKey(obj);
1776
SECStatus rv = SECFailure;
1777
char * label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
1780
rv = nsslowkey_StoreKeyByPublicKeyAlg(lg_getKeyDB(sdb), privKey,
1781
&obj->dbKey, label, sdb, PR_TRUE );
1783
if (rv != SECSuccess) {
1784
crv = CKR_DEVICE_ERROR;
1788
lg_DestroyObjectCache(obj);