security/nss/lib/softoken/legacydb/lgattr.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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"
    10 #include "pcertt.h"
    11 #include "lowkeyi.h"
    12 #include "pcert.h"
    13 #include "blapi.h"
    14 #include "secerr.h"
    15 #include "secasn1.h"
    17 /*
    18  * Cache the object we are working on during Set's and Get's
    19  */
    20 typedef struct LGObjectCacheStr {
    21     CK_OBJECT_CLASS  objclass;
    22     CK_OBJECT_HANDLE handle;
    23     SDB              *sdb;
    24     void             *objectInfo;
    25     LGFreeFunc       infoFree;
    26     SECItem          dbKey;
    27 } LGObjectCache;
    29 static const CK_OBJECT_HANDLE lg_classArray[] = {
    30     0, CKO_PRIVATE_KEY, CKO_PUBLIC_KEY, CKO_SECRET_KEY,
    31     CKO_NSS_TRUST, CKO_NSS_CRL, CKO_NSS_SMIME,
    32      CKO_CERTIFICATE };
    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)
    42 {
    43     LGObjectCache *obj = NULL;
    44     SECStatus rv;
    46     obj = PORT_New(LGObjectCache);
    47     if (obj == NULL) {
    48 	return NULL;
    49     }
    51     obj->objclass = handleToClass(handle);
    52     obj->handle = handle;
    53     obj->sdb = sdb;
    54     obj->objectInfo = NULL;
    55     obj->infoFree = NULL;
    56     obj->dbKey.data = NULL;
    57     obj->dbKey.len = 0;
    58     lg_DBLock(sdb);
    59     if (dbKey == NULL) {
    60 	dbKey = lg_lookupTokenKeyByHandle(sdb,handle);
    61     }
    62     if (dbKey == NULL) {
    63 	lg_DBUnlock(sdb);
    64 	goto loser;
    65     }
    66     rv = SECITEM_CopyItem(NULL,&obj->dbKey,dbKey);
    67     lg_DBUnlock(sdb);
    68     if (rv != SECSuccess) {
    69 	goto loser;
    70     }
    72     return obj;
    73 loser:
    74     if (obj) {
    75 	(void) lg_DestroyObjectCache(obj);
    76     }
    77     return NULL;
    79 }
    81 /*
    82  * free all the data associated with an object. Object reference count must
    83  * be 'zero'.
    84  */
    85 static void
    86 lg_DestroyObjectCache(LGObjectCache *obj)
    87 {
    88     if (obj->dbKey.data) {
    89 	PORT_Free(obj->dbKey.data);
    90 	obj->dbKey.data = NULL;
    91     } 
    92     if (obj->objectInfo) {
    93 	(*obj->infoFree)(obj->objectInfo);
    94 	obj->objectInfo = NULL;
    95 	obj->infoFree = NULL;
    96     }
    97     PORT_Free(obj);
    98 }
    99 /*
   100  * ******************** Attribute Utilities *******************************
   101  */
   103 static CK_RV
   104 lg_ULongAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, CK_ULONG value)
   105 {
   106     unsigned char *data;
   107     int i;
   109     if (attr->pValue == NULL) {
   110 	attr->ulValueLen = 4;
   111 	return CKR_OK;
   112     }
   113     if (attr->ulValueLen < 4) {
   114 	attr->ulValueLen = (CK_ULONG) -1;
   115 	return CKR_BUFFER_TOO_SMALL;
   116     }
   118     data = (unsigned char *)attr->pValue;
   119     for (i=0; i < 4; i++) {
   120 	data[i] = (value >> ((3-i)*8)) & 0xff;
   121     }
   122     attr->ulValueLen = 4;
   123     return CKR_OK;
   124 }
   126 static CK_RV
   127 lg_CopyAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, 
   128 				CK_VOID_PTR value, CK_ULONG len)
   129 {
   131     if (attr->pValue == NULL) {
   132 	attr->ulValueLen = len;
   133 	return CKR_OK;
   134     }
   135     if (attr->ulValueLen < len) {
   136 	attr->ulValueLen = (CK_ULONG) -1;
   137 	return CKR_BUFFER_TOO_SMALL;
   138     }
   139     PORT_Memcpy(attr->pValue,value,len);
   140     attr->ulValueLen = len;
   141     return CKR_OK;
   142 }
   144 static CK_RV
   145 lg_CopyAttributeSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type, 
   146 				void  *value, CK_ULONG len)
   147 {
   148     unsigned char * dval = (unsigned char *)value;
   149     if (*dval == 0) {
   150 	dval++;
   151 	len--;
   152     }
   153     return lg_CopyAttribute(attribute,type,dval,len);
   154 }
   156 static CK_RV
   157 lg_CopyPrivAttribute(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type, 
   158 				void  *value, CK_ULONG len, SDB *sdbpw)
   159 {
   160     SECItem plainText, *cipherText = NULL;
   161     CK_RV crv = CKR_USER_NOT_LOGGED_IN;
   162     SECStatus rv;
   164     plainText.data = value;
   165     plainText.len = len;
   166     rv = lg_util_encrypt(NULL, sdbpw, &plainText, &cipherText);
   167     if (rv != SECSuccess) {
   168 	goto loser;
   169     }
   170     crv = lg_CopyAttribute(attribute,type,cipherText->data,cipherText->len);
   171 loser:
   172     if (cipherText) {
   173 	SECITEM_FreeItem(cipherText,PR_TRUE);
   174     }
   175     return crv;
   176 }
   178 static CK_RV
   179 lg_CopyPrivAttrSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type, 
   180 				void  *value, CK_ULONG len, SDB *sdbpw)
   181 {
   182     unsigned char * dval = (unsigned char *)value;
   184     if (*dval == 0) {
   185 	dval++;
   186 	len--;
   187     }
   188     return lg_CopyPrivAttribute(attribute,type,dval,len,sdbpw);
   189 }
   191 static CK_RV
   192 lg_invalidAttribute(CK_ATTRIBUTE *attr)
   193 {
   194     attr->ulValueLen = (CK_ULONG) -1;
   195     return CKR_ATTRIBUTE_TYPE_INVALID;
   196 }
   199 #define LG_DEF_ATTRIBUTE(value,len) \
   200    { 0, 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));
   216 /*
   217  * helper functions which get the database and call the underlying 
   218  * low level database function.
   219  */
   220 static char *
   221 lg_FindKeyNicknameByPublicKey(SDB *sdb, SECItem *dbKey)
   222 {
   223     NSSLOWKEYDBHandle *keyHandle;
   224     char * label;
   226     keyHandle = lg_getKeyDB(sdb);
   227     if (!keyHandle) {
   228 	return NULL;
   229     }
   231     label = nsslowkey_FindKeyNicknameByPublicKey(keyHandle, dbKey, 
   232 						 sdb);
   233     return label;
   234 }
   237 NSSLOWKEYPrivateKey *
   238 lg_FindKeyByPublicKey(SDB *sdb, SECItem *dbKey)
   239 {
   240     NSSLOWKEYPrivateKey *privKey;
   241     NSSLOWKEYDBHandle   *keyHandle;
   243     keyHandle = lg_getKeyDB(sdb);
   244     if (keyHandle == NULL) {
   245 	return NULL;
   246     }
   247     privKey = nsslowkey_FindKeyByPublicKey(keyHandle, dbKey, sdb);
   248     if (privKey == NULL) {
   249 	return NULL;
   250     }
   251     return privKey;
   252 }
   254 static certDBEntrySMime *
   255 lg_getSMime(LGObjectCache *obj)
   256 {
   257     certDBEntrySMime *entry;
   258     NSSLOWCERTCertDBHandle *certHandle;
   260     if (obj->objclass != CKO_NSS_SMIME) {
   261 	return NULL;
   262     }
   263     if (obj->objectInfo) {
   264 	return (certDBEntrySMime *)obj->objectInfo;
   265     }
   267     certHandle = lg_getCertDB(obj->sdb);
   268     if (!certHandle) {
   269 	return NULL;
   270     }
   271     entry = nsslowcert_ReadDBSMimeEntry(certHandle, (char *)obj->dbKey.data);
   272     obj->objectInfo = (void *)entry;
   273     obj->infoFree = (LGFreeFunc) nsslowcert_DestroyDBEntry;
   274     return entry;
   275 }
   277 static certDBEntryRevocation *
   278 lg_getCrl(LGObjectCache *obj)
   279 {
   280     certDBEntryRevocation *crl;
   281     PRBool isKrl;
   282     NSSLOWCERTCertDBHandle *certHandle;
   284     if (obj->objclass != CKO_NSS_CRL) {
   285 	return NULL;
   286     }
   287     if (obj->objectInfo) {
   288 	return (certDBEntryRevocation *)obj->objectInfo;
   289     }
   291     isKrl = (PRBool) (obj->handle == LG_TOKEN_KRL_HANDLE);
   292     certHandle = lg_getCertDB(obj->sdb);
   293     if (!certHandle) {
   294 	return NULL;
   295     }
   297     crl = nsslowcert_FindCrlByKey(certHandle, &obj->dbKey, isKrl);
   298     obj->objectInfo = (void *)crl;
   299     obj->infoFree = (LGFreeFunc) nsslowcert_DestroyDBEntry;
   300     return crl;
   301 }
   303 static NSSLOWCERTCertificate *
   304 lg_getCert(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle)
   305 {
   306     NSSLOWCERTCertificate *cert;
   307     CK_OBJECT_CLASS objClass = obj->objclass;
   309     if ((objClass != CKO_CERTIFICATE) && (objClass != CKO_NSS_TRUST)) {
   310 	return NULL;
   311     }
   312     if (objClass == CKO_CERTIFICATE && obj->objectInfo) {
   313 	return (NSSLOWCERTCertificate *)obj->objectInfo;
   314     }
   315     cert = nsslowcert_FindCertByKey(certHandle, &obj->dbKey);
   316     if (objClass == CKO_CERTIFICATE) {
   317 	obj->objectInfo = (void *)cert;
   318 	obj->infoFree = (LGFreeFunc) nsslowcert_DestroyCertificate ;
   319     }
   320     return cert;
   321 }
   323 static NSSLOWCERTTrust *
   324 lg_getTrust(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle)
   325 {
   326     NSSLOWCERTTrust *trust;
   328     if (obj->objclass != CKO_NSS_TRUST) {
   329 	return NULL;
   330     }
   331     if (obj->objectInfo) {
   332 	return (NSSLOWCERTTrust *)obj->objectInfo;
   333     }
   334     trust = nsslowcert_FindTrustByKey(certHandle, &obj->dbKey);
   335     obj->objectInfo = (void *)trust;
   336     obj->infoFree = (LGFreeFunc) nsslowcert_DestroyTrust ;
   337     return trust;
   338 }
   340 static NSSLOWKEYPublicKey *
   341 lg_GetPublicKey(LGObjectCache *obj)
   342 {
   343     NSSLOWKEYPublicKey *pubKey;
   344     NSSLOWKEYPrivateKey *privKey;
   346     if (obj->objclass != CKO_PUBLIC_KEY) {
   347 	return NULL;
   348     }
   349     if (obj->objectInfo) {
   350 	return (NSSLOWKEYPublicKey *)obj->objectInfo;
   351     }
   352     privKey = lg_FindKeyByPublicKey(obj->sdb, &obj->dbKey);
   353     if (privKey == NULL) {
   354 	return NULL;
   355     }
   356     pubKey = lg_nsslowkey_ConvertToPublicKey(privKey);
   357     lg_nsslowkey_DestroyPrivateKey(privKey);
   358     obj->objectInfo = (void *) pubKey;
   359     obj->infoFree = (LGFreeFunc) lg_nsslowkey_DestroyPublicKey ;
   360     return pubKey;
   361 }
   363 /*
   364  * we need two versions of lg_GetPrivateKey. One version that takes the 
   365  * DB handle so we can pass the handle we have already acquired in,
   366  *  rather than going through the 'getKeyDB' code again, 
   367  *  which may fail the second time and another which just aquires
   368  *  the key handle from the sdb (where we don't already have a key handle.
   369  * This version does the former.
   370  */
   371 static NSSLOWKEYPrivateKey *
   372 lg_GetPrivateKeyWithDB(LGObjectCache *obj, NSSLOWKEYDBHandle *keyHandle)
   373 {
   374     NSSLOWKEYPrivateKey *privKey;
   376     if ((obj->objclass != CKO_PRIVATE_KEY) && 
   377 			(obj->objclass != CKO_SECRET_KEY)) {
   378 	return NULL;
   379     }
   380     if (obj->objectInfo) {
   381 	return (NSSLOWKEYPrivateKey *)obj->objectInfo;
   382     }
   383     privKey = nsslowkey_FindKeyByPublicKey(keyHandle, &obj->dbKey, obj->sdb);
   384     if (privKey == NULL) {
   385 	return NULL;
   386     }
   387     obj->objectInfo = (void *) privKey;
   388     obj->infoFree = (LGFreeFunc) lg_nsslowkey_DestroyPrivateKey ;
   389     return privKey;
   390 }
   392 /* this version does the latter */
   393 static NSSLOWKEYPrivateKey *
   394 lg_GetPrivateKey(LGObjectCache *obj)
   395 {
   396     NSSLOWKEYDBHandle *keyHandle;
   397     NSSLOWKEYPrivateKey *privKey;
   399     keyHandle = lg_getKeyDB(obj->sdb);
   400     if (!keyHandle) {
   401 	return NULL;
   402     }
   403     privKey = lg_GetPrivateKeyWithDB(obj, keyHandle);
   404     return privKey;
   405 }
   407 /* lg_GetPubItem returns data associated with the public key.
   408  * one only needs to free the public key. This comment is here
   409  * because this sematic would be non-obvious otherwise. All callers
   410  * should include this comment.
   411  */
   412 static SECItem *
   413 lg_GetPubItem(NSSLOWKEYPublicKey *pubKey) {
   414     SECItem *pubItem = NULL;
   415     /* get value to compare from the cert's public key */
   416     switch ( pubKey->keyType ) {
   417     case NSSLOWKEYRSAKey:
   418 	    pubItem = &pubKey->u.rsa.modulus;
   419 	    break;
   420     case NSSLOWKEYDSAKey:
   421 	    pubItem = &pubKey->u.dsa.publicValue;
   422 	    break;
   423     case NSSLOWKEYDHKey:
   424 	    pubItem = &pubKey->u.dh.publicValue;
   425 	    break;
   426 #ifndef NSS_DISABLE_ECC
   427     case NSSLOWKEYECKey:
   428 	    pubItem = &pubKey->u.ec.publicValue;
   429 	    break;
   430 #endif /* NSS_DISABLE_ECC */
   431     default:
   432 	    break;
   433     }
   434     return pubItem;
   435 }
   437 static const SEC_ASN1Template lg_SerialTemplate[] = {
   438     { SEC_ASN1_INTEGER, offsetof(NSSLOWCERTCertificate,serialNumber) },
   439     { 0 }
   440 };
   442 static CK_RV
   443 lg_FindRSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
   444 				CK_ATTRIBUTE *attribute)
   445 {
   446     unsigned char hash[SHA1_LENGTH];
   447     CK_KEY_TYPE keyType = CKK_RSA;
   449     switch (type) {
   450     case CKA_KEY_TYPE:
   451 	return lg_ULongAttribute(attribute, type, keyType);
   452     case CKA_ID:
   453 	SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len);
   454 	return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
   455     case CKA_DERIVE:
   456 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
   457     case CKA_ENCRYPT:
   458     case CKA_VERIFY:
   459     case CKA_VERIFY_RECOVER:
   460     case CKA_WRAP:
   461 	return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
   462     case CKA_MODULUS:
   463 	return lg_CopyAttributeSigned(attribute,type,key->u.rsa.modulus.data,
   464 					key->u.rsa.modulus.len);
   465     case CKA_PUBLIC_EXPONENT:
   466 	return lg_CopyAttributeSigned(attribute, type,
   467 				key->u.rsa.publicExponent.data,
   468 				key->u.rsa.publicExponent.len);
   469     default:
   470 	break;
   471     }
   472     return lg_invalidAttribute(attribute);
   473 }
   475 static CK_RV
   476 lg_FindDSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
   477 				CK_ATTRIBUTE *attribute)
   478 {
   479     unsigned char hash[SHA1_LENGTH];
   480     CK_KEY_TYPE keyType = CKK_DSA;
   482     switch (type) {
   483     case CKA_KEY_TYPE:
   484 	return lg_ULongAttribute(attribute, type, keyType);
   485     case CKA_ID:
   486 	SHA1_HashBuf(hash,key->u.dsa.publicValue.data,
   487 						key->u.dsa.publicValue.len);
   488 	return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
   489     case CKA_DERIVE:
   490     case CKA_ENCRYPT:
   491     case CKA_VERIFY_RECOVER:
   492     case CKA_WRAP:
   493 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
   494     case CKA_VERIFY:
   495 	return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
   496     case CKA_VALUE:
   497 	return lg_CopyAttributeSigned(attribute,type,
   498 					key->u.dsa.publicValue.data,
   499 					key->u.dsa.publicValue.len);
   500     case CKA_PRIME:
   501 	return lg_CopyAttributeSigned(attribute,type,
   502 					key->u.dsa.params.prime.data,
   503 					key->u.dsa.params.prime.len);
   504     case CKA_SUBPRIME:
   505 	return lg_CopyAttributeSigned(attribute,type,
   506 				key->u.dsa.params.subPrime.data,
   507 				key->u.dsa.params.subPrime.len);
   508     case CKA_BASE:
   509 	return lg_CopyAttributeSigned(attribute,type,
   510 					key->u.dsa.params.base.data,
   511 					key->u.dsa.params.base.len);
   512     default:
   513 	break;
   514     }
   515     return lg_invalidAttribute(attribute);
   516 }
   518 static CK_RV
   519 lg_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
   520 				CK_ATTRIBUTE *attribute)
   521 {
   522     unsigned char hash[SHA1_LENGTH];
   523     CK_KEY_TYPE keyType = CKK_DH;
   525     switch (type) {
   526     case CKA_KEY_TYPE:
   527 	return lg_ULongAttribute(attribute, type, keyType);
   528     case CKA_ID:
   529 	SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len);
   530 	return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
   531     case CKA_DERIVE:
   532 	return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
   533     case CKA_ENCRYPT:
   534     case CKA_VERIFY:
   535     case CKA_VERIFY_RECOVER:
   536     case CKA_WRAP:
   537 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
   538     case CKA_VALUE:
   539 	return lg_CopyAttributeSigned(attribute,type,
   540 					key->u.dh.publicValue.data,
   541 					key->u.dh.publicValue.len);
   542     case CKA_PRIME:
   543 	return lg_CopyAttributeSigned(attribute,type,key->u.dh.prime.data,
   544 					key->u.dh.prime.len);
   545     case CKA_BASE:
   546 	return lg_CopyAttributeSigned(attribute,type,key->u.dh.base.data,
   547 					key->u.dh.base.len);
   548     default:
   549 	break;
   550     }
   551     return lg_invalidAttribute(attribute);
   552 }
   554 #ifndef NSS_DISABLE_ECC
   555 static CK_RV
   556 lg_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type,
   557 				CK_ATTRIBUTE *attribute)
   558 {
   559     unsigned char hash[SHA1_LENGTH];
   560     CK_KEY_TYPE keyType = CKK_EC;
   562     switch (type) {
   563     case CKA_KEY_TYPE:
   564 	return lg_ULongAttribute(attribute, type, keyType);
   565     case CKA_ID:
   566 	SHA1_HashBuf(hash, key->u.ec.publicValue.data,
   567 		     key->u.ec.publicValue.len);
   568 	return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
   569     case CKA_DERIVE:
   570     case CKA_VERIFY:
   571 	return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
   572     case CKA_ENCRYPT:
   573     case CKA_VERIFY_RECOVER:
   574     case CKA_WRAP:
   575 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
   576     case CKA_EC_PARAMS:
   577 	return lg_CopyAttributeSigned(attribute,type,
   578 					key->u.ec.ecParams.DEREncoding.data,
   579 					key->u.ec.ecParams.DEREncoding.len);
   580     case CKA_EC_POINT:
   581 	if (getenv("NSS_USE_DECODED_CKA_EC_POINT")) {
   582 	    return lg_CopyAttributeSigned(attribute, type,
   583 					key->u.ec.publicValue.data,
   584 					key->u.ec.publicValue.len);
   585 	} else {
   586 	    SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL, 
   587 					&(key->u.ec.publicValue), 
   588 					SEC_ASN1_GET(SEC_OctetStringTemplate));
   589 	    CK_RV crv;
   590 	    if (!pubValue) {
   591 		return CKR_HOST_MEMORY;
   592 	    }
   593 	    crv = lg_CopyAttributeSigned(attribute, type,
   594 					pubValue->data,
   595 					pubValue->len);
   596 	    SECITEM_FreeItem(pubValue, PR_TRUE);
   597 	    return crv;
   598 	}
   599     default:
   600 	break;
   601     }
   602     return lg_invalidAttribute(attribute);
   603 }
   604 #endif /* NSS_DISABLE_ECC */
   607 static CK_RV
   608 lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
   609 				CK_ATTRIBUTE *attribute)
   610 {
   611     NSSLOWKEYPublicKey   *key;
   612     CK_RV crv;
   613     char *label;
   615     switch (type) {
   616     case CKA_PRIVATE:
   617     case CKA_SENSITIVE:
   618     case CKA_ALWAYS_SENSITIVE:
   619     case CKA_NEVER_EXTRACTABLE:
   620 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
   621     case CKA_MODIFIABLE:
   622     case CKA_EXTRACTABLE:
   623 	return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
   624     case CKA_SUBJECT:
   625 	   return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
   626     case CKA_START_DATE:
   627     case CKA_END_DATE:
   628 	   return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
   629     case CKA_LABEL:
   630         label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
   631 	if (label == NULL) {
   632 	   return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
   633 	}
   634 	crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label));
   635 	PORT_Free(label);
   636 	return crv;
   637     default:
   638 	break;
   639     }
   641     key = lg_GetPublicKey(obj);
   642     if (key == NULL) {
   643 	if (type == CKA_ID) {
   644 	   return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
   645 	}
   646 	return CKR_OBJECT_HANDLE_INVALID;
   647     }
   649     switch (key->keyType) {
   650     case NSSLOWKEYRSAKey:
   651 	return lg_FindRSAPublicKeyAttribute(key,type,attribute);
   652     case NSSLOWKEYDSAKey:
   653 	return lg_FindDSAPublicKeyAttribute(key,type,attribute);
   654     case NSSLOWKEYDHKey:
   655 	return lg_FindDHPublicKeyAttribute(key,type,attribute);
   656 #ifndef NSS_DISABLE_ECC
   657     case NSSLOWKEYECKey:
   658 	return lg_FindECPublicKeyAttribute(key,type,attribute);
   659 #endif /* NSS_DISABLE_ECC */
   660     default:
   661 	break;
   662     }
   664     return lg_invalidAttribute(attribute);
   665 }
   667 static CK_RV
   668 lg_FindSecretKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
   669 				CK_ATTRIBUTE *attribute)
   670 {
   671     NSSLOWKEYPrivateKey  *key;
   672     char *label;
   673     unsigned char *keyString;
   674     CK_RV crv;
   675     int keyTypeLen;
   676     CK_ULONG keyLen;
   677     CK_KEY_TYPE keyType;
   678     PRUint32 keyTypeStorage;
   680     switch (type) {
   681     case CKA_PRIVATE:
   682     case CKA_SENSITIVE:
   683     case CKA_ALWAYS_SENSITIVE:
   684     case CKA_EXTRACTABLE:
   685     case CKA_DERIVE:
   686     case CKA_ENCRYPT:
   687     case CKA_DECRYPT:
   688     case CKA_SIGN:
   689     case CKA_VERIFY:
   690     case CKA_WRAP:
   691     case CKA_UNWRAP:
   692     case CKA_MODIFIABLE:
   693     case CKA_LOCAL:
   694 	return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
   695     case CKA_NEVER_EXTRACTABLE:
   696 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
   697     case CKA_START_DATE:
   698     case CKA_END_DATE:
   699 	   return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
   700     case CKA_LABEL:
   701         label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
   702 	if (label == NULL) {
   703 	   return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
   704 	}
   705 	crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label));
   706 	PORT_Free(label);
   707 	return crv;
   708     case CKA_ID:
   709 	return lg_CopyAttribute(attribute,type,obj->dbKey.data,
   710 						obj->dbKey.len);
   711     case CKA_KEY_TYPE:
   712     case CKA_VALUE_LEN:
   713     case CKA_VALUE:
   714 	break;
   715     default:
   716 	return lg_invalidAttribute(attribute);
   717     }
   719     key = lg_GetPrivateKey(obj);
   720     if (key == NULL) {
   721 	return CKR_OBJECT_HANDLE_INVALID;
   722     }
   723     switch (type) {
   724     case CKA_KEY_TYPE:
   725 	/* handle legacy databases. In legacy databases key_type was stored
   726 	 * in host order, with any leading zeros stripped off. Only key types
   727 	 * under 0x1f (AES) were stored. We assume that any values which are
   728 	 * either 1 byte long (big endian), or have byte[0] between 0 and 
   729 	 * 0x7f and bytes[1]-bytes[3] equal to '0' (little endian). All other
   730 	 * values are assumed to be from the new database, which is always 4
   731 	 * bytes in network order */
   732 	keyType=0;
   733 	keyString = key->u.rsa.coefficient.data;
   734 	keyTypeLen = key->u.rsa.coefficient.len;
   737 	/*
   738  	 * Because of various endian and word lengths The database may have
   739 	 * stored the keyType value in one of the following formats:
   740 	 *   (kt) <= 0x1f 
   741 	 *                                   length data
   742 	 * Big Endian,     pre-3.9, all lengths: 1  (kt)
   743 	 * Little Endian,  pre-3.9, 32 bits:     4  (kt) 0  0  0
   744 	 * Little Endian,  pre-3.9, 64 bits:     8  (kt) 0  0  0   0  0  0  0
   745 	 * All platforms,      3.9, 32 bits:     4    0  0  0 (kt)
   746 	 * Big Endian,         3.9, 64 bits:     8    0  0  0 (kt) 0  0  0  0
   747 	 * Little  Endian,     3.9, 64 bits:     8    0  0  0  0   0  0  0 (kt)
   748 	 * All platforms, >= 3.9.1, all lengths: 4   (a) k1 k2 k3
   749 	 * where (a) is 0 or >= 0x80. currently (a) can only be 0.
   750 	 */
   751 	/*
   752  	 * this key was written on a 64 bit platform with a using NSS 3.9
   753 	 * or earlier. Reduce the 64 bit possibilities above. When we are
   754 	 * through, we will only have:
   755 	 * 
   756 	 * Big Endian,     pre-3.9, all lengths: 1  (kt)
   757 	 * Little Endian,  pre-3.9, all lengths: 4  (kt) 0  0  0
   758 	 * All platforms,      3.9, all lengths: 4    0  0  0 (kt)
   759 	 * All platforms, => 3.9.1, all lengths: 4   (a) k1 k2 k3
   760 	 */
   761 	if (keyTypeLen == 8) {
   762 	    keyTypeStorage = *(PRUint32 *) keyString;
   763 	    if (keyTypeStorage == 0) {
   764 		keyString += sizeof(PRUint32);
   765 	    }
   766 	    keyTypeLen = 4;
   767 	}
   768 	/*
   769 	 * Now Handle:
   770 	 *
   771 	 * All platforms,      3.9, all lengths: 4    0  0  0 (kt)
   772 	 * All platforms, => 3.9.1, all lengths: 4   (a) k1 k2 k3
   773 	 *
   774 	 * NOTE: if  kt == 0 or ak1k2k3 == 0, the test fails and
   775 	 * we handle it as:
   776 	 *
   777 	 * Little Endian,  pre-3.9, all lengths: 4  (kt) 0  0  0
   778 	 */
   779 	if (keyTypeLen == sizeof(keyTypeStorage) &&
   780 	     (((keyString[0] & 0x80) == 0x80) ||
   781 		!((keyString[1] == 0) && (keyString[2] == 0)
   782 	   				    && (keyString[3] == 0))) ) {
   783 	    PORT_Memcpy(&keyTypeStorage, keyString, sizeof(keyTypeStorage));
   784 	    keyType = (CK_KEY_TYPE) PR_ntohl(keyTypeStorage);
   785 	} else {
   786 	/*
   787 	 * Now Handle:
   788 	 *
   789 	 * Big Endian,     pre-3.9, all lengths: 1  (kt)
   790 	 * Little Endian,  pre-3.9, all lengths: 4  (kt) 0  0  0
   791 	 *  -- KeyType == 0 all other cases ---: 4    0  0  0  0
   792 	 */
   793 	    keyType = (CK_KEY_TYPE) keyString[0] ;
   794         }
   795 	return lg_ULongAttribute(attribute, type, keyType);
   796     case CKA_VALUE:
   797 	return lg_CopyPrivAttribute(attribute,type,key->u.rsa.privateExponent.data,
   798 				key->u.rsa.privateExponent.len, obj->sdb);
   799     case CKA_VALUE_LEN:
   800 	keyLen=key->u.rsa.privateExponent.len;
   801 	return lg_ULongAttribute(attribute,type, keyLen);
   802     }
   803     return lg_invalidAttribute(attribute);
   804 }
   806 static CK_RV
   807 lg_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
   808 				CK_ATTRIBUTE *attribute, SDB *sdbpw)
   809 {
   810     unsigned char hash[SHA1_LENGTH];
   811     CK_KEY_TYPE keyType = CKK_RSA;
   813     switch (type) {
   814     case CKA_KEY_TYPE:
   815 	return lg_ULongAttribute(attribute, type, keyType);
   816     case CKA_ID:
   817 	SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len);
   818 	return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
   819     case CKA_DERIVE:
   820 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
   821     case CKA_DECRYPT:
   822     case CKA_SIGN:
   823     case CKA_SIGN_RECOVER:
   824     case CKA_UNWRAP:
   825 	return LG_CLONE_ATTR(attribute, type,lg_StaticTrueAttr);
   826     case CKA_MODULUS:
   827 	return lg_CopyAttributeSigned(attribute,type,key->u.rsa.modulus.data,
   828 					key->u.rsa.modulus.len);
   829     case CKA_PUBLIC_EXPONENT:
   830 	return lg_CopyAttributeSigned(attribute, type,
   831 				key->u.rsa.publicExponent.data,
   832 				key->u.rsa.publicExponent.len);
   833     case CKA_PRIVATE_EXPONENT:
   834 	return lg_CopyPrivAttrSigned(attribute,type,
   835 				key->u.rsa.privateExponent.data,
   836 				key->u.rsa.privateExponent.len, sdbpw);
   837     case CKA_PRIME_1:
   838 	return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime1.data,
   839 				key->u.rsa.prime1.len, sdbpw);
   840     case CKA_PRIME_2:
   841 	return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime2.data,
   842 				key->u.rsa.prime2.len, sdbpw);
   843     case CKA_EXPONENT_1:
   844 	return lg_CopyPrivAttrSigned(attribute, type, 
   845 				key->u.rsa.exponent1.data,
   846 				key->u.rsa.exponent1.len, sdbpw);
   847     case CKA_EXPONENT_2:
   848 	return lg_CopyPrivAttrSigned(attribute, type, 
   849 				key->u.rsa.exponent2.data,
   850 				key->u.rsa.exponent2.len, sdbpw);
   851     case CKA_COEFFICIENT:
   852 	return lg_CopyPrivAttrSigned(attribute, type, 
   853 				key->u.rsa.coefficient.data,
   854 				key->u.rsa.coefficient.len, sdbpw);
   855     default:
   856 	break;
   857     }
   858     return lg_invalidAttribute(attribute);
   859 }
   861 static CK_RV
   862 lg_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
   863 				CK_ATTRIBUTE *attribute, SDB *sdbpw)
   864 {
   865     unsigned char hash[SHA1_LENGTH];
   866     CK_KEY_TYPE keyType = CKK_DSA;
   868     switch (type) {
   869     case CKA_KEY_TYPE:
   870 	return lg_ULongAttribute(attribute, type, keyType);
   871     case CKA_ID:
   872 	SHA1_HashBuf(hash,key->u.dsa.publicValue.data,
   873 			  key->u.dsa.publicValue.len);
   874 	return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
   875     case CKA_DERIVE:
   876     case CKA_DECRYPT:
   877     case CKA_SIGN_RECOVER:
   878     case CKA_UNWRAP:
   879 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
   880     case CKA_SIGN:
   881 	return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
   882     case CKA_VALUE:
   883 	return lg_CopyPrivAttrSigned(attribute, type,
   884 				key->u.dsa.privateValue.data,
   885 				key->u.dsa.privateValue.len, sdbpw);
   886     case CKA_PRIME:
   887 	return lg_CopyAttributeSigned(attribute, type,
   888 					key->u.dsa.params.prime.data,
   889 					key->u.dsa.params.prime.len);
   890     case CKA_SUBPRIME:
   891 	return lg_CopyAttributeSigned(attribute, type,
   892 				key->u.dsa.params.subPrime.data,
   893 				key->u.dsa.params.subPrime.len);
   894     case CKA_BASE:
   895 	return lg_CopyAttributeSigned(attribute, type,
   896 					key->u.dsa.params.base.data,
   897 					key->u.dsa.params.base.len);
   898     case CKA_NETSCAPE_DB:
   899 	return lg_CopyAttributeSigned(attribute, type,
   900 					key->u.dsa.publicValue.data,
   901 					key->u.dsa.publicValue.len);
   902     default:
   903 	break;
   904     }
   905     return lg_invalidAttribute(attribute);
   906 }
   908 static CK_RV
   909 lg_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
   910 				CK_ATTRIBUTE *attribute, SDB *sdbpw)
   911 {
   912     unsigned char hash[SHA1_LENGTH];
   913     CK_KEY_TYPE keyType = CKK_DH;
   915     switch (type) {
   916     case CKA_KEY_TYPE:
   917 	return lg_ULongAttribute(attribute, type, keyType);
   918     case CKA_ID:
   919 	SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len);
   920 	return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
   921     case CKA_DERIVE:
   922 	return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
   923     case CKA_DECRYPT:
   924     case CKA_SIGN:
   925     case CKA_SIGN_RECOVER:
   926     case CKA_UNWRAP:
   927 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
   928     case CKA_VALUE:
   929 	return lg_CopyPrivAttrSigned(attribute, type,
   930 					key->u.dh.privateValue.data,
   931 					key->u.dh.privateValue.len, sdbpw);
   932     case CKA_PRIME:
   933 	return lg_CopyAttributeSigned(attribute, type, key->u.dh.prime.data,
   934 					key->u.dh.prime.len);
   935     case CKA_BASE:
   936 	return lg_CopyAttributeSigned(attribute, type, key->u.dh.base.data,
   937 					key->u.dh.base.len);
   938     case CKA_NETSCAPE_DB:
   939 	return lg_CopyAttributeSigned(attribute, type,
   940 					key->u.dh.publicValue.data,
   941 					key->u.dh.publicValue.len);
   942     default:
   943 	break;
   944     }
   945     return lg_invalidAttribute(attribute);
   946 }
   948 #ifndef NSS_DISABLE_ECC
   949 static CK_RV
   950 lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
   951 				CK_ATTRIBUTE *attribute, SDB *sdbpw)
   952 {
   953     unsigned char hash[SHA1_LENGTH];
   954     CK_KEY_TYPE keyType = CKK_EC;
   956     switch (type) {
   957     case CKA_KEY_TYPE:
   958 	return lg_ULongAttribute(attribute, type, keyType);
   959     case CKA_ID:
   960 	SHA1_HashBuf(hash,key->u.ec.publicValue.data,key->u.ec.publicValue.len);
   961 	return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH);
   962     case CKA_DERIVE:
   963     case CKA_SIGN:
   964 	return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
   965     case CKA_DECRYPT:
   966     case CKA_SIGN_RECOVER:
   967     case CKA_UNWRAP:
   968 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
   969     case CKA_VALUE:
   970 	return lg_CopyPrivAttrSigned(attribute, type,
   971 					key->u.ec.privateValue.data,
   972 					key->u.ec.privateValue.len, sdbpw);
   973     case CKA_EC_PARAMS:
   974 	return lg_CopyAttributeSigned(attribute, type,
   975 					key->u.ec.ecParams.DEREncoding.data,
   976 					key->u.ec.ecParams.DEREncoding.len);
   977     case CKA_NETSCAPE_DB:
   978 	return lg_CopyAttributeSigned(attribute, type,
   979 					key->u.ec.publicValue.data,
   980 					key->u.ec.publicValue.len);
   981     default:
   982 	break;
   983     }
   984     return lg_invalidAttribute(attribute);
   985 }
   986 #endif /* NSS_DISABLE_ECC */
   988 static CK_RV
   989 lg_FindPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
   990 				CK_ATTRIBUTE *attribute)
   991 {
   992     NSSLOWKEYPrivateKey  *key;
   993     char *label;
   994     CK_RV crv;
   996     switch (type) {
   997     case CKA_PRIVATE:
   998     case CKA_SENSITIVE:
   999     case CKA_ALWAYS_SENSITIVE:
  1000     case CKA_EXTRACTABLE:
  1001     case CKA_MODIFIABLE:
  1002     case CKA_LOCAL:
  1003 	return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
  1004     case CKA_NEVER_EXTRACTABLE:
  1005 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
  1006     case CKA_SUBJECT:
  1007 	   return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
  1008     case CKA_START_DATE:
  1009     case CKA_END_DATE:
  1010 	   return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
  1011     case CKA_LABEL:
  1012         label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
  1013 	if (label == NULL) {
  1014 	   return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
  1016 	crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label));
  1017 	PORT_Free(label);
  1018 	return crv;
  1019     default:
  1020 	break;
  1022     key = lg_GetPrivateKey(obj);
  1023     if (key == NULL) {
  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 #ifndef NSS_DISABLE_ECC
  1034     case NSSLOWKEYECKey:
  1035 	return lg_FindECPrivateKeyAttribute(key,type,attribute,obj->sdb);
  1036 #endif /* NSS_DISABLE_ECC */
  1037     default:
  1038 	break;
  1041     return lg_invalidAttribute(attribute);
  1044 static CK_RV
  1045 lg_FindSMIMEAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
  1046 				CK_ATTRIBUTE *attribute)
  1048     certDBEntrySMime *entry;
  1049     switch (type) {
  1050     case CKA_PRIVATE:
  1051     case CKA_MODIFIABLE:
  1052 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
  1053     case CKA_NSS_EMAIL:
  1054 	return lg_CopyAttribute(attribute,type,obj->dbKey.data,
  1055 						obj->dbKey.len-1);
  1056     case CKA_NSS_SMIME_TIMESTAMP:
  1057     case CKA_SUBJECT:
  1058     case CKA_VALUE:
  1059 	break;
  1060     default:
  1061 	return lg_invalidAttribute(attribute);
  1063     entry = lg_getSMime(obj);
  1064     if (entry == NULL) {
  1065 	return CKR_OBJECT_HANDLE_INVALID;
  1067     switch (type) {
  1068     case CKA_NSS_SMIME_TIMESTAMP:
  1069 	return lg_CopyAttribute(attribute,type,entry->optionsDate.data,
  1070 					entry->optionsDate.len);
  1071     case CKA_SUBJECT:
  1072 	return lg_CopyAttribute(attribute,type,entry->subjectName.data,
  1073 					entry->subjectName.len);
  1074     case CKA_VALUE:
  1075 	return lg_CopyAttribute(attribute,type,entry->smimeOptions.data,
  1076 					entry->smimeOptions.len);
  1077     default:
  1078 	break;
  1080     return lg_invalidAttribute(attribute);
  1083 static CK_RV
  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;
  1092     CK_RV crv;
  1094     switch (type) {
  1095     case CKA_PRIVATE:
  1096 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
  1097     case CKA_MODIFIABLE:
  1098 	return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
  1099     case CKA_CERT_SHA1_HASH:
  1100     case CKA_CERT_MD5_HASH:
  1101     case CKA_TRUST_CLIENT_AUTH:
  1102     case CKA_TRUST_SERVER_AUTH:
  1103     case CKA_TRUST_EMAIL_PROTECTION:
  1104     case CKA_TRUST_CODE_SIGNING:
  1105     case CKA_TRUST_STEP_UP_APPROVED:
  1106     case CKA_ISSUER:
  1107     case CKA_SERIAL_NUMBER:
  1108 	break;
  1109     default:
  1110         return lg_invalidAttribute(attribute);
  1112     certHandle = lg_getCertDB(obj->sdb);
  1113     if (!certHandle) {
  1114 	return CKR_OBJECT_HANDLE_INVALID;
  1116     trust = lg_getTrust(obj, certHandle);
  1117     if (trust == NULL) {
  1118 	return CKR_OBJECT_HANDLE_INVALID;
  1120     switch (type) {
  1121     case CKA_CERT_SHA1_HASH:
  1122 	SHA1_HashBuf(hash,trust->derCert->data,trust->derCert->len);
  1123 	return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
  1124     case CKA_CERT_MD5_HASH:
  1125 	MD5_HashBuf(hash,trust->derCert->data,trust->derCert->len);
  1126 	return lg_CopyAttribute(attribute, type, hash, MD5_LENGTH);
  1127     case CKA_TRUST_CLIENT_AUTH:
  1128 	trustFlags = trust->trust->sslFlags & CERTDB_TRUSTED_CLIENT_CA ?
  1129 		trust->trust->sslFlags | CERTDB_TRUSTED_CA : 0 ;
  1130 	goto trust;
  1131     case CKA_TRUST_SERVER_AUTH:
  1132 	trustFlags = trust->trust->sslFlags;
  1133 	goto trust;
  1134     case CKA_TRUST_EMAIL_PROTECTION:
  1135 	trustFlags = trust->trust->emailFlags;
  1136 	goto trust;
  1137     case CKA_TRUST_CODE_SIGNING:
  1138 	trustFlags = trust->trust->objectSigningFlags;
  1139 trust:
  1140 	if (trustFlags & CERTDB_TRUSTED_CA ) {
  1141 	    return lg_ULongAttribute(attribute, type,
  1142 				     CKT_NSS_TRUSTED_DELEGATOR);
  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);
  1164 	} else {
  1165 	    return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
  1167     default:
  1168 	break;
  1172     switch (type) {
  1173     case CKA_ISSUER:
  1174 	cert = lg_getCert(obj, certHandle);
  1175 	if (cert == NULL) break;
  1176 	crv = lg_CopyAttribute(attribute,type,cert->derIssuer.data,
  1177 						cert->derIssuer.len);
  1178 	break;
  1179     case CKA_SERIAL_NUMBER:
  1180 	cert = lg_getCert(obj, certHandle);
  1181 	if (cert == NULL) break;
  1182 	crv =  lg_CopyAttribute(attribute,type,cert->derSN.data,
  1183 						cert->derSN.len);
  1184 	break;
  1185     default:
  1186 	cert = NULL;
  1187 	break;
  1189     if (cert) {
  1190 	nsslowcert_DestroyCertificate(cert);
  1191 	return crv;
  1193     return lg_invalidAttribute(attribute);
  1196 static CK_RV
  1197 lg_FindCrlAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type,
  1198 				CK_ATTRIBUTE *attribute)
  1200     certDBEntryRevocation *crl;
  1202     switch (type) {
  1203     case CKA_PRIVATE:
  1204     case CKA_MODIFIABLE:
  1205 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
  1206     case CKA_NSS_KRL:
  1207 	return ((obj->handle == LG_TOKEN_KRL_HANDLE) 
  1208 		? LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr)
  1209 		: LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr));
  1210     case CKA_SUBJECT:
  1211 	return lg_CopyAttribute(attribute,type,obj->dbKey.data,
  1212 						obj->dbKey.len);
  1213     case CKA_NSS_URL:
  1214     case CKA_VALUE:
  1215 	break;
  1216     default:
  1217 	return lg_invalidAttribute(attribute);
  1219     crl =  lg_getCrl(obj);
  1220     if (!crl) {
  1221 	return CKR_OBJECT_HANDLE_INVALID;
  1223     switch (type) {
  1224     case CKA_NSS_URL:
  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);
  1230     case CKA_VALUE:
  1231 	return lg_CopyAttribute(attribute, type, crl->derCrl.data, 
  1232 						crl->derCrl.len);
  1233     default:
  1234 	break;
  1236     return lg_invalidAttribute(attribute);
  1239 static CK_RV
  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];
  1247     SECItem *item;
  1249     switch (type) {
  1250     case CKA_PRIVATE:
  1251 	return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr);
  1252     case CKA_MODIFIABLE:
  1253 	return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr);
  1254     case CKA_CERTIFICATE_TYPE:
  1255         /* hardcoding X.509 into here */
  1256         return lg_ULongAttribute(attribute, type, CKC_X_509);
  1257     case CKA_VALUE:
  1258     case CKA_ID:
  1259     case CKA_LABEL:
  1260     case CKA_SUBJECT:
  1261     case CKA_ISSUER:
  1262     case CKA_SERIAL_NUMBER:
  1263     case CKA_NSS_EMAIL:
  1264 	break;
  1265     default:
  1266 	return lg_invalidAttribute(attribute);
  1269     certHandle = lg_getCertDB(obj->sdb);
  1270     if (certHandle == NULL) {
  1271 	return CKR_OBJECT_HANDLE_INVALID;
  1274     cert = lg_getCert(obj, certHandle);
  1275     if (cert == NULL) {
  1276 	return CKR_OBJECT_HANDLE_INVALID;
  1278     switch (type) {
  1279     case CKA_VALUE:
  1280 	return lg_CopyAttribute(attribute,type,cert->derCert.data,
  1281 						cert->derCert.len);
  1282     case CKA_ID:
  1283 	if (((cert->trust->sslFlags & CERTDB_USER) == 0) &&
  1284 		((cert->trust->emailFlags & CERTDB_USER) == 0) &&
  1285 		((cert->trust->objectSigningFlags & CERTDB_USER) == 0)) {
  1286 	    return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
  1288 	pubKey = nsslowcert_ExtractPublicKey(cert);
  1289 	if (pubKey == NULL) break;
  1290 	item = lg_GetPubItem(pubKey);
  1291 	if (item == NULL) {
  1292 	    lg_nsslowkey_DestroyPublicKey(pubKey);
  1293 	    break;
  1295 	SHA1_HashBuf(hash,item->data,item->len);
  1296 	/* item is imbedded in pubKey, just free the key */
  1297 	lg_nsslowkey_DestroyPublicKey(pubKey);
  1298 	return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH);
  1299     case CKA_LABEL:
  1300 	return cert->nickname 
  1301 	       ? lg_CopyAttribute(attribute, type, cert->nickname,
  1302 				        PORT_Strlen(cert->nickname))
  1303 	       : LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
  1304     case CKA_SUBJECT:
  1305 	return lg_CopyAttribute(attribute,type,cert->derSubject.data,
  1306 						cert->derSubject.len);
  1307     case CKA_ISSUER:
  1308 	return lg_CopyAttribute(attribute,type,cert->derIssuer.data,
  1309 						cert->derIssuer.len);
  1310     case CKA_SERIAL_NUMBER:
  1311 	return lg_CopyAttribute(attribute,type,cert->derSN.data,
  1312 						cert->derSN.len);
  1313     case CKA_NSS_EMAIL:
  1314 	return (cert->emailAddr && cert->emailAddr[0])
  1315 	    ? lg_CopyAttribute(attribute, type, cert->emailAddr,
  1316 	                             PORT_Strlen(cert->emailAddr))
  1317 	    : LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
  1318     default:
  1319 	break;
  1321     return lg_invalidAttribute(attribute);
  1324 CK_RV
  1325 lg_GetSingleAttribute(LGObjectCache *obj, CK_ATTRIBUTE *attribute)
  1327     /* handle the common ones */
  1328     CK_ATTRIBUTE_TYPE type = attribute->type;
  1329     switch (type) {
  1330     case CKA_CLASS:
  1331 	return lg_ULongAttribute(attribute,type,obj->objclass);
  1332     case CKA_TOKEN:
  1333 	return LG_CLONE_ATTR(attribute, type,lg_StaticTrueAttr);
  1334     case CKA_LABEL:
  1335 	if (  (obj->objclass == CKO_CERTIFICATE) 
  1336 	   || (obj->objclass == CKO_PRIVATE_KEY)
  1337 	   || (obj->objclass == CKO_PUBLIC_KEY)
  1338 	   || (obj->objclass == CKO_SECRET_KEY)) {
  1339 	    break;
  1341 	return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr);
  1342     default:
  1343 	break;
  1345     switch (obj->objclass) {
  1346     case CKO_CERTIFICATE:
  1347 	return lg_FindCertAttribute(obj,type,attribute);
  1348     case CKO_NSS_CRL:
  1349 	return lg_FindCrlAttribute(obj,type,attribute);
  1350     case CKO_NSS_TRUST:
  1351 	return lg_FindTrustAttribute(obj,type,attribute);
  1352     case CKO_NSS_SMIME:
  1353 	return lg_FindSMIMEAttribute(obj,type,attribute);
  1354     case CKO_PUBLIC_KEY:
  1355 	return lg_FindPublicKeyAttribute(obj,type,attribute);
  1356     case CKO_PRIVATE_KEY:
  1357 	return lg_FindPrivateKeyAttribute(obj,type,attribute);
  1358     case CKO_SECRET_KEY:
  1359 	return lg_FindSecretKeyAttribute(obj,type,attribute);
  1360     default:
  1361 	break;
  1363     return lg_invalidAttribute(attribute);
  1366 /*
  1367  * Fill in the attribute template based on the data in the database.
  1368  */    
  1369 CK_RV
  1370 lg_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE *templ, 
  1371 		CK_ULONG count)
  1373     LGObjectCache *obj = lg_NewObjectCache(sdb, NULL, handle & ~LG_TOKEN_MASK);
  1374     CK_RV crv, crvCollect = CKR_OK;
  1375     unsigned int i;
  1377     if (obj == NULL) {
  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);
  1387     return crvCollect;
  1390 PRBool
  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;
  1397     CK_RV crv;
  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);
  1410 	if (!tempBuf) {
  1411 	    return PR_FALSE;
  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 */
  1422 	match = PR_FALSE;
  1424     /* free the buffer we may have allocated */
  1425     if (tempBuf) {
  1426 	PORT_Free(tempBuf);
  1428     return match;
  1431 PRBool
  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);
  1437     unsigned int i;
  1439     if (obj == NULL) {
  1440 	return PR_FALSE;
  1443     for (i=0; i < count; i++) {
  1444 	match = lg_cmpAttribute(obj, &templ[i]);
  1445 	if (!match) {
  1446 	   break;
  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 */
  1455     return match;
  1458 static CK_RV
  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;
  1465     SECStatus rv;
  1466     CK_RV crv;
  1468     /* we can't change  the EMAIL values, but let the
  1469      * upper layers feel better about the fact we tried to set these */
  1470     if (type == CKA_NSS_EMAIL) {
  1471 	return CKR_OK;
  1474     certHandle = lg_getCertDB(obj->sdb);
  1475     if (certHandle == NULL) {
  1476 	crv = CKR_TOKEN_WRITE_PROTECTED;
  1477 	goto done;
  1480     if ((type != CKA_LABEL)  && (type != CKA_ID)) {
  1481 	crv = CKR_ATTRIBUTE_READ_ONLY;
  1482 	goto done;
  1485     cert = lg_getCert(obj, certHandle);
  1486     if (cert == NULL) {
  1487 	crv = CKR_OBJECT_HANDLE_INVALID;
  1488 	goto done;
  1491     /* if the app is trying to set CKA_ID, it's probably because it just
  1492      * imported the key. Look to see if we need to set the CERTDB_USER bits.
  1493      */
  1494     if (type == CKA_ID) {
  1495 	if (((cert->trust->sslFlags & CERTDB_USER) == 0) &&
  1496 		((cert->trust->emailFlags & CERTDB_USER) == 0) &&
  1497 		((cert->trust->objectSigningFlags & CERTDB_USER) == 0)) {
  1498 	    NSSLOWKEYDBHandle      *keyHandle;
  1500 	    keyHandle = lg_getKeyDB(obj->sdb);
  1501 	    if (keyHandle) {
  1502 		if (nsslowkey_KeyForCertExists(keyHandle, cert)) {
  1503 		    NSSLOWCERTCertTrust trust = *cert->trust;
  1504 		    trust.sslFlags |= CERTDB_USER;
  1505 		    trust.emailFlags |= CERTDB_USER;
  1506 		    trust.objectSigningFlags |= CERTDB_USER;
  1507 		    nsslowcert_ChangeCertTrust(certHandle,cert,&trust);
  1511 	crv = CKR_OK;
  1512 	goto done;
  1515     /* must be CKA_LABEL */
  1516     if (value != NULL) {
  1517 	nickname = PORT_ZAlloc(len+1);
  1518 	if (nickname == NULL) {
  1519 	    crv = CKR_HOST_MEMORY;
  1520 	    goto done;
  1522 	PORT_Memcpy(nickname,value,len);
  1523 	nickname[len] = 0;
  1525     rv = nsslowcert_AddPermNickname(certHandle, cert, nickname);
  1526     crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
  1528 done:
  1529     if (nickname) {
  1530 	PORT_Free(nickname);
  1532     return crv;
  1535 static CK_RV
  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;
  1543     SECStatus rv;
  1544     CK_RV crv;
  1546     /* we can't change the ID and we don't store the subject, but let the
  1547      * upper layers feel better about the fact we tried to set these */
  1548     if ((type == CKA_ID) || (type == CKA_SUBJECT) ||
  1549 	(type == CKA_LOCAL) || (type == CKA_NEVER_EXTRACTABLE) ||
  1550 	(type == CKA_ALWAYS_SENSITIVE)) {
  1551 	return CKR_OK;
  1554     keyHandle = lg_getKeyDB(obj->sdb);
  1555     if (keyHandle == NULL) {
  1556 	crv = CKR_TOKEN_WRITE_PROTECTED;
  1557 	goto done;
  1560     privKey = lg_GetPrivateKeyWithDB(obj, keyHandle);
  1561     if (privKey == NULL) {
  1562 	crv = CKR_OBJECT_HANDLE_INVALID;
  1563 	goto done;
  1566     crv = CKR_ATTRIBUTE_READ_ONLY;
  1567     switch(type) {
  1568     case CKA_LABEL:
  1569 	if (value != NULL) {
  1570 	    nickname = PORT_ZAlloc(len+1);
  1571 	    if (nickname == NULL) {
  1572 		crv = CKR_HOST_MEMORY;
  1573 		goto done;
  1575 	    PORT_Memcpy(nickname,value,len);
  1576 	    nickname[len] = 0;
  1578 	rv = nsslowkey_UpdateNickname(keyHandle, privKey, &obj->dbKey, 
  1579 					nickname, obj->sdb);
  1580 	crv = (rv == SECSuccess) ? CKR_OK :  CKR_DEVICE_ERROR;
  1581 	break;
  1582     case CKA_UNWRAP:
  1583     case CKA_SIGN:
  1584     case CKA_DERIVE:
  1585     case CKA_SIGN_RECOVER:
  1586     case CKA_DECRYPT:
  1587 	/* ignore attempts to change restrict these.
  1588 	 * legacyDB ignore these flags and always presents all of them 
  1589 	 * that are valid as true. 
  1590 	 * NOTE: We only get here if the current value and the new value do
  1591 	 * not match. */
  1592 	if (*(char *)value == 0) {
  1593 	    crv = CKR_OK;
  1595 	break;
  1596     case CKA_VALUE:
  1597     case CKA_PRIVATE_EXPONENT:
  1598     case CKA_PRIME_1:
  1599     case CKA_PRIME_2:
  1600     case CKA_EXPONENT_1:
  1601     case CKA_EXPONENT_2:
  1602     case CKA_COEFFICIENT:
  1603 	/* We aren't really changing these values, we are just triggering
  1604 	 * the database to update it's entry */
  1605 	*writePrivate = PR_TRUE;
  1606 	crv = CKR_OK;
  1607 	break;
  1608     default:
  1609 	crv = CKR_ATTRIBUTE_READ_ONLY;
  1610 	break;
  1612 done:
  1613     if (nickname) {
  1614 	PORT_Free(nickname);
  1616     return crv;
  1619 static CK_RV
  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)) {
  1627 	return CKR_OK;
  1629     return  CKR_ATTRIBUTE_READ_ONLY;
  1632 static CK_RV
  1633 lg_SetTrustAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr)
  1635     unsigned int flags;
  1636     CK_TRUST  trust;
  1637     NSSLOWCERTCertificate  *cert;
  1638     NSSLOWCERTCertDBHandle *certHandle;
  1639     NSSLOWCERTCertTrust    dbTrust;
  1640     SECStatus rv;
  1641     CK_RV crv;
  1643     if (attr->type == CKA_LABEL) {
  1644 	return CKR_OK;
  1647     crv = lg_GetULongAttribute(attr->type, attr, 1, &trust);
  1648     if (crv != CKR_OK) {
  1649 	return crv;
  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;
  1657 	goto done;
  1660     cert = lg_getCert(obj, certHandle);
  1661     if (cert == NULL) {
  1662 	crv = CKR_OBJECT_HANDLE_INVALID;
  1663 	goto done;
  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);
  1671 	break;
  1672     case CKA_TRUST_CODE_SIGNING:
  1673 	dbTrust.objectSigningFlags = flags |
  1674 		(cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS);
  1675 	break;
  1676     case CKA_TRUST_CLIENT_AUTH:
  1677 	dbTrust.sslFlags = flags | (cert->trust->sslFlags & 
  1678 				(CERTDB_PRESERVE_TRUST_BITS|CERTDB_TRUSTED_CA));
  1679 	break;
  1680     case CKA_TRUST_SERVER_AUTH:
  1681 	dbTrust.sslFlags = flags | (cert->trust->sslFlags & 
  1682 			(CERTDB_PRESERVE_TRUST_BITS|CERTDB_TRUSTED_CLIENT_CA));
  1683 	break;
  1684     default:
  1685 	crv = CKR_ATTRIBUTE_READ_ONLY;
  1686 	goto done;
  1689     rv = nsslowcert_ChangeCertTrust(certHandle, cert, &dbTrust);
  1690     crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR;
  1691 done:
  1692     return crv;
  1695 static CK_RV
  1696 lg_SetSingleAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr, 
  1697 		      PRBool *writePrivate)
  1699     CK_ATTRIBUTE attribLocal;
  1700     CK_RV crv;
  1702     if ((attr->type == CKA_NETSCAPE_DB) && (obj->objclass == CKO_PRIVATE_KEY)) {
  1703 	*writePrivate = PR_TRUE;
  1704 	return CKR_OK;
  1707     /* Make sure the attribute exists first */
  1708     attribLocal.type = attr->type;
  1709     attribLocal.pValue = NULL;
  1710     attribLocal.ulValueLen = 0;
  1711     crv = lg_GetSingleAttribute(obj, &attribLocal);
  1712     if (crv != CKR_OK) {
  1713 	return crv;
  1716     /* if we are just setting it to the value we already have,
  1717      * allow it to happen. Let label setting go through so
  1718      * we have the opportunity to repair any database corruption. */
  1719     if (attr->type != CKA_LABEL) {
  1720 	if (lg_cmpAttribute(obj,attr)) {
  1721 	    return CKR_OK;
  1725     crv = CKR_ATTRIBUTE_READ_ONLY;
  1726     switch (obj->objclass) {
  1727     case CKO_CERTIFICATE:
  1728 	/* change NICKNAME, EMAIL,  */
  1729 	crv = lg_SetCertAttribute(obj,attr->type,
  1730 				  attr->pValue,attr->ulValueLen);
  1731 	break;
  1732     case CKO_NSS_CRL:
  1733 	/* change URL */
  1734 	break;
  1735     case CKO_NSS_TRUST:
  1736 	crv = lg_SetTrustAttribute(obj,attr);
  1737 	break;
  1738     case CKO_PRIVATE_KEY:
  1739     case CKO_SECRET_KEY:
  1740 	crv = lg_SetPrivateKeyAttribute(obj,attr->type,
  1741 			attr->pValue,attr->ulValueLen, writePrivate);
  1742 	break;
  1743     case CKO_PUBLIC_KEY:
  1744 	crv = lg_SetPublicKeyAttribute(obj,attr->type,
  1745 			attr->pValue,attr->ulValueLen, writePrivate);
  1746 	break;
  1748     return crv;
  1751 /*
  1752  * Fill in the attribute template based on the data in the database.
  1753  */    
  1754 CK_RV
  1755 lg_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle, 
  1756 			const CK_ATTRIBUTE *templ, CK_ULONG count)
  1758     LGObjectCache *obj = lg_NewObjectCache(sdb, NULL, handle & ~LG_TOKEN_MASK);
  1759     CK_RV crv, crvCollect = CKR_OK;
  1760     PRBool writePrivate = PR_FALSE;
  1761     unsigned int i;
  1763     if (obj == NULL) {
  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 */
  1774     if (writePrivate) {
  1775 	NSSLOWKEYPrivateKey *privKey = lg_GetPrivateKey(obj);
  1776 	SECStatus rv = SECFailure;
  1777 	char * label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey);
  1779 	if (privKey) {
  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);
  1789     return crvCollect;

mercurial