Coverage Report

Created: 2024-11-21 07:03

/src/nss-nspr/nss/lib/certdb/stanpcertdb.c
Line
Count
Source (jump to first uncovered line)
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
#include "prtime.h"
6
7
#include "cert.h"
8
#include "certi.h"
9
#include "certdb.h"
10
#include "secitem.h"
11
#include "secder.h"
12
13
/* Call to PK11_FreeSlot below */
14
15
#include "secasn1.h"
16
#include "secerr.h"
17
#include "nssilock.h"
18
#include "prmon.h"
19
#include "base64.h"
20
#include "sechash.h"
21
#include "plhash.h"
22
#include "pk11func.h" /* sigh */
23
24
#include "nsspki.h"
25
#include "pki.h"
26
#include "pkim.h"
27
#include "pki3hack.h"
28
#include "ckhelper.h"
29
#include "base.h"
30
#include "pkistore.h"
31
#include "dev3hack.h"
32
#include "dev.h"
33
#include "secmodi.h"
34
35
extern void CERT_MaybeLockCertTempPerm(const CERTCertificate *cert);
36
extern void CERT_MaybeUnlockCertTempPerm(const CERTCertificate *cert);
37
38
PRBool
39
SEC_CertNicknameConflict(const char *nickname, const SECItem *derSubject,
40
                         CERTCertDBHandle *handle)
41
0
{
42
0
    CERTCertificate *cert;
43
0
    PRBool conflict = PR_FALSE;
44
45
0
    cert = CERT_FindCertByNickname(handle, nickname);
46
47
0
    if (!cert) {
48
0
        return conflict;
49
0
    }
50
51
0
    conflict = !SECITEM_ItemsAreEqual(derSubject, &cert->derSubject);
52
0
    CERT_DestroyCertificate(cert);
53
0
    return conflict;
54
0
}
55
56
SECStatus
57
SEC_DeletePermCertificate(CERTCertificate *cert)
58
0
{
59
0
    PRStatus nssrv;
60
0
    NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
61
0
    NSSCertificate *c = STAN_GetNSSCertificate(cert);
62
0
    CERTCertTrust *certTrust;
63
64
0
    if (c == NULL) {
65
        /* error code is set */
66
0
        return SECFailure;
67
0
    }
68
69
0
    certTrust = nssTrust_GetCERTCertTrustForCert(c, cert);
70
0
    if (certTrust) {
71
0
        NSSTrust *nssTrust = nssTrustDomain_FindTrustForCertificate(td, c);
72
0
        if (nssTrust) {
73
0
            nssrv = STAN_DeleteCertTrustMatchingSlot(c);
74
0
            if (nssrv != PR_SUCCESS) {
75
0
                CERT_MapStanError();
76
0
            }
77
            /* This call always returns PR_SUCCESS! */
78
0
            (void)nssTrust_Destroy(nssTrust);
79
0
        }
80
0
    }
81
82
    /* get rid of the token instances */
83
0
    nssrv = NSSCertificate_DeleteStoredObject(c, NULL);
84
85
    /* get rid of the cache entry */
86
0
    nssTrustDomain_LockCertCache(td);
87
0
    nssTrustDomain_RemoveCertFromCacheLOCKED(td, c);
88
0
    nssTrustDomain_UnlockCertCache(td);
89
90
0
    return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
91
0
}
92
93
SECStatus
94
CERT_GetCertTrust(const CERTCertificate *cert, CERTCertTrust *trust)
95
0
{
96
0
    SECStatus rv;
97
0
    CERT_LockCertTrust(cert);
98
0
    if (!cert || cert->trust == NULL) {
99
0
        rv = SECFailure;
100
0
    } else {
101
0
        *trust = *cert->trust;
102
0
        rv = SECSuccess;
103
0
    }
104
0
    CERT_UnlockCertTrust(cert);
105
0
    return (rv);
106
0
}
107
108
extern const NSSError NSS_ERROR_NO_ERROR;
109
extern const NSSError NSS_ERROR_INTERNAL_ERROR;
110
extern const NSSError NSS_ERROR_NO_MEMORY;
111
extern const NSSError NSS_ERROR_INVALID_POINTER;
112
extern const NSSError NSS_ERROR_INVALID_ARENA;
113
extern const NSSError NSS_ERROR_INVALID_ARENA_MARK;
114
extern const NSSError NSS_ERROR_DUPLICATE_POINTER;
115
extern const NSSError NSS_ERROR_POINTER_NOT_REGISTERED;
116
extern const NSSError NSS_ERROR_TRACKER_NOT_EMPTY;
117
extern const NSSError NSS_ERROR_TRACKER_NOT_INITIALIZED;
118
extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD;
119
extern const NSSError NSS_ERROR_VALUE_TOO_LARGE;
120
extern const NSSError NSS_ERROR_UNSUPPORTED_TYPE;
121
extern const NSSError NSS_ERROR_BUFFER_TOO_SHORT;
122
extern const NSSError NSS_ERROR_INVALID_ATOB_CONTEXT;
123
extern const NSSError NSS_ERROR_INVALID_BASE64;
124
extern const NSSError NSS_ERROR_INVALID_BTOA_CONTEXT;
125
extern const NSSError NSS_ERROR_INVALID_ITEM;
126
extern const NSSError NSS_ERROR_INVALID_STRING;
127
extern const NSSError NSS_ERROR_INVALID_ASN1ENCODER;
128
extern const NSSError NSS_ERROR_INVALID_ASN1DECODER;
129
extern const NSSError NSS_ERROR_INVALID_BER;
130
extern const NSSError NSS_ERROR_INVALID_ATAV;
131
extern const NSSError NSS_ERROR_INVALID_ARGUMENT;
132
extern const NSSError NSS_ERROR_INVALID_UTF8;
133
extern const NSSError NSS_ERROR_INVALID_NSSOID;
134
extern const NSSError NSS_ERROR_UNKNOWN_ATTRIBUTE;
135
extern const NSSError NSS_ERROR_NOT_FOUND;
136
extern const NSSError NSS_ERROR_INVALID_PASSWORD;
137
extern const NSSError NSS_ERROR_USER_CANCELED;
138
extern const NSSError NSS_ERROR_MAXIMUM_FOUND;
139
extern const NSSError NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND;
140
extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE;
141
extern const NSSError NSS_ERROR_HASH_COLLISION;
142
extern const NSSError NSS_ERROR_DEVICE_ERROR;
143
extern const NSSError NSS_ERROR_INVALID_CERTIFICATE;
144
extern const NSSError NSS_ERROR_BUSY;
145
extern const NSSError NSS_ERROR_ALREADY_INITIALIZED;
146
extern const NSSError NSS_ERROR_PKCS11;
147
148
/* Look at the stan error stack and map it to NSS 3 errors */
149
#define STAN_MAP_ERROR(x, y) \
150
0
    else if (error == (x)) { secError = y; }
151
152
/*
153
 * map Stan errors into NSS errors
154
 * This function examines the stan error stack and automatically sets
155
 * PORT_SetError(); to the appropriate SEC_ERROR value.
156
 */
157
void
158
CERT_MapStanError()
159
0
{
160
0
    PRInt32 *errorStack;
161
0
    NSSError error, prevError;
162
0
    int secError;
163
0
    int i;
164
165
0
    errorStack = NSS_GetErrorStack();
166
0
    if (errorStack == 0) {
167
0
        PORT_SetError(0);
168
0
        return;
169
0
    }
170
0
    error = prevError = CKR_GENERAL_ERROR;
171
    /* get the 'top 2' error codes from the stack */
172
0
    for (i = 0; errorStack[i]; i++) {
173
0
        prevError = error;
174
0
        error = errorStack[i];
175
0
    }
176
0
    if (error == NSS_ERROR_PKCS11) {
177
        /* map it */
178
0
        secError = PK11_MapError(prevError);
179
0
    }
180
0
    STAN_MAP_ERROR(NSS_ERROR_NO_ERROR, 0)
181
0
    STAN_MAP_ERROR(NSS_ERROR_NO_MEMORY, SEC_ERROR_NO_MEMORY)
182
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_BASE64, SEC_ERROR_BAD_DATA)
183
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_BER, SEC_ERROR_BAD_DER)
184
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ATAV, SEC_ERROR_INVALID_AVA)
185
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_PASSWORD, SEC_ERROR_BAD_PASSWORD)
186
0
    STAN_MAP_ERROR(NSS_ERROR_BUSY, SEC_ERROR_BUSY)
187
0
    STAN_MAP_ERROR(NSS_ERROR_DEVICE_ERROR, SEC_ERROR_IO)
188
0
    STAN_MAP_ERROR(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND,
189
0
                   SEC_ERROR_UNKNOWN_ISSUER)
190
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_CERTIFICATE, SEC_ERROR_CERT_NOT_VALID)
191
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_UTF8, SEC_ERROR_BAD_DATA)
192
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_NSSOID, SEC_ERROR_BAD_DATA)
193
194
    /* these are library failure for lack of a better error code */
195
0
    STAN_MAP_ERROR(NSS_ERROR_NOT_FOUND, SEC_ERROR_LIBRARY_FAILURE)
196
0
    STAN_MAP_ERROR(NSS_ERROR_CERTIFICATE_IN_CACHE, SEC_ERROR_LIBRARY_FAILURE)
197
0
    STAN_MAP_ERROR(NSS_ERROR_MAXIMUM_FOUND, SEC_ERROR_LIBRARY_FAILURE)
198
0
    STAN_MAP_ERROR(NSS_ERROR_USER_CANCELED, SEC_ERROR_LIBRARY_FAILURE)
199
0
    STAN_MAP_ERROR(NSS_ERROR_TRACKER_NOT_INITIALIZED, SEC_ERROR_LIBRARY_FAILURE)
200
0
    STAN_MAP_ERROR(NSS_ERROR_ALREADY_INITIALIZED, SEC_ERROR_LIBRARY_FAILURE)
201
0
    STAN_MAP_ERROR(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD,
202
0
                   SEC_ERROR_LIBRARY_FAILURE)
203
0
    STAN_MAP_ERROR(NSS_ERROR_HASH_COLLISION, SEC_ERROR_LIBRARY_FAILURE)
204
205
0
    STAN_MAP_ERROR(NSS_ERROR_INTERNAL_ERROR, SEC_ERROR_LIBRARY_FAILURE)
206
207
    /* these are all invalid arguments */
208
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ARGUMENT, SEC_ERROR_INVALID_ARGS)
209
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_POINTER, SEC_ERROR_INVALID_ARGS)
210
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ARENA, SEC_ERROR_INVALID_ARGS)
211
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ARENA_MARK, SEC_ERROR_INVALID_ARGS)
212
0
    STAN_MAP_ERROR(NSS_ERROR_DUPLICATE_POINTER, SEC_ERROR_INVALID_ARGS)
213
0
    STAN_MAP_ERROR(NSS_ERROR_POINTER_NOT_REGISTERED, SEC_ERROR_INVALID_ARGS)
214
0
    STAN_MAP_ERROR(NSS_ERROR_TRACKER_NOT_EMPTY, SEC_ERROR_INVALID_ARGS)
215
0
    STAN_MAP_ERROR(NSS_ERROR_VALUE_TOO_LARGE, SEC_ERROR_INVALID_ARGS)
216
0
    STAN_MAP_ERROR(NSS_ERROR_UNSUPPORTED_TYPE, SEC_ERROR_INVALID_ARGS)
217
0
    STAN_MAP_ERROR(NSS_ERROR_BUFFER_TOO_SHORT, SEC_ERROR_INVALID_ARGS)
218
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ATOB_CONTEXT, SEC_ERROR_INVALID_ARGS)
219
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_BTOA_CONTEXT, SEC_ERROR_INVALID_ARGS)
220
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ITEM, SEC_ERROR_INVALID_ARGS)
221
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_STRING, SEC_ERROR_INVALID_ARGS)
222
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ASN1ENCODER, SEC_ERROR_INVALID_ARGS)
223
0
    STAN_MAP_ERROR(NSS_ERROR_INVALID_ASN1DECODER, SEC_ERROR_INVALID_ARGS)
224
0
    STAN_MAP_ERROR(NSS_ERROR_UNKNOWN_ATTRIBUTE, SEC_ERROR_INVALID_ARGS)
225
0
    else { secError = SEC_ERROR_LIBRARY_FAILURE; }
226
0
    PORT_SetError(secError);
227
0
}
228
229
SECStatus
230
CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert,
231
                     CERTCertTrust *trust)
232
0
{
233
0
    SECStatus rv = SECSuccess;
234
0
    PRStatus ret;
235
236
0
    ret = STAN_ChangeCertTrust(cert, trust);
237
0
    if (ret != PR_SUCCESS) {
238
0
        rv = SECFailure;
239
0
        CERT_MapStanError();
240
0
    }
241
0
    return rv;
242
0
}
243
244
extern const NSSError NSS_ERROR_INVALID_CERTIFICATE;
245
246
SECStatus
247
__CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
248
                         CERTCertTrust *trust)
249
0
{
250
0
    NSSUTF8 *stanNick;
251
0
    PK11SlotInfo *slot;
252
0
    NSSToken *internal;
253
0
    NSSCryptoContext *context;
254
0
    nssCryptokiObject *permInstance;
255
0
    NSSCertificate *c = STAN_GetNSSCertificate(cert);
256
0
    nssCertificateStoreTrace lockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
257
0
    nssCertificateStoreTrace unlockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
258
0
    SECStatus rv;
259
0
    PRStatus ret;
260
261
0
    if (c == NULL) {
262
0
        CERT_MapStanError();
263
0
        return SECFailure;
264
0
    }
265
266
0
    context = c->object.cryptoContext;
267
0
    if (!context) {
268
0
        PORT_SetError(SEC_ERROR_ADDING_CERT);
269
0
        return SECFailure; /* wasn't a temp cert */
270
0
    }
271
0
    stanNick = nssCertificate_GetNickname(c, NULL);
272
0
    if (stanNick && nickname && strcmp(nickname, stanNick) != 0) {
273
        /* different: take the new nickname */
274
0
        cert->nickname = NULL;
275
0
        nss_ZFreeIf(stanNick);
276
0
        stanNick = NULL;
277
0
    }
278
0
    if (!stanNick && nickname) {
279
        /* Either there was no nickname yet, or we have a new nickname */
280
0
        stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, NULL);
281
0
    } /* else: old stanNick is identical to new nickname */
282
    /* Delete the temp instance */
283
0
    nssCertificateStore_Lock(context->certStore, &lockTrace);
284
0
    nssCertificateStore_RemoveCertLOCKED(context->certStore, c);
285
0
    nssCertificateStore_Unlock(context->certStore, &lockTrace, &unlockTrace);
286
0
    c->object.cryptoContext = NULL;
287
288
    /* if the id has not been set explicitly yet, create one from the public
289
     * key. */
290
0
    if (c->id.data == NULL) {
291
0
        SECItem *keyID = pk11_mkcertKeyID(cert);
292
0
        if (keyID) {
293
0
            nssItem_Create(c->object.arena, &c->id, keyID->len, keyID->data);
294
0
            SECITEM_FreeItem(keyID, PR_TRUE);
295
0
        }
296
        /* if any of these failed, continue with our null c->id */
297
0
    }
298
299
    /* Import the perm instance onto the internal token */
300
0
    slot = PK11_GetInternalKeySlot();
301
0
    internal = PK11Slot_GetNSSToken(slot);
302
0
    if (!internal) {
303
0
        PK11_FreeSlot(slot);
304
0
        PORT_SetError(SEC_ERROR_NO_TOKEN);
305
0
        return SECFailure;
306
0
    }
307
0
    permInstance = nssToken_ImportCertificate(
308
0
        internal, NULL, NSSCertificateType_PKIX, &c->id, stanNick, &c->encoding,
309
0
        &c->issuer, &c->subject, &c->serial, cert->emailAddr, PR_TRUE);
310
0
    (void)nssToken_Destroy(internal);
311
0
    nss_ZFreeIf(stanNick);
312
0
    stanNick = NULL;
313
0
    PK11_FreeSlot(slot);
314
0
    if (!permInstance) {
315
0
        if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) {
316
0
            PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL);
317
0
        }
318
0
        return SECFailure;
319
0
    }
320
0
    nssPKIObject_AddInstance(&c->object, permInstance);
321
0
    nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
322
    /* reset the CERTCertificate fields */
323
0
    CERT_LockCertTempPerm(cert);
324
0
    cert->nssCertificate = NULL;
325
0
    CERT_UnlockCertTempPerm(cert);
326
0
    cert = STAN_GetCERTCertificateOrRelease(c); /* should return same pointer */
327
0
    if (!cert) {
328
0
        CERT_MapStanError();
329
0
        return SECFailure;
330
0
    }
331
0
    CERT_LockCertTempPerm(cert);
332
0
    cert->istemp = PR_FALSE;
333
0
    cert->isperm = PR_TRUE;
334
0
    CERT_UnlockCertTempPerm(cert);
335
0
    if (!trust) {
336
0
        return SECSuccess;
337
0
    }
338
0
    ret = STAN_ChangeCertTrust(cert, trust);
339
0
    rv = SECSuccess;
340
0
    if (ret != PR_SUCCESS) {
341
0
        rv = SECFailure;
342
0
        CERT_MapStanError();
343
0
    }
344
0
    return rv;
345
0
}
346
347
SECStatus
348
CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
349
                       CERTCertTrust *trust)
350
0
{
351
0
    return __CERT_AddTempCertToPerm(cert, nickname, trust);
352
0
}
353
354
CERTCertificate *
355
CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
356
                        char *nickname, PRBool isperm, PRBool copyDER)
357
0
{
358
0
    NSSCertificate *c;
359
0
    CERTCertificate *cc;
360
0
    NSSCertificate *tempCert = NULL;
361
0
    nssPKIObject *pkio;
362
0
    NSSCryptoContext *gCC = STAN_GetDefaultCryptoContext();
363
0
    NSSTrustDomain *gTD = STAN_GetDefaultTrustDomain();
364
0
    if (!isperm) {
365
0
        NSSDER encoding;
366
0
        NSSITEM_FROM_SECITEM(&encoding, derCert);
367
        /* First, see if it is already a temp cert */
368
0
        c = NSSCryptoContext_FindCertificateByEncodedCertificate(gCC,
369
0
                                                                 &encoding);
370
0
        if (!c && handle) {
371
            /* Then, see if it is already a perm cert */
372
0
            c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle,
373
0
                                                                   &encoding);
374
0
        }
375
0
        if (c) {
376
            /* actually, that search ends up going by issuer/serial,
377
             * so it is still possible to return a cert with the same
378
             * issuer/serial but a different encoding, and we're
379
             * going to reject that
380
             */
381
0
            if (!nssItem_Equal(&c->encoding, &encoding, NULL)) {
382
0
                nssCertificate_Destroy(c);
383
0
                PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL);
384
0
                cc = NULL;
385
0
            } else {
386
0
                cc = STAN_GetCERTCertificateOrRelease(c);
387
0
                if (cc == NULL) {
388
0
                    CERT_MapStanError();
389
0
                }
390
0
            }
391
0
            return cc;
392
0
        }
393
0
    }
394
0
    pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC, nssPKIMonitor);
395
0
    if (!pkio) {
396
0
        CERT_MapStanError();
397
0
        return NULL;
398
0
    }
399
0
    c = nss_ZNEW(pkio->arena, NSSCertificate);
400
0
    if (!c) {
401
0
        CERT_MapStanError();
402
0
        nssPKIObject_Destroy(pkio);
403
0
        return NULL;
404
0
    }
405
0
    c->object = *pkio;
406
0
    if (copyDER) {
407
0
        nssItem_Create(c->object.arena, &c->encoding, derCert->len,
408
0
                       derCert->data);
409
0
    } else {
410
0
        NSSITEM_FROM_SECITEM(&c->encoding, derCert);
411
0
    }
412
    /* Forces a decoding of the cert in order to obtain the parts used
413
     * below
414
     */
415
    /* 'c' is not adopted here, if we fail loser frees what has been
416
     * allocated so far for 'c' */
417
0
    cc = STAN_GetCERTCertificate(c);
418
0
    if (!cc) {
419
0
        CERT_MapStanError();
420
0
        goto loser;
421
0
    }
422
0
    nssItem_Create(c->object.arena, &c->issuer, cc->derIssuer.len,
423
0
                   cc->derIssuer.data);
424
0
    nssItem_Create(c->object.arena, &c->subject, cc->derSubject.len,
425
0
                   cc->derSubject.data);
426
    /* CERTCertificate stores serial numbers decoded.  I need the DER
427
     * here.  sigh.
428
     */
429
0
    SECItem derSerial = { 0 };
430
0
    CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial);
431
0
    if (!derSerial.data)
432
0
        goto loser;
433
0
    nssItem_Create(c->object.arena, &c->serial, derSerial.len,
434
0
                   derSerial.data);
435
0
    PORT_Free(derSerial.data);
436
437
0
    if (nickname) {
438
0
        c->object.tempName =
439
0
            nssUTF8_Create(c->object.arena, nssStringType_UTF8String,
440
0
                           (NSSUTF8 *)nickname, PORT_Strlen(nickname));
441
0
    }
442
0
    if (cc->emailAddr && cc->emailAddr[0]) {
443
0
        c->email = nssUTF8_Create(
444
0
            c->object.arena, nssStringType_PrintableString,
445
0
            (NSSUTF8 *)cc->emailAddr, PORT_Strlen(cc->emailAddr));
446
0
    }
447
448
0
    tempCert = NSSCryptoContext_FindOrImportCertificate(gCC, c);
449
0
    if (!tempCert) {
450
0
        CERT_MapStanError();
451
0
        goto loser;
452
0
    }
453
    /* destroy our copy */
454
0
    NSSCertificate_Destroy(c);
455
    /* and use the stored entry */
456
0
    c = tempCert;
457
0
    cc = STAN_GetCERTCertificateOrRelease(c);
458
0
    if (!cc) {
459
        /* STAN_GetCERTCertificateOrRelease destroys c on failure. */
460
0
        CERT_MapStanError();
461
0
        return NULL;
462
0
    }
463
464
0
    CERT_LockCertTempPerm(cc);
465
0
    cc->istemp = PR_TRUE;
466
0
    cc->isperm = PR_FALSE;
467
0
    CERT_UnlockCertTempPerm(cc);
468
0
    return cc;
469
0
loser:
470
    /* Perhaps this should be nssCertificate_Destroy(c) */
471
0
    nssPKIObject_Destroy(&c->object);
472
0
    return NULL;
473
0
}
474
475
/* This symbol is exported for backward compatibility. */
476
CERTCertificate *
477
__CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert,
478
                          char *nickname, PRBool isperm, PRBool copyDER)
479
0
{
480
0
    return CERT_NewTempCertificate(handle, derCert, nickname, isperm, copyDER);
481
0
}
482
483
static CERTCertificate *
484
common_FindCertByIssuerAndSN(CERTCertDBHandle *handle,
485
                             CERTIssuerAndSN *issuerAndSN,
486
                             void *wincx)
487
0
{
488
0
    PK11SlotInfo *slot;
489
0
    CERTCertificate *cert;
490
491
0
    cert = PK11_FindCertByIssuerAndSN(&slot, issuerAndSN, wincx);
492
0
    if (cert && slot) {
493
0
        PK11_FreeSlot(slot);
494
0
    }
495
496
0
    return cert;
497
0
}
498
499
/* maybe all the wincx's should be some const for internal token login? */
500
CERTCertificate *
501
CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle,
502
                           CERTIssuerAndSN *issuerAndSN)
503
0
{
504
0
    return common_FindCertByIssuerAndSN(handle, issuerAndSN, NULL);
505
0
}
506
507
/* maybe all the wincx's should be some const for internal token login? */
508
CERTCertificate *
509
CERT_FindCertByIssuerAndSNCX(CERTCertDBHandle *handle,
510
                             CERTIssuerAndSN *issuerAndSN,
511
                             void *wincx)
512
0
{
513
0
    return common_FindCertByIssuerAndSN(handle, issuerAndSN, wincx);
514
0
}
515
516
static NSSCertificate *
517
get_best_temp_or_perm(NSSCertificate *ct, NSSCertificate *cp)
518
0
{
519
0
    NSSUsage usage;
520
0
    NSSCertificate *arr[3];
521
0
    if (!ct) {
522
0
        return nssCertificate_AddRef(cp);
523
0
    } else if (!cp) {
524
0
        return nssCertificate_AddRef(ct);
525
0
    }
526
0
    arr[0] = ct;
527
0
    arr[1] = cp;
528
0
    arr[2] = NULL;
529
0
    usage.anyUsage = PR_TRUE;
530
0
    return nssCertificateArray_FindBestCertificate(arr, NULL, &usage, NULL);
531
0
}
532
533
CERTCertificate *
534
CERT_FindCertByName(CERTCertDBHandle *handle, SECItem *name)
535
0
{
536
0
    NSSCertificate *cp, *ct, *c;
537
0
    NSSDER subject;
538
0
    NSSUsage usage;
539
0
    NSSCryptoContext *cc;
540
0
    NSSITEM_FROM_SECITEM(&subject, name);
541
0
    usage.anyUsage = PR_TRUE;
542
0
    cc = STAN_GetDefaultCryptoContext();
543
0
    ct = NSSCryptoContext_FindBestCertificateBySubject(cc, &subject, NULL,
544
0
                                                       &usage, NULL);
545
0
    cp = NSSTrustDomain_FindBestCertificateBySubject(handle, &subject, NULL,
546
0
                                                     &usage, NULL);
547
0
    c = get_best_temp_or_perm(ct, cp);
548
0
    if (ct) {
549
0
        CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
550
0
    }
551
0
    if (cp) {
552
0
        CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(cp));
553
0
    }
554
0
    return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
555
0
}
556
557
CERTCertificate *
558
CERT_FindCertByKeyID(CERTCertDBHandle *handle, SECItem *name, SECItem *keyID)
559
0
{
560
0
    CERTCertList *list;
561
0
    CERTCertificate *cert = NULL;
562
0
    CERTCertListNode *node;
563
564
0
    list = CERT_CreateSubjectCertList(NULL, handle, name, 0, PR_FALSE);
565
0
    if (list == NULL)
566
0
        return NULL;
567
568
0
    node = CERT_LIST_HEAD(list);
569
0
    while (!CERT_LIST_END(node, list)) {
570
0
        if (node->cert &&
571
0
            SECITEM_ItemsAreEqual(&node->cert->subjectKeyID, keyID)) {
572
0
            cert = CERT_DupCertificate(node->cert);
573
0
            goto done;
574
0
        }
575
0
        node = CERT_LIST_NEXT(node);
576
0
    }
577
0
    PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
578
579
0
done:
580
0
    CERT_DestroyCertList(list);
581
0
    return cert;
582
0
}
583
584
CERTCertificate *
585
CERT_FindCertByNickname(CERTCertDBHandle *handle, const char *nickname)
586
0
{
587
0
    NSSCryptoContext *cc;
588
0
    NSSCertificate *c, *ct;
589
0
    CERTCertificate *cert;
590
0
    NSSUsage usage;
591
0
    usage.anyUsage = PR_TRUE;
592
0
    cc = STAN_GetDefaultCryptoContext();
593
0
    ct = NSSCryptoContext_FindBestCertificateByNickname(cc, nickname, NULL,
594
0
                                                        &usage, NULL);
595
0
    cert = PK11_FindCertFromNickname(nickname, NULL);
596
0
    c = NULL;
597
0
    if (cert) {
598
0
        c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert));
599
0
        CERT_DestroyCertificate(cert);
600
0
        if (ct) {
601
0
            CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
602
0
        }
603
0
    } else {
604
0
        c = ct;
605
0
    }
606
0
    return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
607
0
}
608
609
CERTCertificate *
610
CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert)
611
0
{
612
0
    NSSCryptoContext *cc;
613
0
    NSSCertificate *c;
614
0
    NSSDER encoding;
615
0
    NSSITEM_FROM_SECITEM(&encoding, derCert);
616
0
    cc = STAN_GetDefaultCryptoContext();
617
0
    c = NSSCryptoContext_FindCertificateByEncodedCertificate(cc, &encoding);
618
0
    if (!c) {
619
0
        c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle,
620
0
                                                               &encoding);
621
0
        if (!c)
622
0
            return NULL;
623
0
    }
624
0
    return STAN_GetCERTCertificateOrRelease(c);
625
0
}
626
627
static CERTCertificate *
628
common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
629
                                             const char *name, PRBool anyUsage,
630
                                             SECCertUsage lookingForUsage,
631
                                             void *wincx)
632
0
{
633
0
    NSSCryptoContext *cc;
634
0
    NSSCertificate *c, *ct;
635
0
    CERTCertificate *cert = NULL;
636
0
    NSSUsage usage;
637
0
    CERTCertList *certlist;
638
639
0
    if (NULL == name) {
640
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
641
0
        return NULL;
642
0
    }
643
644
0
    usage.anyUsage = anyUsage;
645
646
0
    if (!anyUsage) {
647
0
        usage.nss3lookingForCA = PR_FALSE;
648
0
        usage.nss3usage = lookingForUsage;
649
0
    }
650
651
0
    cc = STAN_GetDefaultCryptoContext();
652
0
    ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name, NULL, &usage,
653
0
                                                        NULL);
654
0
    if (!ct && PORT_Strchr(name, '@') != NULL) {
655
0
        char *lowercaseName = CERT_FixupEmailAddr(name);
656
0
        if (lowercaseName) {
657
0
            ct = NSSCryptoContext_FindBestCertificateByEmail(
658
0
                cc, lowercaseName, NULL, &usage, NULL);
659
0
            PORT_Free(lowercaseName);
660
0
        }
661
0
    }
662
663
0
    if (anyUsage) {
664
0
        cert = PK11_FindCertFromNickname(name, wincx);
665
0
    } else {
666
0
        if (ct) {
667
            /* Does ct really have the required usage? */
668
0
            nssDecodedCert *dc;
669
0
            dc = nssCertificate_GetDecoding(ct);
670
0
            if (!dc->matchUsage(dc, &usage)) {
671
0
                CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
672
0
                ct = NULL;
673
0
            }
674
0
        }
675
676
0
        certlist = PK11_FindCertsFromNickname(name, wincx);
677
0
        if (certlist) {
678
0
            SECStatus rv =
679
0
                CERT_FilterCertListByUsage(certlist, lookingForUsage, PR_FALSE);
680
0
            if (SECSuccess == rv && !CERT_LIST_EMPTY(certlist)) {
681
0
                cert = CERT_DupCertificate(CERT_LIST_HEAD(certlist)->cert);
682
0
            }
683
0
            CERT_DestroyCertList(certlist);
684
0
        }
685
0
    }
686
687
0
    if (cert) {
688
0
        c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert));
689
0
        CERT_DestroyCertificate(cert);
690
0
        if (ct) {
691
0
            CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct));
692
0
        }
693
0
    } else {
694
0
        c = ct;
695
0
    }
696
0
    return c ? STAN_GetCERTCertificateOrRelease(c) : NULL;
697
0
}
698
699
CERTCertificate *
700
CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name)
701
0
{
702
0
    return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_TRUE,
703
0
                                                        0, NULL);
704
0
}
705
706
CERTCertificate *
707
CERT_FindCertByNicknameOrEmailAddrCX(CERTCertDBHandle *handle, const char *name,
708
                                     void *wincx)
709
0
{
710
0
    return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_TRUE,
711
0
                                                        0, wincx);
712
0
}
713
714
CERTCertificate *
715
CERT_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle,
716
                                           const char *name,
717
                                           SECCertUsage lookingForUsage)
718
0
{
719
0
    return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_FALSE,
720
0
                                                        lookingForUsage, NULL);
721
0
}
722
723
CERTCertificate *
724
CERT_FindCertByNicknameOrEmailAddrForUsageCX(CERTCertDBHandle *handle,
725
                                             const char *name,
726
                                             SECCertUsage lookingForUsage,
727
                                             void *wincx)
728
0
{
729
0
    return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_FALSE,
730
0
                                                        lookingForUsage, wincx);
731
0
}
732
733
static void
734
add_to_subject_list(CERTCertList *certList, CERTCertificate *cert,
735
                    PRBool validOnly, PRTime sorttime)
736
0
{
737
0
    SECStatus secrv;
738
0
    if (!validOnly ||
739
0
        CERT_CheckCertValidTimes(cert, sorttime, PR_FALSE) ==
740
0
            secCertTimeValid) {
741
0
        secrv = CERT_AddCertToListSorted(certList, cert, CERT_SortCBValidity,
742
0
                                         (void *)&sorttime);
743
0
        if (secrv != SECSuccess) {
744
0
            CERT_DestroyCertificate(cert);
745
0
        }
746
0
    } else {
747
0
        CERT_DestroyCertificate(cert);
748
0
    }
749
0
}
750
751
CERTCertList *
752
CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle,
753
                           const SECItem *name, PRTime sorttime,
754
                           PRBool validOnly)
755
0
{
756
0
    NSSCryptoContext *cc;
757
0
    NSSCertificate **tSubjectCerts, **pSubjectCerts;
758
0
    NSSCertificate **ci;
759
0
    CERTCertificate *cert;
760
0
    NSSDER subject;
761
0
    PRBool myList = PR_FALSE;
762
0
    cc = STAN_GetDefaultCryptoContext();
763
0
    NSSITEM_FROM_SECITEM(&subject, name);
764
    /* Collect both temp and perm certs for the subject */
765
0
    tSubjectCerts =
766
0
        NSSCryptoContext_FindCertificatesBySubject(cc, &subject, NULL, 0, NULL);
767
0
    pSubjectCerts = NSSTrustDomain_FindCertificatesBySubject(handle, &subject,
768
0
                                                             NULL, 0, NULL);
769
0
    if (!tSubjectCerts && !pSubjectCerts) {
770
0
        return NULL;
771
0
    }
772
0
    if (certList == NULL) {
773
0
        certList = CERT_NewCertList();
774
0
        myList = PR_TRUE;
775
0
        if (!certList)
776
0
            goto loser;
777
0
    }
778
    /* Iterate over the matching temp certs.  Add them to the list */
779
0
    ci = tSubjectCerts;
780
0
    while (ci && *ci) {
781
0
        cert = STAN_GetCERTCertificateOrRelease(*ci);
782
        /* *ci may be invalid at this point, don't reference it again */
783
0
        if (cert) {
784
            /* NOTE: add_to_subject_list adopts the incoming cert. */
785
0
            add_to_subject_list(certList, cert, validOnly, sorttime);
786
0
        }
787
0
        ci++;
788
0
    }
789
    /* Iterate over the matching perm certs.  Add them to the list */
790
0
    ci = pSubjectCerts;
791
0
    while (ci && *ci) {
792
0
        cert = STAN_GetCERTCertificateOrRelease(*ci);
793
        /* *ci may be invalid at this point, don't reference it again */
794
0
        if (cert) {
795
            /* NOTE: add_to_subject_list adopts the incoming cert. */
796
0
            add_to_subject_list(certList, cert, validOnly, sorttime);
797
0
        }
798
0
        ci++;
799
0
    }
800
    /* all the references have been adopted or freed at this point, just
801
     * free the arrays now */
802
0
    nss_ZFreeIf(tSubjectCerts);
803
0
    nss_ZFreeIf(pSubjectCerts);
804
0
    return certList;
805
0
loser:
806
    /* need to free the references in tSubjectCerts and pSubjectCerts! */
807
0
    nssCertificateArray_Destroy(tSubjectCerts);
808
0
    nssCertificateArray_Destroy(pSubjectCerts);
809
0
    if (myList && certList != NULL) {
810
0
        CERT_DestroyCertList(certList);
811
0
    }
812
0
    return NULL;
813
0
}
814
815
void
816
CERT_DestroyCertificate(CERTCertificate *cert)
817
0
{
818
0
    if (cert) {
819
        /* don't use STAN_GetNSSCertificate because we don't want to
820
         * go to the trouble of translating the CERTCertificate into
821
         * an NSSCertificate just to destroy it.  If it hasn't been done
822
         * yet, don't do it at all
823
         *
824
         * cert->nssCertificate contains its own locks and refcount, but as it
825
         * may be NULL, the pointer itself must be guarded by some other lock.
826
         * Rather than creating a new global lock for only this purpose, share
827
         * an existing global lock that happens to be taken near the write in
828
         * fill_CERTCertificateFields(). The longer-term goal is to refactor
829
         * all these global locks to be certificate-scoped. */
830
0
        CERT_MaybeLockCertTempPerm(cert);
831
0
        NSSCertificate *tmp = cert->nssCertificate;
832
0
        CERT_MaybeUnlockCertTempPerm(cert);
833
0
        if (tmp) {
834
            /* delete the NSSCertificate */
835
0
            NSSCertificate_Destroy(tmp);
836
0
        } else if (cert->arena) {
837
0
            PORT_FreeArena(cert->arena, PR_FALSE);
838
0
        }
839
0
    }
840
0
    return;
841
0
}
842
843
int
844
CERT_GetDBContentVersion(CERTCertDBHandle *handle)
845
0
{
846
    /* should read the DB content version from the pkcs #11 device */
847
0
    return 0;
848
0
}
849
850
SECStatus
851
certdb_SaveSingleProfile(CERTCertificate *cert, const char *emailAddr,
852
                         SECItem *emailProfile, SECItem *profileTime)
853
0
{
854
0
    PRTime oldtime;
855
0
    PRTime newtime;
856
0
    SECStatus rv = SECFailure;
857
0
    PRBool saveit;
858
0
    SECItem oldprof, oldproftime;
859
0
    SECItem *oldProfile = NULL;
860
0
    SECItem *oldProfileTime = NULL;
861
0
    PK11SlotInfo *slot = NULL;
862
0
    NSSCertificate *c;
863
0
    NSSCryptoContext *cc;
864
0
    nssSMIMEProfile *stanProfile = NULL;
865
0
    PRBool freeOldProfile = PR_FALSE;
866
867
0
    c = STAN_GetNSSCertificate(cert);
868
0
    if (!c)
869
0
        return SECFailure;
870
0
    cc = c->object.cryptoContext;
871
0
    if (cc != NULL) {
872
0
        stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c);
873
0
        if (stanProfile) {
874
0
            PORT_Assert(stanProfile->profileData);
875
0
            SECITEM_FROM_NSSITEM(&oldprof, stanProfile->profileData);
876
0
            oldProfile = &oldprof;
877
0
            SECITEM_FROM_NSSITEM(&oldproftime, stanProfile->profileTime);
878
0
            oldProfileTime = &oldproftime;
879
0
        }
880
0
    } else {
881
0
        oldProfile = PK11_FindSMimeProfile(&slot, (char *)emailAddr,
882
0
                                           &cert->derSubject, &oldProfileTime);
883
0
        freeOldProfile = PR_TRUE;
884
0
    }
885
886
0
    saveit = PR_FALSE;
887
888
    /* both profileTime and emailProfile have to exist or not exist */
889
0
    if (emailProfile == NULL) {
890
0
        profileTime = NULL;
891
0
    } else if (profileTime == NULL) {
892
0
        emailProfile = NULL;
893
0
    }
894
895
0
    if (oldProfileTime == NULL) {
896
0
        saveit = PR_TRUE;
897
0
    } else {
898
        /* there was already a profile for this email addr */
899
0
        if (profileTime) {
900
            /* we have an old and new profile - save whichever is more recent*/
901
0
            if (oldProfileTime->len == 0) {
902
                /* always replace if old entry doesn't have a time */
903
0
                oldtime = LL_MININT;
904
0
            } else {
905
0
                rv = DER_UTCTimeToTime(&oldtime, oldProfileTime);
906
0
                if (rv != SECSuccess) {
907
0
                    goto loser;
908
0
                }
909
0
            }
910
911
0
            rv = DER_UTCTimeToTime(&newtime, profileTime);
912
0
            if (rv != SECSuccess) {
913
0
                goto loser;
914
0
            }
915
916
0
            if (LL_CMP(newtime, >, oldtime)) {
917
                /* this is a newer profile, save it and cert */
918
0
                saveit = PR_TRUE;
919
0
            }
920
0
        } else {
921
0
            saveit = PR_TRUE;
922
0
        }
923
0
    }
924
925
0
    if (saveit) {
926
0
        if (cc) {
927
0
            if (stanProfile && profileTime && emailProfile) {
928
                /* stanProfile is already stored in the crypto context,
929
                 * overwrite the data
930
                 */
931
0
                NSSArena *arena = stanProfile->object.arena;
932
0
                stanProfile->profileTime = nssItem_Create(
933
0
                    arena, NULL, profileTime->len, profileTime->data);
934
0
                stanProfile->profileData = nssItem_Create(
935
0
                    arena, NULL, emailProfile->len, emailProfile->data);
936
0
            } else if (profileTime && emailProfile) {
937
0
                PRStatus nssrv;
938
0
                NSSItem profTime, profData;
939
0
                NSSITEM_FROM_SECITEM(&profTime, profileTime);
940
0
                NSSITEM_FROM_SECITEM(&profData, emailProfile);
941
0
                stanProfile = nssSMIMEProfile_Create(c, &profTime, &profData);
942
0
                if (!stanProfile)
943
0
                    goto loser;
944
0
                nssrv = nssCryptoContext_ImportSMIMEProfile(cc, stanProfile);
945
0
                rv = (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
946
0
            }
947
0
        } else {
948
0
            rv = PK11_SaveSMimeProfile(slot, (char *)emailAddr,
949
0
                                       &cert->derSubject, emailProfile,
950
0
                                       profileTime);
951
0
        }
952
0
    } else {
953
0
        rv = SECSuccess;
954
0
    }
955
956
0
loser:
957
0
    if (oldProfile && freeOldProfile) {
958
0
        SECITEM_FreeItem(oldProfile, PR_TRUE);
959
0
    }
960
0
    if (oldProfileTime && freeOldProfile) {
961
0
        SECITEM_FreeItem(oldProfileTime, PR_TRUE);
962
0
    }
963
0
    if (stanProfile) {
964
0
        nssSMIMEProfile_Destroy(stanProfile);
965
0
    }
966
0
    if (slot) {
967
0
        PK11_FreeSlot(slot);
968
0
    }
969
970
0
    return (rv);
971
0
}
972
973
/*
974
 *
975
 * Manage S/MIME profiles
976
 *
977
 */
978
979
SECStatus
980
CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
981
                      SECItem *profileTime)
982
0
{
983
0
    const char *emailAddr;
984
0
    SECStatus rv;
985
0
    PRBool isperm = PR_FALSE;
986
987
0
    if (!cert) {
988
0
        return SECFailure;
989
0
    }
990
991
0
    if (cert->slot && !PK11_IsInternal(cert->slot)) {
992
        /* this cert comes from an external source, we need to add it
993
        to the cert db before creating an S/MIME profile */
994
0
        PK11SlotInfo *internalslot = PK11_GetInternalKeySlot();
995
0
        if (!internalslot) {
996
0
            return SECFailure;
997
0
        }
998
0
        rv = PK11_ImportCert(internalslot, cert, CK_INVALID_HANDLE, NULL,
999
0
                             PR_FALSE);
1000
1001
0
        PK11_FreeSlot(internalslot);
1002
0
        if (rv != SECSuccess) {
1003
0
            return SECFailure;
1004
0
        }
1005
0
    }
1006
1007
0
    rv = CERT_GetCertIsPerm(cert, &isperm);
1008
0
    if (rv != SECSuccess) {
1009
0
        return SECFailure;
1010
0
    }
1011
0
    if (cert->slot && isperm && CERT_IsUserCert(cert) &&
1012
0
        (!emailProfile || !emailProfile->len)) {
1013
        /* Don't clobber emailProfile for user certs. */
1014
0
        return SECSuccess;
1015
0
    }
1016
1017
0
    for (emailAddr = CERT_GetFirstEmailAddress(cert); emailAddr != NULL;
1018
0
         emailAddr = CERT_GetNextEmailAddress(cert, emailAddr)) {
1019
0
        rv = certdb_SaveSingleProfile(cert, emailAddr, emailProfile,
1020
0
                                      profileTime);
1021
0
        if (rv != SECSuccess) {
1022
0
            return SECFailure;
1023
0
        }
1024
0
    }
1025
0
    return SECSuccess;
1026
0
}
1027
1028
SECItem *
1029
CERT_FindSMimeProfile(CERTCertificate *cert)
1030
0
{
1031
0
    PK11SlotInfo *slot = NULL;
1032
0
    NSSCertificate *c;
1033
0
    NSSCryptoContext *cc;
1034
0
    SECItem *rvItem = NULL;
1035
1036
0
    if (!cert || !cert->emailAddr || !cert->emailAddr[0]) {
1037
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
1038
0
        return NULL;
1039
0
    }
1040
0
    c = STAN_GetNSSCertificate(cert);
1041
0
    if (!c)
1042
0
        return NULL;
1043
0
    cc = c->object.cryptoContext;
1044
0
    if (cc != NULL) {
1045
0
        nssSMIMEProfile *stanProfile;
1046
0
        stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c);
1047
0
        if (stanProfile) {
1048
0
            rvItem =
1049
0
                SECITEM_AllocItem(NULL, NULL, stanProfile->profileData->size);
1050
0
            if (rvItem) {
1051
0
                rvItem->data = stanProfile->profileData->data;
1052
0
            }
1053
0
            nssSMIMEProfile_Destroy(stanProfile);
1054
0
        }
1055
0
        return rvItem;
1056
0
    }
1057
0
    rvItem =
1058
0
        PK11_FindSMimeProfile(&slot, cert->emailAddr, &cert->derSubject, NULL);
1059
0
    if (slot) {
1060
0
        PK11_FreeSlot(slot);
1061
0
    }
1062
0
    return rvItem;
1063
0
}
1064
1065
SECStatus
1066
CERT_GetCertIsPerm(const CERTCertificate *cert, PRBool *isperm)
1067
0
{
1068
0
    if (cert == NULL) {
1069
0
        return SECFailure;
1070
0
    }
1071
1072
0
    CERT_LockCertTempPerm(cert);
1073
0
    *isperm = cert->isperm;
1074
0
    CERT_UnlockCertTempPerm(cert);
1075
0
    return SECSuccess;
1076
0
}
1077
1078
SECStatus
1079
CERT_GetCertIsTemp(const CERTCertificate *cert, PRBool *istemp)
1080
0
{
1081
0
    if (cert == NULL) {
1082
0
        return SECFailure;
1083
0
    }
1084
1085
0
    CERT_LockCertTempPerm(cert);
1086
0
    *istemp = cert->istemp;
1087
0
    CERT_UnlockCertTempPerm(cert);
1088
0
    return SECSuccess;
1089
0
}
1090
1091
/*
1092
 * deprecated functions that are now just stubs.
1093
 */
1094
/*
1095
 * Close the database
1096
 */
1097
void
1098
__CERT_ClosePermCertDB(CERTCertDBHandle *handle)
1099
0
{
1100
0
    PORT_Assert("CERT_ClosePermCertDB is Deprecated" == NULL);
1101
0
    return;
1102
0
}
1103
1104
SECStatus
1105
CERT_OpenCertDBFilename(CERTCertDBHandle *handle, char *certdbname,
1106
                        PRBool readOnly)
1107
0
{
1108
0
    PORT_Assert("CERT_OpenCertDBFilename is Deprecated" == NULL);
1109
0
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1110
0
    return SECFailure;
1111
0
}
1112
1113
SECItem *
1114
SECKEY_HashPassword(char *pw, SECItem *salt)
1115
0
{
1116
0
    PORT_Assert("SECKEY_HashPassword is Deprecated" == NULL);
1117
0
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1118
0
    return NULL;
1119
0
}
1120
1121
SECStatus
1122
__CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle,
1123
                                   SECItem *derSubject, void *cb, void *cbarg)
1124
0
{
1125
0
    PORT_Assert("CERT_TraversePermCertsForSubject is Deprecated" == NULL);
1126
0
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1127
0
    return SECFailure;
1128
0
}
1129
1130
SECStatus
1131
__CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname,
1132
                                    void *cb, void *cbarg)
1133
0
{
1134
0
    PORT_Assert("CERT_TraversePermCertsForNickname is Deprecated" == NULL);
1135
0
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1136
0
    return SECFailure;
1137
0
}