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