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

« back to all changes in this revision

Viewing changes to nss/lib/pki/certificate.c

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This Source Code Form is subject to the terms of the Mozilla Public
 
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
4
 
 
5
#ifndef NSSPKI_H
 
6
#include "nsspki.h"
 
7
#endif /* NSSPKI_H */
 
8
 
 
9
#ifndef PKIT_H
 
10
#include "pkit.h"
 
11
#endif /* PKIT_H */
 
12
 
 
13
#ifndef PKIM_H
 
14
#include "pkim.h"
 
15
#endif /* PKIM_H */
 
16
 
 
17
#ifndef DEV_H
 
18
#include "dev.h"
 
19
#endif /* DEV_H */
 
20
 
 
21
#include "pkistore.h"
 
22
 
 
23
#include "pki3hack.h"
 
24
#include "pk11func.h"
 
25
#include "hasht.h"
 
26
 
 
27
#ifndef BASE_H
 
28
#include "base.h"
 
29
#endif /* BASE_H */
 
30
 
 
31
extern const NSSError NSS_ERROR_NOT_FOUND;
 
32
 
 
33
/* Creates a certificate from a base object */
 
34
NSS_IMPLEMENT NSSCertificate *
 
35
nssCertificate_Create (
 
36
  nssPKIObject *object
 
37
)
 
38
{
 
39
    PRStatus status;
 
40
    NSSCertificate *rvCert;
 
41
    nssArenaMark * mark;
 
42
    NSSArena *arena = object->arena;
 
43
    PR_ASSERT(object->instances != NULL && object->numInstances > 0);
 
44
    PR_ASSERT(object->lockType == nssPKIMonitor);
 
45
    mark = nssArena_Mark(arena);
 
46
    rvCert = nss_ZNEW(arena, NSSCertificate);
 
47
    if (!rvCert) {
 
48
        return (NSSCertificate *)NULL;
 
49
    }
 
50
    rvCert->object = *object;
 
51
    /* XXX should choose instance based on some criteria */
 
52
    status = nssCryptokiCertificate_GetAttributes(object->instances[0],
 
53
                                                  NULL,  /* XXX sessionOpt */
 
54
                                                  arena,
 
55
                                                  &rvCert->type,
 
56
                                                  &rvCert->id,
 
57
                                                  &rvCert->encoding,
 
58
                                                  &rvCert->issuer,
 
59
                                                  &rvCert->serial,
 
60
                                                  &rvCert->subject);
 
61
    if (status != PR_SUCCESS ||
 
62
        !rvCert->encoding.data ||
 
63
        !rvCert->encoding.size ||
 
64
        !rvCert->issuer.data ||
 
65
        !rvCert->issuer.size ||
 
66
        !rvCert->serial.data ||
 
67
        !rvCert->serial.size) {
 
68
        if (mark)
 
69
            nssArena_Release(arena, mark);
 
70
        return (NSSCertificate *)NULL;
 
71
    }
 
72
    if (mark)
 
73
        nssArena_Unmark(arena, mark);
 
74
    return rvCert;
 
75
}
 
76
 
 
77
NSS_IMPLEMENT NSSCertificate *
 
78
nssCertificate_AddRef (
 
79
  NSSCertificate *c
 
80
)
 
81
{
 
82
    if (c) {
 
83
        nssPKIObject_AddRef(&c->object);
 
84
    }
 
85
    return c;
 
86
}
 
87
 
 
88
NSS_IMPLEMENT PRStatus
 
89
nssCertificate_Destroy (
 
90
  NSSCertificate *c
 
91
)
 
92
{
 
93
    nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
 
94
    nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
 
95
 
 
96
    if (c) {
 
97
        PRUint32 i;
 
98
        nssDecodedCert *dc = c->decoding;
 
99
        NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
 
100
        NSSCryptoContext *cc = c->object.cryptoContext;
 
101
 
 
102
        PR_ASSERT(c->object.refCount > 0);
 
103
 
 
104
        /* --- LOCK storage --- */
 
105
        if (cc) {
 
106
            nssCertificateStore_Lock(cc->certStore, &lockTrace);
 
107
        } else {
 
108
            nssTrustDomain_LockCertCache(td);
 
109
        }
 
110
        if (PR_ATOMIC_DECREMENT(&c->object.refCount) == 0) {
 
111
            /* --- remove cert and UNLOCK storage --- */
 
112
            if (cc) {
 
113
                nssCertificateStore_RemoveCertLOCKED(cc->certStore, c);
 
114
                nssCertificateStore_Unlock(cc->certStore, &lockTrace,
 
115
                                           &unlockTrace);
 
116
            } else {
 
117
                nssTrustDomain_RemoveCertFromCacheLOCKED(td, c);
 
118
                nssTrustDomain_UnlockCertCache(td);
 
119
            }
 
120
            /* free cert data */
 
121
            for (i=0; i<c->object.numInstances; i++) {
 
122
                nssCryptokiObject_Destroy(c->object.instances[i]);
 
123
            }
 
124
            nssPKIObject_DestroyLock(&c->object);
 
125
            nssArena_Destroy(c->object.arena);
 
126
            nssDecodedCert_Destroy(dc);
 
127
        } else {
 
128
            /* --- UNLOCK storage --- */
 
129
            if (cc) {
 
130
                nssCertificateStore_Unlock(cc->certStore,
 
131
                                           &lockTrace,
 
132
                                           &unlockTrace);
 
133
            } else {
 
134
                nssTrustDomain_UnlockCertCache(td);
 
135
            }
 
136
        }
 
137
    }
 
138
    return PR_SUCCESS;
 
139
}
 
140
 
 
141
NSS_IMPLEMENT PRStatus
 
142
NSSCertificate_Destroy (
 
143
  NSSCertificate *c
 
144
)
 
145
{
 
146
    return nssCertificate_Destroy(c);
 
147
}
 
148
 
 
149
NSS_IMPLEMENT NSSDER *
 
150
nssCertificate_GetEncoding (
 
151
  NSSCertificate *c
 
152
)
 
153
{
 
154
    if (c->encoding.size > 0 && c->encoding.data) {
 
155
        return &c->encoding;
 
156
    } else {
 
157
        return (NSSDER *)NULL;
 
158
    }
 
159
}
 
160
 
 
161
NSS_IMPLEMENT NSSDER *
 
162
nssCertificate_GetIssuer (
 
163
  NSSCertificate *c
 
164
)
 
165
{
 
166
    if (c->issuer.size > 0 && c->issuer.data) {
 
167
        return &c->issuer;
 
168
    } else {
 
169
        return (NSSDER *)NULL;
 
170
    }
 
171
}
 
172
 
 
173
NSS_IMPLEMENT NSSDER *
 
174
nssCertificate_GetSerialNumber (
 
175
  NSSCertificate *c
 
176
)
 
177
{
 
178
    if (c->serial.size > 0 && c->serial.data) {
 
179
        return &c->serial;
 
180
    } else {
 
181
        return (NSSDER *)NULL;
 
182
    }
 
183
}
 
184
 
 
185
NSS_IMPLEMENT NSSDER *
 
186
nssCertificate_GetSubject (
 
187
  NSSCertificate *c
 
188
)
 
189
{
 
190
    if (c->subject.size > 0 && c->subject.data) {
 
191
        return &c->subject;
 
192
    } else {
 
193
        return (NSSDER *)NULL;
 
194
    }
 
195
}
 
196
 
 
197
/* Returns a copy, Caller must free using nss_ZFreeIf */
 
198
NSS_IMPLEMENT NSSUTF8 *
 
199
nssCertificate_GetNickname (
 
200
  NSSCertificate *c,
 
201
  NSSToken *tokenOpt
 
202
)
 
203
{
 
204
    return nssPKIObject_GetNicknameForToken(&c->object, tokenOpt);
 
205
}
 
206
 
 
207
NSS_IMPLEMENT NSSASCII7 *
 
208
nssCertificate_GetEmailAddress (
 
209
  NSSCertificate *c
 
210
)
 
211
{
 
212
    return c->email;
 
213
}
 
214
 
 
215
NSS_IMPLEMENT PRStatus
 
216
NSSCertificate_DeleteStoredObject (
 
217
  NSSCertificate *c,
 
218
  NSSCallback *uhh
 
219
)
 
220
{
 
221
    return nssPKIObject_DeleteStoredObject(&c->object, uhh, PR_TRUE);
 
222
}
 
223
 
 
224
NSS_IMPLEMENT PRStatus
 
225
NSSCertificate_Validate (
 
226
  NSSCertificate *c,
 
227
  NSSTime *timeOpt, /* NULL for "now" */
 
228
  NSSUsage *usage,
 
229
  NSSPolicies *policiesOpt /* NULL for none */
 
230
)
 
231
{
 
232
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
233
    return PR_FAILURE;
 
234
}
 
235
 
 
236
NSS_IMPLEMENT void ** /* void *[] */
 
237
NSSCertificate_ValidateCompletely (
 
238
  NSSCertificate *c,
 
239
  NSSTime *timeOpt, /* NULL for "now" */
 
240
  NSSUsage *usage,
 
241
  NSSPolicies *policiesOpt, /* NULL for none */
 
242
  void **rvOpt, /* NULL for allocate */
 
243
  PRUint32 rvLimit, /* zero for no limit */
 
244
  NSSArena *arenaOpt /* NULL for heap */
 
245
)
 
246
{
 
247
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
248
    return NULL;
 
249
}
 
250
 
 
251
NSS_IMPLEMENT PRStatus
 
252
NSSCertificate_ValidateAndDiscoverUsagesAndPolicies (
 
253
  NSSCertificate *c,
 
254
  NSSTime **notBeforeOutOpt,
 
255
  NSSTime **notAfterOutOpt,
 
256
  void *allowedUsages,
 
257
  void *disallowedUsages,
 
258
  void *allowedPolicies,
 
259
  void *disallowedPolicies,
 
260
  /* more args.. work on this fgmr */
 
261
  NSSArena *arenaOpt
 
262
)
 
263
{
 
264
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
265
    return PR_FAILURE;
 
266
}
 
267
 
 
268
NSS_IMPLEMENT NSSDER *
 
269
NSSCertificate_Encode (
 
270
  NSSCertificate *c,
 
271
  NSSDER *rvOpt,
 
272
  NSSArena *arenaOpt
 
273
)
 
274
{
 
275
    /* Item, DER, BER are all typedefs now... */
 
276
    return nssItem_Duplicate((NSSItem *)&c->encoding, arenaOpt, rvOpt);
 
277
}
 
278
 
 
279
NSS_IMPLEMENT nssDecodedCert *
 
280
nssCertificate_GetDecoding (
 
281
  NSSCertificate *c
 
282
)
 
283
{
 
284
    nssDecodedCert* deco = NULL;
 
285
    if (c->type == NSSCertificateType_PKIX) {
 
286
        (void)STAN_GetCERTCertificate(c);
 
287
    }
 
288
    nssPKIObject_Lock(&c->object);
 
289
    if (!c->decoding) {
 
290
        deco = nssDecodedCert_Create(NULL, &c->encoding, c->type);
 
291
        PORT_Assert(!c->decoding); 
 
292
        c->decoding = deco;
 
293
    } else {
 
294
        deco = c->decoding;
 
295
    }
 
296
    nssPKIObject_Unlock(&c->object);
 
297
    return deco;
 
298
}
 
299
 
 
300
static NSSCertificate **
 
301
filter_subject_certs_for_id (
 
302
  NSSCertificate **subjectCerts, 
 
303
  void *id
 
304
)
 
305
{
 
306
    NSSCertificate **si;
 
307
    nssDecodedCert *dcp;
 
308
    int nextOpenSlot = 0;
 
309
    int i;
 
310
    nssCertIDMatch matchLevel = nssCertIDMatch_Unknown;
 
311
    nssCertIDMatch match;
 
312
 
 
313
    /* walk the subject certs */
 
314
    for (si = subjectCerts; *si; si++) {
 
315
        dcp = nssCertificate_GetDecoding(*si);
 
316
        if (!dcp) {
 
317
            NSSCertificate_Destroy(*si);
 
318
            continue;
 
319
        }
 
320
        match = dcp->matchIdentifier(dcp, id);
 
321
        switch (match) {
 
322
        case nssCertIDMatch_Yes:
 
323
            if (matchLevel == nssCertIDMatch_Unknown) {
 
324
                /* we have non-definitive matches, forget them */
 
325
                for (i = 0; i < nextOpenSlot; i++) {
 
326
                    NSSCertificate_Destroy(subjectCerts[i]);
 
327
                    subjectCerts[i] = NULL;
 
328
                }
 
329
                nextOpenSlot = 0;
 
330
                /* only keep definitive matches from now on */
 
331
                matchLevel = nssCertIDMatch_Yes;
 
332
            }
 
333
            /* keep the cert */
 
334
            subjectCerts[nextOpenSlot++] = *si;
 
335
            break;
 
336
        case nssCertIDMatch_Unknown:
 
337
            if (matchLevel == nssCertIDMatch_Unknown) {
 
338
                /* only have non-definitive matches so far, keep it */
 
339
                subjectCerts[nextOpenSlot++] = *si;
 
340
                break;
 
341
            }
 
342
            /* else fall through, we have a definitive match already */
 
343
        case nssCertIDMatch_No:
 
344
        default:
 
345
            NSSCertificate_Destroy(*si);
 
346
            *si = NULL;
 
347
        }
 
348
    }
 
349
    subjectCerts[nextOpenSlot] = NULL;
 
350
    return subjectCerts;
 
351
}
 
352
 
 
353
static NSSCertificate **
 
354
filter_certs_for_valid_issuers (
 
355
  NSSCertificate **certs
 
356
)
 
357
{
 
358
    NSSCertificate **cp;
 
359
    nssDecodedCert *dcp;
 
360
    int nextOpenSlot = 0;
 
361
 
 
362
    for (cp = certs; *cp; cp++) {
 
363
        dcp = nssCertificate_GetDecoding(*cp);
 
364
        if (dcp && dcp->isValidIssuer(dcp)) {
 
365
            certs[nextOpenSlot++] = *cp;
 
366
        } else {
 
367
            NSSCertificate_Destroy(*cp);
 
368
        }
 
369
    }
 
370
    certs[nextOpenSlot] = NULL;
 
371
    return certs;
 
372
}
 
373
 
 
374
static NSSCertificate *
 
375
find_cert_issuer (
 
376
  NSSCertificate *c,
 
377
  NSSTime *timeOpt,
 
378
  NSSUsage *usage,
 
379
  NSSPolicies *policiesOpt,
 
380
  NSSTrustDomain *td,
 
381
  NSSCryptoContext *cc
 
382
)
 
383
{
 
384
    NSSArena *arena;
 
385
    NSSCertificate **certs = NULL;
 
386
    NSSCertificate **ccIssuers = NULL;
 
387
    NSSCertificate **tdIssuers = NULL;
 
388
    NSSCertificate *issuer = NULL;
 
389
 
 
390
    if (!cc)
 
391
        cc = c->object.cryptoContext;
 
392
    if (!td)
 
393
        td = NSSCertificate_GetTrustDomain(c);
 
394
    arena = nssArena_Create();
 
395
    if (!arena) {
 
396
        return (NSSCertificate *)NULL;
 
397
    }
 
398
    if (cc) {
 
399
        ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc,
 
400
                                                               &c->issuer,
 
401
                                                               NULL,
 
402
                                                               0,
 
403
                                                               arena);
 
404
    }
 
405
    if (td)
 
406
        tdIssuers = nssTrustDomain_FindCertificatesBySubject(td,
 
407
                                                         &c->issuer,
 
408
                                                         NULL,
 
409
                                                         0,
 
410
                                                         arena);
 
411
    certs = nssCertificateArray_Join(ccIssuers, tdIssuers);
 
412
    if (certs) {
 
413
        nssDecodedCert *dc = NULL;
 
414
        void *issuerID = NULL;
 
415
        dc = nssCertificate_GetDecoding(c);
 
416
        if (dc) {
 
417
            issuerID = dc->getIssuerIdentifier(dc);
 
418
        }
 
419
        /* XXX review based on CERT_FindCertIssuer
 
420
         * this function is not using the authCertIssuer field as a fallback
 
421
         * if authority key id does not exist
 
422
         */
 
423
        if (issuerID) {
 
424
            certs = filter_subject_certs_for_id(certs, issuerID);
 
425
        }
 
426
        certs = filter_certs_for_valid_issuers(certs);
 
427
        issuer = nssCertificateArray_FindBestCertificate(certs,
 
428
                                                         timeOpt,
 
429
                                                         usage,
 
430
                                                         policiesOpt);
 
431
        nssCertificateArray_Destroy(certs);
 
432
    }
 
433
    nssArena_Destroy(arena);
 
434
    return issuer;
 
435
}
 
436
 
 
437
/* This function returns the built chain, as far as it gets,
 
438
** even if/when it fails to find an issuer, and returns PR_FAILURE
 
439
*/
 
440
NSS_IMPLEMENT NSSCertificate **
 
441
nssCertificate_BuildChain (
 
442
  NSSCertificate *c,
 
443
  NSSTime *timeOpt,
 
444
  NSSUsage *usage,
 
445
  NSSPolicies *policiesOpt,
 
446
  NSSCertificate **rvOpt,
 
447
  PRUint32 rvLimit,
 
448
  NSSArena *arenaOpt,
 
449
  PRStatus *statusOpt,
 
450
  NSSTrustDomain *td,
 
451
  NSSCryptoContext *cc 
 
452
)
 
453
{
 
454
    NSSCertificate **rvChain = NULL;
 
455
    NSSUsage issuerUsage = *usage;
 
456
    nssPKIObjectCollection *collection = NULL;
 
457
    PRUint32  rvCount = 0;
 
458
    PRStatus  st;
 
459
    PRStatus  ret = PR_SUCCESS;
 
460
 
 
461
    if (!c || !cc ||
 
462
        (!td && (td = NSSCertificate_GetTrustDomain(c)) == NULL)) {
 
463
        goto loser;
 
464
    }
 
465
    /* bump the usage up to CA level */
 
466
    issuerUsage.nss3lookingForCA = PR_TRUE;
 
467
    collection = nssCertificateCollection_Create(td, NULL);
 
468
    if (!collection)
 
469
        goto loser;
 
470
    st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
 
471
    if (st != PR_SUCCESS)
 
472
        goto loser;
 
473
    for (rvCount = 1; (!rvLimit || rvCount < rvLimit); ++rvCount) {
 
474
        CERTCertificate *cCert = STAN_GetCERTCertificate(c);
 
475
        if (cCert->isRoot) {
 
476
            /* not including the issuer of the self-signed cert, which is,
 
477
             * of course, itself
 
478
             */
 
479
            break;
 
480
        }
 
481
        c = find_cert_issuer(c, timeOpt, &issuerUsage, policiesOpt, td, cc);
 
482
        if (!c) {
 
483
            ret = PR_FAILURE;
 
484
            break;
 
485
        }
 
486
        st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
 
487
        nssCertificate_Destroy(c); /* collection has it */
 
488
        if (st != PR_SUCCESS)
 
489
            goto loser;
 
490
    }
 
491
    rvChain = nssPKIObjectCollection_GetCertificates(collection, 
 
492
                                                     rvOpt, 
 
493
                                                     rvLimit, 
 
494
                                                     arenaOpt);
 
495
    if (rvChain) {
 
496
        nssPKIObjectCollection_Destroy(collection);
 
497
        if (statusOpt) 
 
498
            *statusOpt = ret;
 
499
        if (ret != PR_SUCCESS)
 
500
            nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
 
501
        return rvChain;
 
502
    }
 
503
 
 
504
loser:
 
505
    if (collection)
 
506
        nssPKIObjectCollection_Destroy(collection);
 
507
    if (statusOpt) 
 
508
        *statusOpt = PR_FAILURE;
 
509
    nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
 
510
    return rvChain;
 
511
}
 
512
 
 
513
NSS_IMPLEMENT NSSCertificate **
 
514
NSSCertificate_BuildChain (
 
515
  NSSCertificate *c,
 
516
  NSSTime *timeOpt,
 
517
  NSSUsage *usage,
 
518
  NSSPolicies *policiesOpt,
 
519
  NSSCertificate **rvOpt,
 
520
  PRUint32 rvLimit, /* zero for no limit */
 
521
  NSSArena *arenaOpt,
 
522
  PRStatus *statusOpt,
 
523
  NSSTrustDomain *td,
 
524
  NSSCryptoContext *cc 
 
525
)
 
526
{
 
527
    return nssCertificate_BuildChain(c, timeOpt, usage, policiesOpt,
 
528
                                     rvOpt, rvLimit, arenaOpt, statusOpt,
 
529
                                     td, cc);
 
530
}
 
531
 
 
532
NSS_IMPLEMENT NSSCryptoContext *
 
533
nssCertificate_GetCryptoContext (
 
534
  NSSCertificate *c
 
535
)
 
536
{
 
537
    return c->object.cryptoContext;
 
538
}
 
539
 
 
540
NSS_IMPLEMENT NSSTrustDomain *
 
541
nssCertificate_GetTrustDomain (
 
542
  NSSCertificate *c
 
543
)
 
544
{
 
545
    return c->object.trustDomain;
 
546
}
 
547
 
 
548
NSS_IMPLEMENT NSSTrustDomain *
 
549
NSSCertificate_GetTrustDomain (
 
550
  NSSCertificate *c
 
551
)
 
552
{
 
553
    return nssCertificate_GetTrustDomain(c);
 
554
}
 
555
 
 
556
NSS_IMPLEMENT NSSToken *
 
557
NSSCertificate_GetToken (
 
558
  NSSCertificate *c,
 
559
  PRStatus *statusOpt
 
560
)
 
561
{
 
562
    return (NSSToken *)NULL;
 
563
}
 
564
 
 
565
NSS_IMPLEMENT NSSSlot *
 
566
NSSCertificate_GetSlot (
 
567
  NSSCertificate *c,
 
568
  PRStatus *statusOpt
 
569
)
 
570
{
 
571
    return (NSSSlot *)NULL;
 
572
}
 
573
 
 
574
NSS_IMPLEMENT NSSModule *
 
575
NSSCertificate_GetModule (
 
576
  NSSCertificate *c,
 
577
  PRStatus *statusOpt
 
578
)
 
579
{
 
580
    return (NSSModule *)NULL;
 
581
}
 
582
 
 
583
NSS_IMPLEMENT NSSItem *
 
584
NSSCertificate_Encrypt (
 
585
  NSSCertificate *c,
 
586
  NSSAlgorithmAndParameters *apOpt,
 
587
  NSSItem *data,
 
588
  NSSTime *timeOpt,
 
589
  NSSUsage *usage,
 
590
  NSSPolicies *policiesOpt,
 
591
  NSSCallback *uhh,
 
592
  NSSItem *rvOpt,
 
593
  NSSArena *arenaOpt
 
594
)
 
595
{
 
596
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
597
    return NULL;
 
598
}
 
599
 
 
600
NSS_IMPLEMENT PRStatus
 
601
NSSCertificate_Verify (
 
602
  NSSCertificate *c,
 
603
  NSSAlgorithmAndParameters *apOpt,
 
604
  NSSItem *data,
 
605
  NSSItem *signature,
 
606
  NSSTime *timeOpt,
 
607
  NSSUsage *usage,
 
608
  NSSPolicies *policiesOpt,
 
609
  NSSCallback *uhh
 
610
)
 
611
{
 
612
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
613
    return PR_FAILURE;
 
614
}
 
615
 
 
616
NSS_IMPLEMENT NSSItem *
 
617
NSSCertificate_VerifyRecover (
 
618
  NSSCertificate *c,
 
619
  NSSAlgorithmAndParameters *apOpt,
 
620
  NSSItem *signature,
 
621
  NSSTime *timeOpt,
 
622
  NSSUsage *usage,
 
623
  NSSPolicies *policiesOpt,
 
624
  NSSCallback *uhh,
 
625
  NSSItem *rvOpt,
 
626
  NSSArena *arenaOpt
 
627
)
 
628
{
 
629
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
630
    return NULL;
 
631
}
 
632
 
 
633
NSS_IMPLEMENT NSSItem *
 
634
NSSCertificate_WrapSymmetricKey (
 
635
  NSSCertificate *c,
 
636
  NSSAlgorithmAndParameters *apOpt,
 
637
  NSSSymmetricKey *keyToWrap,
 
638
  NSSTime *timeOpt,
 
639
  NSSUsage *usage,
 
640
  NSSPolicies *policiesOpt,
 
641
  NSSCallback *uhh,
 
642
  NSSItem *rvOpt,
 
643
  NSSArena *arenaOpt
 
644
)
 
645
{
 
646
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
647
    return NULL;
 
648
}
 
649
 
 
650
NSS_IMPLEMENT NSSCryptoContext *
 
651
NSSCertificate_CreateCryptoContext (
 
652
  NSSCertificate *c,
 
653
  NSSAlgorithmAndParameters *apOpt,
 
654
  NSSTime *timeOpt,
 
655
  NSSUsage *usage,
 
656
  NSSPolicies *policiesOpt,
 
657
  NSSCallback *uhh  
 
658
)
 
659
{
 
660
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
661
    return NULL;
 
662
}
 
663
 
 
664
NSS_IMPLEMENT NSSPublicKey *
 
665
NSSCertificate_GetPublicKey (
 
666
  NSSCertificate *c
 
667
)
 
668
{
 
669
#if 0
 
670
    CK_ATTRIBUTE pubktemplate[] = {
 
671
        { CKA_CLASS,   NULL, 0 },
 
672
        { CKA_ID,      NULL, 0 },
 
673
        { CKA_SUBJECT, NULL, 0 }
 
674
    };
 
675
    PRStatus nssrv;
 
676
    CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]);
 
677
    NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey);
 
678
    if (c->id.size > 0) {
 
679
        /* CKA_ID */
 
680
        NSS_CK_ITEM_TO_ATTRIBUTE(&c->id, &pubktemplate[1]);
 
681
    } else {
 
682
        /* failure, yes? */
 
683
        return (NSSPublicKey *)NULL;
 
684
    }
 
685
    if (c->subject.size > 0) {
 
686
        /* CKA_SUBJECT */
 
687
        NSS_CK_ITEM_TO_ATTRIBUTE(&c->subject, &pubktemplate[2]);
 
688
    } else {
 
689
        /* failure, yes? */
 
690
        return (NSSPublicKey *)NULL;
 
691
    }
 
692
    /* Try the cert's token first */
 
693
    if (c->token) {
 
694
        nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
 
695
    }
 
696
#endif
 
697
    /* Try all other key tokens */
 
698
    return (NSSPublicKey *)NULL;
 
699
}
 
700
 
 
701
NSS_IMPLEMENT NSSPrivateKey *
 
702
NSSCertificate_FindPrivateKey (
 
703
  NSSCertificate *c,
 
704
  NSSCallback *uhh
 
705
)
 
706
{
 
707
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
708
    return NULL;
 
709
}
 
710
 
 
711
NSS_IMPLEMENT PRBool
 
712
NSSCertificate_IsPrivateKeyAvailable (
 
713
  NSSCertificate *c,
 
714
  NSSCallback *uhh,
 
715
  PRStatus *statusOpt
 
716
)
 
717
{
 
718
    PRBool isUser = PR_FALSE;
 
719
    nssCryptokiObject **ip;
 
720
    nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
 
721
    if (!instances) {
 
722
        return PR_FALSE;
 
723
    }
 
724
    for (ip = instances; *ip; ip++) {
 
725
        nssCryptokiObject *instance = *ip;
 
726
        if (nssToken_IsPrivateKeyAvailable(instance->token, c, instance)) {
 
727
            isUser = PR_TRUE;
 
728
        }
 
729
    }
 
730
    nssCryptokiObjectArray_Destroy(instances);
 
731
    return isUser;
 
732
}
 
733
 
 
734
/* sort the subject cert list from newest to oldest */
 
735
PRIntn
 
736
nssCertificate_SubjectListSort (
 
737
  void *v1,
 
738
  void *v2
 
739
)
 
740
{
 
741
    NSSCertificate *c1 = (NSSCertificate *)v1;
 
742
    NSSCertificate *c2 = (NSSCertificate *)v2;
 
743
    nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1);
 
744
    nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2);
 
745
    if (!dc1) {
 
746
        return dc2 ? 1 : 0;
 
747
    } else if (!dc2) {
 
748
        return -1;
 
749
    } else {
 
750
        return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
 
751
    }
 
752
}
 
753
 
 
754
NSS_IMPLEMENT PRBool
 
755
NSSUserCertificate_IsStillPresent (
 
756
  NSSUserCertificate *uc,
 
757
  PRStatus *statusOpt
 
758
)
 
759
{
 
760
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
761
    return PR_FALSE;
 
762
}
 
763
 
 
764
NSS_IMPLEMENT NSSItem *
 
765
NSSUserCertificate_Decrypt (
 
766
  NSSUserCertificate *uc,
 
767
  NSSAlgorithmAndParameters *apOpt,
 
768
  NSSItem *data,
 
769
  NSSTime *timeOpt,
 
770
  NSSUsage *usage,
 
771
  NSSPolicies *policiesOpt,
 
772
  NSSCallback *uhh,
 
773
  NSSItem *rvOpt,
 
774
  NSSArena *arenaOpt
 
775
)
 
776
{
 
777
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
778
    return NULL;
 
779
}
 
780
 
 
781
NSS_IMPLEMENT NSSItem *
 
782
NSSUserCertificate_Sign (
 
783
  NSSUserCertificate *uc,
 
784
  NSSAlgorithmAndParameters *apOpt,
 
785
  NSSItem *data,
 
786
  NSSTime *timeOpt,
 
787
  NSSUsage *usage,
 
788
  NSSPolicies *policiesOpt,
 
789
  NSSCallback *uhh,
 
790
  NSSItem *rvOpt,
 
791
  NSSArena *arenaOpt
 
792
)
 
793
{
 
794
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
795
    return NULL;
 
796
}
 
797
 
 
798
NSS_IMPLEMENT NSSItem *
 
799
NSSUserCertificate_SignRecover (
 
800
  NSSUserCertificate *uc,
 
801
  NSSAlgorithmAndParameters *apOpt,
 
802
  NSSItem *data,
 
803
  NSSTime *timeOpt,
 
804
  NSSUsage *usage,
 
805
  NSSPolicies *policiesOpt,
 
806
  NSSCallback *uhh,
 
807
  NSSItem *rvOpt,
 
808
  NSSArena *arenaOpt
 
809
)
 
810
{
 
811
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
812
    return NULL;
 
813
}
 
814
 
 
815
NSS_IMPLEMENT NSSSymmetricKey *
 
816
NSSUserCertificate_UnwrapSymmetricKey (
 
817
  NSSUserCertificate *uc,
 
818
  NSSAlgorithmAndParameters *apOpt,
 
819
  NSSItem *wrappedKey,
 
820
  NSSTime *timeOpt,
 
821
  NSSUsage *usage,
 
822
  NSSPolicies *policiesOpt,
 
823
  NSSCallback *uhh,
 
824
  NSSItem *rvOpt,
 
825
  NSSArena *arenaOpt
 
826
)
 
827
{
 
828
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
829
    return NULL;
 
830
}
 
831
 
 
832
NSS_IMPLEMENT NSSSymmetricKey *
 
833
NSSUserCertificate_DeriveSymmetricKey (
 
834
  NSSUserCertificate *uc, /* provides private key */
 
835
  NSSCertificate *c, /* provides public key */
 
836
  NSSAlgorithmAndParameters *apOpt,
 
837
  NSSOID *target,
 
838
  PRUint32 keySizeOpt, /* zero for best allowed */
 
839
  NSSOperations operations,
 
840
  NSSCallback *uhh
 
841
)
 
842
{
 
843
    nss_SetError(NSS_ERROR_NOT_FOUND);
 
844
    return NULL;
 
845
}
 
846
 
 
847
NSS_IMPLEMENT nssSMIMEProfile *
 
848
nssSMIMEProfile_Create (
 
849
  NSSCertificate *cert,
 
850
  NSSItem *profileTime,
 
851
  NSSItem *profileData
 
852
)
 
853
{
 
854
    NSSArena *arena;
 
855
    nssSMIMEProfile *rvProfile;
 
856
    nssPKIObject *object;
 
857
    NSSTrustDomain *td = nssCertificate_GetTrustDomain(cert);
 
858
    NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert);
 
859
    arena = nssArena_Create();
 
860
    if (!arena) {
 
861
        return NULL;
 
862
    }
 
863
    object = nssPKIObject_Create(arena, NULL, td, cc, nssPKILock);
 
864
    if (!object) {
 
865
        goto loser;
 
866
    }
 
867
    rvProfile = nss_ZNEW(arena, nssSMIMEProfile);
 
868
    if (!rvProfile) {
 
869
        goto loser;
 
870
    }
 
871
    rvProfile->object = *object;
 
872
    rvProfile->certificate = cert;
 
873
    rvProfile->email = nssUTF8_Duplicate(cert->email, arena);
 
874
    rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL);
 
875
    if (profileTime) {
 
876
        rvProfile->profileTime = nssItem_Duplicate(profileTime, arena, NULL);
 
877
    }
 
878
    if (profileData) {
 
879
        rvProfile->profileData = nssItem_Duplicate(profileData, arena, NULL);
 
880
    }
 
881
    return rvProfile;
 
882
loser:
 
883
    if (object) nssPKIObject_Destroy(object);
 
884
    else if (arena)  nssArena_Destroy(arena);
 
885
    return (nssSMIMEProfile *)NULL;
 
886
}
 
887
 
 
888
/* execute a callback function on all members of a cert list */
 
889
NSS_EXTERN PRStatus
 
890
nssCertificateList_DoCallback (
 
891
  nssList *certList, 
 
892
  PRStatus (* callback)(NSSCertificate *c, void *arg),
 
893
  void *arg
 
894
)
 
895
{
 
896
    nssListIterator *certs;
 
897
    NSSCertificate *cert;
 
898
    PRStatus nssrv;
 
899
    certs = nssList_CreateIterator(certList);
 
900
    if (!certs) {
 
901
        return PR_FAILURE;
 
902
    }
 
903
    for (cert  = (NSSCertificate *)nssListIterator_Start(certs);
 
904
         cert != (NSSCertificate *)NULL;
 
905
         cert  = (NSSCertificate *)nssListIterator_Next(certs))
 
906
    {
 
907
        nssrv = (*callback)(cert, arg);
 
908
    }
 
909
    nssListIterator_Finish(certs);
 
910
    nssListIterator_Destroy(certs);
 
911
    return PR_SUCCESS;
 
912
}
 
913
 
 
914
static PRStatus add_ref_callback(NSSCertificate *c, void *a)
 
915
{
 
916
    nssCertificate_AddRef(c);
 
917
    return PR_SUCCESS;
 
918
}
 
919
 
 
920
NSS_IMPLEMENT void
 
921
nssCertificateList_AddReferences (
 
922
  nssList *certList
 
923
)
 
924
{
 
925
    (void)nssCertificateList_DoCallback(certList, add_ref_callback, NULL);
 
926
}
 
927
 
 
928
 
 
929
/*
 
930
 * Is this trust record safe to apply to all certs of the same issuer/SN 
 
931
 * independent of the cert matching the hash. This is only true is the trust 
 
932
 * is unknown or distrusted. In general this feature is only useful to 
 
933
 * explicitly distrusting certs. It is not safe to use to trust certs, so 
 
934
 * only allow unknown and untrusted trust types.
 
935
 */
 
936
PRBool
 
937
nssTrust_IsSafeToIgnoreCertHash(nssTrustLevel serverAuth, 
 
938
                nssTrustLevel clientAuth, nssTrustLevel codeSigning, 
 
939
                nssTrustLevel email, PRBool stepup)
 
940
{
 
941
    /* step up is a trust type, if it's on, we must have a hash for the cert */
 
942
    if (stepup) {
 
943
        return PR_FALSE;
 
944
    }
 
945
    if ((serverAuth != nssTrustLevel_Unknown) && 
 
946
        (serverAuth != nssTrustLevel_NotTrusted)) {
 
947
        return PR_FALSE;
 
948
    }
 
949
    if ((clientAuth != nssTrustLevel_Unknown) && 
 
950
        (clientAuth != nssTrustLevel_NotTrusted)) {
 
951
        return PR_FALSE;
 
952
    }
 
953
    if ((codeSigning != nssTrustLevel_Unknown) && 
 
954
        (codeSigning != nssTrustLevel_NotTrusted)) {
 
955
        return PR_FALSE;
 
956
    }
 
957
    if ((email != nssTrustLevel_Unknown) && 
 
958
        (email != nssTrustLevel_NotTrusted)) {
 
959
        return PR_FALSE;
 
960
    }
 
961
    /* record only has Unknown and Untrusted entries, ok to accept without a 
 
962
     * hash */
 
963
    return PR_TRUE;
 
964
}
 
965
 
 
966
NSS_IMPLEMENT NSSTrust *
 
967
nssTrust_Create (
 
968
  nssPKIObject *object,
 
969
  NSSItem *certData
 
970
)
 
971
{
 
972
    PRStatus status;
 
973
    PRUint32 i;
 
974
    PRUint32 lastTrustOrder, myTrustOrder;
 
975
    unsigned char sha1_hashcmp[SHA1_LENGTH];
 
976
    unsigned char sha1_hashin[SHA1_LENGTH];
 
977
    NSSItem sha1_hash;
 
978
    NSSTrust *rvt;
 
979
    nssCryptokiObject *instance;
 
980
    nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection;
 
981
    SECStatus rv; /* Should be stan flavor */
 
982
    PRBool stepUp;
 
983
 
 
984
    lastTrustOrder = 1<<16; /* just make it big */
 
985
    PR_ASSERT(object->instances != NULL && object->numInstances > 0);
 
986
    rvt = nss_ZNEW(object->arena, NSSTrust);
 
987
    if (!rvt) {
 
988
        return (NSSTrust *)NULL;
 
989
    }
 
990
    rvt->object = *object;
 
991
 
 
992
    /* should be stan flavor of Hashbuf */
 
993
    rv = PK11_HashBuf(SEC_OID_SHA1,sha1_hashcmp,certData->data,certData->size);
 
994
    if (rv != SECSuccess) {
 
995
        return (NSSTrust *)NULL;
 
996
    }
 
997
    sha1_hash.data = sha1_hashin;
 
998
    sha1_hash.size = sizeof (sha1_hashin);
 
999
    /* trust has to peek into the base object members */
 
1000
    nssPKIObject_Lock(object);
 
1001
    for (i=0; i<object->numInstances; i++) {
 
1002
        instance = object->instances[i];
 
1003
        myTrustOrder = nssToken_GetTrustOrder(instance->token);
 
1004
        status = nssCryptokiTrust_GetAttributes(instance, NULL,
 
1005
                                                &sha1_hash,
 
1006
                                                &serverAuth,
 
1007
                                                &clientAuth,
 
1008
                                                &codeSigning,
 
1009
                                                &emailProtection,
 
1010
                                                &stepUp);
 
1011
        if (status != PR_SUCCESS) {
 
1012
            nssPKIObject_Unlock(object);
 
1013
            return (NSSTrust *)NULL;
 
1014
        }
 
1015
        /* if no hash is specified, then trust applies to all certs with
 
1016
         * this issuer/SN. NOTE: This is only true for entries that
 
1017
         * have distrust and unknown record */
 
1018
        if (!(
 
1019
            /* we continue if there is no hash, and the trust type is
 
1020
             * safe to accept without a hash ... or ... */
 
1021
             ((sha1_hash.size == 0)  && 
 
1022
                nssTrust_IsSafeToIgnoreCertHash(serverAuth,clientAuth,
 
1023
                codeSigning, emailProtection,stepUp)) 
 
1024
           ||
 
1025
            /* we have a hash of the correct size, and it matches */
 
1026
            ((sha1_hash.size == SHA1_LENGTH) && (PORT_Memcmp(sha1_hashin,
 
1027
                sha1_hashcmp,SHA1_LENGTH) == 0))   )) {
 
1028
            nssPKIObject_Unlock(object);
 
1029
            return (NSSTrust *)NULL;
 
1030
        }
 
1031
        if (rvt->serverAuth == nssTrustLevel_Unknown ||
 
1032
            myTrustOrder < lastTrustOrder) 
 
1033
        {
 
1034
            rvt->serverAuth = serverAuth;
 
1035
        }
 
1036
        if (rvt->clientAuth == nssTrustLevel_Unknown ||
 
1037
            myTrustOrder < lastTrustOrder) 
 
1038
        {
 
1039
            rvt->clientAuth = clientAuth;
 
1040
        }
 
1041
        if (rvt->emailProtection == nssTrustLevel_Unknown ||
 
1042
            myTrustOrder < lastTrustOrder) 
 
1043
        {
 
1044
            rvt->emailProtection = emailProtection;
 
1045
        }
 
1046
        if (rvt->codeSigning == nssTrustLevel_Unknown ||
 
1047
            myTrustOrder < lastTrustOrder) 
 
1048
        {
 
1049
            rvt->codeSigning = codeSigning;
 
1050
        }
 
1051
        rvt->stepUpApproved = stepUp;
 
1052
        lastTrustOrder = myTrustOrder;
 
1053
    }
 
1054
    nssPKIObject_Unlock(object);
 
1055
    return rvt;
 
1056
}
 
1057
 
 
1058
NSS_IMPLEMENT NSSTrust *
 
1059
nssTrust_AddRef (
 
1060
  NSSTrust *trust
 
1061
)
 
1062
{
 
1063
    if (trust) {
 
1064
        nssPKIObject_AddRef(&trust->object);
 
1065
    }
 
1066
    return trust;
 
1067
}
 
1068
 
 
1069
NSS_IMPLEMENT PRStatus
 
1070
nssTrust_Destroy (
 
1071
  NSSTrust *trust
 
1072
)
 
1073
{
 
1074
    if (trust) {
 
1075
        (void)nssPKIObject_Destroy(&trust->object);
 
1076
    }
 
1077
    return PR_SUCCESS;
 
1078
}
 
1079
 
 
1080
NSS_IMPLEMENT nssSMIMEProfile *
 
1081
nssSMIMEProfile_AddRef (
 
1082
  nssSMIMEProfile *profile
 
1083
)
 
1084
{
 
1085
    if (profile) {
 
1086
        nssPKIObject_AddRef(&profile->object);
 
1087
    }
 
1088
    return profile;
 
1089
}
 
1090
 
 
1091
NSS_IMPLEMENT PRStatus
 
1092
nssSMIMEProfile_Destroy (
 
1093
  nssSMIMEProfile *profile
 
1094
)
 
1095
{
 
1096
    if (profile) {
 
1097
        (void)nssPKIObject_Destroy(&profile->object);
 
1098
    }
 
1099
    return PR_SUCCESS;
 
1100
}
 
1101
 
 
1102
NSS_IMPLEMENT NSSCRL *
 
1103
nssCRL_Create (
 
1104
  nssPKIObject *object
 
1105
)
 
1106
{
 
1107
    PRStatus status;
 
1108
    NSSCRL *rvCRL;
 
1109
    NSSArena *arena = object->arena;
 
1110
    PR_ASSERT(object->instances != NULL && object->numInstances > 0);
 
1111
    rvCRL = nss_ZNEW(arena, NSSCRL);
 
1112
    if (!rvCRL) {
 
1113
        return (NSSCRL *)NULL;
 
1114
    }
 
1115
    rvCRL->object = *object;
 
1116
    /* XXX should choose instance based on some criteria */
 
1117
    status = nssCryptokiCRL_GetAttributes(object->instances[0],
 
1118
                                          NULL,  /* XXX sessionOpt */
 
1119
                                          arena,
 
1120
                                          &rvCRL->encoding,
 
1121
                                          NULL, /* subject */
 
1122
                                          NULL, /* class */
 
1123
                                          &rvCRL->url,
 
1124
                                          &rvCRL->isKRL);
 
1125
    if (status != PR_SUCCESS) {
 
1126
        return (NSSCRL *)NULL;
 
1127
    }
 
1128
    return rvCRL;
 
1129
}
 
1130
 
 
1131
NSS_IMPLEMENT NSSCRL *
 
1132
nssCRL_AddRef (
 
1133
  NSSCRL *crl
 
1134
)
 
1135
{
 
1136
    if (crl) {
 
1137
        nssPKIObject_AddRef(&crl->object);
 
1138
    }
 
1139
    return crl;
 
1140
}
 
1141
 
 
1142
NSS_IMPLEMENT PRStatus
 
1143
nssCRL_Destroy (
 
1144
  NSSCRL *crl
 
1145
)
 
1146
{
 
1147
    if (crl) {
 
1148
        (void)nssPKIObject_Destroy(&crl->object);
 
1149
    }
 
1150
    return PR_SUCCESS;
 
1151
}
 
1152
 
 
1153
NSS_IMPLEMENT PRStatus
 
1154
nssCRL_DeleteStoredObject (
 
1155
  NSSCRL *crl,
 
1156
  NSSCallback *uhh
 
1157
)
 
1158
{
 
1159
    return nssPKIObject_DeleteStoredObject(&crl->object, uhh, PR_TRUE);
 
1160
}
 
1161
 
 
1162
NSS_IMPLEMENT NSSDER *
 
1163
nssCRL_GetEncoding (
 
1164
  NSSCRL *crl
 
1165
)
 
1166
{
 
1167
    if (crl && crl->encoding.data != NULL && crl->encoding.size > 0) {
 
1168
        return &crl->encoding;
 
1169
    } else {
 
1170
        return (NSSDER *)NULL;
 
1171
    }
 
1172
}