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