Coverage Report

Created: 2018-09-25 14:53

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