~ubuntu-branches/ubuntu/intrepid/xulrunner-1.9/intrepid

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack, Alexander Sack, Fabien Tassin
  • Date: 2008-02-13 11:47:21 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080213114721-7om0mgzngvuk9czv
Tags: 1.9~b3+nobinonly-0ubuntu1
* release FIREFOX_3_0b3_RELEASE

[ Alexander Sack ]
* submit patch that ships xpcshell to bugzilla
  - rename debian/patches/ship_xpcshell.patch =>
           debian/patches/bz410617_att295212_ship_xpcshell.patch
  - update debian/patches/series
* fix tooltip in epiphany: previously displayed out of screen bounds
  (LP: #37507)
  - add debian/patches/bz233371_att297343_fix_outofscreen_embed_tooltip.patch
  - update debian/patches/series
* use default upstream gcc tweaks for improved performance - especially of the
  javascript engine
  - update debian/rules
* update global extension/plugin patch to apply cleanly against latest code
  - update debian/patches/bzXXX_gre_extension_plugin_support.patch
* fix pyxpcom build failure introduced by recent commit
  - add debian/patches/bzXXX_fix_pyxpcom_build_failure.patch
  - update debian/patches/series
* add distro independent global install locations for extensions,
  /usr/lib/mozilla/extensions and /usr/share/mozilla/extensions
  - update debian/xulrunner-1.9.dirs
* support embedded tarball layout when either there is a *.tar.bz2 in orig tarball
  or if DEBIAN_MOZCLIENT_EMBEDDED is not unset (you will need this to produce embedded
  tarballs during |get-orig-source|
  - update debian/rules
* bump minimum libnss3-dev build requirements to >= 3.12.0~1.9b3
  - update debian/control
* bump minimum libnspr4-dev build requirements to >= 4.7.0~1.9b3
  - update debian/control

[ Fabien Tassin ]
* Drop patches applied upstream
  - drop debian/patches/bz410617_att295212_ship_xpcshell.patch
  - drop debian/patches/bz404634_att294921.patch
  - drop debian/patches/bz386610_python2.5_ftbfs_amd64.patch
  - drop debian/patches/bz373918_att295042.patch
  - drop debian/patches/bz408062_unstable_pc.patch
  - drop debian/patches/bz384304_fix_recursive_symlinks.patch
  - update debian/patches/series
* Refresh diverged patches:
  - update debian/patches/bzXXX_pc_honour_system_nspr_nss.patch
  - update debian/patches/rename_venkman_addon.patch
  - update debian/patches/bz344818_cairo_xrender.patch
* Install links for all .so libs in the -dev package
  - update debian/patches/dont_install_so_in_dev.patch
* Bump gtk requirement to 2.12 as per Mozilla bug 412432
  - update debian/control
* Add #DEBHELPER# token to postinst/prerm scripts
  - update debian/xulrunner-1.9.{postinst,prerm}
* Install previously missed libdbusservice.so
  - update debian/xulrunner-1.9.install
* Update venkman patch to also rename locales
  - update debian/patches/rename_venkman_addon.patch
* Bump requirement for system cairo to >= 1.5.8 as we now need
  the newly added cairo_path_extents()
  - update debian/rules
* Include mozilla-devscripts file using -include so ifneq could be omitted
  - update debian/rules
* Fix missing .so symlinks regression
  - update debian/patches/dont_install_so_in_dev.patch

Show diffs side-by-side

added added

removed removed

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