~ubuntu-branches/ubuntu/quantal/nss/quantal-updates

« back to all changes in this revision

Viewing changes to nss/lib/softoken/legacydb/lgattr.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2013-11-14 14:58:07 UTC
  • mfrom: (1.1.19)
  • Revision ID: package-import@ubuntu.com-20131114145807-vj6v4erz8xj6kwz3
Tags: 3.15.3-0ubuntu0.12.10.1
* SECURITY UPDATE: New upstream release to fix multiple security issues
  and add TLSv1.2 support.
  - CVE-2013-1739
  - CVE-2013-1741
  - CVE-2013-5605
  - CVE-2013-5606
* Adjusted packaging for 3.15.3:
  - debian/patches/*: refreshed.
  - debian/patches/lower-dhe-priority.patch: removed, no longer needed,
    was a workaround for an old version of firefox.
  - debian/libnss3.symbols: added new symbols.
  - debian/rules: updated for new source layout.

Show diffs side-by-side

added added

removed removed

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