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 * nss_pkix_proxy.h
6 *
7 * PKIX - NSS proxy functions
8 *
9 * NOTE: All structures, functions, data types are parts of library private
10 * api and are subjects to change in any following releases.
11 *
12 */
13 #include "prerror.h"
14 #include "prprf.h"
15
16 #include "nspr.h"
17 #include "pk11func.h"
18 #include "certdb.h"
19 #include "cert.h"
20 #include "secerr.h"
21 #include "nssb64.h"
22 #include "secasn1.h"
23 #include "secder.h"
24 #include "pkit.h"
25
26 #ifndef NSS_DISABLE_LIBPKIX
27 #include "pkix_pl_common.h"
28
29 extern PRLogModuleInfo *pkixLog;
30
31 #ifdef PKIX_OBJECT_LEAK_TEST
32
33 extern PKIX_UInt32
34 pkix_pl_lifecycle_ObjectLeakCheck(int *);
35
36 extern SECStatus
37 pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable);
38
39 PRInt32 parallelFnInvocationCount;
40 #endif /* PKIX_OBJECT_LEAK_TEST */
41
42 static PRBool usePKIXValidationEngine = PR_FALSE;
43 #endif /* NSS_DISABLE_LIBPKIX */
44
45 /*
46 * FUNCTION: CERT_SetUsePKIXForValidation
47 * DESCRIPTION:
48 *
49 * Enables or disables use of libpkix for certificate validation
50 *
51 * PARAMETERS:
52 * "enable"
53 * PR_TRUE: enables use of libpkix for cert validation.
54 * PR_FALSE: disables.
55 * THREAD SAFETY:
56 * NOT Thread Safe.
57 * RETURNS:
58 * Returns SECSuccess if successfully enabled
59 */
60 SECStatus
CERT_SetUsePKIXForValidation(PRBool enable)61 CERT_SetUsePKIXForValidation(PRBool enable)
62 {
63 #ifdef NSS_DISABLE_LIBPKIX
64 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
65 return SECFailure;
66 #else
67 usePKIXValidationEngine = (enable > 0) ? PR_TRUE : PR_FALSE;
68 return SECSuccess;
69 #endif /* NSS_DISABLE_LIBPKIX */
70 }
71
72 /*
73 * FUNCTION: CERT_GetUsePKIXForValidation
74 * DESCRIPTION:
75 *
76 * Checks if libpkix building function should be use for certificate
77 * chain building.
78 *
79 * PARAMETERS:
80 * NONE
81 * THREAD SAFETY:
82 * NOT Thread Safe
83 * RETURNS:
84 * Returns PR_TRUE if libpkix should be used. PR_FALSE otherwise.
85 */
86 PRBool
CERT_GetUsePKIXForValidation()87 CERT_GetUsePKIXForValidation()
88 {
89 #ifdef NSS_DISABLE_LIBPKIX
90 return PR_FALSE;
91 #else
92 return usePKIXValidationEngine;
93 #endif /* NSS_DISABLE_LIBPKIX */
94 }
95
96 #ifndef NSS_DISABLE_LIBPKIX
97 #ifdef NOTDEF
98 /*
99 * FUNCTION: cert_NssKeyUsagesToPkix
100 * DESCRIPTION:
101 *
102 * Converts nss key usage bit field(PRUint32) to pkix key usage
103 * bit field.
104 *
105 * PARAMETERS:
106 * "nssKeyUsage"
107 * Nss key usage bit field.
108 * "pkixKeyUsage"
109 * Pkix key usage big field.
110 * "plContext"
111 * Platform-specific context pointer.
112 * THREAD SAFETY:
113 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
114 * RETURNS:
115 * Returns NULL if the function succeeds.
116 * Returns a Fatal Error if the function fails in an unrecoverable way.
117 */
118 static PKIX_Error *
cert_NssKeyUsagesToPkix(PRUint32 nssKeyUsage,PKIX_UInt32 * pPkixKeyUsage,void * plContext)119 cert_NssKeyUsagesToPkix(
120 PRUint32 nssKeyUsage,
121 PKIX_UInt32 *pPkixKeyUsage,
122 void *plContext)
123 {
124 PKIX_UInt32 pkixKeyUsage = 0;
125
126 PKIX_ENTER(CERTVFYPKIX, "cert_NssKeyUsagesToPkix");
127 PKIX_NULLCHECK_ONE(pPkixKeyUsage);
128
129 *pPkixKeyUsage = 0;
130
131 if (nssKeyUsage & KU_DIGITAL_SIGNATURE) {
132 pkixKeyUsage |= PKIX_DIGITAL_SIGNATURE;
133 }
134
135 if (nssKeyUsage & KU_NON_REPUDIATION) {
136 pkixKeyUsage |= PKIX_NON_REPUDIATION;
137 }
138
139 if (nssKeyUsage & KU_KEY_ENCIPHERMENT) {
140 pkixKeyUsage |= PKIX_KEY_ENCIPHERMENT;
141 }
142
143 if (nssKeyUsage & KU_DATA_ENCIPHERMENT) {
144 pkixKeyUsage |= PKIX_DATA_ENCIPHERMENT;
145 }
146
147 if (nssKeyUsage & KU_KEY_AGREEMENT) {
148 pkixKeyUsage |= PKIX_KEY_AGREEMENT;
149 }
150
151 if (nssKeyUsage & KU_KEY_CERT_SIGN) {
152 pkixKeyUsage |= PKIX_KEY_CERT_SIGN;
153 }
154
155 if (nssKeyUsage & KU_CRL_SIGN) {
156 pkixKeyUsage |= PKIX_CRL_SIGN;
157 }
158
159 if (nssKeyUsage & KU_ENCIPHER_ONLY) {
160 pkixKeyUsage |= PKIX_ENCIPHER_ONLY;
161 }
162
163 /* Not supported. XXX we should support this once it is
164 * fixed in NSS */
165 /* pkixKeyUsage |= PKIX_DECIPHER_ONLY; */
166
167 *pPkixKeyUsage = pkixKeyUsage;
168
169 PKIX_RETURN(CERTVFYPKIX);
170 }
171
172 extern SECOidTag ekuOidStrings[];
173
174 enum {
175 ekuIndexSSLServer = 0,
176 ekuIndexSSLClient,
177 ekuIndexCodeSigner,
178 ekuIndexEmail,
179 ekuIndexTimeStamp,
180 ekuIndexStatusResponder,
181 ekuIndexUnknown
182 } ekuIndex;
183
184 typedef struct {
185 SECCertUsage certUsage;
186 PRUint32 ekuStringIndex;
187 } SECCertUsageToEku;
188
189 const SECCertUsageToEku certUsageEkuStringMap[] = {
190 { certUsageSSLClient, ekuIndexSSLClient },
191 { certUsageSSLServer, ekuIndexSSLServer },
192 { certUsageSSLCA, ekuIndexSSLServer },
193 { certUsageEmailSigner, ekuIndexEmail },
194 { certUsageEmailRecipient, ekuIndexEmail },
195 { certUsageObjectSigner, ekuIndexCodeSigner },
196 { certUsageUserCertImport, ekuIndexUnknown },
197 { certUsageVerifyCA, ekuIndexUnknown },
198 { certUsageProtectedObjectSigner, ekuIndexUnknown },
199 { certUsageStatusResponder, ekuIndexStatusResponder },
200 { certUsageAnyCA, ekuIndexUnknown },
201 };
202
203 /*
204 * FUNCTION: cert_NssCertificateUsageToPkixKUAndEKU
205 * DESCRIPTION:
206 *
207 * Converts nss CERTCertificateUsage bit field to pkix key and
208 * extended key usages.
209 *
210 * PARAMETERS:
211 * "cert"
212 * Pointer to CERTCertificate structure of validating cert.
213 * "requiredCertUsages"
214 * Required usage that will be converted to pkix eku and ku.
215 * "requiredKeyUsage",
216 * Additional key usages impose to cert.
217 * "isCA",
218 * it true, convert usages for cert that is a CA cert.
219 * "ppkixEKUList"
220 * Returned address of a list of pkix extended key usages.
221 * "ppkixKU"
222 * Returned address of pkix required key usages bit field.
223 * "plContext"
224 * Platform-specific context pointer.
225 * THREAD SAFETY:
226 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
227 * RETURNS:
228 * Returns NULL if the function succeeds.
229 * Returns a Cert Verify Error if the function fails in an unrecoverable way.
230 * Returns a Fatal Error if the function fails in an unrecoverable way.
231 */
232 static PKIX_Error *
cert_NssCertificateUsageToPkixKUAndEKU(CERTCertificate * cert,SECCertUsage requiredCertUsage,PRUint32 requiredKeyUsages,PRBool isCA,PKIX_List ** ppkixEKUList,PKIX_UInt32 * ppkixKU,void * plContext)233 cert_NssCertificateUsageToPkixKUAndEKU(
234 CERTCertificate *cert,
235 SECCertUsage requiredCertUsage,
236 PRUint32 requiredKeyUsages,
237 PRBool isCA,
238 PKIX_List **ppkixEKUList,
239 PKIX_UInt32 *ppkixKU,
240 void *plContext)
241 {
242 PKIX_List *ekuOidsList = NULL;
243 PKIX_PL_OID *ekuOid = NULL;
244 int i = 0;
245 int ekuIndex = ekuIndexUnknown;
246
247 PKIX_ENTER(CERTVFYPKIX, "cert_NssCertificateUsageToPkixEku");
248 PKIX_NULLCHECK_TWO(ppkixEKUList, ppkixKU);
249
250 PKIX_CHECK(
251 PKIX_List_Create(&ekuOidsList, plContext),
252 PKIX_LISTCREATEFAILED);
253
254 for (; i < PR_ARRAY_SIZE(certUsageEkuStringMap); i++) {
255 const SECCertUsageToEku *usageToEkuElem =
256 &certUsageEkuStringMap[i];
257 if (usageToEkuElem->certUsage == requiredCertUsage) {
258 ekuIndex = usageToEkuElem->ekuStringIndex;
259 break;
260 }
261 }
262 if (ekuIndex != ekuIndexUnknown) {
263 PRUint32 reqKeyUsage = 0;
264 PRUint32 reqCertType = 0;
265
266 CERT_KeyUsageAndTypeForCertUsage(requiredCertUsage, isCA,
267 &reqKeyUsage,
268 &reqCertType);
269
270 requiredKeyUsages |= reqKeyUsage;
271
272 PKIX_CHECK(
273 PKIX_PL_OID_Create(ekuOidStrings[ekuIndex], &ekuOid,
274 plContext),
275 PKIX_OIDCREATEFAILED);
276
277 PKIX_CHECK(
278 PKIX_List_AppendItem(ekuOidsList, (PKIX_PL_Object *)ekuOid,
279 plContext),
280 PKIX_LISTAPPENDITEMFAILED);
281
282 PKIX_DECREF(ekuOid);
283 }
284
285 PKIX_CHECK(
286 cert_NssKeyUsagesToPkix(requiredKeyUsages, ppkixKU, plContext),
287 PKIX_NSSCERTIFICATEUSAGETOPKIXKUANDEKUFAILED);
288
289 *ppkixEKUList = ekuOidsList;
290 ekuOidsList = NULL;
291
292 cleanup:
293
294 PKIX_DECREF(ekuOid);
295 PKIX_DECREF(ekuOidsList);
296
297 PKIX_RETURN(CERTVFYPKIX);
298 }
299
300 #endif
301
302 /*
303 * FUNCTION: cert_ProcessingParamsSetKeyAndCertUsage
304 * DESCRIPTION:
305 *
306 * Converts cert usage to pkix KU type and sets
307 * converted data into PKIX_ProcessingParams object. It also sets
308 * proper cert usage into nsscontext object.
309 *
310 * PARAMETERS:
311 * "procParams"
312 * Pointer to PKIX_ProcessingParams used during validation.
313 * "requiredCertUsage"
314 * Required certificate usages the certificate and chain is built and
315 * validated for.
316 * "requiredKeyUsage"
317 * Request additional key usages the certificate should be validated for.
318 * "plContext"
319 * Platform-specific context pointer.
320 * THREAD SAFETY:
321 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
322 * RETURNS:
323 * Returns NULL if the function succeeds.
324 * Returns a Cert Verify Error if the function fails in an unrecoverable way.
325 * Returns a Fatal Error if the function fails in an unrecoverable way.
326 */
327 static PKIX_Error *
cert_ProcessingParamsSetKeyAndCertUsage(PKIX_ProcessingParams * procParams,SECCertUsage requiredCertUsage,PRUint32 requiredKeyUsages,void * plContext)328 cert_ProcessingParamsSetKeyAndCertUsage(
329 PKIX_ProcessingParams *procParams,
330 SECCertUsage requiredCertUsage,
331 PRUint32 requiredKeyUsages,
332 void *plContext)
333 {
334 PKIX_CertSelector *certSelector = NULL;
335 PKIX_ComCertSelParams *certSelParams = NULL;
336 PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext *)plContext;
337
338 PKIX_ENTER(CERTVFYPKIX, "cert_ProcessingParamsSetKeyAndCertUsage");
339 PKIX_NULLCHECK_TWO(procParams, nssContext);
340
341 PKIX_CHECK(
342 pkix_pl_NssContext_SetCertUsage(
343 ((SECCertificateUsage)1) << requiredCertUsage, nssContext),
344 PKIX_NSSCONTEXTSETCERTUSAGEFAILED);
345
346 if (requiredKeyUsages) {
347 PKIX_CHECK(
348 PKIX_ProcessingParams_GetTargetCertConstraints(procParams,
349 &certSelector, plContext),
350 PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);
351
352 PKIX_CHECK(
353 PKIX_CertSelector_GetCommonCertSelectorParams(certSelector,
354 &certSelParams, plContext),
355 PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);
356
357 PKIX_CHECK(
358 PKIX_ComCertSelParams_SetKeyUsage(certSelParams, requiredKeyUsages,
359 plContext),
360 PKIX_COMCERTSELPARAMSSETKEYUSAGEFAILED);
361 }
362 cleanup:
363 PKIX_DECREF(certSelector);
364 PKIX_DECREF(certSelParams);
365
366 PKIX_RETURN(CERTVFYPKIX);
367 }
368
369 /*
370 * Unused parameters:
371 *
372 * CERTCertList *initialChain,
373 * CERTCertStores certStores,
374 * CERTCertRevCheckers certRevCheckers,
375 * CERTCertChainCheckers certChainCheckers,
376 * SECItem *initPolicies,
377 * PRBool policyQualifierRejected,
378 * PRBool anyPolicyInhibited,
379 * PRBool reqExplicitPolicy,
380 * PRBool policyMappingInhibited,
381 * PKIX_CertSelector certConstraints,
382 */
383
384 /*
385 * FUNCTION: cert_CreatePkixProcessingParams
386 * DESCRIPTION:
387 *
388 * Creates and fills in PKIX_ProcessingParams structure to be used
389 * for certificate chain building.
390 *
391 * PARAMETERS:
392 * "cert"
393 * Pointer to the CERTCertificate: the leaf certificate of a chain.
394 * "time"
395 * Validity time.
396 * "wincx"
397 * Nss db password token.
398 * "useArena"
399 * Flags to use arena for data allocation during chain building process.
400 * "pprocParams"
401 * Address to return created processing parameters.
402 * "plContext"
403 * Platform-specific context pointer.
404 * THREAD SAFETY:
405 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
406 * RETURNS:
407 * Returns NULL if the function succeeds.
408 * Returns a Cert Verify Error if the function fails in an unrecoverable way.
409 * Returns a Fatal Error if the function fails in an unrecoverable way.
410 */
411 static PKIX_Error *
cert_CreatePkixProcessingParams(CERTCertificate * cert,PRBool checkSig,PRTime time,void * wincx,PRBool useArena,PRBool disableOCSPRemoteFetching,PKIX_ProcessingParams ** pprocParams,void ** pplContext)412 cert_CreatePkixProcessingParams(
413 CERTCertificate *cert,
414 PRBool checkSig,
415 PRTime time,
416 void *wincx,
417 PRBool useArena,
418 PRBool disableOCSPRemoteFetching,
419 PKIX_ProcessingParams **pprocParams,
420 void **pplContext)
421 {
422 PKIX_List *anchors = NULL;
423 PKIX_PL_Cert *targetCert = NULL;
424 PKIX_PL_Date *date = NULL;
425 PKIX_ProcessingParams *procParams = NULL;
426 PKIX_CertSelector *certSelector = NULL;
427 PKIX_ComCertSelParams *certSelParams = NULL;
428 PKIX_CertStore *certStore = NULL;
429 PKIX_List *certStores = NULL;
430 PKIX_RevocationChecker *revChecker = NULL;
431 PKIX_UInt32 methodFlags = 0;
432 void *plContext = NULL;
433 CERTStatusConfig *statusConfig = NULL;
434
435 PKIX_ENTER(CERTVFYPKIX, "cert_CreatePkixProcessingParams");
436 PKIX_NULLCHECK_TWO(cert, pprocParams);
437
438 PKIX_CHECK(
439 PKIX_PL_NssContext_Create(0, useArena, wincx, &plContext),
440 PKIX_NSSCONTEXTCREATEFAILED);
441
442 *pplContext = plContext;
443
444 /* Functions should be implemented in patch for 390532 */
445 PKIX_CHECK(
446 pkix_pl_NssContext_SetCertSignatureCheck(checkSig,
447 (PKIX_PL_NssContext *)plContext),
448 PKIX_NSSCONTEXTSETCERTSIGNCHECKFAILED);
449
450 PKIX_CHECK(
451 PKIX_ProcessingParams_Create(&procParams, plContext),
452 PKIX_PROCESSINGPARAMSCREATEFAILED);
453
454 PKIX_CHECK(
455 PKIX_ComCertSelParams_Create(&certSelParams, plContext),
456 PKIX_COMCERTSELPARAMSCREATEFAILED);
457
458 PKIX_CHECK(
459 PKIX_PL_Cert_CreateFromCERTCertificate(cert, &targetCert, plContext),
460 PKIX_CERTCREATEWITHNSSCERTFAILED);
461
462 PKIX_CHECK(
463 PKIX_ComCertSelParams_SetCertificate(certSelParams,
464 targetCert, plContext),
465 PKIX_COMCERTSELPARAMSSETCERTIFICATEFAILED);
466
467 PKIX_CHECK(
468 PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext),
469 PKIX_COULDNOTCREATECERTSELECTOROBJECT);
470
471 PKIX_CHECK(
472 PKIX_CertSelector_SetCommonCertSelectorParams(certSelector,
473 certSelParams, plContext),
474 PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED);
475
476 PKIX_CHECK(
477 PKIX_ProcessingParams_SetTargetCertConstraints(procParams,
478 certSelector, plContext),
479 PKIX_PROCESSINGPARAMSSETTARGETCERTCONSTRAINTSFAILED);
480
481 /* Turn off quialification of target cert since leaf cert is
482 * already check for date validity, key usages and extended
483 * key usages. */
484 PKIX_CHECK(
485 PKIX_ProcessingParams_SetQualifyTargetCert(procParams, PKIX_FALSE,
486 plContext),
487 PKIX_PROCESSINGPARAMSSETQUALIFYTARGETCERTFLAGFAILED);
488
489 PKIX_CHECK(
490 PKIX_PL_Pk11CertStore_Create(&certStore, plContext),
491 PKIX_PK11CERTSTORECREATEFAILED);
492
493 PKIX_CHECK(
494 PKIX_List_Create(&certStores, plContext),
495 PKIX_UNABLETOCREATELIST);
496
497 PKIX_CHECK(
498 PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore,
499 plContext),
500 PKIX_LISTAPPENDITEMFAILED);
501
502 PKIX_CHECK(
503 PKIX_ProcessingParams_SetCertStores(procParams, certStores,
504 plContext),
505 PKIX_PROCESSINGPARAMSADDCERTSTOREFAILED);
506
507 PKIX_CHECK(
508 PKIX_PL_Date_CreateFromPRTime(time, &date, plContext),
509 PKIX_DATECREATEFROMPRTIMEFAILED);
510
511 PKIX_CHECK(
512 PKIX_ProcessingParams_SetDate(procParams, date, plContext),
513 PKIX_PROCESSINGPARAMSSETDATEFAILED);
514
515 PKIX_CHECK(
516 PKIX_RevocationChecker_Create(
517 PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST |
518 PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT,
519 PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST |
520 PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT,
521 &revChecker, plContext),
522 PKIX_REVOCATIONCHECKERCREATEFAILED);
523
524 PKIX_CHECK(
525 PKIX_ProcessingParams_SetRevocationChecker(procParams, revChecker,
526 plContext),
527 PKIX_PROCESSINGPARAMSSETREVOCATIONCHECKERFAILED);
528
529 /* CRL method flags */
530 methodFlags =
531 PKIX_REV_M_TEST_USING_THIS_METHOD |
532 PKIX_REV_M_FORBID_NETWORK_FETCHING |
533 PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE | /* 0 */
534 PKIX_REV_M_IGNORE_MISSING_FRESH_INFO | /* 0 */
535 PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO;
536
537 /* add CRL revocation method to check the leaf certificate */
538 PKIX_CHECK(
539 PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
540 PKIX_RevocationMethod_CRL, methodFlags,
541 0, NULL, PKIX_TRUE, plContext),
542 PKIX_REVOCATIONCHECKERADDMETHODFAILED);
543
544 /* add CRL revocation method for other certs in the chain. */
545 PKIX_CHECK(
546 PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
547 PKIX_RevocationMethod_CRL, methodFlags,
548 0, NULL, PKIX_FALSE, plContext),
549 PKIX_REVOCATIONCHECKERADDMETHODFAILED);
550
551 /* For compatibility with the old code, need to check that
552 * statusConfig is set in the db handle and status checker
553 * is defined befor allow ocsp status check on the leaf cert.*/
554 statusConfig = CERT_GetStatusConfig(CERT_GetDefaultCertDB());
555 if (statusConfig != NULL && statusConfig->statusChecker != NULL) {
556
557 /* Enable OCSP revocation checking for the leaf cert. */
558 /* OCSP method flags */
559 methodFlags =
560 PKIX_REV_M_TEST_USING_THIS_METHOD |
561 PKIX_REV_M_ALLOW_NETWORK_FETCHING | /* 0 */
562 PKIX_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE | /* 0 */
563 PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE | /* 0 */
564 PKIX_REV_M_IGNORE_MISSING_FRESH_INFO | /* 0 */
565 PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO;
566
567 /* Disabling ocsp fetching when checking the status
568 * of ocsp response signer. Here and in the next if,
569 * adjust flags for ocsp signer cert validation case. */
570 if (disableOCSPRemoteFetching) {
571 methodFlags |= PKIX_REV_M_FORBID_NETWORK_FETCHING;
572 }
573
574 if (ocsp_FetchingFailureIsVerificationFailure() &&
575 !disableOCSPRemoteFetching) {
576 methodFlags |=
577 PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO;
578 }
579
580 /* add OCSP revocation method to check only the leaf certificate.*/
581 PKIX_CHECK(
582 PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
583 PKIX_RevocationMethod_OCSP, methodFlags,
584 1, NULL, PKIX_TRUE, plContext),
585 PKIX_REVOCATIONCHECKERADDMETHODFAILED);
586 }
587
588 PKIX_CHECK(
589 PKIX_ProcessingParams_SetAnyPolicyInhibited(procParams, PR_FALSE,
590 plContext),
591 PKIX_PROCESSINGPARAMSSETANYPOLICYINHIBITED);
592
593 PKIX_CHECK(
594 PKIX_ProcessingParams_SetExplicitPolicyRequired(procParams, PR_FALSE,
595 plContext),
596 PKIX_PROCESSINGPARAMSSETEXPLICITPOLICYREQUIRED);
597
598 PKIX_CHECK(
599 PKIX_ProcessingParams_SetPolicyMappingInhibited(procParams, PR_FALSE,
600 plContext),
601 PKIX_PROCESSINGPARAMSSETPOLICYMAPPINGINHIBITED);
602
603 *pprocParams = procParams;
604 procParams = NULL;
605
606 cleanup:
607 PKIX_DECREF(anchors);
608 PKIX_DECREF(targetCert);
609 PKIX_DECREF(date);
610 PKIX_DECREF(certSelector);
611 PKIX_DECREF(certSelParams);
612 PKIX_DECREF(certStore);
613 PKIX_DECREF(certStores);
614 PKIX_DECREF(procParams);
615 PKIX_DECREF(revChecker);
616
617 PKIX_RETURN(CERTVFYPKIX);
618 }
619
620 /*
621 * FUNCTION: cert_PkixToNssCertsChain
622 * DESCRIPTION:
623 *
624 * Converts pkix cert list into nss cert list.
625 *
626 * PARAMETERS:
627 * "pkixCertChain"
628 * Pkix certificate list.
629 * "pvalidChain"
630 * An address of returned nss certificate list.
631 * "plContext"
632 * Platform-specific context pointer.
633 * THREAD SAFETY:
634 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
635 * RETURNS:
636 * Returns NULL if the function succeeds.
637 * Returns a Cert Verify Error if the function fails in an unrecoverable way.
638 * Returns a Fatal Error if the function fails in an unrecoverable way.
639 */
640 static PKIX_Error *
cert_PkixToNssCertsChain(PKIX_List * pkixCertChain,CERTCertList ** pvalidChain,void * plContext)641 cert_PkixToNssCertsChain(
642 PKIX_List *pkixCertChain,
643 CERTCertList **pvalidChain,
644 void *plContext)
645 {
646 PLArenaPool *arena = NULL;
647 CERTCertificate *nssCert = NULL;
648 CERTCertList *validChain = NULL;
649 PKIX_PL_Object *certItem = NULL;
650 PKIX_UInt32 length = 0;
651 PKIX_UInt32 i = 0;
652
653 PKIX_ENTER(CERTVFYPKIX, "cert_PkixToNssCertsChain");
654 PKIX_NULLCHECK_ONE(pvalidChain);
655
656 if (pkixCertChain == NULL) {
657 goto cleanup;
658 }
659 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
660 if (arena == NULL) {
661 PKIX_ERROR(PKIX_OUTOFMEMORY);
662 }
663 validChain = (CERTCertList *)PORT_ArenaZAlloc(arena, sizeof(CERTCertList));
664 if (validChain == NULL) {
665 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
666 }
667 PR_INIT_CLIST(&validChain->list);
668 validChain->arena = arena;
669 arena = NULL;
670
671 PKIX_CHECK(
672 PKIX_List_GetLength(pkixCertChain, &length, plContext),
673 PKIX_LISTGETLENGTHFAILED);
674
675 for (i = 0; i < length; i++) {
676 CERTCertListNode *node = NULL;
677
678 PKIX_CHECK(
679 PKIX_List_GetItem(pkixCertChain, i, &certItem, plContext),
680 PKIX_LISTGETITEMFAILED);
681
682 PKIX_CHECK(
683 PKIX_PL_Cert_GetCERTCertificate((PKIX_PL_Cert *)certItem, &nssCert,
684 plContext),
685 PKIX_CERTGETCERTCERTIFICATEFAILED);
686
687 node =
688 (CERTCertListNode *)PORT_ArenaZAlloc(validChain->arena,
689 sizeof(CERTCertListNode));
690 if (node == NULL) {
691 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
692 }
693
694 PR_INSERT_BEFORE(&node->links, &validChain->list);
695
696 node->cert = nssCert;
697 nssCert = NULL;
698
699 PKIX_DECREF(certItem);
700 }
701
702 *pvalidChain = validChain;
703
704 cleanup:
705 if (PKIX_ERROR_RECEIVED) {
706 if (validChain) {
707 CERT_DestroyCertList(validChain);
708 } else if (arena) {
709 PORT_FreeArena(arena, PR_FALSE);
710 }
711 if (nssCert) {
712 CERT_DestroyCertificate(nssCert);
713 }
714 }
715 PKIX_DECREF(certItem);
716
717 PKIX_RETURN(CERTVFYPKIX);
718 }
719
720 /*
721 * FUNCTION: cert_BuildAndValidateChain
722 * DESCRIPTION:
723 *
724 * The function builds and validates a cert chain based on certificate
725 * selection criterias from procParams. This function call PKIX_BuildChain
726 * to accomplish chain building. If PKIX_BuildChain returns with incomplete
727 * IO, the function waits with PR_Poll until the blocking IO is finished and
728 * return control back to PKIX_BuildChain.
729 *
730 * PARAMETERS:
731 * "procParams"
732 * Processing parameters to be used during chain building.
733 * "pResult"
734 * Returned build result.
735 * "pVerifyNode"
736 * Returned pointed to verify node structure: the tree-like structure
737 * that reports points of chain building failures.
738 * "plContext"
739 * Platform-specific context pointer.
740 * THREAD SAFETY:
741 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
742 * RETURNS:
743 * Returns NULL if the function succeeds.
744 * Returns a Cert Verify Error if the function fails in an unrecoverable way.
745 * Returns a Fatal Error if the function fails in an unrecoverable way.
746 */
747 static PKIX_Error *
cert_BuildAndValidateChain(PKIX_ProcessingParams * procParams,PKIX_BuildResult ** pResult,PKIX_VerifyNode ** pVerifyNode,void * plContext)748 cert_BuildAndValidateChain(
749 PKIX_ProcessingParams *procParams,
750 PKIX_BuildResult **pResult,
751 PKIX_VerifyNode **pVerifyNode,
752 void *plContext)
753 {
754 PKIX_BuildResult *result = NULL;
755 PKIX_VerifyNode *verifyNode = NULL;
756 void *nbioContext = NULL;
757 void *state = NULL;
758
759 PKIX_ENTER(CERTVFYPKIX, "cert_BuildAndVerifyChain");
760 PKIX_NULLCHECK_TWO(procParams, pResult);
761
762 do {
763 if (nbioContext && state) {
764 /* PKIX-XXX: need to test functionality of NBIO handling in libPkix.
765 * See bug 391180 */
766 PRInt32 filesReady = 0;
767 PRPollDesc *pollDesc = (PRPollDesc *)nbioContext;
768 filesReady = PR_Poll(pollDesc, 1, PR_INTERVAL_NO_TIMEOUT);
769 if (filesReady <= 0) {
770 PKIX_ERROR(PKIX_PRPOLLRETBADFILENUM);
771 }
772 }
773
774 PKIX_CHECK(
775 PKIX_BuildChain(procParams, &nbioContext, &state,
776 &result, &verifyNode, plContext),
777 PKIX_UNABLETOBUILDCHAIN);
778
779 } while (nbioContext && state);
780
781 *pResult = result;
782
783 cleanup:
784 if (pVerifyNode) {
785 *pVerifyNode = verifyNode;
786 }
787
788 PKIX_RETURN(CERTVFYPKIX);
789 }
790
791 /*
792 * FUNCTION: cert_PkixErrorToNssCode
793 * DESCRIPTION:
794 *
795 * Converts pkix error(PKIX_Error) structure to PR error codes.
796 *
797 * PKIX-XXX to be implemented. See 391183.
798 *
799 * PARAMETERS:
800 * "error"
801 * Pkix error that will be converted.
802 * "nssCode"
803 * Corresponding nss error code.
804 * "plContext"
805 * Platform-specific context pointer.
806 * THREAD SAFETY:
807 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
808 * RETURNS:
809 * Returns NULL if the function succeeds.
810 * Returns a Cert Verify Error if the function fails in an unrecoverable way.
811 * Returns a Fatal Error if the function fails in an unrecoverable way.
812 */
813 static PKIX_Error *
cert_PkixErrorToNssCode(PKIX_Error * error,SECErrorCodes * pNssErr,void * plContext)814 cert_PkixErrorToNssCode(
815 PKIX_Error *error,
816 SECErrorCodes *pNssErr,
817 void *plContext)
818 {
819 int errLevel = 0;
820 (void)errLevel; /* Suppress unused var warning (Bug 1738028) */
821
822 PKIX_Int32 nssErr = 0;
823 PKIX_Error *errPtr = error;
824
825 PKIX_ENTER(CERTVFYPKIX, "cert_PkixErrorToNssCode");
826 PKIX_NULLCHECK_TWO(error, pNssErr);
827
828 /* Loop until we find at least one error with non-null
829 * plErr code, that is going to be nss error code. */
830 while (errPtr) {
831 if (errPtr->plErr && !nssErr) {
832 nssErr = errPtr->plErr;
833 if (!pkixLog)
834 break;
835 }
836 if (pkixLog) {
837 #ifdef PKIX_ERROR_DESCRIPTION
838 PR_LOG(pkixLog, 2, ("Error at level %d: %s\n", errLevel,
839 PKIX_ErrorText[errPtr->errCode]));
840 #else
841 PR_LOG(pkixLog, 2, ("Error at level %d: Error code %d\n", errLevel,
842 errPtr->errCode));
843 #endif /* PKIX_ERROR_DESCRIPTION */
844 }
845 errPtr = errPtr->cause;
846 errLevel += 1;
847 }
848 PORT_Assert(nssErr);
849 if (!nssErr) {
850 *pNssErr = SEC_ERROR_LIBPKIX_INTERNAL;
851 } else {
852 *pNssErr = nssErr;
853 }
854
855 PKIX_RETURN(CERTVFYPKIX);
856 }
857
858 /*
859 * FUNCTION: cert_GetLogFromVerifyNode
860 * DESCRIPTION:
861 *
862 * Recursive function that converts verify node tree-like set of structures
863 * to CERTVerifyLog.
864 *
865 * PARAMETERS:
866 * "log"
867 * Pointed to already allocated CERTVerifyLog structure.
868 * "node"
869 * A node of PKIX_VerifyNode tree.
870 * "plContext"
871 * Platform-specific context pointer.
872 * THREAD SAFETY:
873 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
874 * RETURNS:
875 * Returns NULL if the function succeeds.
876 * Returns a Cert Verify Error if the function fails in an unrecoverable way.
877 * Returns a Fatal Error if the function fails in an unrecoverable way.
878 */
879 static PKIX_Error *
cert_GetLogFromVerifyNode(CERTVerifyLog * log,PKIX_VerifyNode * node,void * plContext)880 cert_GetLogFromVerifyNode(
881 CERTVerifyLog *log,
882 PKIX_VerifyNode *node,
883 void *plContext)
884 {
885 PKIX_List *children = NULL;
886 PKIX_VerifyNode *childNode = NULL;
887
888 PKIX_ENTER(CERTVFYPKIX, "cert_GetLogFromVerifyNode");
889
890 children = node->children;
891
892 if (children == NULL) {
893 PKIX_ERRORCODE errCode = PKIX_ANCHORDIDNOTCHAINTOCERT;
894 if (node->error && node->error->errCode != errCode) {
895 if (log != NULL) {
896 SECErrorCodes nssErrorCode = 0;
897 CERTCertificate *cert = NULL;
898
899 cert = node->verifyCert->nssCert;
900
901 PKIX_CHECK(
902 cert_PkixErrorToNssCode(node->error, &nssErrorCode,
903 plContext),
904 PKIX_GETPKIXERRORCODEFAILED);
905
906 cert_AddToVerifyLog(log, cert, nssErrorCode, node->depth, NULL);
907 }
908 }
909 PKIX_RETURN(CERTVFYPKIX);
910 } else {
911 PRUint32 i = 0;
912 PKIX_UInt32 length = 0;
913
914 PKIX_CHECK(
915 PKIX_List_GetLength(children, &length, plContext),
916 PKIX_LISTGETLENGTHFAILED);
917
918 for (i = 0; i < length; i++) {
919
920 PKIX_CHECK(
921 PKIX_List_GetItem(children, i, (PKIX_PL_Object **)&childNode,
922 plContext),
923 PKIX_LISTGETITEMFAILED);
924
925 PKIX_CHECK(
926 cert_GetLogFromVerifyNode(log, childNode, plContext),
927 PKIX_ERRORINRECURSIVEEQUALSCALL);
928
929 PKIX_DECREF(childNode);
930 }
931 }
932
933 cleanup:
934 PKIX_DECREF(childNode);
935
936 PKIX_RETURN(CERTVFYPKIX);
937 }
938
939 /*
940 * FUNCTION: cert_GetBuildResults
941 * DESCRIPTION:
942 *
943 * Converts pkix build results to nss results. This function is called
944 * regardless of build result.
945 *
946 * If it called after chain was successfully constructed, then it will
947 * convert:
948 * * pkix cert list that represent the chain to nss cert list
949 * * trusted root the chain was anchored to nss certificate.
950 *
951 * In case of failure it will convert:
952 * * pkix error to PR error code(will set it with PORT_SetError)
953 * * pkix validation log to nss CERTVerifyLog
954 *
955 * PARAMETERS:
956 * "buildResult"
957 * Build results returned by PKIX_BuildChain.
958 * "verifyNode"
959 * Tree-like structure of chain building/validation failures
960 * returned by PKIX_BuildChain. Ignored in case of success.
961 * "error"
962 * Final error returned by PKIX_BuildChain. Should be NULL in
963 * case of success.
964 * "log"
965 * Address of pre-allocated(if not NULL) CERTVerifyLog structure.
966 * "ptrustedRoot"
967 * Address of returned trusted root the chain was anchored to.
968 * "pvalidChain"
969 * Address of returned valid chain.
970 * "plContext"
971 * Platform-specific context pointer.
972 * THREAD SAFETY:
973 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
974 * RETURNS:
975 * Returns NULL if the function succeeds.
976 * Returns a Cert Verify Error if the function fails in an unrecoverable way.
977 * Returns a Fatal Error if the function fails in an unrecoverable way.
978 */
979 static PKIX_Error *
cert_GetBuildResults(PKIX_BuildResult * buildResult,PKIX_VerifyNode * verifyNode,PKIX_Error * error,CERTVerifyLog * log,CERTCertificate ** ptrustedRoot,CERTCertList ** pvalidChain,void * plContext)980 cert_GetBuildResults(
981 PKIX_BuildResult *buildResult,
982 PKIX_VerifyNode *verifyNode,
983 PKIX_Error *error,
984 CERTVerifyLog *log,
985 CERTCertificate **ptrustedRoot,
986 CERTCertList **pvalidChain,
987 void *plContext)
988 {
989 PKIX_ValidateResult *validResult = NULL;
990 CERTCertList *validChain = NULL;
991 CERTCertificate *trustedRoot = NULL;
992 PKIX_TrustAnchor *trustAnchor = NULL;
993 PKIX_PL_Cert *trustedCert = NULL;
994 PKIX_List *pkixCertChain = NULL;
995
996 PKIX_ENTER(CERTVFYPKIX, "cert_GetBuildResults");
997 if (buildResult == NULL && error == NULL) {
998 PKIX_ERROR(PKIX_NULLARGUMENT);
999 }
1000
1001 if (error) {
1002 SECErrorCodes nssErrorCode = 0;
1003 if (verifyNode) {
1004 PKIX_Error *tmpError =
1005 cert_GetLogFromVerifyNode(log, verifyNode, plContext);
1006 if (tmpError) {
1007 PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext);
1008 }
1009 }
1010 cert_PkixErrorToNssCode(error, &nssErrorCode, plContext);
1011 PORT_SetError(nssErrorCode);
1012 goto cleanup;
1013 }
1014
1015 if (pvalidChain) {
1016 PKIX_CHECK(
1017 PKIX_BuildResult_GetCertChain(buildResult, &pkixCertChain,
1018 plContext),
1019 PKIX_BUILDRESULTGETCERTCHAINFAILED);
1020
1021 PKIX_CHECK(
1022 cert_PkixToNssCertsChain(pkixCertChain, &validChain, plContext),
1023 PKIX_CERTCHAINTONSSCHAINFAILED);
1024 }
1025
1026 if (ptrustedRoot) {
1027 PKIX_CHECK(
1028 PKIX_BuildResult_GetValidateResult(buildResult, &validResult,
1029 plContext),
1030 PKIX_BUILDRESULTGETVALIDATERESULTFAILED);
1031
1032 PKIX_CHECK(
1033 PKIX_ValidateResult_GetTrustAnchor(validResult, &trustAnchor,
1034 plContext),
1035 PKIX_VALIDATERESULTGETTRUSTANCHORFAILED);
1036
1037 PKIX_CHECK(
1038 PKIX_TrustAnchor_GetTrustedCert(trustAnchor, &trustedCert,
1039 plContext),
1040 PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);
1041
1042 PKIX_CHECK(
1043 PKIX_PL_Cert_GetCERTCertificate(trustedCert, &trustedRoot,
1044 plContext),
1045 PKIX_CERTGETCERTCERTIFICATEFAILED);
1046 }
1047
1048 PORT_Assert(!PKIX_ERROR_RECEIVED);
1049
1050 if (trustedRoot) {
1051 *ptrustedRoot = trustedRoot;
1052 }
1053 if (validChain) {
1054 *pvalidChain = validChain;
1055 }
1056
1057 cleanup:
1058 if (PKIX_ERROR_RECEIVED) {
1059 if (trustedRoot) {
1060 CERT_DestroyCertificate(trustedRoot);
1061 }
1062 if (validChain) {
1063 CERT_DestroyCertList(validChain);
1064 }
1065 }
1066 PKIX_DECREF(trustAnchor);
1067 PKIX_DECREF(trustedCert);
1068 PKIX_DECREF(pkixCertChain);
1069 PKIX_DECREF(validResult);
1070 PKIX_DECREF(error);
1071 PKIX_DECREF(verifyNode);
1072 PKIX_DECREF(buildResult);
1073
1074 PKIX_RETURN(CERTVFYPKIX);
1075 }
1076 #endif /* NSS_DISABLE_LIBPKIX */
1077
1078 /*
1079 * FUNCTION: cert_VerifyCertChainPkix
1080 * DESCRIPTION:
1081 *
1082 * The main wrapper function that is called from CERT_VerifyCert and
1083 * CERT_VerifyCACertForUsage functions to validate cert with libpkix.
1084 *
1085 * PARAMETERS:
1086 * "cert"
1087 * Leaf certificate of a chain we want to build.
1088 * "checkSig"
1089 * Certificate signatures will not be verified if this
1090 * flag is set to PR_FALSE.
1091 * "requiredUsage"
1092 * Required usage for certificate and chain.
1093 * "time"
1094 * Validity time.
1095 * "wincx"
1096 * Nss database password token.
1097 * "log"
1098 * Address of already allocated CERTVerifyLog structure. Not
1099 * used if NULL;
1100 * "pSigerror"
1101 * Address of PRBool. If not NULL, returns true is cert chain
1102 * was invalidated because of bad certificate signature.
1103 * "pRevoked"
1104 * Address of PRBool. If not NULL, returns true is cert chain
1105 * was invalidated because a revoked certificate was found in
1106 * the chain.
1107 * THREAD SAFETY:
1108 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1109 * RETURNS:
1110 * SECFailure is chain building process has failed. SECSuccess otherwise.
1111 */
1112 SECStatus
cert_VerifyCertChainPkix(CERTCertificate * cert,PRBool checkSig,SECCertUsage requiredUsage,PRTime time,void * wincx,CERTVerifyLog * log,PRBool * pSigerror,PRBool * pRevoked)1113 cert_VerifyCertChainPkix(
1114 CERTCertificate *cert,
1115 PRBool checkSig,
1116 SECCertUsage requiredUsage,
1117 PRTime time,
1118 void *wincx,
1119 CERTVerifyLog *log,
1120 PRBool *pSigerror,
1121 PRBool *pRevoked)
1122 {
1123 #ifdef NSS_DISABLE_LIBPKIX
1124 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1125 return SECFailure;
1126 #else
1127 PKIX_ProcessingParams *procParams = NULL;
1128 PKIX_BuildResult *result = NULL;
1129 PKIX_VerifyNode *verifyNode = NULL;
1130 PKIX_Error *error = NULL;
1131
1132 SECStatus rv = SECFailure;
1133 void *plContext = NULL;
1134
1135 #ifdef PKIX_OBJECT_LEAK_TEST
1136 int leakedObjNum = 0;
1137 int memLeakLoopCount = 0;
1138 int objCountTable[PKIX_NUMTYPES];
1139 int fnInvLocalCount = 0;
1140 PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine;
1141
1142 if (usePKIXValidationEngine) {
1143 /* current memory leak testing implementation does not allow
1144 * to run simultaneous tests one the same or a different threads.
1145 * Setting the variable to false, to make additional chain
1146 * validations be handled by old nss. */
1147 usePKIXValidationEngine = PR_FALSE;
1148 }
1149 testStartFnStackPosition = 2;
1150 fnStackNameArr[0] = "cert_VerifyCertChainPkix";
1151 fnStackInvCountArr[0] = 0;
1152 PKIX_Boolean abortOnLeak =
1153 (PR_GetEnvSecure("PKIX_OBJECT_LEAK_TEST_ABORT_ON_LEAK") == NULL) ? PKIX_FALSE
1154 : PKIX_TRUE;
1155 runningLeakTest = PKIX_TRUE;
1156
1157 /* Prevent multi-threaded run of object leak test */
1158 fnInvLocalCount = PR_ATOMIC_INCREMENT(¶llelFnInvocationCount);
1159 PORT_Assert(fnInvLocalCount == 1);
1160
1161 do {
1162 rv = SECFailure;
1163 plContext = NULL;
1164 procParams = NULL;
1165 result = NULL;
1166 verifyNode = NULL;
1167 error = NULL;
1168 errorGenerated = PKIX_FALSE;
1169 stackPosition = 0;
1170
1171 if (leakedObjNum) {
1172 pkix_pl_lifecycle_ObjectTableUpdate(objCountTable);
1173 }
1174 memLeakLoopCount += 1;
1175 #endif /* PKIX_OBJECT_LEAK_TEST */
1176
1177 error =
1178 cert_CreatePkixProcessingParams(cert, checkSig, time, wincx,
1179 PR_FALSE /*use arena*/,
1180 requiredUsage == certUsageStatusResponder,
1181 &procParams, &plContext);
1182 if (error) {
1183 goto cleanup;
1184 }
1185
1186 error =
1187 cert_ProcessingParamsSetKeyAndCertUsage(procParams, requiredUsage, 0,
1188 plContext);
1189 if (error) {
1190 goto cleanup;
1191 }
1192
1193 error =
1194 cert_BuildAndValidateChain(procParams, &result, &verifyNode, plContext);
1195 if (error) {
1196 goto cleanup;
1197 }
1198
1199 if (pRevoked) {
1200 /* Currently always PR_FALSE. Will be fixed as a part of 394077 */
1201 *pRevoked = PR_FALSE;
1202 }
1203 if (pSigerror) {
1204 /* Currently always PR_FALSE. Will be fixed as a part of 394077 */
1205 *pSigerror = PR_FALSE;
1206 }
1207 rv = SECSuccess;
1208
1209 cleanup:
1210 error = cert_GetBuildResults(result, verifyNode, error, log, NULL, NULL,
1211 plContext);
1212 if (error) {
1213 PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
1214 }
1215 if (procParams) {
1216 PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext);
1217 }
1218 if (plContext) {
1219 PKIX_PL_NssContext_Destroy(plContext);
1220 }
1221
1222 #ifdef PKIX_OBJECT_LEAK_TEST
1223 leakedObjNum =
1224 pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL);
1225
1226 if (pkixLog && leakedObjNum) {
1227 PR_LOG(pkixLog, 1, ("The generated error caused an object leaks. Loop %d."
1228 "Stack %s\n",
1229 memLeakLoopCount, errorFnStackString));
1230 }
1231 PR_Free(errorFnStackString);
1232 errorFnStackString = NULL;
1233 if (abortOnLeak) {
1234 PORT_Assert(leakedObjNum == 0);
1235 }
1236
1237 } while (errorGenerated);
1238
1239 runningLeakTest = PKIX_FALSE;
1240 PR_ATOMIC_DECREMENT(¶llelFnInvocationCount);
1241 usePKIXValidationEngine = savedUsePkixEngFlag;
1242 #endif /* PKIX_OBJECT_LEAK_TEST */
1243
1244 return rv;
1245 #endif /* NSS_DISABLE_LIBPKIX */
1246 }
1247
1248 #ifndef NSS_DISABLE_LIBPKIX
1249 PKIX_CertSelector *
cert_GetTargetCertConstraints(CERTCertificate * target,void * plContext)1250 cert_GetTargetCertConstraints(CERTCertificate *target, void *plContext)
1251 {
1252 PKIX_ComCertSelParams *certSelParams = NULL;
1253 PKIX_CertSelector *certSelector = NULL;
1254 PKIX_CertSelector *r = NULL;
1255 PKIX_PL_Cert *eeCert = NULL;
1256 PKIX_Error *error = NULL;
1257
1258 error = PKIX_PL_Cert_CreateFromCERTCertificate(target, &eeCert, plContext);
1259 if (error != NULL)
1260 goto cleanup;
1261
1262 error = PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext);
1263 if (error != NULL)
1264 goto cleanup;
1265
1266 error = PKIX_ComCertSelParams_Create(&certSelParams, plContext);
1267 if (error != NULL)
1268 goto cleanup;
1269
1270 error = PKIX_ComCertSelParams_SetCertificate(
1271 certSelParams, eeCert, plContext);
1272 if (error != NULL)
1273 goto cleanup;
1274
1275 error = PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext);
1276 if (error != NULL)
1277 goto cleanup;
1278
1279 error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certSelector, plContext);
1280 if (error == NULL)
1281 r = certSelector;
1282
1283 cleanup:
1284 if (certSelParams != NULL)
1285 PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelParams, plContext);
1286
1287 if (eeCert != NULL)
1288 PKIX_PL_Object_DecRef((PKIX_PL_Object *)eeCert, plContext);
1289
1290 if (certSelector != NULL)
1291 PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext);
1292
1293 if (error != NULL) {
1294 SECErrorCodes nssErr;
1295
1296 cert_PkixErrorToNssCode(error, &nssErr, plContext);
1297 PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
1298 PORT_SetError(nssErr);
1299 }
1300
1301 return r;
1302 }
1303
1304 static PKIX_List *
cert_GetCertStores(void * plContext)1305 cert_GetCertStores(void *plContext)
1306 {
1307 PKIX_CertStore *certStore = NULL;
1308 PKIX_List *certStores = NULL;
1309 PKIX_List *r = NULL;
1310 PKIX_Error *error = NULL;
1311
1312 error = PKIX_PL_Pk11CertStore_Create(&certStore, plContext);
1313 if (error != NULL)
1314 goto cleanup;
1315
1316 error = PKIX_List_Create(&certStores, plContext);
1317 if (error != NULL)
1318 goto cleanup;
1319
1320 error = PKIX_List_AppendItem(certStores,
1321 (PKIX_PL_Object *)certStore, plContext);
1322 if (error != NULL)
1323 goto cleanup;
1324
1325 error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certStores, plContext);
1326 if (error == NULL)
1327 r = certStores;
1328
1329 cleanup:
1330 if (certStores != NULL)
1331 PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext);
1332
1333 if (certStore != NULL)
1334 PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStore, plContext);
1335
1336 if (error != NULL) {
1337 SECErrorCodes nssErr;
1338
1339 cert_PkixErrorToNssCode(error, &nssErr, plContext);
1340 PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
1341 PORT_SetError(nssErr);
1342 }
1343
1344 return r;
1345 }
1346
1347 struct fake_PKIX_PL_CertStruct {
1348 CERTCertificate *nssCert;
1349 };
1350
1351 /* This needs to be part of the PKIX_PL_* */
1352 /* This definitely needs to go away, and be replaced with
1353 a real accessor function in PKIX */
1354 static CERTCertificate *
cert_NSSCertFromPKIXCert(const PKIX_PL_Cert * pkix_cert)1355 cert_NSSCertFromPKIXCert(const PKIX_PL_Cert *pkix_cert)
1356 {
1357 struct fake_PKIX_PL_CertStruct *fcert = NULL;
1358
1359 fcert = (struct fake_PKIX_PL_CertStruct *)pkix_cert;
1360
1361 return CERT_DupCertificate(fcert->nssCert);
1362 }
1363
1364 PKIX_List *
cert_PKIXMakeOIDList(const SECOidTag * oids,int oidCount,void * plContext)1365 cert_PKIXMakeOIDList(const SECOidTag *oids, int oidCount, void *plContext)
1366 {
1367 PKIX_List *r = NULL;
1368 PKIX_List *policyList = NULL;
1369 PKIX_PL_OID *policyOID = NULL;
1370 PKIX_Error *error = NULL;
1371 int i;
1372
1373 error = PKIX_List_Create(&policyList, plContext);
1374 if (error != NULL) {
1375 goto cleanup;
1376 }
1377
1378 for (i = 0; i < oidCount; i++) {
1379 error = PKIX_PL_OID_Create(oids[i], &policyOID, plContext);
1380 if (error) {
1381 goto cleanup;
1382 }
1383 error = PKIX_List_AppendItem(policyList,
1384 (PKIX_PL_Object *)policyOID, plContext);
1385 if (error != NULL) {
1386 goto cleanup;
1387 }
1388 PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext);
1389 policyOID = NULL;
1390 }
1391
1392 error = PKIX_List_SetImmutable(policyList, plContext);
1393 if (error != NULL)
1394 goto cleanup;
1395
1396 error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)policyList, plContext);
1397 if (error == NULL)
1398 r = policyList;
1399
1400 cleanup:
1401 if (policyOID != NULL) {
1402 PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext);
1403 }
1404 if (policyList != NULL) {
1405 PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyList, plContext);
1406 }
1407 if (error != NULL) {
1408 PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
1409 }
1410
1411 return r;
1412 }
1413
1414 CERTValOutParam *
cert_pkix_FindOutputParam(CERTValOutParam * params,const CERTValParamOutType t)1415 cert_pkix_FindOutputParam(CERTValOutParam *params, const CERTValParamOutType t)
1416 {
1417 CERTValOutParam *i;
1418 if (params == NULL) {
1419 return NULL;
1420 }
1421 for (i = params; i->type != cert_po_end; i++) {
1422 if (i->type == t) {
1423 return i;
1424 }
1425 }
1426 return NULL;
1427 }
1428
1429 static PKIX_Error *
setRevocationMethod(PKIX_RevocationChecker * revChecker,PKIX_ProcessingParams * procParams,const CERTRevocationTests * revTest,CERTRevocationMethodIndex certRevMethod,PKIX_RevocationMethodType pkixRevMethod,PKIX_Boolean verifyResponderUsages,PKIX_Boolean isLeafTest,void * plContext)1430 setRevocationMethod(PKIX_RevocationChecker *revChecker,
1431 PKIX_ProcessingParams *procParams,
1432 const CERTRevocationTests *revTest,
1433 CERTRevocationMethodIndex certRevMethod,
1434 PKIX_RevocationMethodType pkixRevMethod,
1435 PKIX_Boolean verifyResponderUsages,
1436 PKIX_Boolean isLeafTest,
1437 void *plContext)
1438 {
1439 PKIX_UInt32 methodFlags = 0;
1440 PKIX_Error *error = NULL;
1441 PKIX_UInt32 priority = 0;
1442
1443 if (revTest->number_of_defined_methods <= (PRUint32)certRevMethod) {
1444 return NULL;
1445 }
1446 if (revTest->preferred_methods) {
1447 unsigned int i = 0;
1448 for (; i < revTest->number_of_preferred_methods; i++) {
1449 if (revTest->preferred_methods[i] == certRevMethod)
1450 break;
1451 }
1452 priority = i;
1453 }
1454 methodFlags = revTest->cert_rev_flags_per_method[certRevMethod];
1455 if (verifyResponderUsages &&
1456 pkixRevMethod == PKIX_RevocationMethod_OCSP) {
1457 methodFlags |= PKIX_REV_M_FORBID_NETWORK_FETCHING;
1458 }
1459 error =
1460 PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
1461 pkixRevMethod, methodFlags,
1462 priority, NULL,
1463 isLeafTest, plContext);
1464 return error;
1465 }
1466
1467 SECStatus
cert_pkixSetParam(PKIX_ProcessingParams * procParams,const CERTValInParam * param,void * plContext)1468 cert_pkixSetParam(PKIX_ProcessingParams *procParams,
1469 const CERTValInParam *param, void *plContext)
1470 {
1471 PKIX_Error *error = NULL;
1472 SECStatus r = SECSuccess;
1473 PKIX_PL_Date *date = NULL;
1474 PKIX_List *policyOIDList = NULL;
1475 PKIX_List *certListPkix = NULL;
1476 const CERTRevocationFlags *flags;
1477 SECErrorCodes errCode = SEC_ERROR_INVALID_ARGS;
1478 const CERTCertList *certList = NULL;
1479 CERTCertListNode *node;
1480 PKIX_PL_Cert *certPkix = NULL;
1481 PKIX_TrustAnchor *trustAnchor = NULL;
1482 PKIX_RevocationChecker *revChecker = NULL;
1483 PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext *)plContext;
1484
1485 /* XXX we need a way to map generic PKIX error to generic NSS errors */
1486
1487 switch (param->type) {
1488
1489 case cert_pi_policyOID:
1490
1491 /* needed? */
1492 error = PKIX_ProcessingParams_SetExplicitPolicyRequired(
1493 procParams, PKIX_TRUE, plContext);
1494
1495 if (error != NULL) {
1496 break;
1497 }
1498
1499 policyOIDList = cert_PKIXMakeOIDList(param->value.array.oids,
1500 param->value.arraySize, plContext);
1501 if (policyOIDList == NULL) {
1502 r = SECFailure;
1503 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1504 break;
1505 }
1506
1507 error = PKIX_ProcessingParams_SetInitialPolicies(
1508 procParams, policyOIDList, plContext);
1509 break;
1510
1511 case cert_pi_date:
1512 if (param->value.scalar.time == 0) {
1513 error = PKIX_PL_Date_Create_UTCTime(NULL, &date, plContext);
1514 if (error != NULL) {
1515 errCode = SEC_ERROR_INVALID_TIME;
1516 break;
1517 }
1518 } else {
1519 error = pkix_pl_Date_CreateFromPRTime(param->value.scalar.time,
1520 &date, plContext);
1521 if (error != NULL) {
1522 errCode = SEC_ERROR_INVALID_TIME;
1523 break;
1524 }
1525 }
1526
1527 error = PKIX_ProcessingParams_SetDate(procParams, date, plContext);
1528 if (error != NULL) {
1529 errCode = SEC_ERROR_INVALID_TIME;
1530 }
1531 break;
1532
1533 case cert_pi_revocationFlags: {
1534 PKIX_UInt32 leafIMFlags = 0;
1535 PKIX_UInt32 chainIMFlags = 0;
1536 PKIX_Boolean validatingResponderCert = PKIX_FALSE;
1537
1538 flags = param->value.pointer.revocation;
1539 if (!flags) {
1540 PORT_SetError(errCode);
1541 r = SECFailure;
1542 break;
1543 }
1544
1545 leafIMFlags =
1546 flags->leafTests.cert_rev_method_independent_flags;
1547 chainIMFlags =
1548 flags->chainTests.cert_rev_method_independent_flags;
1549
1550 error =
1551 PKIX_RevocationChecker_Create(leafIMFlags, chainIMFlags,
1552 &revChecker, plContext);
1553 if (error) {
1554 break;
1555 }
1556
1557 error =
1558 PKIX_ProcessingParams_SetRevocationChecker(procParams,
1559 revChecker, plContext);
1560 if (error) {
1561 break;
1562 }
1563
1564 if (((PKIX_PL_NssContext *)plContext)->certificateUsage &
1565 certificateUsageStatusResponder) {
1566 validatingResponderCert = PKIX_TRUE;
1567 }
1568
1569 error = setRevocationMethod(revChecker,
1570 procParams, &flags->leafTests,
1571 cert_revocation_method_crl,
1572 PKIX_RevocationMethod_CRL,
1573 validatingResponderCert,
1574 PKIX_TRUE, plContext);
1575 if (error) {
1576 break;
1577 }
1578
1579 error = setRevocationMethod(revChecker,
1580 procParams, &flags->leafTests,
1581 cert_revocation_method_ocsp,
1582 PKIX_RevocationMethod_OCSP,
1583 validatingResponderCert,
1584 PKIX_TRUE, plContext);
1585 if (error) {
1586 break;
1587 }
1588
1589 error = setRevocationMethod(revChecker,
1590 procParams, &flags->chainTests,
1591 cert_revocation_method_crl,
1592 PKIX_RevocationMethod_CRL,
1593 validatingResponderCert,
1594 PKIX_FALSE, plContext);
1595 if (error) {
1596 break;
1597 }
1598
1599 error = setRevocationMethod(revChecker,
1600 procParams, &flags->chainTests,
1601 cert_revocation_method_ocsp,
1602 PKIX_RevocationMethod_OCSP,
1603 validatingResponderCert,
1604 PKIX_FALSE, plContext);
1605 if (error) {
1606 break;
1607 }
1608
1609 } break;
1610
1611 case cert_pi_trustAnchors:
1612 certList = param->value.pointer.chain;
1613 if (!certList) {
1614 PORT_SetError(errCode);
1615 r = SECFailure;
1616 break;
1617 }
1618 error = PKIX_List_Create(&certListPkix, plContext);
1619 if (error != NULL) {
1620 break;
1621 }
1622 for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList);
1623 node = CERT_LIST_NEXT(node)) {
1624 error = PKIX_PL_Cert_CreateFromCERTCertificate(node->cert,
1625 &certPkix, plContext);
1626 if (error) {
1627 break;
1628 }
1629 error = PKIX_TrustAnchor_CreateWithCert(certPkix, &trustAnchor,
1630 plContext);
1631 if (error) {
1632 break;
1633 }
1634 error = PKIX_List_AppendItem(certListPkix,
1635 (PKIX_PL_Object *)trustAnchor, plContext);
1636 if (error) {
1637 break;
1638 }
1639 PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);
1640 trustAnchor = NULL;
1641 PKIX_PL_Object_DecRef((PKIX_PL_Object *)certPkix, plContext);
1642 certPkix = NULL;
1643 }
1644 error =
1645 PKIX_ProcessingParams_SetTrustAnchors(procParams, certListPkix,
1646 plContext);
1647 break;
1648
1649 case cert_pi_useAIACertFetch:
1650 error =
1651 PKIX_ProcessingParams_SetUseAIAForCertFetching(procParams,
1652 (PRBool)(param->value.scalar.b !=
1653 0),
1654 plContext);
1655 break;
1656
1657 case cert_pi_chainVerifyCallback: {
1658 const CERTChainVerifyCallback *chainVerifyCallback =
1659 param->value.pointer.chainVerifyCallback;
1660 if (!chainVerifyCallback || !chainVerifyCallback->isChainValid) {
1661 PORT_SetError(errCode);
1662 r = SECFailure;
1663 break;
1664 }
1665
1666 nssContext->chainVerifyCallback = *chainVerifyCallback;
1667 } break;
1668
1669 case cert_pi_useOnlyTrustAnchors:
1670 error =
1671 PKIX_ProcessingParams_SetUseOnlyTrustAnchors(procParams,
1672 (PRBool)(param->value.scalar.b !=
1673 0),
1674 plContext);
1675 break;
1676
1677 default:
1678 PORT_SetError(errCode);
1679 r = SECFailure;
1680 break;
1681 }
1682
1683 if (policyOIDList != NULL)
1684 PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOIDList, plContext);
1685
1686 if (date != NULL)
1687 PKIX_PL_Object_DecRef((PKIX_PL_Object *)date, plContext);
1688
1689 if (revChecker != NULL)
1690 PKIX_PL_Object_DecRef((PKIX_PL_Object *)revChecker, plContext);
1691
1692 if (certListPkix)
1693 PKIX_PL_Object_DecRef((PKIX_PL_Object *)certListPkix, plContext);
1694
1695 if (trustAnchor)
1696 PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);
1697
1698 if (certPkix)
1699 PKIX_PL_Object_DecRef((PKIX_PL_Object *)certPkix, plContext);
1700
1701 if (error != NULL) {
1702 PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
1703 PORT_SetError(errCode);
1704 r = SECFailure;
1705 }
1706
1707 return r;
1708 }
1709
1710 void
cert_pkixDestroyValOutParam(CERTValOutParam * params)1711 cert_pkixDestroyValOutParam(CERTValOutParam *params)
1712 {
1713 CERTValOutParam *i;
1714
1715 if (params == NULL) {
1716 return;
1717 }
1718 for (i = params; i->type != cert_po_end; i++) {
1719 switch (i->type) {
1720 case cert_po_trustAnchor:
1721 if (i->value.pointer.cert) {
1722 CERT_DestroyCertificate(i->value.pointer.cert);
1723 i->value.pointer.cert = NULL;
1724 }
1725 break;
1726
1727 case cert_po_certList:
1728 if (i->value.pointer.chain) {
1729 CERT_DestroyCertList(i->value.pointer.chain);
1730 i->value.pointer.chain = NULL;
1731 }
1732 break;
1733
1734 default:
1735 break;
1736 }
1737 }
1738 }
1739
1740 static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_LeafFlags[2] = {
1741 /* crl */
1742 CERT_REV_M_TEST_USING_THIS_METHOD |
1743 CERT_REV_M_FORBID_NETWORK_FETCHING |
1744 CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
1745 /* ocsp */
1746 CERT_REV_M_TEST_USING_THIS_METHOD
1747 };
1748
1749 static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_ChainFlags[2] = {
1750 /* crl */
1751 CERT_REV_M_TEST_USING_THIS_METHOD |
1752 CERT_REV_M_FORBID_NETWORK_FETCHING |
1753 CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
1754 /* ocsp */
1755 0
1756 };
1757
1758 static CERTRevocationMethodIndex
1759 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_Method_Preference = {
1760 cert_revocation_method_crl
1761 };
1762
1763 static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy = {
1764 { /* leafTests */
1765 2,
1766 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_LeafFlags,
1767 1,
1768 &certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_Method_Preference,
1769 0 },
1770 { /* chainTests */
1771 2,
1772 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_ChainFlags,
1773 0,
1774 0,
1775 0 }
1776 };
1777 #endif /* NSS_DISABLE_LIBPKIX */
1778
1779 extern const CERTRevocationFlags *
CERT_GetClassicOCSPEnabledSoftFailurePolicy()1780 CERT_GetClassicOCSPEnabledSoftFailurePolicy()
1781 {
1782 #ifdef NSS_DISABLE_LIBPKIX
1783 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1784 return NULL;
1785 #else
1786 return &certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy;
1787 #endif /* NSS_DISABLE_LIBPKIX */
1788 }
1789
1790 #ifndef NSS_DISABLE_LIBPKIX
1791 static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_LeafFlags[2] = {
1792 /* crl */
1793 CERT_REV_M_TEST_USING_THIS_METHOD |
1794 CERT_REV_M_FORBID_NETWORK_FETCHING |
1795 CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
1796 /* ocsp */
1797 CERT_REV_M_TEST_USING_THIS_METHOD |
1798 CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO
1799 };
1800
1801 static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_ChainFlags[2] = {
1802 /* crl */
1803 CERT_REV_M_TEST_USING_THIS_METHOD |
1804 CERT_REV_M_FORBID_NETWORK_FETCHING |
1805 CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
1806 /* ocsp */
1807 0
1808 };
1809
1810 static CERTRevocationMethodIndex
1811 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_Method_Preference = {
1812 cert_revocation_method_crl
1813 };
1814
1815 static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy = {
1816 { /* leafTests */
1817 2,
1818 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_LeafFlags,
1819 1,
1820 &certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_Method_Preference,
1821 0 },
1822 { /* chainTests */
1823 2,
1824 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_ChainFlags,
1825 0,
1826 0,
1827 0 }
1828 };
1829 #endif /* NSS_DISABLE_LIBPKIX */
1830
1831 extern const CERTRevocationFlags *
CERT_GetClassicOCSPEnabledHardFailurePolicy()1832 CERT_GetClassicOCSPEnabledHardFailurePolicy()
1833 {
1834 #ifdef NSS_DISABLE_LIBPKIX
1835 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1836 return NULL;
1837 #else
1838 return &certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy;
1839 #endif /* NSS_DISABLE_LIBPKIX */
1840 }
1841
1842 #ifndef NSS_DISABLE_LIBPKIX
1843 static PRUint64 certRev_NSS_3_11_Ocsp_Disabled_Policy_LeafFlags[2] = {
1844 /* crl */
1845 CERT_REV_M_TEST_USING_THIS_METHOD |
1846 CERT_REV_M_FORBID_NETWORK_FETCHING |
1847 CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
1848 /* ocsp */
1849 0
1850 };
1851
1852 static PRUint64 certRev_NSS_3_11_Ocsp_Disabled_Policy_ChainFlags[2] = {
1853 /* crl */
1854 CERT_REV_M_TEST_USING_THIS_METHOD |
1855 CERT_REV_M_FORBID_NETWORK_FETCHING |
1856 CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
1857 /* ocsp */
1858 0
1859 };
1860
1861 static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Disabled_Policy = {
1862 { /* leafTests */
1863 2,
1864 certRev_NSS_3_11_Ocsp_Disabled_Policy_LeafFlags,
1865 0,
1866 0,
1867 0 },
1868 { /* chainTests */
1869 2,
1870 certRev_NSS_3_11_Ocsp_Disabled_Policy_ChainFlags,
1871 0,
1872 0,
1873 0 }
1874 };
1875 #endif /* NSS_DISABLE_LIBPKIX */
1876
1877 extern const CERTRevocationFlags *
CERT_GetClassicOCSPDisabledPolicy()1878 CERT_GetClassicOCSPDisabledPolicy()
1879 {
1880 #ifdef NSS_DISABLE_LIBPKIX
1881 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1882 return NULL;
1883 #else
1884 return &certRev_NSS_3_11_Ocsp_Disabled_Policy;
1885 #endif /* NSS_DISABLE_LIBPKIX */
1886 }
1887
1888 #ifndef NSS_DISABLE_LIBPKIX
1889 static PRUint64 certRev_PKIX_Verify_Nist_Policy_LeafFlags[2] = {
1890 /* crl */
1891 CERT_REV_M_TEST_USING_THIS_METHOD |
1892 CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO |
1893 CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE,
1894 /* ocsp */
1895 0
1896 };
1897
1898 static PRUint64 certRev_PKIX_Verify_Nist_Policy_ChainFlags[2] = {
1899 /* crl */
1900 CERT_REV_M_TEST_USING_THIS_METHOD |
1901 CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO |
1902 CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE,
1903 /* ocsp */
1904 0
1905 };
1906
1907 static const CERTRevocationFlags certRev_PKIX_Verify_Nist_Policy = {
1908 { /* leafTests */
1909 2,
1910 certRev_PKIX_Verify_Nist_Policy_LeafFlags,
1911 0,
1912 0,
1913 0 },
1914 { /* chainTests */
1915 2,
1916 certRev_PKIX_Verify_Nist_Policy_ChainFlags,
1917 0,
1918 0,
1919 0 }
1920 };
1921 #endif /* NSS_DISABLE_LIBPKIX */
1922
1923 extern const CERTRevocationFlags *
CERT_GetPKIXVerifyNistRevocationPolicy()1924 CERT_GetPKIXVerifyNistRevocationPolicy()
1925 {
1926 #ifdef NSS_DISABLE_LIBPKIX
1927 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1928 return NULL;
1929 #else
1930 return &certRev_PKIX_Verify_Nist_Policy;
1931 #endif /* NSS_DISABLE_LIBPKIX */
1932 }
1933
1934 CERTRevocationFlags *
CERT_AllocCERTRevocationFlags(PRUint32 number_leaf_methods,PRUint32 number_leaf_pref_methods,PRUint32 number_chain_methods,PRUint32 number_chain_pref_methods)1935 CERT_AllocCERTRevocationFlags(
1936 PRUint32 number_leaf_methods, PRUint32 number_leaf_pref_methods,
1937 PRUint32 number_chain_methods, PRUint32 number_chain_pref_methods)
1938 {
1939 #ifdef NSS_DISABLE_LIBPKIX
1940 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1941 return NULL;
1942 #else
1943 CERTRevocationFlags *flags;
1944
1945 flags = PORT_New(CERTRevocationFlags);
1946 if (!flags)
1947 return (NULL);
1948
1949 flags->leafTests.number_of_defined_methods = number_leaf_methods;
1950 flags->leafTests.cert_rev_flags_per_method =
1951 PORT_NewArray(PRUint64, number_leaf_methods);
1952
1953 flags->leafTests.number_of_preferred_methods = number_leaf_pref_methods;
1954 flags->leafTests.preferred_methods =
1955 PORT_NewArray(CERTRevocationMethodIndex, number_leaf_pref_methods);
1956
1957 flags->chainTests.number_of_defined_methods = number_chain_methods;
1958 flags->chainTests.cert_rev_flags_per_method =
1959 PORT_NewArray(PRUint64, number_chain_methods);
1960
1961 flags->chainTests.number_of_preferred_methods = number_chain_pref_methods;
1962 flags->chainTests.preferred_methods =
1963 PORT_NewArray(CERTRevocationMethodIndex, number_chain_pref_methods);
1964
1965 if (!flags->leafTests.cert_rev_flags_per_method ||
1966 !flags->leafTests.preferred_methods ||
1967 !flags->chainTests.cert_rev_flags_per_method ||
1968 !flags->chainTests.preferred_methods) {
1969 CERT_DestroyCERTRevocationFlags(flags);
1970 return (NULL);
1971 }
1972
1973 return flags;
1974 #endif /* NSS_DISABLE_LIBPKIX */
1975 }
1976
1977 void
CERT_DestroyCERTRevocationFlags(CERTRevocationFlags * flags)1978 CERT_DestroyCERTRevocationFlags(CERTRevocationFlags *flags)
1979 {
1980 #ifdef NSS_DISABLE_LIBPKIX
1981 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
1982 return;
1983 #else
1984 if (!flags)
1985 return;
1986
1987 if (flags->leafTests.cert_rev_flags_per_method)
1988 PORT_Free(flags->leafTests.cert_rev_flags_per_method);
1989
1990 if (flags->leafTests.preferred_methods)
1991 PORT_Free(flags->leafTests.preferred_methods);
1992
1993 if (flags->chainTests.cert_rev_flags_per_method)
1994 PORT_Free(flags->chainTests.cert_rev_flags_per_method);
1995
1996 if (flags->chainTests.preferred_methods)
1997 PORT_Free(flags->chainTests.preferred_methods);
1998
1999 PORT_Free(flags);
2000 #endif /* NSS_DISABLE_LIBPKIX */
2001 }
2002
2003 /*
2004 * CERT_PKIXVerifyCert
2005 *
2006 * Verify a Certificate using the PKIX library.
2007 *
2008 * Parameters:
2009 * cert - the target certificate to verify. Must be non-null
2010 * params - an array of type/value parameters which can be
2011 * used to modify the behavior of the validation
2012 * algorithm, or supply additional constraints.
2013 *
2014 * outputTrustAnchor - the trust anchor which the certificate
2015 * chains to. The caller is responsible
2016 * for freeing this.
2017 *
2018 * Example Usage:
2019 * CERTValParam args[3];
2020 * args[0].type = cvpt_policyOID;
2021 * args[0].value.si = oid;
2022 * args[1].type = revCheckRequired;
2023 * args[1].value.b = PR_TRUE;
2024 * args[2].type = cvpt_end;
2025 *
2026 * CERT_PKIXVerifyCert(cert, &output, args
2027 */
2028 SECStatus
CERT_PKIXVerifyCert(CERTCertificate * cert,SECCertificateUsage usages,CERTValInParam * paramsIn,CERTValOutParam * paramsOut,void * wincx)2029 CERT_PKIXVerifyCert(
2030 CERTCertificate *cert,
2031 SECCertificateUsage usages,
2032 CERTValInParam *paramsIn,
2033 CERTValOutParam *paramsOut,
2034 void *wincx)
2035 {
2036 #ifdef NSS_DISABLE_LIBPKIX
2037 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
2038 return SECFailure;
2039 #else
2040 SECStatus r = SECFailure;
2041 PKIX_Error *error = NULL;
2042 PKIX_ProcessingParams *procParams = NULL;
2043 PKIX_BuildResult *buildResult = NULL;
2044 void *nbioContext = NULL; /* for non-blocking IO */
2045 void *buildState = NULL; /* for non-blocking IO */
2046 PKIX_CertSelector *certSelector = NULL;
2047 PKIX_List *certStores = NULL;
2048 PKIX_ValidateResult *valResult = NULL;
2049 PKIX_VerifyNode *verifyNode = NULL;
2050 PKIX_TrustAnchor *trustAnchor = NULL;
2051 PKIX_PL_Cert *trustAnchorCert = NULL;
2052 PKIX_List *builtCertList = NULL;
2053 CERTValOutParam *oparam = NULL;
2054 int i = 0;
2055
2056 void *plContext = NULL;
2057
2058 #ifdef PKIX_OBJECT_LEAK_TEST
2059 int leakedObjNum = 0;
2060 int memLeakLoopCount = 0;
2061 int objCountTable[PKIX_NUMTYPES];
2062 int fnInvLocalCount = 0;
2063 PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine;
2064
2065 if (usePKIXValidationEngine) {
2066 /* current memory leak testing implementation does not allow
2067 * to run simultaneous tests one the same or a different threads.
2068 * Setting the variable to false, to make additional chain
2069 * validations be handled by old nss. */
2070 usePKIXValidationEngine = PR_FALSE;
2071 }
2072 testStartFnStackPosition = 1;
2073 fnStackNameArr[0] = "CERT_PKIXVerifyCert";
2074 fnStackInvCountArr[0] = 0;
2075 PKIX_Boolean abortOnLeak =
2076 (PR_GetEnvSecure("PKIX_OBJECT_LEAK_TEST_ABORT_ON_LEAK") == NULL) ? PKIX_FALSE
2077 : PKIX_TRUE;
2078 runningLeakTest = PKIX_TRUE;
2079
2080 /* Prevent multi-threaded run of object leak test */
2081 fnInvLocalCount = PR_ATOMIC_INCREMENT(¶llelFnInvocationCount);
2082 PORT_Assert(fnInvLocalCount == 1);
2083
2084 do {
2085 r = SECFailure;
2086 error = NULL;
2087 procParams = NULL;
2088 buildResult = NULL;
2089 nbioContext = NULL; /* for non-blocking IO */
2090 buildState = NULL; /* for non-blocking IO */
2091 certSelector = NULL;
2092 certStores = NULL;
2093 valResult = NULL;
2094 verifyNode = NULL;
2095 trustAnchor = NULL;
2096 trustAnchorCert = NULL;
2097 builtCertList = NULL;
2098 oparam = NULL;
2099 i = 0;
2100 errorGenerated = PKIX_FALSE;
2101 stackPosition = 0;
2102
2103 if (leakedObjNum) {
2104 pkix_pl_lifecycle_ObjectTableUpdate(objCountTable);
2105 }
2106 memLeakLoopCount += 1;
2107 #endif /* PKIX_OBJECT_LEAK_TEST */
2108
2109 error = PKIX_PL_NssContext_Create(
2110 0, PR_FALSE /*use arena*/, wincx, &plContext);
2111 if (error != NULL) { /* need pkix->nss error map */
2112 PORT_SetError(SEC_ERROR_CERT_NOT_VALID);
2113 goto cleanup;
2114 }
2115
2116 error = pkix_pl_NssContext_SetCertUsage(usages, plContext);
2117 if (error != NULL) {
2118 PORT_SetError(SEC_ERROR_INVALID_ARGS);
2119 goto cleanup;
2120 }
2121
2122 error = PKIX_ProcessingParams_Create(&procParams, plContext);
2123 if (error != NULL) { /* need pkix->nss error map */
2124 PORT_SetError(SEC_ERROR_CERT_NOT_VALID);
2125 goto cleanup;
2126 }
2127
2128 /* local cert store should be set into procParams before
2129 * filling in revocation settings. */
2130 certStores = cert_GetCertStores(plContext);
2131 if (certStores == NULL) {
2132 goto cleanup;
2133 }
2134 error = PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext);
2135 if (error != NULL) {
2136 goto cleanup;
2137 }
2138
2139 /* now process the extensible input parameters structure */
2140 if (paramsIn != NULL) {
2141 i = 0;
2142 while (paramsIn[i].type != cert_pi_end) {
2143 if (paramsIn[i].type >= cert_pi_max) {
2144 PORT_SetError(SEC_ERROR_INVALID_ARGS);
2145 goto cleanup;
2146 }
2147 if (cert_pkixSetParam(procParams,
2148 ¶msIn[i], plContext) !=
2149 SECSuccess) {
2150 PORT_SetError(SEC_ERROR_INVALID_ARGS);
2151 goto cleanup;
2152 }
2153 i++;
2154 }
2155 }
2156
2157 certSelector = cert_GetTargetCertConstraints(cert, plContext);
2158 if (certSelector == NULL) {
2159 goto cleanup;
2160 }
2161 error = PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext);
2162 if (error != NULL) {
2163 goto cleanup;
2164 }
2165
2166 error = PKIX_BuildChain(procParams, &nbioContext,
2167 &buildState, &buildResult, &verifyNode,
2168 plContext);
2169 if (error != NULL) {
2170 goto cleanup;
2171 }
2172
2173 error = PKIX_BuildResult_GetValidateResult(buildResult, &valResult,
2174 plContext);
2175 if (error != NULL) {
2176 goto cleanup;
2177 }
2178
2179 error = PKIX_ValidateResult_GetTrustAnchor(valResult, &trustAnchor,
2180 plContext);
2181 if (error != NULL) {
2182 goto cleanup;
2183 }
2184
2185 if (trustAnchor != NULL) {
2186 error = PKIX_TrustAnchor_GetTrustedCert(trustAnchor, &trustAnchorCert,
2187 plContext);
2188 if (error != NULL) {
2189 goto cleanup;
2190 }
2191 }
2192
2193 #ifdef PKIX_OBJECT_LEAK_TEST
2194 /* Can not continue if error was generated but not returned.
2195 * Jumping to cleanup. */
2196 if (errorGenerated)
2197 goto cleanup;
2198 #endif /* PKIX_OBJECT_LEAK_TEST */
2199
2200 oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_trustAnchor);
2201 if (oparam != NULL) {
2202 if (trustAnchorCert != NULL) {
2203 oparam->value.pointer.cert =
2204 cert_NSSCertFromPKIXCert(trustAnchorCert);
2205 } else {
2206 oparam->value.pointer.cert = NULL;
2207 }
2208 }
2209
2210 error = PKIX_BuildResult_GetCertChain(buildResult, &builtCertList,
2211 plContext);
2212 if (error != NULL) {
2213 goto cleanup;
2214 }
2215
2216 oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_certList);
2217 if (oparam != NULL) {
2218 error = cert_PkixToNssCertsChain(builtCertList,
2219 &oparam->value.pointer.chain,
2220 plContext);
2221 if (error)
2222 goto cleanup;
2223 }
2224
2225 r = SECSuccess;
2226
2227 cleanup:
2228 if (verifyNode) {
2229 /* Return validation log only upon error. */
2230 oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_errorLog);
2231 #ifdef PKIX_OBJECT_LEAK_TEST
2232 if (!errorGenerated)
2233 #endif /* PKIX_OBJECT_LEAK_TEST */
2234 if (r && oparam != NULL) {
2235 PKIX_Error *tmpError =
2236 cert_GetLogFromVerifyNode(oparam->value.pointer.log,
2237 verifyNode, plContext);
2238 if (tmpError) {
2239 PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext);
2240 }
2241 }
2242 PKIX_PL_Object_DecRef((PKIX_PL_Object *)verifyNode, plContext);
2243 }
2244
2245 if (procParams != NULL)
2246 PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext);
2247
2248 if (trustAnchorCert != NULL)
2249 PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchorCert, plContext);
2250
2251 if (trustAnchor != NULL)
2252 PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);
2253
2254 if (valResult != NULL)
2255 PKIX_PL_Object_DecRef((PKIX_PL_Object *)valResult, plContext);
2256
2257 if (buildResult != NULL)
2258 PKIX_PL_Object_DecRef((PKIX_PL_Object *)buildResult, plContext);
2259
2260 if (certStores != NULL)
2261 PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext);
2262
2263 if (certSelector != NULL)
2264 PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext);
2265
2266 if (builtCertList != NULL)
2267 PKIX_PL_Object_DecRef((PKIX_PL_Object *)builtCertList, plContext);
2268
2269 if (error != NULL) {
2270 SECErrorCodes nssErrorCode = 0;
2271
2272 cert_PkixErrorToNssCode(error, &nssErrorCode, plContext);
2273 cert_pkixDestroyValOutParam(paramsOut);
2274 PORT_SetError(nssErrorCode);
2275 PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
2276 }
2277
2278 PKIX_PL_NssContext_Destroy(plContext);
2279
2280 #ifdef PKIX_OBJECT_LEAK_TEST
2281 leakedObjNum =
2282 pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL);
2283
2284 if (pkixLog && leakedObjNum) {
2285 PR_LOG(pkixLog, 1, ("The generated error caused an object leaks. Loop %d."
2286 "Stack %s\n",
2287 memLeakLoopCount, errorFnStackString));
2288 }
2289 PR_Free(errorFnStackString);
2290 errorFnStackString = NULL;
2291 if (abortOnLeak) {
2292 PORT_Assert(leakedObjNum == 0);
2293 }
2294
2295 } while (errorGenerated);
2296
2297 runningLeakTest = PKIX_FALSE;
2298 PR_ATOMIC_DECREMENT(¶llelFnInvocationCount);
2299 usePKIXValidationEngine = savedUsePkixEngFlag;
2300 #endif /* PKIX_OBJECT_LEAK_TEST */
2301
2302 return r;
2303 #endif /* NSS_DISABLE_LIBPKIX */
2304 }
2305