1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/softoken/legacydb/lgattr.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1790 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +/* 1.8 + * Internal PKCS #11 functions. Should only be called by pkcs11.c 1.9 + */ 1.10 +#include "pkcs11.h" 1.11 +#include "lgdb.h" 1.12 + 1.13 +#include "pcertt.h" 1.14 +#include "lowkeyi.h" 1.15 +#include "pcert.h" 1.16 +#include "blapi.h" 1.17 +#include "secerr.h" 1.18 +#include "secasn1.h" 1.19 + 1.20 +/* 1.21 + * Cache the object we are working on during Set's and Get's 1.22 + */ 1.23 +typedef struct LGObjectCacheStr { 1.24 + CK_OBJECT_CLASS objclass; 1.25 + CK_OBJECT_HANDLE handle; 1.26 + SDB *sdb; 1.27 + void *objectInfo; 1.28 + LGFreeFunc infoFree; 1.29 + SECItem dbKey; 1.30 +} LGObjectCache; 1.31 + 1.32 +static const CK_OBJECT_HANDLE lg_classArray[] = { 1.33 + 0, CKO_PRIVATE_KEY, CKO_PUBLIC_KEY, CKO_SECRET_KEY, 1.34 + CKO_NSS_TRUST, CKO_NSS_CRL, CKO_NSS_SMIME, 1.35 + CKO_CERTIFICATE }; 1.36 + 1.37 +#define handleToClass(handle) \ 1.38 + lg_classArray[((handle & LG_TOKEN_TYPE_MASK))>>LG_TOKEN_TYPE_SHIFT] 1.39 + 1.40 + 1.41 +static void lg_DestroyObjectCache(LGObjectCache *obj); 1.42 + 1.43 +static LGObjectCache * 1.44 +lg_NewObjectCache(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE handle) 1.45 +{ 1.46 + LGObjectCache *obj = NULL; 1.47 + SECStatus rv; 1.48 + 1.49 + obj = PORT_New(LGObjectCache); 1.50 + if (obj == NULL) { 1.51 + return NULL; 1.52 + } 1.53 + 1.54 + obj->objclass = handleToClass(handle); 1.55 + obj->handle = handle; 1.56 + obj->sdb = sdb; 1.57 + obj->objectInfo = NULL; 1.58 + obj->infoFree = NULL; 1.59 + obj->dbKey.data = NULL; 1.60 + obj->dbKey.len = 0; 1.61 + lg_DBLock(sdb); 1.62 + if (dbKey == NULL) { 1.63 + dbKey = lg_lookupTokenKeyByHandle(sdb,handle); 1.64 + } 1.65 + if (dbKey == NULL) { 1.66 + lg_DBUnlock(sdb); 1.67 + goto loser; 1.68 + } 1.69 + rv = SECITEM_CopyItem(NULL,&obj->dbKey,dbKey); 1.70 + lg_DBUnlock(sdb); 1.71 + if (rv != SECSuccess) { 1.72 + goto loser; 1.73 + } 1.74 + 1.75 + return obj; 1.76 +loser: 1.77 + if (obj) { 1.78 + (void) lg_DestroyObjectCache(obj); 1.79 + } 1.80 + return NULL; 1.81 + 1.82 +} 1.83 + 1.84 +/* 1.85 + * free all the data associated with an object. Object reference count must 1.86 + * be 'zero'. 1.87 + */ 1.88 +static void 1.89 +lg_DestroyObjectCache(LGObjectCache *obj) 1.90 +{ 1.91 + if (obj->dbKey.data) { 1.92 + PORT_Free(obj->dbKey.data); 1.93 + obj->dbKey.data = NULL; 1.94 + } 1.95 + if (obj->objectInfo) { 1.96 + (*obj->infoFree)(obj->objectInfo); 1.97 + obj->objectInfo = NULL; 1.98 + obj->infoFree = NULL; 1.99 + } 1.100 + PORT_Free(obj); 1.101 +} 1.102 +/* 1.103 + * ******************** Attribute Utilities ******************************* 1.104 + */ 1.105 + 1.106 +static CK_RV 1.107 +lg_ULongAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, CK_ULONG value) 1.108 +{ 1.109 + unsigned char *data; 1.110 + int i; 1.111 + 1.112 + if (attr->pValue == NULL) { 1.113 + attr->ulValueLen = 4; 1.114 + return CKR_OK; 1.115 + } 1.116 + if (attr->ulValueLen < 4) { 1.117 + attr->ulValueLen = (CK_ULONG) -1; 1.118 + return CKR_BUFFER_TOO_SMALL; 1.119 + } 1.120 + 1.121 + data = (unsigned char *)attr->pValue; 1.122 + for (i=0; i < 4; i++) { 1.123 + data[i] = (value >> ((3-i)*8)) & 0xff; 1.124 + } 1.125 + attr->ulValueLen = 4; 1.126 + return CKR_OK; 1.127 +} 1.128 + 1.129 +static CK_RV 1.130 +lg_CopyAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type, 1.131 + CK_VOID_PTR value, CK_ULONG len) 1.132 +{ 1.133 + 1.134 + if (attr->pValue == NULL) { 1.135 + attr->ulValueLen = len; 1.136 + return CKR_OK; 1.137 + } 1.138 + if (attr->ulValueLen < len) { 1.139 + attr->ulValueLen = (CK_ULONG) -1; 1.140 + return CKR_BUFFER_TOO_SMALL; 1.141 + } 1.142 + PORT_Memcpy(attr->pValue,value,len); 1.143 + attr->ulValueLen = len; 1.144 + return CKR_OK; 1.145 +} 1.146 + 1.147 +static CK_RV 1.148 +lg_CopyAttributeSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type, 1.149 + void *value, CK_ULONG len) 1.150 +{ 1.151 + unsigned char * dval = (unsigned char *)value; 1.152 + if (*dval == 0) { 1.153 + dval++; 1.154 + len--; 1.155 + } 1.156 + return lg_CopyAttribute(attribute,type,dval,len); 1.157 +} 1.158 + 1.159 +static CK_RV 1.160 +lg_CopyPrivAttribute(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type, 1.161 + void *value, CK_ULONG len, SDB *sdbpw) 1.162 +{ 1.163 + SECItem plainText, *cipherText = NULL; 1.164 + CK_RV crv = CKR_USER_NOT_LOGGED_IN; 1.165 + SECStatus rv; 1.166 + 1.167 + plainText.data = value; 1.168 + plainText.len = len; 1.169 + rv = lg_util_encrypt(NULL, sdbpw, &plainText, &cipherText); 1.170 + if (rv != SECSuccess) { 1.171 + goto loser; 1.172 + } 1.173 + crv = lg_CopyAttribute(attribute,type,cipherText->data,cipherText->len); 1.174 +loser: 1.175 + if (cipherText) { 1.176 + SECITEM_FreeItem(cipherText,PR_TRUE); 1.177 + } 1.178 + return crv; 1.179 +} 1.180 + 1.181 +static CK_RV 1.182 +lg_CopyPrivAttrSigned(CK_ATTRIBUTE *attribute, CK_ATTRIBUTE_TYPE type, 1.183 + void *value, CK_ULONG len, SDB *sdbpw) 1.184 +{ 1.185 + unsigned char * dval = (unsigned char *)value; 1.186 + 1.187 + if (*dval == 0) { 1.188 + dval++; 1.189 + len--; 1.190 + } 1.191 + return lg_CopyPrivAttribute(attribute,type,dval,len,sdbpw); 1.192 +} 1.193 + 1.194 +static CK_RV 1.195 +lg_invalidAttribute(CK_ATTRIBUTE *attr) 1.196 +{ 1.197 + attr->ulValueLen = (CK_ULONG) -1; 1.198 + return CKR_ATTRIBUTE_TYPE_INVALID; 1.199 +} 1.200 + 1.201 + 1.202 +#define LG_DEF_ATTRIBUTE(value,len) \ 1.203 + { 0, value, len } 1.204 + 1.205 +#define LG_CLONE_ATTR(attribute, type, staticAttr) \ 1.206 + lg_CopyAttribute(attribute, type, staticAttr.pValue, staticAttr.ulValueLen) 1.207 + 1.208 +CK_BBOOL lg_staticTrueValue = CK_TRUE; 1.209 +CK_BBOOL lg_staticFalseValue = CK_FALSE; 1.210 +static const CK_ATTRIBUTE lg_StaticTrueAttr = 1.211 + LG_DEF_ATTRIBUTE(&lg_staticTrueValue,sizeof(lg_staticTrueValue)); 1.212 +static const CK_ATTRIBUTE lg_StaticFalseAttr = 1.213 + LG_DEF_ATTRIBUTE(&lg_staticFalseValue,sizeof(lg_staticFalseValue)); 1.214 +static const CK_ATTRIBUTE lg_StaticNullAttr = LG_DEF_ATTRIBUTE(NULL,0); 1.215 +char lg_StaticOneValue = 1; 1.216 +static const CK_ATTRIBUTE lg_StaticOneAttr = 1.217 + LG_DEF_ATTRIBUTE(&lg_StaticOneValue,sizeof(lg_StaticOneValue)); 1.218 + 1.219 +/* 1.220 + * helper functions which get the database and call the underlying 1.221 + * low level database function. 1.222 + */ 1.223 +static char * 1.224 +lg_FindKeyNicknameByPublicKey(SDB *sdb, SECItem *dbKey) 1.225 +{ 1.226 + NSSLOWKEYDBHandle *keyHandle; 1.227 + char * label; 1.228 + 1.229 + keyHandle = lg_getKeyDB(sdb); 1.230 + if (!keyHandle) { 1.231 + return NULL; 1.232 + } 1.233 + 1.234 + label = nsslowkey_FindKeyNicknameByPublicKey(keyHandle, dbKey, 1.235 + sdb); 1.236 + return label; 1.237 +} 1.238 + 1.239 + 1.240 +NSSLOWKEYPrivateKey * 1.241 +lg_FindKeyByPublicKey(SDB *sdb, SECItem *dbKey) 1.242 +{ 1.243 + NSSLOWKEYPrivateKey *privKey; 1.244 + NSSLOWKEYDBHandle *keyHandle; 1.245 + 1.246 + keyHandle = lg_getKeyDB(sdb); 1.247 + if (keyHandle == NULL) { 1.248 + return NULL; 1.249 + } 1.250 + privKey = nsslowkey_FindKeyByPublicKey(keyHandle, dbKey, sdb); 1.251 + if (privKey == NULL) { 1.252 + return NULL; 1.253 + } 1.254 + return privKey; 1.255 +} 1.256 + 1.257 +static certDBEntrySMime * 1.258 +lg_getSMime(LGObjectCache *obj) 1.259 +{ 1.260 + certDBEntrySMime *entry; 1.261 + NSSLOWCERTCertDBHandle *certHandle; 1.262 + 1.263 + if (obj->objclass != CKO_NSS_SMIME) { 1.264 + return NULL; 1.265 + } 1.266 + if (obj->objectInfo) { 1.267 + return (certDBEntrySMime *)obj->objectInfo; 1.268 + } 1.269 + 1.270 + certHandle = lg_getCertDB(obj->sdb); 1.271 + if (!certHandle) { 1.272 + return NULL; 1.273 + } 1.274 + entry = nsslowcert_ReadDBSMimeEntry(certHandle, (char *)obj->dbKey.data); 1.275 + obj->objectInfo = (void *)entry; 1.276 + obj->infoFree = (LGFreeFunc) nsslowcert_DestroyDBEntry; 1.277 + return entry; 1.278 +} 1.279 + 1.280 +static certDBEntryRevocation * 1.281 +lg_getCrl(LGObjectCache *obj) 1.282 +{ 1.283 + certDBEntryRevocation *crl; 1.284 + PRBool isKrl; 1.285 + NSSLOWCERTCertDBHandle *certHandle; 1.286 + 1.287 + if (obj->objclass != CKO_NSS_CRL) { 1.288 + return NULL; 1.289 + } 1.290 + if (obj->objectInfo) { 1.291 + return (certDBEntryRevocation *)obj->objectInfo; 1.292 + } 1.293 + 1.294 + isKrl = (PRBool) (obj->handle == LG_TOKEN_KRL_HANDLE); 1.295 + certHandle = lg_getCertDB(obj->sdb); 1.296 + if (!certHandle) { 1.297 + return NULL; 1.298 + } 1.299 + 1.300 + crl = nsslowcert_FindCrlByKey(certHandle, &obj->dbKey, isKrl); 1.301 + obj->objectInfo = (void *)crl; 1.302 + obj->infoFree = (LGFreeFunc) nsslowcert_DestroyDBEntry; 1.303 + return crl; 1.304 +} 1.305 + 1.306 +static NSSLOWCERTCertificate * 1.307 +lg_getCert(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle) 1.308 +{ 1.309 + NSSLOWCERTCertificate *cert; 1.310 + CK_OBJECT_CLASS objClass = obj->objclass; 1.311 + 1.312 + if ((objClass != CKO_CERTIFICATE) && (objClass != CKO_NSS_TRUST)) { 1.313 + return NULL; 1.314 + } 1.315 + if (objClass == CKO_CERTIFICATE && obj->objectInfo) { 1.316 + return (NSSLOWCERTCertificate *)obj->objectInfo; 1.317 + } 1.318 + cert = nsslowcert_FindCertByKey(certHandle, &obj->dbKey); 1.319 + if (objClass == CKO_CERTIFICATE) { 1.320 + obj->objectInfo = (void *)cert; 1.321 + obj->infoFree = (LGFreeFunc) nsslowcert_DestroyCertificate ; 1.322 + } 1.323 + return cert; 1.324 +} 1.325 + 1.326 +static NSSLOWCERTTrust * 1.327 +lg_getTrust(LGObjectCache *obj, NSSLOWCERTCertDBHandle *certHandle) 1.328 +{ 1.329 + NSSLOWCERTTrust *trust; 1.330 + 1.331 + if (obj->objclass != CKO_NSS_TRUST) { 1.332 + return NULL; 1.333 + } 1.334 + if (obj->objectInfo) { 1.335 + return (NSSLOWCERTTrust *)obj->objectInfo; 1.336 + } 1.337 + trust = nsslowcert_FindTrustByKey(certHandle, &obj->dbKey); 1.338 + obj->objectInfo = (void *)trust; 1.339 + obj->infoFree = (LGFreeFunc) nsslowcert_DestroyTrust ; 1.340 + return trust; 1.341 +} 1.342 + 1.343 +static NSSLOWKEYPublicKey * 1.344 +lg_GetPublicKey(LGObjectCache *obj) 1.345 +{ 1.346 + NSSLOWKEYPublicKey *pubKey; 1.347 + NSSLOWKEYPrivateKey *privKey; 1.348 + 1.349 + if (obj->objclass != CKO_PUBLIC_KEY) { 1.350 + return NULL; 1.351 + } 1.352 + if (obj->objectInfo) { 1.353 + return (NSSLOWKEYPublicKey *)obj->objectInfo; 1.354 + } 1.355 + privKey = lg_FindKeyByPublicKey(obj->sdb, &obj->dbKey); 1.356 + if (privKey == NULL) { 1.357 + return NULL; 1.358 + } 1.359 + pubKey = lg_nsslowkey_ConvertToPublicKey(privKey); 1.360 + lg_nsslowkey_DestroyPrivateKey(privKey); 1.361 + obj->objectInfo = (void *) pubKey; 1.362 + obj->infoFree = (LGFreeFunc) lg_nsslowkey_DestroyPublicKey ; 1.363 + return pubKey; 1.364 +} 1.365 + 1.366 +/* 1.367 + * we need two versions of lg_GetPrivateKey. One version that takes the 1.368 + * DB handle so we can pass the handle we have already acquired in, 1.369 + * rather than going through the 'getKeyDB' code again, 1.370 + * which may fail the second time and another which just aquires 1.371 + * the key handle from the sdb (where we don't already have a key handle. 1.372 + * This version does the former. 1.373 + */ 1.374 +static NSSLOWKEYPrivateKey * 1.375 +lg_GetPrivateKeyWithDB(LGObjectCache *obj, NSSLOWKEYDBHandle *keyHandle) 1.376 +{ 1.377 + NSSLOWKEYPrivateKey *privKey; 1.378 + 1.379 + if ((obj->objclass != CKO_PRIVATE_KEY) && 1.380 + (obj->objclass != CKO_SECRET_KEY)) { 1.381 + return NULL; 1.382 + } 1.383 + if (obj->objectInfo) { 1.384 + return (NSSLOWKEYPrivateKey *)obj->objectInfo; 1.385 + } 1.386 + privKey = nsslowkey_FindKeyByPublicKey(keyHandle, &obj->dbKey, obj->sdb); 1.387 + if (privKey == NULL) { 1.388 + return NULL; 1.389 + } 1.390 + obj->objectInfo = (void *) privKey; 1.391 + obj->infoFree = (LGFreeFunc) lg_nsslowkey_DestroyPrivateKey ; 1.392 + return privKey; 1.393 +} 1.394 + 1.395 +/* this version does the latter */ 1.396 +static NSSLOWKEYPrivateKey * 1.397 +lg_GetPrivateKey(LGObjectCache *obj) 1.398 +{ 1.399 + NSSLOWKEYDBHandle *keyHandle; 1.400 + NSSLOWKEYPrivateKey *privKey; 1.401 + 1.402 + keyHandle = lg_getKeyDB(obj->sdb); 1.403 + if (!keyHandle) { 1.404 + return NULL; 1.405 + } 1.406 + privKey = lg_GetPrivateKeyWithDB(obj, keyHandle); 1.407 + return privKey; 1.408 +} 1.409 + 1.410 +/* lg_GetPubItem returns data associated with the public key. 1.411 + * one only needs to free the public key. This comment is here 1.412 + * because this sematic would be non-obvious otherwise. All callers 1.413 + * should include this comment. 1.414 + */ 1.415 +static SECItem * 1.416 +lg_GetPubItem(NSSLOWKEYPublicKey *pubKey) { 1.417 + SECItem *pubItem = NULL; 1.418 + /* get value to compare from the cert's public key */ 1.419 + switch ( pubKey->keyType ) { 1.420 + case NSSLOWKEYRSAKey: 1.421 + pubItem = &pubKey->u.rsa.modulus; 1.422 + break; 1.423 + case NSSLOWKEYDSAKey: 1.424 + pubItem = &pubKey->u.dsa.publicValue; 1.425 + break; 1.426 + case NSSLOWKEYDHKey: 1.427 + pubItem = &pubKey->u.dh.publicValue; 1.428 + break; 1.429 +#ifndef NSS_DISABLE_ECC 1.430 + case NSSLOWKEYECKey: 1.431 + pubItem = &pubKey->u.ec.publicValue; 1.432 + break; 1.433 +#endif /* NSS_DISABLE_ECC */ 1.434 + default: 1.435 + break; 1.436 + } 1.437 + return pubItem; 1.438 +} 1.439 + 1.440 +static const SEC_ASN1Template lg_SerialTemplate[] = { 1.441 + { SEC_ASN1_INTEGER, offsetof(NSSLOWCERTCertificate,serialNumber) }, 1.442 + { 0 } 1.443 +}; 1.444 + 1.445 +static CK_RV 1.446 +lg_FindRSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, 1.447 + CK_ATTRIBUTE *attribute) 1.448 +{ 1.449 + unsigned char hash[SHA1_LENGTH]; 1.450 + CK_KEY_TYPE keyType = CKK_RSA; 1.451 + 1.452 + switch (type) { 1.453 + case CKA_KEY_TYPE: 1.454 + return lg_ULongAttribute(attribute, type, keyType); 1.455 + case CKA_ID: 1.456 + SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len); 1.457 + return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); 1.458 + case CKA_DERIVE: 1.459 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.460 + case CKA_ENCRYPT: 1.461 + case CKA_VERIFY: 1.462 + case CKA_VERIFY_RECOVER: 1.463 + case CKA_WRAP: 1.464 + return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); 1.465 + case CKA_MODULUS: 1.466 + return lg_CopyAttributeSigned(attribute,type,key->u.rsa.modulus.data, 1.467 + key->u.rsa.modulus.len); 1.468 + case CKA_PUBLIC_EXPONENT: 1.469 + return lg_CopyAttributeSigned(attribute, type, 1.470 + key->u.rsa.publicExponent.data, 1.471 + key->u.rsa.publicExponent.len); 1.472 + default: 1.473 + break; 1.474 + } 1.475 + return lg_invalidAttribute(attribute); 1.476 +} 1.477 + 1.478 +static CK_RV 1.479 +lg_FindDSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, 1.480 + CK_ATTRIBUTE *attribute) 1.481 +{ 1.482 + unsigned char hash[SHA1_LENGTH]; 1.483 + CK_KEY_TYPE keyType = CKK_DSA; 1.484 + 1.485 + switch (type) { 1.486 + case CKA_KEY_TYPE: 1.487 + return lg_ULongAttribute(attribute, type, keyType); 1.488 + case CKA_ID: 1.489 + SHA1_HashBuf(hash,key->u.dsa.publicValue.data, 1.490 + key->u.dsa.publicValue.len); 1.491 + return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); 1.492 + case CKA_DERIVE: 1.493 + case CKA_ENCRYPT: 1.494 + case CKA_VERIFY_RECOVER: 1.495 + case CKA_WRAP: 1.496 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.497 + case CKA_VERIFY: 1.498 + return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); 1.499 + case CKA_VALUE: 1.500 + return lg_CopyAttributeSigned(attribute,type, 1.501 + key->u.dsa.publicValue.data, 1.502 + key->u.dsa.publicValue.len); 1.503 + case CKA_PRIME: 1.504 + return lg_CopyAttributeSigned(attribute,type, 1.505 + key->u.dsa.params.prime.data, 1.506 + key->u.dsa.params.prime.len); 1.507 + case CKA_SUBPRIME: 1.508 + return lg_CopyAttributeSigned(attribute,type, 1.509 + key->u.dsa.params.subPrime.data, 1.510 + key->u.dsa.params.subPrime.len); 1.511 + case CKA_BASE: 1.512 + return lg_CopyAttributeSigned(attribute,type, 1.513 + key->u.dsa.params.base.data, 1.514 + key->u.dsa.params.base.len); 1.515 + default: 1.516 + break; 1.517 + } 1.518 + return lg_invalidAttribute(attribute); 1.519 +} 1.520 + 1.521 +static CK_RV 1.522 +lg_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, 1.523 + CK_ATTRIBUTE *attribute) 1.524 +{ 1.525 + unsigned char hash[SHA1_LENGTH]; 1.526 + CK_KEY_TYPE keyType = CKK_DH; 1.527 + 1.528 + switch (type) { 1.529 + case CKA_KEY_TYPE: 1.530 + return lg_ULongAttribute(attribute, type, keyType); 1.531 + case CKA_ID: 1.532 + SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len); 1.533 + return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); 1.534 + case CKA_DERIVE: 1.535 + return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); 1.536 + case CKA_ENCRYPT: 1.537 + case CKA_VERIFY: 1.538 + case CKA_VERIFY_RECOVER: 1.539 + case CKA_WRAP: 1.540 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.541 + case CKA_VALUE: 1.542 + return lg_CopyAttributeSigned(attribute,type, 1.543 + key->u.dh.publicValue.data, 1.544 + key->u.dh.publicValue.len); 1.545 + case CKA_PRIME: 1.546 + return lg_CopyAttributeSigned(attribute,type,key->u.dh.prime.data, 1.547 + key->u.dh.prime.len); 1.548 + case CKA_BASE: 1.549 + return lg_CopyAttributeSigned(attribute,type,key->u.dh.base.data, 1.550 + key->u.dh.base.len); 1.551 + default: 1.552 + break; 1.553 + } 1.554 + return lg_invalidAttribute(attribute); 1.555 +} 1.556 + 1.557 +#ifndef NSS_DISABLE_ECC 1.558 +static CK_RV 1.559 +lg_FindECPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type, 1.560 + CK_ATTRIBUTE *attribute) 1.561 +{ 1.562 + unsigned char hash[SHA1_LENGTH]; 1.563 + CK_KEY_TYPE keyType = CKK_EC; 1.564 + 1.565 + switch (type) { 1.566 + case CKA_KEY_TYPE: 1.567 + return lg_ULongAttribute(attribute, type, keyType); 1.568 + case CKA_ID: 1.569 + SHA1_HashBuf(hash, key->u.ec.publicValue.data, 1.570 + key->u.ec.publicValue.len); 1.571 + return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); 1.572 + case CKA_DERIVE: 1.573 + case CKA_VERIFY: 1.574 + return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); 1.575 + case CKA_ENCRYPT: 1.576 + case CKA_VERIFY_RECOVER: 1.577 + case CKA_WRAP: 1.578 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.579 + case CKA_EC_PARAMS: 1.580 + return lg_CopyAttributeSigned(attribute,type, 1.581 + key->u.ec.ecParams.DEREncoding.data, 1.582 + key->u.ec.ecParams.DEREncoding.len); 1.583 + case CKA_EC_POINT: 1.584 + if (getenv("NSS_USE_DECODED_CKA_EC_POINT")) { 1.585 + return lg_CopyAttributeSigned(attribute, type, 1.586 + key->u.ec.publicValue.data, 1.587 + key->u.ec.publicValue.len); 1.588 + } else { 1.589 + SECItem *pubValue = SEC_ASN1EncodeItem(NULL, NULL, 1.590 + &(key->u.ec.publicValue), 1.591 + SEC_ASN1_GET(SEC_OctetStringTemplate)); 1.592 + CK_RV crv; 1.593 + if (!pubValue) { 1.594 + return CKR_HOST_MEMORY; 1.595 + } 1.596 + crv = lg_CopyAttributeSigned(attribute, type, 1.597 + pubValue->data, 1.598 + pubValue->len); 1.599 + SECITEM_FreeItem(pubValue, PR_TRUE); 1.600 + return crv; 1.601 + } 1.602 + default: 1.603 + break; 1.604 + } 1.605 + return lg_invalidAttribute(attribute); 1.606 +} 1.607 +#endif /* NSS_DISABLE_ECC */ 1.608 + 1.609 + 1.610 +static CK_RV 1.611 +lg_FindPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, 1.612 + CK_ATTRIBUTE *attribute) 1.613 +{ 1.614 + NSSLOWKEYPublicKey *key; 1.615 + CK_RV crv; 1.616 + char *label; 1.617 + 1.618 + switch (type) { 1.619 + case CKA_PRIVATE: 1.620 + case CKA_SENSITIVE: 1.621 + case CKA_ALWAYS_SENSITIVE: 1.622 + case CKA_NEVER_EXTRACTABLE: 1.623 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.624 + case CKA_MODIFIABLE: 1.625 + case CKA_EXTRACTABLE: 1.626 + return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); 1.627 + case CKA_SUBJECT: 1.628 + return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.629 + case CKA_START_DATE: 1.630 + case CKA_END_DATE: 1.631 + return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.632 + case CKA_LABEL: 1.633 + label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey); 1.634 + if (label == NULL) { 1.635 + return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.636 + } 1.637 + crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label)); 1.638 + PORT_Free(label); 1.639 + return crv; 1.640 + default: 1.641 + break; 1.642 + } 1.643 + 1.644 + key = lg_GetPublicKey(obj); 1.645 + if (key == NULL) { 1.646 + if (type == CKA_ID) { 1.647 + return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.648 + } 1.649 + return CKR_OBJECT_HANDLE_INVALID; 1.650 + } 1.651 + 1.652 + switch (key->keyType) { 1.653 + case NSSLOWKEYRSAKey: 1.654 + return lg_FindRSAPublicKeyAttribute(key,type,attribute); 1.655 + case NSSLOWKEYDSAKey: 1.656 + return lg_FindDSAPublicKeyAttribute(key,type,attribute); 1.657 + case NSSLOWKEYDHKey: 1.658 + return lg_FindDHPublicKeyAttribute(key,type,attribute); 1.659 +#ifndef NSS_DISABLE_ECC 1.660 + case NSSLOWKEYECKey: 1.661 + return lg_FindECPublicKeyAttribute(key,type,attribute); 1.662 +#endif /* NSS_DISABLE_ECC */ 1.663 + default: 1.664 + break; 1.665 + } 1.666 + 1.667 + return lg_invalidAttribute(attribute); 1.668 +} 1.669 + 1.670 +static CK_RV 1.671 +lg_FindSecretKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, 1.672 + CK_ATTRIBUTE *attribute) 1.673 +{ 1.674 + NSSLOWKEYPrivateKey *key; 1.675 + char *label; 1.676 + unsigned char *keyString; 1.677 + CK_RV crv; 1.678 + int keyTypeLen; 1.679 + CK_ULONG keyLen; 1.680 + CK_KEY_TYPE keyType; 1.681 + PRUint32 keyTypeStorage; 1.682 + 1.683 + switch (type) { 1.684 + case CKA_PRIVATE: 1.685 + case CKA_SENSITIVE: 1.686 + case CKA_ALWAYS_SENSITIVE: 1.687 + case CKA_EXTRACTABLE: 1.688 + case CKA_DERIVE: 1.689 + case CKA_ENCRYPT: 1.690 + case CKA_DECRYPT: 1.691 + case CKA_SIGN: 1.692 + case CKA_VERIFY: 1.693 + case CKA_WRAP: 1.694 + case CKA_UNWRAP: 1.695 + case CKA_MODIFIABLE: 1.696 + case CKA_LOCAL: 1.697 + return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); 1.698 + case CKA_NEVER_EXTRACTABLE: 1.699 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.700 + case CKA_START_DATE: 1.701 + case CKA_END_DATE: 1.702 + return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.703 + case CKA_LABEL: 1.704 + label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey); 1.705 + if (label == NULL) { 1.706 + return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.707 + } 1.708 + crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label)); 1.709 + PORT_Free(label); 1.710 + return crv; 1.711 + case CKA_ID: 1.712 + return lg_CopyAttribute(attribute,type,obj->dbKey.data, 1.713 + obj->dbKey.len); 1.714 + case CKA_KEY_TYPE: 1.715 + case CKA_VALUE_LEN: 1.716 + case CKA_VALUE: 1.717 + break; 1.718 + default: 1.719 + return lg_invalidAttribute(attribute); 1.720 + } 1.721 + 1.722 + key = lg_GetPrivateKey(obj); 1.723 + if (key == NULL) { 1.724 + return CKR_OBJECT_HANDLE_INVALID; 1.725 + } 1.726 + switch (type) { 1.727 + case CKA_KEY_TYPE: 1.728 + /* handle legacy databases. In legacy databases key_type was stored 1.729 + * in host order, with any leading zeros stripped off. Only key types 1.730 + * under 0x1f (AES) were stored. We assume that any values which are 1.731 + * either 1 byte long (big endian), or have byte[0] between 0 and 1.732 + * 0x7f and bytes[1]-bytes[3] equal to '0' (little endian). All other 1.733 + * values are assumed to be from the new database, which is always 4 1.734 + * bytes in network order */ 1.735 + keyType=0; 1.736 + keyString = key->u.rsa.coefficient.data; 1.737 + keyTypeLen = key->u.rsa.coefficient.len; 1.738 + 1.739 + 1.740 + /* 1.741 + * Because of various endian and word lengths The database may have 1.742 + * stored the keyType value in one of the following formats: 1.743 + * (kt) <= 0x1f 1.744 + * length data 1.745 + * Big Endian, pre-3.9, all lengths: 1 (kt) 1.746 + * Little Endian, pre-3.9, 32 bits: 4 (kt) 0 0 0 1.747 + * Little Endian, pre-3.9, 64 bits: 8 (kt) 0 0 0 0 0 0 0 1.748 + * All platforms, 3.9, 32 bits: 4 0 0 0 (kt) 1.749 + * Big Endian, 3.9, 64 bits: 8 0 0 0 (kt) 0 0 0 0 1.750 + * Little Endian, 3.9, 64 bits: 8 0 0 0 0 0 0 0 (kt) 1.751 + * All platforms, >= 3.9.1, all lengths: 4 (a) k1 k2 k3 1.752 + * where (a) is 0 or >= 0x80. currently (a) can only be 0. 1.753 + */ 1.754 + /* 1.755 + * this key was written on a 64 bit platform with a using NSS 3.9 1.756 + * or earlier. Reduce the 64 bit possibilities above. When we are 1.757 + * through, we will only have: 1.758 + * 1.759 + * Big Endian, pre-3.9, all lengths: 1 (kt) 1.760 + * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0 1.761 + * All platforms, 3.9, all lengths: 4 0 0 0 (kt) 1.762 + * All platforms, => 3.9.1, all lengths: 4 (a) k1 k2 k3 1.763 + */ 1.764 + if (keyTypeLen == 8) { 1.765 + keyTypeStorage = *(PRUint32 *) keyString; 1.766 + if (keyTypeStorage == 0) { 1.767 + keyString += sizeof(PRUint32); 1.768 + } 1.769 + keyTypeLen = 4; 1.770 + } 1.771 + /* 1.772 + * Now Handle: 1.773 + * 1.774 + * All platforms, 3.9, all lengths: 4 0 0 0 (kt) 1.775 + * All platforms, => 3.9.1, all lengths: 4 (a) k1 k2 k3 1.776 + * 1.777 + * NOTE: if kt == 0 or ak1k2k3 == 0, the test fails and 1.778 + * we handle it as: 1.779 + * 1.780 + * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0 1.781 + */ 1.782 + if (keyTypeLen == sizeof(keyTypeStorage) && 1.783 + (((keyString[0] & 0x80) == 0x80) || 1.784 + !((keyString[1] == 0) && (keyString[2] == 0) 1.785 + && (keyString[3] == 0))) ) { 1.786 + PORT_Memcpy(&keyTypeStorage, keyString, sizeof(keyTypeStorage)); 1.787 + keyType = (CK_KEY_TYPE) PR_ntohl(keyTypeStorage); 1.788 + } else { 1.789 + /* 1.790 + * Now Handle: 1.791 + * 1.792 + * Big Endian, pre-3.9, all lengths: 1 (kt) 1.793 + * Little Endian, pre-3.9, all lengths: 4 (kt) 0 0 0 1.794 + * -- KeyType == 0 all other cases ---: 4 0 0 0 0 1.795 + */ 1.796 + keyType = (CK_KEY_TYPE) keyString[0] ; 1.797 + } 1.798 + return lg_ULongAttribute(attribute, type, keyType); 1.799 + case CKA_VALUE: 1.800 + return lg_CopyPrivAttribute(attribute,type,key->u.rsa.privateExponent.data, 1.801 + key->u.rsa.privateExponent.len, obj->sdb); 1.802 + case CKA_VALUE_LEN: 1.803 + keyLen=key->u.rsa.privateExponent.len; 1.804 + return lg_ULongAttribute(attribute,type, keyLen); 1.805 + } 1.806 + return lg_invalidAttribute(attribute); 1.807 +} 1.808 + 1.809 +static CK_RV 1.810 +lg_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, 1.811 + CK_ATTRIBUTE *attribute, SDB *sdbpw) 1.812 +{ 1.813 + unsigned char hash[SHA1_LENGTH]; 1.814 + CK_KEY_TYPE keyType = CKK_RSA; 1.815 + 1.816 + switch (type) { 1.817 + case CKA_KEY_TYPE: 1.818 + return lg_ULongAttribute(attribute, type, keyType); 1.819 + case CKA_ID: 1.820 + SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len); 1.821 + return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); 1.822 + case CKA_DERIVE: 1.823 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.824 + case CKA_DECRYPT: 1.825 + case CKA_SIGN: 1.826 + case CKA_SIGN_RECOVER: 1.827 + case CKA_UNWRAP: 1.828 + return LG_CLONE_ATTR(attribute, type,lg_StaticTrueAttr); 1.829 + case CKA_MODULUS: 1.830 + return lg_CopyAttributeSigned(attribute,type,key->u.rsa.modulus.data, 1.831 + key->u.rsa.modulus.len); 1.832 + case CKA_PUBLIC_EXPONENT: 1.833 + return lg_CopyAttributeSigned(attribute, type, 1.834 + key->u.rsa.publicExponent.data, 1.835 + key->u.rsa.publicExponent.len); 1.836 + case CKA_PRIVATE_EXPONENT: 1.837 + return lg_CopyPrivAttrSigned(attribute,type, 1.838 + key->u.rsa.privateExponent.data, 1.839 + key->u.rsa.privateExponent.len, sdbpw); 1.840 + case CKA_PRIME_1: 1.841 + return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime1.data, 1.842 + key->u.rsa.prime1.len, sdbpw); 1.843 + case CKA_PRIME_2: 1.844 + return lg_CopyPrivAttrSigned(attribute, type, key->u.rsa.prime2.data, 1.845 + key->u.rsa.prime2.len, sdbpw); 1.846 + case CKA_EXPONENT_1: 1.847 + return lg_CopyPrivAttrSigned(attribute, type, 1.848 + key->u.rsa.exponent1.data, 1.849 + key->u.rsa.exponent1.len, sdbpw); 1.850 + case CKA_EXPONENT_2: 1.851 + return lg_CopyPrivAttrSigned(attribute, type, 1.852 + key->u.rsa.exponent2.data, 1.853 + key->u.rsa.exponent2.len, sdbpw); 1.854 + case CKA_COEFFICIENT: 1.855 + return lg_CopyPrivAttrSigned(attribute, type, 1.856 + key->u.rsa.coefficient.data, 1.857 + key->u.rsa.coefficient.len, sdbpw); 1.858 + default: 1.859 + break; 1.860 + } 1.861 + return lg_invalidAttribute(attribute); 1.862 +} 1.863 + 1.864 +static CK_RV 1.865 +lg_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, 1.866 + CK_ATTRIBUTE *attribute, SDB *sdbpw) 1.867 +{ 1.868 + unsigned char hash[SHA1_LENGTH]; 1.869 + CK_KEY_TYPE keyType = CKK_DSA; 1.870 + 1.871 + switch (type) { 1.872 + case CKA_KEY_TYPE: 1.873 + return lg_ULongAttribute(attribute, type, keyType); 1.874 + case CKA_ID: 1.875 + SHA1_HashBuf(hash,key->u.dsa.publicValue.data, 1.876 + key->u.dsa.publicValue.len); 1.877 + return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); 1.878 + case CKA_DERIVE: 1.879 + case CKA_DECRYPT: 1.880 + case CKA_SIGN_RECOVER: 1.881 + case CKA_UNWRAP: 1.882 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.883 + case CKA_SIGN: 1.884 + return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); 1.885 + case CKA_VALUE: 1.886 + return lg_CopyPrivAttrSigned(attribute, type, 1.887 + key->u.dsa.privateValue.data, 1.888 + key->u.dsa.privateValue.len, sdbpw); 1.889 + case CKA_PRIME: 1.890 + return lg_CopyAttributeSigned(attribute, type, 1.891 + key->u.dsa.params.prime.data, 1.892 + key->u.dsa.params.prime.len); 1.893 + case CKA_SUBPRIME: 1.894 + return lg_CopyAttributeSigned(attribute, type, 1.895 + key->u.dsa.params.subPrime.data, 1.896 + key->u.dsa.params.subPrime.len); 1.897 + case CKA_BASE: 1.898 + return lg_CopyAttributeSigned(attribute, type, 1.899 + key->u.dsa.params.base.data, 1.900 + key->u.dsa.params.base.len); 1.901 + case CKA_NETSCAPE_DB: 1.902 + return lg_CopyAttributeSigned(attribute, type, 1.903 + key->u.dsa.publicValue.data, 1.904 + key->u.dsa.publicValue.len); 1.905 + default: 1.906 + break; 1.907 + } 1.908 + return lg_invalidAttribute(attribute); 1.909 +} 1.910 + 1.911 +static CK_RV 1.912 +lg_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, 1.913 + CK_ATTRIBUTE *attribute, SDB *sdbpw) 1.914 +{ 1.915 + unsigned char hash[SHA1_LENGTH]; 1.916 + CK_KEY_TYPE keyType = CKK_DH; 1.917 + 1.918 + switch (type) { 1.919 + case CKA_KEY_TYPE: 1.920 + return lg_ULongAttribute(attribute, type, keyType); 1.921 + case CKA_ID: 1.922 + SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len); 1.923 + return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); 1.924 + case CKA_DERIVE: 1.925 + return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); 1.926 + case CKA_DECRYPT: 1.927 + case CKA_SIGN: 1.928 + case CKA_SIGN_RECOVER: 1.929 + case CKA_UNWRAP: 1.930 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.931 + case CKA_VALUE: 1.932 + return lg_CopyPrivAttrSigned(attribute, type, 1.933 + key->u.dh.privateValue.data, 1.934 + key->u.dh.privateValue.len, sdbpw); 1.935 + case CKA_PRIME: 1.936 + return lg_CopyAttributeSigned(attribute, type, key->u.dh.prime.data, 1.937 + key->u.dh.prime.len); 1.938 + case CKA_BASE: 1.939 + return lg_CopyAttributeSigned(attribute, type, key->u.dh.base.data, 1.940 + key->u.dh.base.len); 1.941 + case CKA_NETSCAPE_DB: 1.942 + return lg_CopyAttributeSigned(attribute, type, 1.943 + key->u.dh.publicValue.data, 1.944 + key->u.dh.publicValue.len); 1.945 + default: 1.946 + break; 1.947 + } 1.948 + return lg_invalidAttribute(attribute); 1.949 +} 1.950 + 1.951 +#ifndef NSS_DISABLE_ECC 1.952 +static CK_RV 1.953 +lg_FindECPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type, 1.954 + CK_ATTRIBUTE *attribute, SDB *sdbpw) 1.955 +{ 1.956 + unsigned char hash[SHA1_LENGTH]; 1.957 + CK_KEY_TYPE keyType = CKK_EC; 1.958 + 1.959 + switch (type) { 1.960 + case CKA_KEY_TYPE: 1.961 + return lg_ULongAttribute(attribute, type, keyType); 1.962 + case CKA_ID: 1.963 + SHA1_HashBuf(hash,key->u.ec.publicValue.data,key->u.ec.publicValue.len); 1.964 + return lg_CopyAttribute(attribute,type,hash,SHA1_LENGTH); 1.965 + case CKA_DERIVE: 1.966 + case CKA_SIGN: 1.967 + return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); 1.968 + case CKA_DECRYPT: 1.969 + case CKA_SIGN_RECOVER: 1.970 + case CKA_UNWRAP: 1.971 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.972 + case CKA_VALUE: 1.973 + return lg_CopyPrivAttrSigned(attribute, type, 1.974 + key->u.ec.privateValue.data, 1.975 + key->u.ec.privateValue.len, sdbpw); 1.976 + case CKA_EC_PARAMS: 1.977 + return lg_CopyAttributeSigned(attribute, type, 1.978 + key->u.ec.ecParams.DEREncoding.data, 1.979 + key->u.ec.ecParams.DEREncoding.len); 1.980 + case CKA_NETSCAPE_DB: 1.981 + return lg_CopyAttributeSigned(attribute, type, 1.982 + key->u.ec.publicValue.data, 1.983 + key->u.ec.publicValue.len); 1.984 + default: 1.985 + break; 1.986 + } 1.987 + return lg_invalidAttribute(attribute); 1.988 +} 1.989 +#endif /* NSS_DISABLE_ECC */ 1.990 + 1.991 +static CK_RV 1.992 +lg_FindPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, 1.993 + CK_ATTRIBUTE *attribute) 1.994 +{ 1.995 + NSSLOWKEYPrivateKey *key; 1.996 + char *label; 1.997 + CK_RV crv; 1.998 + 1.999 + switch (type) { 1.1000 + case CKA_PRIVATE: 1.1001 + case CKA_SENSITIVE: 1.1002 + case CKA_ALWAYS_SENSITIVE: 1.1003 + case CKA_EXTRACTABLE: 1.1004 + case CKA_MODIFIABLE: 1.1005 + case CKA_LOCAL: 1.1006 + return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); 1.1007 + case CKA_NEVER_EXTRACTABLE: 1.1008 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.1009 + case CKA_SUBJECT: 1.1010 + return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.1011 + case CKA_START_DATE: 1.1012 + case CKA_END_DATE: 1.1013 + return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.1014 + case CKA_LABEL: 1.1015 + label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey); 1.1016 + if (label == NULL) { 1.1017 + return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.1018 + } 1.1019 + crv = lg_CopyAttribute(attribute,type,label,PORT_Strlen(label)); 1.1020 + PORT_Free(label); 1.1021 + return crv; 1.1022 + default: 1.1023 + break; 1.1024 + } 1.1025 + key = lg_GetPrivateKey(obj); 1.1026 + if (key == NULL) { 1.1027 + return CKR_OBJECT_HANDLE_INVALID; 1.1028 + } 1.1029 + switch (key->keyType) { 1.1030 + case NSSLOWKEYRSAKey: 1.1031 + return lg_FindRSAPrivateKeyAttribute(key,type,attribute,obj->sdb); 1.1032 + case NSSLOWKEYDSAKey: 1.1033 + return lg_FindDSAPrivateKeyAttribute(key,type,attribute,obj->sdb); 1.1034 + case NSSLOWKEYDHKey: 1.1035 + return lg_FindDHPrivateKeyAttribute(key,type,attribute,obj->sdb); 1.1036 +#ifndef NSS_DISABLE_ECC 1.1037 + case NSSLOWKEYECKey: 1.1038 + return lg_FindECPrivateKeyAttribute(key,type,attribute,obj->sdb); 1.1039 +#endif /* NSS_DISABLE_ECC */ 1.1040 + default: 1.1041 + break; 1.1042 + } 1.1043 + 1.1044 + return lg_invalidAttribute(attribute); 1.1045 +} 1.1046 + 1.1047 +static CK_RV 1.1048 +lg_FindSMIMEAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, 1.1049 + CK_ATTRIBUTE *attribute) 1.1050 +{ 1.1051 + certDBEntrySMime *entry; 1.1052 + switch (type) { 1.1053 + case CKA_PRIVATE: 1.1054 + case CKA_MODIFIABLE: 1.1055 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.1056 + case CKA_NSS_EMAIL: 1.1057 + return lg_CopyAttribute(attribute,type,obj->dbKey.data, 1.1058 + obj->dbKey.len-1); 1.1059 + case CKA_NSS_SMIME_TIMESTAMP: 1.1060 + case CKA_SUBJECT: 1.1061 + case CKA_VALUE: 1.1062 + break; 1.1063 + default: 1.1064 + return lg_invalidAttribute(attribute); 1.1065 + } 1.1066 + entry = lg_getSMime(obj); 1.1067 + if (entry == NULL) { 1.1068 + return CKR_OBJECT_HANDLE_INVALID; 1.1069 + } 1.1070 + switch (type) { 1.1071 + case CKA_NSS_SMIME_TIMESTAMP: 1.1072 + return lg_CopyAttribute(attribute,type,entry->optionsDate.data, 1.1073 + entry->optionsDate.len); 1.1074 + case CKA_SUBJECT: 1.1075 + return lg_CopyAttribute(attribute,type,entry->subjectName.data, 1.1076 + entry->subjectName.len); 1.1077 + case CKA_VALUE: 1.1078 + return lg_CopyAttribute(attribute,type,entry->smimeOptions.data, 1.1079 + entry->smimeOptions.len); 1.1080 + default: 1.1081 + break; 1.1082 + } 1.1083 + return lg_invalidAttribute(attribute); 1.1084 +} 1.1085 + 1.1086 +static CK_RV 1.1087 +lg_FindTrustAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, 1.1088 + CK_ATTRIBUTE *attribute) 1.1089 +{ 1.1090 + NSSLOWCERTTrust *trust; 1.1091 + NSSLOWCERTCertDBHandle *certHandle; 1.1092 + NSSLOWCERTCertificate *cert; 1.1093 + unsigned char hash[SHA1_LENGTH]; 1.1094 + unsigned int trustFlags; 1.1095 + CK_RV crv; 1.1096 + 1.1097 + switch (type) { 1.1098 + case CKA_PRIVATE: 1.1099 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.1100 + case CKA_MODIFIABLE: 1.1101 + return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); 1.1102 + case CKA_CERT_SHA1_HASH: 1.1103 + case CKA_CERT_MD5_HASH: 1.1104 + case CKA_TRUST_CLIENT_AUTH: 1.1105 + case CKA_TRUST_SERVER_AUTH: 1.1106 + case CKA_TRUST_EMAIL_PROTECTION: 1.1107 + case CKA_TRUST_CODE_SIGNING: 1.1108 + case CKA_TRUST_STEP_UP_APPROVED: 1.1109 + case CKA_ISSUER: 1.1110 + case CKA_SERIAL_NUMBER: 1.1111 + break; 1.1112 + default: 1.1113 + return lg_invalidAttribute(attribute); 1.1114 + } 1.1115 + certHandle = lg_getCertDB(obj->sdb); 1.1116 + if (!certHandle) { 1.1117 + return CKR_OBJECT_HANDLE_INVALID; 1.1118 + } 1.1119 + trust = lg_getTrust(obj, certHandle); 1.1120 + if (trust == NULL) { 1.1121 + return CKR_OBJECT_HANDLE_INVALID; 1.1122 + } 1.1123 + switch (type) { 1.1124 + case CKA_CERT_SHA1_HASH: 1.1125 + SHA1_HashBuf(hash,trust->derCert->data,trust->derCert->len); 1.1126 + return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH); 1.1127 + case CKA_CERT_MD5_HASH: 1.1128 + MD5_HashBuf(hash,trust->derCert->data,trust->derCert->len); 1.1129 + return lg_CopyAttribute(attribute, type, hash, MD5_LENGTH); 1.1130 + case CKA_TRUST_CLIENT_AUTH: 1.1131 + trustFlags = trust->trust->sslFlags & CERTDB_TRUSTED_CLIENT_CA ? 1.1132 + trust->trust->sslFlags | CERTDB_TRUSTED_CA : 0 ; 1.1133 + goto trust; 1.1134 + case CKA_TRUST_SERVER_AUTH: 1.1135 + trustFlags = trust->trust->sslFlags; 1.1136 + goto trust; 1.1137 + case CKA_TRUST_EMAIL_PROTECTION: 1.1138 + trustFlags = trust->trust->emailFlags; 1.1139 + goto trust; 1.1140 + case CKA_TRUST_CODE_SIGNING: 1.1141 + trustFlags = trust->trust->objectSigningFlags; 1.1142 +trust: 1.1143 + if (trustFlags & CERTDB_TRUSTED_CA ) { 1.1144 + return lg_ULongAttribute(attribute, type, 1.1145 + CKT_NSS_TRUSTED_DELEGATOR); 1.1146 + } 1.1147 + if (trustFlags & CERTDB_TRUSTED) { 1.1148 + return lg_ULongAttribute(attribute, type, CKT_NSS_TRUSTED); 1.1149 + } 1.1150 + if (trustFlags & CERTDB_MUST_VERIFY) { 1.1151 + return lg_ULongAttribute(attribute, type, 1.1152 + CKT_NSS_MUST_VERIFY_TRUST); 1.1153 + } 1.1154 + if (trustFlags & CERTDB_TRUSTED_UNKNOWN) { 1.1155 + return lg_ULongAttribute(attribute, type, CKT_NSS_TRUST_UNKNOWN); 1.1156 + } 1.1157 + if (trustFlags & CERTDB_VALID_CA) { 1.1158 + return lg_ULongAttribute(attribute, type, CKT_NSS_VALID_DELEGATOR); 1.1159 + } 1.1160 + if (trustFlags & CERTDB_TERMINAL_RECORD) { 1.1161 + return lg_ULongAttribute(attribute, type, CKT_NSS_NOT_TRUSTED); 1.1162 + } 1.1163 + return lg_ULongAttribute(attribute, type, CKT_NSS_TRUST_UNKNOWN); 1.1164 + case CKA_TRUST_STEP_UP_APPROVED: 1.1165 + if (trust->trust->sslFlags & CERTDB_GOVT_APPROVED_CA) { 1.1166 + return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); 1.1167 + } else { 1.1168 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.1169 + } 1.1170 + default: 1.1171 + break; 1.1172 + } 1.1173 + 1.1174 + 1.1175 + switch (type) { 1.1176 + case CKA_ISSUER: 1.1177 + cert = lg_getCert(obj, certHandle); 1.1178 + if (cert == NULL) break; 1.1179 + crv = lg_CopyAttribute(attribute,type,cert->derIssuer.data, 1.1180 + cert->derIssuer.len); 1.1181 + break; 1.1182 + case CKA_SERIAL_NUMBER: 1.1183 + cert = lg_getCert(obj, certHandle); 1.1184 + if (cert == NULL) break; 1.1185 + crv = lg_CopyAttribute(attribute,type,cert->derSN.data, 1.1186 + cert->derSN.len); 1.1187 + break; 1.1188 + default: 1.1189 + cert = NULL; 1.1190 + break; 1.1191 + } 1.1192 + if (cert) { 1.1193 + nsslowcert_DestroyCertificate(cert); 1.1194 + return crv; 1.1195 + } 1.1196 + return lg_invalidAttribute(attribute); 1.1197 +} 1.1198 + 1.1199 +static CK_RV 1.1200 +lg_FindCrlAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, 1.1201 + CK_ATTRIBUTE *attribute) 1.1202 +{ 1.1203 + certDBEntryRevocation *crl; 1.1204 + 1.1205 + switch (type) { 1.1206 + case CKA_PRIVATE: 1.1207 + case CKA_MODIFIABLE: 1.1208 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.1209 + case CKA_NSS_KRL: 1.1210 + return ((obj->handle == LG_TOKEN_KRL_HANDLE) 1.1211 + ? LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr) 1.1212 + : LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr)); 1.1213 + case CKA_SUBJECT: 1.1214 + return lg_CopyAttribute(attribute,type,obj->dbKey.data, 1.1215 + obj->dbKey.len); 1.1216 + case CKA_NSS_URL: 1.1217 + case CKA_VALUE: 1.1218 + break; 1.1219 + default: 1.1220 + return lg_invalidAttribute(attribute); 1.1221 + } 1.1222 + crl = lg_getCrl(obj); 1.1223 + if (!crl) { 1.1224 + return CKR_OBJECT_HANDLE_INVALID; 1.1225 + } 1.1226 + switch (type) { 1.1227 + case CKA_NSS_URL: 1.1228 + if (crl->url == NULL) { 1.1229 + return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.1230 + } 1.1231 + return lg_CopyAttribute(attribute, type, crl->url, 1.1232 + PORT_Strlen(crl->url)+1); 1.1233 + case CKA_VALUE: 1.1234 + return lg_CopyAttribute(attribute, type, crl->derCrl.data, 1.1235 + crl->derCrl.len); 1.1236 + default: 1.1237 + break; 1.1238 + } 1.1239 + return lg_invalidAttribute(attribute); 1.1240 +} 1.1241 + 1.1242 +static CK_RV 1.1243 +lg_FindCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, 1.1244 + CK_ATTRIBUTE *attribute) 1.1245 +{ 1.1246 + NSSLOWCERTCertificate *cert; 1.1247 + NSSLOWCERTCertDBHandle *certHandle; 1.1248 + NSSLOWKEYPublicKey *pubKey; 1.1249 + unsigned char hash[SHA1_LENGTH]; 1.1250 + SECItem *item; 1.1251 + 1.1252 + switch (type) { 1.1253 + case CKA_PRIVATE: 1.1254 + return LG_CLONE_ATTR(attribute,type,lg_StaticFalseAttr); 1.1255 + case CKA_MODIFIABLE: 1.1256 + return LG_CLONE_ATTR(attribute,type,lg_StaticTrueAttr); 1.1257 + case CKA_CERTIFICATE_TYPE: 1.1258 + /* hardcoding X.509 into here */ 1.1259 + return lg_ULongAttribute(attribute, type, CKC_X_509); 1.1260 + case CKA_VALUE: 1.1261 + case CKA_ID: 1.1262 + case CKA_LABEL: 1.1263 + case CKA_SUBJECT: 1.1264 + case CKA_ISSUER: 1.1265 + case CKA_SERIAL_NUMBER: 1.1266 + case CKA_NSS_EMAIL: 1.1267 + break; 1.1268 + default: 1.1269 + return lg_invalidAttribute(attribute); 1.1270 + } 1.1271 + 1.1272 + certHandle = lg_getCertDB(obj->sdb); 1.1273 + if (certHandle == NULL) { 1.1274 + return CKR_OBJECT_HANDLE_INVALID; 1.1275 + } 1.1276 + 1.1277 + cert = lg_getCert(obj, certHandle); 1.1278 + if (cert == NULL) { 1.1279 + return CKR_OBJECT_HANDLE_INVALID; 1.1280 + } 1.1281 + switch (type) { 1.1282 + case CKA_VALUE: 1.1283 + return lg_CopyAttribute(attribute,type,cert->derCert.data, 1.1284 + cert->derCert.len); 1.1285 + case CKA_ID: 1.1286 + if (((cert->trust->sslFlags & CERTDB_USER) == 0) && 1.1287 + ((cert->trust->emailFlags & CERTDB_USER) == 0) && 1.1288 + ((cert->trust->objectSigningFlags & CERTDB_USER) == 0)) { 1.1289 + return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.1290 + } 1.1291 + pubKey = nsslowcert_ExtractPublicKey(cert); 1.1292 + if (pubKey == NULL) break; 1.1293 + item = lg_GetPubItem(pubKey); 1.1294 + if (item == NULL) { 1.1295 + lg_nsslowkey_DestroyPublicKey(pubKey); 1.1296 + break; 1.1297 + } 1.1298 + SHA1_HashBuf(hash,item->data,item->len); 1.1299 + /* item is imbedded in pubKey, just free the key */ 1.1300 + lg_nsslowkey_DestroyPublicKey(pubKey); 1.1301 + return lg_CopyAttribute(attribute, type, hash, SHA1_LENGTH); 1.1302 + case CKA_LABEL: 1.1303 + return cert->nickname 1.1304 + ? lg_CopyAttribute(attribute, type, cert->nickname, 1.1305 + PORT_Strlen(cert->nickname)) 1.1306 + : LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.1307 + case CKA_SUBJECT: 1.1308 + return lg_CopyAttribute(attribute,type,cert->derSubject.data, 1.1309 + cert->derSubject.len); 1.1310 + case CKA_ISSUER: 1.1311 + return lg_CopyAttribute(attribute,type,cert->derIssuer.data, 1.1312 + cert->derIssuer.len); 1.1313 + case CKA_SERIAL_NUMBER: 1.1314 + return lg_CopyAttribute(attribute,type,cert->derSN.data, 1.1315 + cert->derSN.len); 1.1316 + case CKA_NSS_EMAIL: 1.1317 + return (cert->emailAddr && cert->emailAddr[0]) 1.1318 + ? lg_CopyAttribute(attribute, type, cert->emailAddr, 1.1319 + PORT_Strlen(cert->emailAddr)) 1.1320 + : LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.1321 + default: 1.1322 + break; 1.1323 + } 1.1324 + return lg_invalidAttribute(attribute); 1.1325 +} 1.1326 + 1.1327 +CK_RV 1.1328 +lg_GetSingleAttribute(LGObjectCache *obj, CK_ATTRIBUTE *attribute) 1.1329 +{ 1.1330 + /* handle the common ones */ 1.1331 + CK_ATTRIBUTE_TYPE type = attribute->type; 1.1332 + switch (type) { 1.1333 + case CKA_CLASS: 1.1334 + return lg_ULongAttribute(attribute,type,obj->objclass); 1.1335 + case CKA_TOKEN: 1.1336 + return LG_CLONE_ATTR(attribute, type,lg_StaticTrueAttr); 1.1337 + case CKA_LABEL: 1.1338 + if ( (obj->objclass == CKO_CERTIFICATE) 1.1339 + || (obj->objclass == CKO_PRIVATE_KEY) 1.1340 + || (obj->objclass == CKO_PUBLIC_KEY) 1.1341 + || (obj->objclass == CKO_SECRET_KEY)) { 1.1342 + break; 1.1343 + } 1.1344 + return LG_CLONE_ATTR(attribute,type,lg_StaticNullAttr); 1.1345 + default: 1.1346 + break; 1.1347 + } 1.1348 + switch (obj->objclass) { 1.1349 + case CKO_CERTIFICATE: 1.1350 + return lg_FindCertAttribute(obj,type,attribute); 1.1351 + case CKO_NSS_CRL: 1.1352 + return lg_FindCrlAttribute(obj,type,attribute); 1.1353 + case CKO_NSS_TRUST: 1.1354 + return lg_FindTrustAttribute(obj,type,attribute); 1.1355 + case CKO_NSS_SMIME: 1.1356 + return lg_FindSMIMEAttribute(obj,type,attribute); 1.1357 + case CKO_PUBLIC_KEY: 1.1358 + return lg_FindPublicKeyAttribute(obj,type,attribute); 1.1359 + case CKO_PRIVATE_KEY: 1.1360 + return lg_FindPrivateKeyAttribute(obj,type,attribute); 1.1361 + case CKO_SECRET_KEY: 1.1362 + return lg_FindSecretKeyAttribute(obj,type,attribute); 1.1363 + default: 1.1364 + break; 1.1365 + } 1.1366 + return lg_invalidAttribute(attribute); 1.1367 +} 1.1368 + 1.1369 +/* 1.1370 + * Fill in the attribute template based on the data in the database. 1.1371 + */ 1.1372 +CK_RV 1.1373 +lg_GetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle, CK_ATTRIBUTE *templ, 1.1374 + CK_ULONG count) 1.1375 +{ 1.1376 + LGObjectCache *obj = lg_NewObjectCache(sdb, NULL, handle & ~LG_TOKEN_MASK); 1.1377 + CK_RV crv, crvCollect = CKR_OK; 1.1378 + unsigned int i; 1.1379 + 1.1380 + if (obj == NULL) { 1.1381 + return CKR_OBJECT_HANDLE_INVALID; 1.1382 + } 1.1383 + 1.1384 + for (i=0; i < count; i++) { 1.1385 + crv = lg_GetSingleAttribute(obj, &templ[i]); 1.1386 + if (crvCollect == CKR_OK) crvCollect = crv; 1.1387 + } 1.1388 + 1.1389 + lg_DestroyObjectCache(obj); 1.1390 + return crvCollect; 1.1391 +} 1.1392 + 1.1393 +PRBool 1.1394 +lg_cmpAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attribute) 1.1395 +{ 1.1396 + unsigned char buf[LG_BUF_SPACE]; 1.1397 + CK_ATTRIBUTE testAttr; 1.1398 + unsigned char *tempBuf = NULL; 1.1399 + PRBool match = PR_TRUE; 1.1400 + CK_RV crv; 1.1401 + 1.1402 + /* we're going to compare 'attribute' with the actual attribute from 1.1403 + * the object. We'll use the length of 'attribute' to decide how much 1.1404 + * space we need to read the test attribute. If 'attribute' doesn't give 1.1405 + * enough space, then we know the values don't match and that will 1.1406 + * show up as ckr != CKR_OK */ 1.1407 + testAttr = *attribute; 1.1408 + testAttr.pValue = buf; 1.1409 + 1.1410 + /* if we don't have enough space, malloc it */ 1.1411 + if (attribute->ulValueLen > LG_BUF_SPACE) { 1.1412 + tempBuf = PORT_Alloc(attribute->ulValueLen); 1.1413 + if (!tempBuf) { 1.1414 + return PR_FALSE; 1.1415 + } 1.1416 + testAttr.pValue = tempBuf; 1.1417 + } 1.1418 + 1.1419 + /* get the attribute */ 1.1420 + crv = lg_GetSingleAttribute(obj, &testAttr); 1.1421 + /* if the attribute was read OK, compare it */ 1.1422 + if ((crv != CKR_OK) || (attribute->ulValueLen != testAttr.ulValueLen) || 1.1423 + (PORT_Memcmp(attribute->pValue,testAttr.pValue,testAttr.ulValueLen)!= 0)){ 1.1424 + /* something didn't match, this isn't the object we are looking for */ 1.1425 + match = PR_FALSE; 1.1426 + } 1.1427 + /* free the buffer we may have allocated */ 1.1428 + if (tempBuf) { 1.1429 + PORT_Free(tempBuf); 1.1430 + } 1.1431 + return match; 1.1432 +} 1.1433 + 1.1434 +PRBool 1.1435 +lg_tokenMatch(SDB *sdb, const SECItem *dbKey, CK_OBJECT_HANDLE class, 1.1436 + const CK_ATTRIBUTE *templ, CK_ULONG count) 1.1437 +{ 1.1438 + PRBool match = PR_TRUE; 1.1439 + LGObjectCache *obj = lg_NewObjectCache(sdb, dbKey, class); 1.1440 + unsigned int i; 1.1441 + 1.1442 + if (obj == NULL) { 1.1443 + return PR_FALSE; 1.1444 + } 1.1445 + 1.1446 + for (i=0; i < count; i++) { 1.1447 + match = lg_cmpAttribute(obj, &templ[i]); 1.1448 + if (!match) { 1.1449 + break; 1.1450 + } 1.1451 + } 1.1452 + 1.1453 + /* done looking, free up our cache */ 1.1454 + lg_DestroyObjectCache(obj); 1.1455 + 1.1456 + /* if we get through the whole list without finding a mismatched attribute, 1.1457 + * then this object fits the criteria we are matching */ 1.1458 + return match; 1.1459 +} 1.1460 + 1.1461 +static CK_RV 1.1462 +lg_SetCertAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, 1.1463 + const void *value, unsigned int len) 1.1464 +{ 1.1465 + NSSLOWCERTCertificate *cert; 1.1466 + NSSLOWCERTCertDBHandle *certHandle; 1.1467 + char *nickname = NULL; 1.1468 + SECStatus rv; 1.1469 + CK_RV crv; 1.1470 + 1.1471 + /* we can't change the EMAIL values, but let the 1.1472 + * upper layers feel better about the fact we tried to set these */ 1.1473 + if (type == CKA_NSS_EMAIL) { 1.1474 + return CKR_OK; 1.1475 + } 1.1476 + 1.1477 + certHandle = lg_getCertDB(obj->sdb); 1.1478 + if (certHandle == NULL) { 1.1479 + crv = CKR_TOKEN_WRITE_PROTECTED; 1.1480 + goto done; 1.1481 + } 1.1482 + 1.1483 + if ((type != CKA_LABEL) && (type != CKA_ID)) { 1.1484 + crv = CKR_ATTRIBUTE_READ_ONLY; 1.1485 + goto done; 1.1486 + } 1.1487 + 1.1488 + cert = lg_getCert(obj, certHandle); 1.1489 + if (cert == NULL) { 1.1490 + crv = CKR_OBJECT_HANDLE_INVALID; 1.1491 + goto done; 1.1492 + } 1.1493 + 1.1494 + /* if the app is trying to set CKA_ID, it's probably because it just 1.1495 + * imported the key. Look to see if we need to set the CERTDB_USER bits. 1.1496 + */ 1.1497 + if (type == CKA_ID) { 1.1498 + if (((cert->trust->sslFlags & CERTDB_USER) == 0) && 1.1499 + ((cert->trust->emailFlags & CERTDB_USER) == 0) && 1.1500 + ((cert->trust->objectSigningFlags & CERTDB_USER) == 0)) { 1.1501 + NSSLOWKEYDBHandle *keyHandle; 1.1502 + 1.1503 + keyHandle = lg_getKeyDB(obj->sdb); 1.1504 + if (keyHandle) { 1.1505 + if (nsslowkey_KeyForCertExists(keyHandle, cert)) { 1.1506 + NSSLOWCERTCertTrust trust = *cert->trust; 1.1507 + trust.sslFlags |= CERTDB_USER; 1.1508 + trust.emailFlags |= CERTDB_USER; 1.1509 + trust.objectSigningFlags |= CERTDB_USER; 1.1510 + nsslowcert_ChangeCertTrust(certHandle,cert,&trust); 1.1511 + } 1.1512 + } 1.1513 + } 1.1514 + crv = CKR_OK; 1.1515 + goto done; 1.1516 + } 1.1517 + 1.1518 + /* must be CKA_LABEL */ 1.1519 + if (value != NULL) { 1.1520 + nickname = PORT_ZAlloc(len+1); 1.1521 + if (nickname == NULL) { 1.1522 + crv = CKR_HOST_MEMORY; 1.1523 + goto done; 1.1524 + } 1.1525 + PORT_Memcpy(nickname,value,len); 1.1526 + nickname[len] = 0; 1.1527 + } 1.1528 + rv = nsslowcert_AddPermNickname(certHandle, cert, nickname); 1.1529 + crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; 1.1530 + 1.1531 +done: 1.1532 + if (nickname) { 1.1533 + PORT_Free(nickname); 1.1534 + } 1.1535 + return crv; 1.1536 +} 1.1537 + 1.1538 +static CK_RV 1.1539 +lg_SetPrivateKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, 1.1540 + const void *value, unsigned int len, 1.1541 + PRBool *writePrivate) 1.1542 +{ 1.1543 + NSSLOWKEYPrivateKey *privKey; 1.1544 + NSSLOWKEYDBHandle *keyHandle; 1.1545 + char *nickname = NULL; 1.1546 + SECStatus rv; 1.1547 + CK_RV crv; 1.1548 + 1.1549 + /* we can't change the ID and we don't store the subject, but let the 1.1550 + * upper layers feel better about the fact we tried to set these */ 1.1551 + if ((type == CKA_ID) || (type == CKA_SUBJECT) || 1.1552 + (type == CKA_LOCAL) || (type == CKA_NEVER_EXTRACTABLE) || 1.1553 + (type == CKA_ALWAYS_SENSITIVE)) { 1.1554 + return CKR_OK; 1.1555 + } 1.1556 + 1.1557 + keyHandle = lg_getKeyDB(obj->sdb); 1.1558 + if (keyHandle == NULL) { 1.1559 + crv = CKR_TOKEN_WRITE_PROTECTED; 1.1560 + goto done; 1.1561 + } 1.1562 + 1.1563 + privKey = lg_GetPrivateKeyWithDB(obj, keyHandle); 1.1564 + if (privKey == NULL) { 1.1565 + crv = CKR_OBJECT_HANDLE_INVALID; 1.1566 + goto done; 1.1567 + } 1.1568 + 1.1569 + crv = CKR_ATTRIBUTE_READ_ONLY; 1.1570 + switch(type) { 1.1571 + case CKA_LABEL: 1.1572 + if (value != NULL) { 1.1573 + nickname = PORT_ZAlloc(len+1); 1.1574 + if (nickname == NULL) { 1.1575 + crv = CKR_HOST_MEMORY; 1.1576 + goto done; 1.1577 + } 1.1578 + PORT_Memcpy(nickname,value,len); 1.1579 + nickname[len] = 0; 1.1580 + } 1.1581 + rv = nsslowkey_UpdateNickname(keyHandle, privKey, &obj->dbKey, 1.1582 + nickname, obj->sdb); 1.1583 + crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; 1.1584 + break; 1.1585 + case CKA_UNWRAP: 1.1586 + case CKA_SIGN: 1.1587 + case CKA_DERIVE: 1.1588 + case CKA_SIGN_RECOVER: 1.1589 + case CKA_DECRYPT: 1.1590 + /* ignore attempts to change restrict these. 1.1591 + * legacyDB ignore these flags and always presents all of them 1.1592 + * that are valid as true. 1.1593 + * NOTE: We only get here if the current value and the new value do 1.1594 + * not match. */ 1.1595 + if (*(char *)value == 0) { 1.1596 + crv = CKR_OK; 1.1597 + } 1.1598 + break; 1.1599 + case CKA_VALUE: 1.1600 + case CKA_PRIVATE_EXPONENT: 1.1601 + case CKA_PRIME_1: 1.1602 + case CKA_PRIME_2: 1.1603 + case CKA_EXPONENT_1: 1.1604 + case CKA_EXPONENT_2: 1.1605 + case CKA_COEFFICIENT: 1.1606 + /* We aren't really changing these values, we are just triggering 1.1607 + * the database to update it's entry */ 1.1608 + *writePrivate = PR_TRUE; 1.1609 + crv = CKR_OK; 1.1610 + break; 1.1611 + default: 1.1612 + crv = CKR_ATTRIBUTE_READ_ONLY; 1.1613 + break; 1.1614 + } 1.1615 +done: 1.1616 + if (nickname) { 1.1617 + PORT_Free(nickname); 1.1618 + } 1.1619 + return crv; 1.1620 +} 1.1621 + 1.1622 +static CK_RV 1.1623 +lg_SetPublicKeyAttribute(LGObjectCache *obj, CK_ATTRIBUTE_TYPE type, 1.1624 + const void *value, unsigned int len, 1.1625 + PRBool *writePrivate) 1.1626 +{ 1.1627 + /* we can't change the ID and we don't store the subject, but let the 1.1628 + * upper layers feel better about the fact we tried to set these */ 1.1629 + if ((type == CKA_ID) || (type == CKA_SUBJECT) || (type == CKA_LABEL)) { 1.1630 + return CKR_OK; 1.1631 + } 1.1632 + return CKR_ATTRIBUTE_READ_ONLY; 1.1633 +} 1.1634 + 1.1635 +static CK_RV 1.1636 +lg_SetTrustAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr) 1.1637 +{ 1.1638 + unsigned int flags; 1.1639 + CK_TRUST trust; 1.1640 + NSSLOWCERTCertificate *cert; 1.1641 + NSSLOWCERTCertDBHandle *certHandle; 1.1642 + NSSLOWCERTCertTrust dbTrust; 1.1643 + SECStatus rv; 1.1644 + CK_RV crv; 1.1645 + 1.1646 + if (attr->type == CKA_LABEL) { 1.1647 + return CKR_OK; 1.1648 + } 1.1649 + 1.1650 + crv = lg_GetULongAttribute(attr->type, attr, 1, &trust); 1.1651 + if (crv != CKR_OK) { 1.1652 + return crv; 1.1653 + } 1.1654 + flags = lg_MapTrust(trust, (PRBool) (attr->type == CKA_TRUST_CLIENT_AUTH)); 1.1655 + 1.1656 + certHandle = lg_getCertDB(obj->sdb); 1.1657 + 1.1658 + if (certHandle == NULL) { 1.1659 + crv = CKR_TOKEN_WRITE_PROTECTED; 1.1660 + goto done; 1.1661 + } 1.1662 + 1.1663 + cert = lg_getCert(obj, certHandle); 1.1664 + if (cert == NULL) { 1.1665 + crv = CKR_OBJECT_HANDLE_INVALID; 1.1666 + goto done; 1.1667 + } 1.1668 + dbTrust = *cert->trust; 1.1669 + 1.1670 + switch (attr->type) { 1.1671 + case CKA_TRUST_EMAIL_PROTECTION: 1.1672 + dbTrust.emailFlags = flags | 1.1673 + (cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS); 1.1674 + break; 1.1675 + case CKA_TRUST_CODE_SIGNING: 1.1676 + dbTrust.objectSigningFlags = flags | 1.1677 + (cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS); 1.1678 + break; 1.1679 + case CKA_TRUST_CLIENT_AUTH: 1.1680 + dbTrust.sslFlags = flags | (cert->trust->sslFlags & 1.1681 + (CERTDB_PRESERVE_TRUST_BITS|CERTDB_TRUSTED_CA)); 1.1682 + break; 1.1683 + case CKA_TRUST_SERVER_AUTH: 1.1684 + dbTrust.sslFlags = flags | (cert->trust->sslFlags & 1.1685 + (CERTDB_PRESERVE_TRUST_BITS|CERTDB_TRUSTED_CLIENT_CA)); 1.1686 + break; 1.1687 + default: 1.1688 + crv = CKR_ATTRIBUTE_READ_ONLY; 1.1689 + goto done; 1.1690 + } 1.1691 + 1.1692 + rv = nsslowcert_ChangeCertTrust(certHandle, cert, &dbTrust); 1.1693 + crv = (rv == SECSuccess) ? CKR_OK : CKR_DEVICE_ERROR; 1.1694 +done: 1.1695 + return crv; 1.1696 +} 1.1697 + 1.1698 +static CK_RV 1.1699 +lg_SetSingleAttribute(LGObjectCache *obj, const CK_ATTRIBUTE *attr, 1.1700 + PRBool *writePrivate) 1.1701 +{ 1.1702 + CK_ATTRIBUTE attribLocal; 1.1703 + CK_RV crv; 1.1704 + 1.1705 + if ((attr->type == CKA_NETSCAPE_DB) && (obj->objclass == CKO_PRIVATE_KEY)) { 1.1706 + *writePrivate = PR_TRUE; 1.1707 + return CKR_OK; 1.1708 + } 1.1709 + 1.1710 + /* Make sure the attribute exists first */ 1.1711 + attribLocal.type = attr->type; 1.1712 + attribLocal.pValue = NULL; 1.1713 + attribLocal.ulValueLen = 0; 1.1714 + crv = lg_GetSingleAttribute(obj, &attribLocal); 1.1715 + if (crv != CKR_OK) { 1.1716 + return crv; 1.1717 + } 1.1718 + 1.1719 + /* if we are just setting it to the value we already have, 1.1720 + * allow it to happen. Let label setting go through so 1.1721 + * we have the opportunity to repair any database corruption. */ 1.1722 + if (attr->type != CKA_LABEL) { 1.1723 + if (lg_cmpAttribute(obj,attr)) { 1.1724 + return CKR_OK; 1.1725 + } 1.1726 + } 1.1727 + 1.1728 + crv = CKR_ATTRIBUTE_READ_ONLY; 1.1729 + switch (obj->objclass) { 1.1730 + case CKO_CERTIFICATE: 1.1731 + /* change NICKNAME, EMAIL, */ 1.1732 + crv = lg_SetCertAttribute(obj,attr->type, 1.1733 + attr->pValue,attr->ulValueLen); 1.1734 + break; 1.1735 + case CKO_NSS_CRL: 1.1736 + /* change URL */ 1.1737 + break; 1.1738 + case CKO_NSS_TRUST: 1.1739 + crv = lg_SetTrustAttribute(obj,attr); 1.1740 + break; 1.1741 + case CKO_PRIVATE_KEY: 1.1742 + case CKO_SECRET_KEY: 1.1743 + crv = lg_SetPrivateKeyAttribute(obj,attr->type, 1.1744 + attr->pValue,attr->ulValueLen, writePrivate); 1.1745 + break; 1.1746 + case CKO_PUBLIC_KEY: 1.1747 + crv = lg_SetPublicKeyAttribute(obj,attr->type, 1.1748 + attr->pValue,attr->ulValueLen, writePrivate); 1.1749 + break; 1.1750 + } 1.1751 + return crv; 1.1752 +} 1.1753 + 1.1754 +/* 1.1755 + * Fill in the attribute template based on the data in the database. 1.1756 + */ 1.1757 +CK_RV 1.1758 +lg_SetAttributeValue(SDB *sdb, CK_OBJECT_HANDLE handle, 1.1759 + const CK_ATTRIBUTE *templ, CK_ULONG count) 1.1760 +{ 1.1761 + LGObjectCache *obj = lg_NewObjectCache(sdb, NULL, handle & ~LG_TOKEN_MASK); 1.1762 + CK_RV crv, crvCollect = CKR_OK; 1.1763 + PRBool writePrivate = PR_FALSE; 1.1764 + unsigned int i; 1.1765 + 1.1766 + if (obj == NULL) { 1.1767 + return CKR_OBJECT_HANDLE_INVALID; 1.1768 + } 1.1769 + 1.1770 + for (i=0; i < count; i++) { 1.1771 + crv = lg_SetSingleAttribute(obj, &templ[i], &writePrivate); 1.1772 + if (crvCollect == CKR_OK) crvCollect = crv; 1.1773 + } 1.1774 + 1.1775 + /* Write any collected changes out for private and secret keys. 1.1776 + * don't do the write for just the label */ 1.1777 + if (writePrivate) { 1.1778 + NSSLOWKEYPrivateKey *privKey = lg_GetPrivateKey(obj); 1.1779 + SECStatus rv = SECFailure; 1.1780 + char * label = lg_FindKeyNicknameByPublicKey(obj->sdb, &obj->dbKey); 1.1781 + 1.1782 + if (privKey) { 1.1783 + rv = nsslowkey_StoreKeyByPublicKeyAlg(lg_getKeyDB(sdb), privKey, 1.1784 + &obj->dbKey, label, sdb, PR_TRUE ); 1.1785 + } 1.1786 + if (rv != SECSuccess) { 1.1787 + crv = CKR_DEVICE_ERROR; 1.1788 + } 1.1789 + } 1.1790 + 1.1791 + lg_DestroyObjectCache(obj); 1.1792 + return crvCollect; 1.1793 +}