~ubuntu-branches/ubuntu/trusty/xulrunner/trusty

« back to all changes in this revision

Viewing changes to security/nss-fips/lib/dev/ckhelper.c

  • Committer: Bazaar Package Importer
  • Author(s): Devid Antonio Filoni
  • Date: 2008-08-25 13:04:18 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20080825130418-ck1i2ms384tzb9m0
Tags: 1.8.1.16+nobinonly-0ubuntu1
* New upstream release (taken from upstream CVS), LP: #254618.
* Fix MFSA 2008-35, MFSA 2008-34, MFSA 2008-33, MFSA 2008-32, MFSA 2008-31,
  MFSA 2008-30, MFSA 2008-29, MFSA 2008-28, MFSA 2008-27, MFSA 2008-25,
  MFSA 2008-24, MFSA 2008-23, MFSA 2008-22, MFSA 2008-21, MFSA 2008-26 also
  known as CVE-2008-2933, CVE-2008-2785, CVE-2008-2811, CVE-2008-2810,
  CVE-2008-2809, CVE-2008-2808, CVE-2008-2807, CVE-2008-2806, CVE-2008-2805,
  CVE-2008-2803, CVE-2008-2802, CVE-2008-2801, CVE-2008-2800, CVE-2008-2798.
* Drop 89_bz419350_attachment_306066 patch, merged upstream.
* Bump Standards-Version to 3.8.0.

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
 *
 
23
 * Alternatively, the contents of this file may be used under the terms of
 
24
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
25
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
26
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
27
 * of those above. If you wish to allow use of your version of this file only
 
28
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
29
 * use your version of this file under the terms of the MPL, indicate your
 
30
 * decision by deleting the provisions above and replace them with the notice
 
31
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
32
 * the provisions above, a recipient may use your version of this file under
 
33
 * the terms of any one of the MPL, the GPL or the LGPL.
 
34
 *
 
35
 * ***** END LICENSE BLOCK ***** */
 
36
 
 
37
#ifdef DEBUG
 
38
static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.34 $ $Date: 2005/04/04 18:46:23 $";
 
39
#endif /* DEBUG */
 
40
 
 
41
#ifndef NSSCKEPV_H
 
42
#include "nssckepv.h"
 
43
#endif /* NSSCKEPV_H */
 
44
 
 
45
#ifndef DEVM_H
 
46
#include "devm.h"
 
47
#endif /* DEVM_H */
 
48
 
 
49
#ifndef CKHELPER_H
 
50
#include "ckhelper.h"
 
51
#endif /* CKHELPER_H */
 
52
 
 
53
extern const NSSError NSS_ERROR_DEVICE_ERROR;
 
54
 
 
55
static const CK_BBOOL s_true = CK_TRUE;
 
56
NSS_IMPLEMENT_DATA const NSSItem
 
57
g_ck_true = { (CK_VOID_PTR)&s_true, sizeof(s_true) };
 
58
 
 
59
static const CK_BBOOL s_false = CK_FALSE;
 
60
NSS_IMPLEMENT_DATA const NSSItem
 
61
g_ck_false = { (CK_VOID_PTR)&s_false, sizeof(s_false) };
 
62
 
 
63
static const CK_OBJECT_CLASS s_class_cert = CKO_CERTIFICATE;
 
64
NSS_IMPLEMENT_DATA const NSSItem
 
65
g_ck_class_cert = { (CK_VOID_PTR)&s_class_cert, sizeof(s_class_cert) };
 
66
 
 
67
static const CK_OBJECT_CLASS s_class_pubkey = CKO_PUBLIC_KEY;
 
68
NSS_IMPLEMENT_DATA const NSSItem
 
69
g_ck_class_pubkey = { (CK_VOID_PTR)&s_class_pubkey, sizeof(s_class_pubkey) };
 
70
 
 
71
static const CK_OBJECT_CLASS s_class_privkey = CKO_PRIVATE_KEY;
 
72
NSS_IMPLEMENT_DATA const NSSItem
 
73
g_ck_class_privkey = { (CK_VOID_PTR)&s_class_privkey, sizeof(s_class_privkey) };
 
74
 
 
75
static PRBool
 
76
is_string_attribute (
 
77
  CK_ATTRIBUTE_TYPE aType
 
78
)
 
79
{
 
80
    PRBool isString;
 
81
    switch (aType) {
 
82
    case CKA_LABEL:
 
83
    case CKA_NETSCAPE_EMAIL:
 
84
        isString = PR_TRUE;
 
85
        break;
 
86
    default:
 
87
        isString = PR_FALSE;
 
88
        break;
 
89
    }
 
90
    return isString;
 
91
}
 
92
 
 
93
NSS_IMPLEMENT PRStatus 
 
94
nssCKObject_GetAttributes (
 
95
  CK_OBJECT_HANDLE object,
 
96
  CK_ATTRIBUTE_PTR obj_template,
 
97
  CK_ULONG count,
 
98
  NSSArena *arenaOpt,
 
99
  nssSession *session,
 
100
  NSSSlot *slot
 
101
)
 
102
{
 
103
    nssArenaMark *mark = NULL;
 
104
    CK_SESSION_HANDLE hSession;
 
105
    CK_ULONG i = 0;
 
106
    CK_RV ckrv;
 
107
    PRStatus nssrv;
 
108
    PRBool alloced = PR_FALSE;
 
109
    void *epv = nssSlot_GetCryptokiEPV(slot);
 
110
    hSession = session->handle; 
 
111
    if (arenaOpt) {
 
112
        mark = nssArena_Mark(arenaOpt);
 
113
        if (!mark) {
 
114
            goto loser;
 
115
        }
 
116
    }
 
117
    nssSession_EnterMonitor(session);
 
118
    /* XXX kinda hacky, if the storage size is already in the first template
 
119
     * item, then skip the alloc portion
 
120
     */
 
121
    if (obj_template[0].ulValueLen == 0) {
 
122
        /* Get the storage size needed for each attribute */
 
123
        ckrv = CKAPI(epv)->C_GetAttributeValue(hSession,
 
124
                                               object, obj_template, count);
 
125
        if (ckrv != CKR_OK && 
 
126
            ckrv != CKR_ATTRIBUTE_TYPE_INVALID &&
 
127
            ckrv != CKR_ATTRIBUTE_SENSITIVE) 
 
128
        {
 
129
            nssSession_ExitMonitor(session);
 
130
            nss_SetError(NSS_ERROR_DEVICE_ERROR);
 
131
            goto loser;
 
132
        }
 
133
        /* Allocate memory for each attribute. */
 
134
        for (i=0; i<count; i++) {
 
135
            CK_ULONG ulValueLen = obj_template[i].ulValueLen;
 
136
            if (ulValueLen == 0) continue;
 
137
            if (ulValueLen == (CK_ULONG) -1) {
 
138
                obj_template[i].ulValueLen = 0;
 
139
                continue;
 
140
            }
 
141
            if (is_string_attribute(obj_template[i].type)) {
 
142
                ulValueLen++;
 
143
            }
 
144
            obj_template[i].pValue = nss_ZAlloc(arenaOpt, ulValueLen);
 
145
            if (!obj_template[i].pValue) {
 
146
                nssSession_ExitMonitor(session);
 
147
                goto loser;
 
148
            }
 
149
        }
 
150
        alloced = PR_TRUE;
 
151
    }
 
152
    /* Obtain the actual attribute values. */
 
153
    ckrv = CKAPI(epv)->C_GetAttributeValue(hSession,
 
154
                                           object, obj_template, count);
 
155
    nssSession_ExitMonitor(session);
 
156
    if (ckrv != CKR_OK && 
 
157
        ckrv != CKR_ATTRIBUTE_TYPE_INVALID &&
 
158
        ckrv != CKR_ATTRIBUTE_SENSITIVE) 
 
159
    {
 
160
        nss_SetError(NSS_ERROR_DEVICE_ERROR);
 
161
        goto loser;
 
162
    }
 
163
    if (alloced && arenaOpt) {
 
164
        nssrv = nssArena_Unmark(arenaOpt, mark);
 
165
        if (nssrv != PR_SUCCESS) {
 
166
            goto loser;
 
167
        }
 
168
    }
 
169
 
 
170
    if (count > 1 && ((ckrv == CKR_ATTRIBUTE_TYPE_INVALID) || 
 
171
                                        (ckrv == CKR_ATTRIBUTE_SENSITIVE))) {
 
172
        /* old tokens would keep the length of '0' and not deal with any
 
173
         * of the attributes we passed. For those tokens read them one at
 
174
         * a time */
 
175
        for (i=0; i < count; i++) {
 
176
            if ((obj_template[i].ulValueLen == 0) 
 
177
                                || (obj_template[i].ulValueLen == -1)) {
 
178
                obj_template[i].ulValueLen=0;
 
179
                (void) nssCKObject_GetAttributes(object,&obj_template[i], 1,
 
180
                        arenaOpt, session, slot);
 
181
            }
 
182
        }
 
183
    }
 
184
    return PR_SUCCESS;
 
185
loser:
 
186
    if (alloced) {
 
187
        if (arenaOpt) {
 
188
            /* release all arena memory allocated before the failure. */
 
189
            (void)nssArena_Release(arenaOpt, mark);
 
190
        } else {
 
191
            CK_ULONG j;
 
192
            /* free each heap object that was allocated before the failure. */
 
193
            for (j=0; j<i; j++) {
 
194
                nss_ZFreeIf(obj_template[j].pValue);
 
195
            }
 
196
        }
 
197
    }
 
198
    return PR_FAILURE;
 
199
}
 
200
 
 
201
NSS_IMPLEMENT PRStatus
 
202
nssCKObject_GetAttributeItem (
 
203
  CK_OBJECT_HANDLE object,
 
204
  CK_ATTRIBUTE_TYPE attribute,
 
205
  NSSArena *arenaOpt,
 
206
  nssSession *session,
 
207
  NSSSlot *slot,
 
208
  NSSItem *rvItem
 
209
)
 
210
{
 
211
    CK_ATTRIBUTE attr = { 0, NULL, 0 };
 
212
    PRStatus nssrv;
 
213
    attr.type = attribute;
 
214
    nssrv = nssCKObject_GetAttributes(object, &attr, 1, 
 
215
                                      arenaOpt, session, slot);
 
216
    if (nssrv != PR_SUCCESS) {
 
217
        return nssrv;
 
218
    }
 
219
    rvItem->data = (void *)attr.pValue;
 
220
    rvItem->size = (PRUint32)attr.ulValueLen;
 
221
    return PR_SUCCESS;
 
222
}
 
223
 
 
224
NSS_IMPLEMENT PRBool
 
225
nssCKObject_IsAttributeTrue (
 
226
  CK_OBJECT_HANDLE object,
 
227
  CK_ATTRIBUTE_TYPE attribute,
 
228
  nssSession *session,
 
229
  NSSSlot *slot,
 
230
  PRStatus *rvStatus
 
231
)
 
232
{
 
233
    CK_BBOOL bool;
 
234
    CK_ATTRIBUTE_PTR attr;
 
235
    CK_ATTRIBUTE atemplate = { 0, NULL, 0 };
 
236
    CK_RV ckrv;
 
237
    void *epv = nssSlot_GetCryptokiEPV(slot);
 
238
    attr = &atemplate;
 
239
    NSS_CK_SET_ATTRIBUTE_VAR(attr, attribute, bool);
 
240
    nssSession_EnterMonitor(session);
 
241
    ckrv = CKAPI(epv)->C_GetAttributeValue(session->handle, object, 
 
242
                                           &atemplate, 1);
 
243
    nssSession_ExitMonitor(session);
 
244
    if (ckrv != CKR_OK) {
 
245
        *rvStatus = PR_FAILURE;
 
246
        return PR_FALSE;
 
247
    }
 
248
    *rvStatus = PR_SUCCESS;
 
249
    return (PRBool)(bool == CK_TRUE);
 
250
}
 
251
 
 
252
NSS_IMPLEMENT PRStatus 
 
253
nssCKObject_SetAttributes (
 
254
  CK_OBJECT_HANDLE object,
 
255
  CK_ATTRIBUTE_PTR obj_template,
 
256
  CK_ULONG count,
 
257
  nssSession *session,
 
258
  NSSSlot  *slot
 
259
)
 
260
{
 
261
    CK_RV ckrv;
 
262
    void *epv = nssSlot_GetCryptokiEPV(slot);
 
263
    nssSession_EnterMonitor(session);
 
264
    ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle, object, 
 
265
                                           obj_template, count);
 
266
    nssSession_ExitMonitor(session);
 
267
    if (ckrv == CKR_OK) {
 
268
        return PR_SUCCESS;
 
269
    } else {
 
270
        return PR_FAILURE;
 
271
    }
 
272
}
 
273
 
 
274
NSS_IMPLEMENT PRBool
 
275
nssCKObject_IsTokenObjectTemplate (
 
276
  CK_ATTRIBUTE_PTR objectTemplate, 
 
277
  CK_ULONG otsize
 
278
)
 
279
{
 
280
    CK_ULONG ul;
 
281
    for (ul=0; ul<otsize; ul++) {
 
282
        if (objectTemplate[ul].type == CKA_TOKEN) {
 
283
            return (*((CK_BBOOL*)objectTemplate[ul].pValue) == CK_TRUE);
 
284
        }
 
285
    }
 
286
    return PR_FALSE;
 
287
}
 
288
 
 
289
static NSSCertificateType
 
290
nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
 
291
{
 
292
    CK_CERTIFICATE_TYPE ckCertType;
 
293
    if (!attrib->pValue) {
 
294
        /* default to PKIX */
 
295
        return NSSCertificateType_PKIX;
 
296
    }
 
297
    ckCertType = *((CK_ULONG *)attrib->pValue);
 
298
    switch (ckCertType) {
 
299
    case CKC_X_509:
 
300
        return NSSCertificateType_PKIX;
 
301
    default:
 
302
        break;
 
303
    }
 
304
    return NSSCertificateType_Unknown;
 
305
}
 
306
 
 
307
/* incoming pointers must be valid */
 
308
NSS_IMPLEMENT PRStatus
 
309
nssCryptokiCertificate_GetAttributes (
 
310
  nssCryptokiObject *certObject,
 
311
  nssSession *sessionOpt,
 
312
  NSSArena *arenaOpt,
 
313
  NSSCertificateType *certTypeOpt,
 
314
  NSSItem *idOpt,
 
315
  NSSDER *encodingOpt,
 
316
  NSSDER *issuerOpt,
 
317
  NSSDER *serialOpt,
 
318
  NSSDER *subjectOpt
 
319
)
 
320
{
 
321
    PRStatus status;
 
322
    PRUint32 i;
 
323
    nssSession *session;
 
324
    NSSSlot *slot;
 
325
    CK_ULONG template_size;
 
326
    CK_ATTRIBUTE_PTR attr;
 
327
    CK_ATTRIBUTE cert_template[6];
 
328
    /* Set up a template of all options chosen by caller */
 
329
    NSS_CK_TEMPLATE_START(cert_template, attr, template_size);
 
330
    if (certTypeOpt) {
 
331
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CERTIFICATE_TYPE);
 
332
    }
 
333
    if (idOpt) {
 
334
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
 
335
    }
 
336
    if (encodingOpt) {
 
337
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
 
338
    }
 
339
    if (issuerOpt) {
 
340
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ISSUER);
 
341
    }
 
342
    if (serialOpt) {
 
343
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SERIAL_NUMBER);
 
344
    }
 
345
    if (subjectOpt) {
 
346
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT);
 
347
    }
 
348
    NSS_CK_TEMPLATE_FINISH(cert_template, attr, template_size);
 
349
    if (template_size == 0) {
 
350
        /* caller didn't want anything */
 
351
        return PR_SUCCESS;
 
352
    }
 
353
 
 
354
    status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt,
 
355
                                                certObject, CKO_CERTIFICATE,
 
356
                                                cert_template, template_size);
 
357
    if (status != PR_SUCCESS) {
 
358
 
 
359
        session = sessionOpt ? 
 
360
                  sessionOpt : 
 
361
                  nssToken_GetDefaultSession(certObject->token);
 
362
 
 
363
        slot = nssToken_GetSlot(certObject->token);
 
364
        status = nssCKObject_GetAttributes(certObject->handle, 
 
365
                                           cert_template, template_size,
 
366
                                           arenaOpt, session, slot);
 
367
        nssSlot_Destroy(slot);
 
368
        if (status != PR_SUCCESS) {
 
369
            return status;
 
370
        }
 
371
    }
 
372
 
 
373
    i=0;
 
374
    if (certTypeOpt) {
 
375
        *certTypeOpt = nss_cert_type_from_ck_attrib(&cert_template[i]); i++;
 
376
    }
 
377
    if (idOpt) {
 
378
        NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], idOpt); i++;
 
379
    }
 
380
    if (encodingOpt) {
 
381
        NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], encodingOpt); i++;
 
382
    }
 
383
    if (issuerOpt) {
 
384
        NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], issuerOpt); i++;
 
385
    }
 
386
    if (serialOpt) {
 
387
        NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], serialOpt); i++;
 
388
    }
 
389
    if (subjectOpt) {
 
390
        NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[i], subjectOpt); i++;
 
391
    }
 
392
    return PR_SUCCESS;
 
393
}
 
394
 
 
395
#ifdef PURE_STAN_BUILD
 
396
static NSSKeyPairType
 
397
nss_key_pair_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
 
398
{
 
399
    CK_KEY_TYPE ckKeyType;
 
400
    PR_ASSERT(attrib->pValue);
 
401
    ckKeyType = *((CK_ULONG *)attrib->pValue);
 
402
    switch (ckKeyType) {
 
403
    case CKK_RSA: return NSSKeyPairType_RSA;
 
404
    case CKK_DSA: return NSSKeyPairType_DSA;
 
405
    default: break;
 
406
    }
 
407
    return NSSKeyPairType_Unknown;
 
408
}
 
409
 
 
410
NSS_IMPLEMENT PRStatus
 
411
nssCryptokiPrivateKey_GetAttributes (
 
412
  nssCryptokiObject *keyObject,
 
413
  nssSession *sessionOpt,
 
414
  NSSArena *arenaOpt,
 
415
  NSSKeyPairType *keyTypeOpt,
 
416
  NSSItem *idOpt
 
417
)
 
418
{
 
419
    PRStatus status;
 
420
    PRUint32 i;
 
421
    nssSession *session;
 
422
    NSSSlot *slot;
 
423
    CK_ULONG template_size;
 
424
    CK_ATTRIBUTE_PTR attr;
 
425
    CK_ATTRIBUTE key_template[2];
 
426
    /* Set up a template of all options chosen by caller */
 
427
    NSS_CK_TEMPLATE_START(key_template, attr, template_size);
 
428
    if (keyTypeOpt) {
 
429
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_KEY_TYPE);
 
430
    }
 
431
    if (idOpt) {
 
432
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
 
433
    }
 
434
    NSS_CK_TEMPLATE_FINISH(key_template, attr, template_size);
 
435
    if (template_size == 0) {
 
436
        /* caller didn't want anything */
 
437
        return PR_SUCCESS;
 
438
    }
 
439
 
 
440
    session = sessionOpt ? 
 
441
              sessionOpt : 
 
442
              nssToken_GetDefaultSession(keyObject->token);
 
443
 
 
444
    slot = nssToken_GetSlot(keyObject->token);
 
445
    status = nssCKObject_GetAttributes(keyObject->handle, 
 
446
                                       key_template, template_size,
 
447
                                       arenaOpt, session, slot);
 
448
    nssSlot_Destroy(slot);
 
449
    if (status != PR_SUCCESS) {
 
450
        return status;
 
451
    }
 
452
 
 
453
    i=0;
 
454
    if (keyTypeOpt) {
 
455
        *keyTypeOpt = nss_key_pair_type_from_ck_attrib(&key_template[i]); i++;
 
456
    }
 
457
    if (idOpt) {
 
458
        NSS_CK_ATTRIBUTE_TO_ITEM(&key_template[i], idOpt); i++;
 
459
    }
 
460
    return PR_SUCCESS;
 
461
}
 
462
 
 
463
NSS_IMPLEMENT PRStatus
 
464
nssCryptokiPublicKey_GetAttributes (
 
465
  nssCryptokiObject *keyObject,
 
466
  nssSession *sessionOpt,
 
467
  NSSArena *arenaOpt,
 
468
  NSSKeyPairType *keyTypeOpt,
 
469
  NSSItem *idOpt
 
470
)
 
471
{
 
472
    PRStatus status;
 
473
    PRUint32 i;
 
474
    nssSession *session;
 
475
    NSSSlot *slot;
 
476
    CK_ULONG template_size;
 
477
    CK_ATTRIBUTE_PTR attr;
 
478
    CK_ATTRIBUTE key_template[2];
 
479
    /* Set up a template of all options chosen by caller */
 
480
    NSS_CK_TEMPLATE_START(key_template, attr, template_size);
 
481
    if (keyTypeOpt) {
 
482
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_KEY_TYPE);
 
483
    }
 
484
    if (idOpt) {
 
485
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_ID);
 
486
    }
 
487
    NSS_CK_TEMPLATE_FINISH(key_template, attr, template_size);
 
488
    if (template_size == 0) {
 
489
        /* caller didn't want anything */
 
490
        return PR_SUCCESS;
 
491
    }
 
492
 
 
493
    session = sessionOpt ? 
 
494
              sessionOpt : 
 
495
              nssToken_GetDefaultSession(keyObject->token);
 
496
 
 
497
    slot = nssToken_GetSlot(keyObject->token);
 
498
    status = nssCKObject_GetAttributes(keyObject->handle, 
 
499
                                       key_template, template_size,
 
500
                                       arenaOpt, session, slot);
 
501
    nssSlot_Destroy(slot);
 
502
    if (status != PR_SUCCESS) {
 
503
        return status;
 
504
    }
 
505
 
 
506
    i=0;
 
507
    if (keyTypeOpt) {
 
508
        *keyTypeOpt = nss_key_pair_type_from_ck_attrib(&key_template[i]); i++;
 
509
    }
 
510
    if (idOpt) {
 
511
        NSS_CK_ATTRIBUTE_TO_ITEM(&key_template[i], idOpt); i++;
 
512
    }
 
513
    return PR_SUCCESS;
 
514
}
 
515
#endif /* PURE_STAN_BUILD */
 
516
 
 
517
static nssTrustLevel 
 
518
get_nss_trust (
 
519
  CK_TRUST ckt
 
520
)
 
521
{
 
522
    nssTrustLevel t;
 
523
    switch (ckt) {
 
524
    case CKT_NETSCAPE_UNTRUSTED: t = nssTrustLevel_NotTrusted; break;
 
525
    case CKT_NETSCAPE_TRUSTED_DELEGATOR: t = nssTrustLevel_TrustedDelegator; 
 
526
        break;
 
527
    case CKT_NETSCAPE_VALID_DELEGATOR: t = nssTrustLevel_ValidDelegator; break;
 
528
    case CKT_NETSCAPE_TRUSTED: t = nssTrustLevel_Trusted; break;
 
529
    case CKT_NETSCAPE_VALID: t = nssTrustLevel_Valid; break;
 
530
    case CKT_NETSCAPE_MUST_VERIFY:
 
531
    case CKT_NETSCAPE_TRUST_UNKNOWN:
 
532
    default:
 
533
        t = nssTrustLevel_Unknown; break;
 
534
    }
 
535
    return t;
 
536
}
 
537
 
 
538
NSS_IMPLEMENT PRStatus
 
539
nssCryptokiTrust_GetAttributes (
 
540
  nssCryptokiObject *trustObject,
 
541
  nssSession *sessionOpt,
 
542
  NSSItem *sha1_hash,
 
543
  nssTrustLevel *serverAuth,
 
544
  nssTrustLevel *clientAuth,
 
545
  nssTrustLevel *codeSigning,
 
546
  nssTrustLevel *emailProtection,
 
547
  PRBool *stepUpApproved
 
548
)
 
549
{
 
550
    PRStatus status;
 
551
    NSSSlot *slot;
 
552
    nssSession *session;
 
553
    CK_BBOOL isToken = PR_FALSE;
 
554
    CK_BBOOL stepUp = PR_FALSE;
 
555
    CK_TRUST saTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
 
556
    CK_TRUST caTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
 
557
    CK_TRUST epTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
 
558
    CK_TRUST csTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
 
559
    CK_ATTRIBUTE_PTR attr;
 
560
    CK_ATTRIBUTE trust_template[7];
 
561
    CK_ULONG trust_size;
 
562
 
 
563
    /* Use the trust object to find the trust settings */
 
564
    NSS_CK_TEMPLATE_START(trust_template, attr, trust_size);
 
565
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN,                  isToken);
 
566
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_SERVER_AUTH,      saTrust);
 
567
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CLIENT_AUTH,      caTrust);
 
568
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_EMAIL_PROTECTION, epTrust);
 
569
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING,     csTrust);
 
570
    NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_STEP_UP_APPROVED, stepUp);
 
571
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CERT_SHA1_HASH,     sha1_hash);
 
572
    NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size);
 
573
 
 
574
    status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL,
 
575
                                                trustObject, 
 
576
                                                CKO_NETSCAPE_TRUST,
 
577
                                                trust_template, trust_size);
 
578
    if (status != PR_SUCCESS) {
 
579
        session = sessionOpt ? 
 
580
                  sessionOpt : 
 
581
                  nssToken_GetDefaultSession(trustObject->token);
 
582
 
 
583
        slot = nssToken_GetSlot(trustObject->token);
 
584
        status = nssCKObject_GetAttributes(trustObject->handle,
 
585
                                           trust_template, trust_size,
 
586
                                           NULL, session, slot);
 
587
        nssSlot_Destroy(slot);
 
588
        if (status != PR_SUCCESS) {
 
589
            return status;
 
590
        }
 
591
    }
 
592
 
 
593
    *serverAuth = get_nss_trust(saTrust);
 
594
    *clientAuth = get_nss_trust(caTrust);
 
595
    *emailProtection = get_nss_trust(epTrust);
 
596
    *codeSigning = get_nss_trust(csTrust);
 
597
    *stepUpApproved = stepUp;
 
598
    return PR_SUCCESS;
 
599
}
 
600
 
 
601
NSS_IMPLEMENT PRStatus
 
602
nssCryptokiCRL_GetAttributes (
 
603
  nssCryptokiObject *crlObject,
 
604
  nssSession *sessionOpt,
 
605
  NSSArena *arenaOpt,
 
606
  NSSItem *encodingOpt,
 
607
  NSSItem *subjectOpt,
 
608
  CK_ULONG* crl_class,
 
609
  NSSUTF8 **urlOpt,
 
610
  PRBool *isKRLOpt
 
611
)
 
612
{
 
613
    PRStatus status;
 
614
    NSSSlot *slot;
 
615
    nssSession *session;
 
616
    CK_ATTRIBUTE_PTR attr;
 
617
    CK_ATTRIBUTE crl_template[7];
 
618
    CK_ULONG crl_size;
 
619
    PRUint32 i;
 
620
 
 
621
    NSS_CK_TEMPLATE_START(crl_template, attr, crl_size);
 
622
    if (crl_class) {
 
623
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_CLASS);
 
624
    }
 
625
    if (encodingOpt) {
 
626
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
 
627
    }
 
628
    if (urlOpt) {
 
629
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_URL);
 
630
    }
 
631
    if (isKRLOpt) {
 
632
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_KRL);
 
633
    }
 
634
    if (subjectOpt) {
 
635
        NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_SUBJECT);
 
636
    }
 
637
    NSS_CK_TEMPLATE_FINISH(crl_template, attr, crl_size);
 
638
 
 
639
    status = nssToken_GetCachedObjectAttributes(crlObject->token, NULL,
 
640
                                                crlObject, 
 
641
                                                CKO_NETSCAPE_CRL,
 
642
                                                crl_template, crl_size);
 
643
    if (status != PR_SUCCESS) {
 
644
        session = sessionOpt ? 
 
645
                  sessionOpt : 
 
646
                  nssToken_GetDefaultSession(crlObject->token);
 
647
 
 
648
        slot = nssToken_GetSlot(crlObject->token);
 
649
        status = nssCKObject_GetAttributes(crlObject->handle, 
 
650
                                           crl_template, crl_size,
 
651
                                           arenaOpt, session, slot);
 
652
        nssSlot_Destroy(slot);
 
653
        if (status != PR_SUCCESS) {
 
654
            return status;
 
655
        }
 
656
    }
 
657
 
 
658
    i=0;
 
659
    if (crl_class) {
 
660
        NSS_CK_ATTRIBUTE_TO_ULONG(&crl_template[i], *crl_class); i++;
 
661
    }
 
662
    if (encodingOpt) {
 
663
        NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], encodingOpt); i++;
 
664
    }
 
665
    if (urlOpt) {
 
666
        NSS_CK_ATTRIBUTE_TO_UTF8(&crl_template[i], *urlOpt); i++;
 
667
    }
 
668
    if (isKRLOpt) {
 
669
        NSS_CK_ATTRIBUTE_TO_BOOL(&crl_template[i], *isKRLOpt); i++;
 
670
    }
 
671
    if (subjectOpt) {
 
672
        NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], subjectOpt); i++;
 
673
    }
 
674
    return PR_SUCCESS;
 
675
}
 
676
 
 
677
NSS_IMPLEMENT PRStatus
 
678
nssCryptokiPrivateKey_SetCertificate (
 
679
  nssCryptokiObject *keyObject,
 
680
  nssSession *sessionOpt,
 
681
  NSSUTF8 *nickname,
 
682
  NSSItem *id,
 
683
  NSSDER *subject
 
684
)
 
685
{
 
686
    CK_RV ckrv;
 
687
    CK_ATTRIBUTE_PTR attr;
 
688
    CK_ATTRIBUTE key_template[3];
 
689
    CK_ULONG key_size;
 
690
    void *epv = nssToken_GetCryptokiEPV(keyObject->token);
 
691
    nssSession *session;
 
692
    NSSToken *token = keyObject->token;
 
693
    nssSession *defaultSession = nssToken_GetDefaultSession(token);
 
694
    PRBool createdSession = PR_FALSE;
 
695
 
 
696
    NSS_CK_TEMPLATE_START(key_template, attr, key_size);
 
697
    NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
 
698
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
 
699
    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
 
700
    NSS_CK_TEMPLATE_FINISH(key_template, attr, key_size);
 
701
 
 
702
    if (sessionOpt) {
 
703
        if (!nssSession_IsReadWrite(sessionOpt)) {
 
704
            return PR_FAILURE;
 
705
        } else {
 
706
            session = sessionOpt;
 
707
        }
 
708
    } else if (nssSession_IsReadWrite(defaultSession)) {
 
709
        session = defaultSession;
 
710
    } else {
 
711
        NSSSlot *slot = nssToken_GetSlot(token);
 
712
        session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE);
 
713
        createdSession = PR_TRUE;
 
714
        nssSlot_Destroy(slot);
 
715
    }
 
716
 
 
717
    ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle,
 
718
                                           keyObject->handle,
 
719
                                           key_template,
 
720
                                           key_size);
 
721
 
 
722
    if (createdSession) {
 
723
        nssSession_Destroy(session);
 
724
    }
 
725
 
 
726
    return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
 
727
}
 
728