Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: nss/lib/certhigh/certvfypkix.c

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

Powered by Google App Engine
This is Rietveld 408576698