/src/nss-nspr/nss/lib/certhigh/certvfypkix.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | | /* |
5 | | * 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_TRUE; |
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 |
61 | | CERT_SetUsePKIXForValidation(PRBool enable) |
62 | 0 | { |
63 | 0 | #ifdef NSS_DISABLE_LIBPKIX |
64 | 0 | PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
65 | 0 | return SECFailure; |
66 | | #else |
67 | | usePKIXValidationEngine = (enable > 0) ? PR_TRUE : PR_FALSE; |
68 | | return SECSuccess; |
69 | | #endif /* NSS_DISABLE_LIBPKIX */ |
70 | 0 | } |
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 |
87 | | CERT_GetUsePKIXForValidation() |
88 | 0 | { |
89 | 0 | #ifdef NSS_DISABLE_LIBPKIX |
90 | 0 | return PR_FALSE; |
91 | | #else |
92 | | return usePKIXValidationEngine; |
93 | | #endif /* NSS_DISABLE_LIBPKIX */ |
94 | 0 | } |
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 * |
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 * |
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 * |
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 * |
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 * |
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 * |
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 * |
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, PKIX_ErrorText[errPtr->errCode])); |
839 | | #else |
840 | | PR_LOG(pkixLog, 2, ("Error at level %d: Error code %d\n", errLevel, errPtr->errCode)); |
841 | | #endif /* PKIX_ERROR_DESCRIPTION */ |
842 | | } |
843 | | errPtr = errPtr->cause; |
844 | | errLevel += 1; |
845 | | } |
846 | | PORT_Assert(nssErr); |
847 | | if (!nssErr) { |
848 | | *pNssErr = SEC_ERROR_LIBPKIX_INTERNAL; |
849 | | } else { |
850 | | *pNssErr = nssErr; |
851 | | } |
852 | | |
853 | | PKIX_RETURN(CERTVFYPKIX); |
854 | | } |
855 | | |
856 | | /* |
857 | | * FUNCTION: cert_GetLogFromVerifyNode |
858 | | * DESCRIPTION: |
859 | | * |
860 | | * Recursive function that converts verify node tree-like set of structures |
861 | | * to CERTVerifyLog. |
862 | | * |
863 | | * PARAMETERS: |
864 | | * "log" |
865 | | * Pointed to already allocated CERTVerifyLog structure. |
866 | | * "node" |
867 | | * A node of PKIX_VerifyNode tree. |
868 | | * "plContext" |
869 | | * Platform-specific context pointer. |
870 | | * THREAD SAFETY: |
871 | | * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
872 | | * RETURNS: |
873 | | * Returns NULL if the function succeeds. |
874 | | * Returns a Cert Verify Error if the function fails in an unrecoverable way. |
875 | | * Returns a Fatal Error if the function fails in an unrecoverable way. |
876 | | */ |
877 | | static PKIX_Error * |
878 | | cert_GetLogFromVerifyNode( |
879 | | CERTVerifyLog *log, |
880 | | PKIX_VerifyNode *node, |
881 | | void *plContext) |
882 | | { |
883 | | PKIX_List *children = NULL; |
884 | | PKIX_VerifyNode *childNode = NULL; |
885 | | |
886 | | PKIX_ENTER(CERTVFYPKIX, "cert_GetLogFromVerifyNode"); |
887 | | |
888 | | children = node->children; |
889 | | |
890 | | if (children == NULL) { |
891 | | PKIX_ERRORCODE errCode = PKIX_ANCHORDIDNOTCHAINTOCERT; |
892 | | if (node->error && node->error->errCode != errCode) { |
893 | | if (log != NULL) { |
894 | | SECErrorCodes nssErrorCode = 0; |
895 | | CERTCertificate *cert = NULL; |
896 | | |
897 | | cert = node->verifyCert->nssCert; |
898 | | |
899 | | PKIX_CHECK( |
900 | | cert_PkixErrorToNssCode(node->error, &nssErrorCode, |
901 | | plContext), |
902 | | PKIX_GETPKIXERRORCODEFAILED); |
903 | | |
904 | | cert_AddToVerifyLog(log, cert, nssErrorCode, node->depth, NULL); |
905 | | } |
906 | | } |
907 | | PKIX_RETURN(CERTVFYPKIX); |
908 | | } else { |
909 | | PRUint32 i = 0; |
910 | | PKIX_UInt32 length = 0; |
911 | | |
912 | | PKIX_CHECK( |
913 | | PKIX_List_GetLength(children, &length, plContext), |
914 | | PKIX_LISTGETLENGTHFAILED); |
915 | | |
916 | | for (i = 0; i < length; i++) { |
917 | | |
918 | | PKIX_CHECK( |
919 | | PKIX_List_GetItem(children, i, (PKIX_PL_Object **)&childNode, |
920 | | plContext), |
921 | | PKIX_LISTGETITEMFAILED); |
922 | | |
923 | | PKIX_CHECK( |
924 | | cert_GetLogFromVerifyNode(log, childNode, plContext), |
925 | | PKIX_ERRORINRECURSIVEEQUALSCALL); |
926 | | |
927 | | PKIX_DECREF(childNode); |
928 | | } |
929 | | } |
930 | | |
931 | | cleanup: |
932 | | PKIX_DECREF(childNode); |
933 | | |
934 | | PKIX_RETURN(CERTVFYPKIX); |
935 | | } |
936 | | |
937 | | /* |
938 | | * FUNCTION: cert_GetBuildResults |
939 | | * DESCRIPTION: |
940 | | * |
941 | | * Converts pkix build results to nss results. This function is called |
942 | | * regardless of build result. |
943 | | * |
944 | | * If it called after chain was successfully constructed, then it will |
945 | | * convert: |
946 | | * * pkix cert list that represent the chain to nss cert list |
947 | | * * trusted root the chain was anchored to nss certificate. |
948 | | * |
949 | | * In case of failure it will convert: |
950 | | * * pkix error to PR error code(will set it with PORT_SetError) |
951 | | * * pkix validation log to nss CERTVerifyLog |
952 | | * |
953 | | * PARAMETERS: |
954 | | * "buildResult" |
955 | | * Build results returned by PKIX_BuildChain. |
956 | | * "verifyNode" |
957 | | * Tree-like structure of chain building/validation failures |
958 | | * returned by PKIX_BuildChain. Ignored in case of success. |
959 | | * "error" |
960 | | * Final error returned by PKIX_BuildChain. Should be NULL in |
961 | | * case of success. |
962 | | * "log" |
963 | | * Address of pre-allocated(if not NULL) CERTVerifyLog structure. |
964 | | * "ptrustedRoot" |
965 | | * Address of returned trusted root the chain was anchored to. |
966 | | * "pvalidChain" |
967 | | * Address of returned valid chain. |
968 | | * "plContext" |
969 | | * Platform-specific context pointer. |
970 | | * THREAD SAFETY: |
971 | | * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
972 | | * RETURNS: |
973 | | * Returns NULL if the function succeeds. |
974 | | * Returns a Cert Verify Error if the function fails in an unrecoverable way. |
975 | | * Returns a Fatal Error if the function fails in an unrecoverable way. |
976 | | */ |
977 | | static PKIX_Error * |
978 | | cert_GetBuildResults( |
979 | | PKIX_BuildResult *buildResult, |
980 | | PKIX_VerifyNode *verifyNode, |
981 | | PKIX_Error *error, |
982 | | CERTVerifyLog *log, |
983 | | CERTCertificate **ptrustedRoot, |
984 | | CERTCertList **pvalidChain, |
985 | | void *plContext) |
986 | | { |
987 | | PKIX_ValidateResult *validResult = NULL; |
988 | | CERTCertList *validChain = NULL; |
989 | | CERTCertificate *trustedRoot = NULL; |
990 | | PKIX_TrustAnchor *trustAnchor = NULL; |
991 | | PKIX_PL_Cert *trustedCert = NULL; |
992 | | PKIX_List *pkixCertChain = NULL; |
993 | | |
994 | | PKIX_ENTER(CERTVFYPKIX, "cert_GetBuildResults"); |
995 | | if (buildResult == NULL && error == NULL) { |
996 | | PKIX_ERROR(PKIX_NULLARGUMENT); |
997 | | } |
998 | | |
999 | | if (error) { |
1000 | | SECErrorCodes nssErrorCode = 0; |
1001 | | if (verifyNode) { |
1002 | | PKIX_Error *tmpError = |
1003 | | cert_GetLogFromVerifyNode(log, verifyNode, plContext); |
1004 | | if (tmpError) { |
1005 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext); |
1006 | | } |
1007 | | } |
1008 | | cert_PkixErrorToNssCode(error, &nssErrorCode, plContext); |
1009 | | PORT_SetError(nssErrorCode); |
1010 | | goto cleanup; |
1011 | | } |
1012 | | |
1013 | | if (pvalidChain) { |
1014 | | PKIX_CHECK( |
1015 | | PKIX_BuildResult_GetCertChain(buildResult, &pkixCertChain, |
1016 | | plContext), |
1017 | | PKIX_BUILDRESULTGETCERTCHAINFAILED); |
1018 | | |
1019 | | PKIX_CHECK( |
1020 | | cert_PkixToNssCertsChain(pkixCertChain, &validChain, plContext), |
1021 | | PKIX_CERTCHAINTONSSCHAINFAILED); |
1022 | | } |
1023 | | |
1024 | | if (ptrustedRoot) { |
1025 | | PKIX_CHECK( |
1026 | | PKIX_BuildResult_GetValidateResult(buildResult, &validResult, |
1027 | | plContext), |
1028 | | PKIX_BUILDRESULTGETVALIDATERESULTFAILED); |
1029 | | |
1030 | | PKIX_CHECK( |
1031 | | PKIX_ValidateResult_GetTrustAnchor(validResult, &trustAnchor, |
1032 | | plContext), |
1033 | | PKIX_VALIDATERESULTGETTRUSTANCHORFAILED); |
1034 | | |
1035 | | PKIX_CHECK( |
1036 | | PKIX_TrustAnchor_GetTrustedCert(trustAnchor, &trustedCert, |
1037 | | plContext), |
1038 | | PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); |
1039 | | |
1040 | | PKIX_CHECK( |
1041 | | PKIX_PL_Cert_GetCERTCertificate(trustedCert, &trustedRoot, |
1042 | | plContext), |
1043 | | PKIX_CERTGETCERTCERTIFICATEFAILED); |
1044 | | } |
1045 | | |
1046 | | PORT_Assert(!PKIX_ERROR_RECEIVED); |
1047 | | |
1048 | | if (trustedRoot) { |
1049 | | *ptrustedRoot = trustedRoot; |
1050 | | } |
1051 | | if (validChain) { |
1052 | | *pvalidChain = validChain; |
1053 | | } |
1054 | | |
1055 | | cleanup: |
1056 | | if (PKIX_ERROR_RECEIVED) { |
1057 | | if (trustedRoot) { |
1058 | | CERT_DestroyCertificate(trustedRoot); |
1059 | | } |
1060 | | if (validChain) { |
1061 | | CERT_DestroyCertList(validChain); |
1062 | | } |
1063 | | } |
1064 | | PKIX_DECREF(trustAnchor); |
1065 | | PKIX_DECREF(trustedCert); |
1066 | | PKIX_DECREF(pkixCertChain); |
1067 | | PKIX_DECREF(validResult); |
1068 | | PKIX_DECREF(error); |
1069 | | PKIX_DECREF(verifyNode); |
1070 | | PKIX_DECREF(buildResult); |
1071 | | |
1072 | | PKIX_RETURN(CERTVFYPKIX); |
1073 | | } |
1074 | | #endif /* NSS_DISABLE_LIBPKIX */ |
1075 | | |
1076 | | /* |
1077 | | * FUNCTION: cert_VerifyCertChainPkix |
1078 | | * DESCRIPTION: |
1079 | | * |
1080 | | * The main wrapper function that is called from CERT_VerifyCert and |
1081 | | * CERT_VerifyCACertForUsage functions to validate cert with libpkix. |
1082 | | * |
1083 | | * PARAMETERS: |
1084 | | * "cert" |
1085 | | * Leaf certificate of a chain we want to build. |
1086 | | * "checkSig" |
1087 | | * Certificate signatures will not be verified if this |
1088 | | * flag is set to PR_FALSE. |
1089 | | * "requiredUsage" |
1090 | | * Required usage for certificate and chain. |
1091 | | * "time" |
1092 | | * Validity time. |
1093 | | * "wincx" |
1094 | | * Nss database password token. |
1095 | | * "log" |
1096 | | * Address of already allocated CERTVerifyLog structure. Not |
1097 | | * used if NULL; |
1098 | | * "pSigerror" |
1099 | | * Address of PRBool. If not NULL, returns true is cert chain |
1100 | | * was invalidated because of bad certificate signature. |
1101 | | * "pRevoked" |
1102 | | * Address of PRBool. If not NULL, returns true is cert chain |
1103 | | * was invalidated because a revoked certificate was found in |
1104 | | * the chain. |
1105 | | * THREAD SAFETY: |
1106 | | * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
1107 | | * RETURNS: |
1108 | | * SECFailure is chain building process has failed. SECSuccess otherwise. |
1109 | | */ |
1110 | | SECStatus |
1111 | | cert_VerifyCertChainPkix( |
1112 | | CERTCertificate *cert, |
1113 | | PRBool checkSig, |
1114 | | SECCertUsage requiredUsage, |
1115 | | PRTime time, |
1116 | | void *wincx, |
1117 | | CERTVerifyLog *log, |
1118 | | PRBool *pSigerror, |
1119 | | PRBool *pRevoked) |
1120 | 0 | { |
1121 | 0 | #ifdef NSS_DISABLE_LIBPKIX |
1122 | 0 | PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
1123 | 0 | return SECFailure; |
1124 | | #else |
1125 | | PKIX_ProcessingParams *procParams = NULL; |
1126 | | PKIX_BuildResult *result = NULL; |
1127 | | PKIX_VerifyNode *verifyNode = NULL; |
1128 | | PKIX_Error *error = NULL; |
1129 | | |
1130 | | SECStatus rv = SECFailure; |
1131 | | void *plContext = NULL; |
1132 | | |
1133 | | #ifdef PKIX_OBJECT_LEAK_TEST |
1134 | | int leakedObjNum = 0; |
1135 | | int memLeakLoopCount = 0; |
1136 | | int objCountTable[PKIX_NUMTYPES]; |
1137 | | int fnInvLocalCount = 0; |
1138 | | PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine; |
1139 | | |
1140 | | if (usePKIXValidationEngine) { |
1141 | | /* current memory leak testing implementation does not allow |
1142 | | * to run simultaneous tests one the same or a different threads. |
1143 | | * Setting the variable to false, to make additional chain |
1144 | | * validations be handled by old nss. */ |
1145 | | usePKIXValidationEngine = PR_FALSE; |
1146 | | } |
1147 | | testStartFnStackPosition = 2; |
1148 | | fnStackNameArr[0] = "cert_VerifyCertChainPkix"; |
1149 | | fnStackInvCountArr[0] = 0; |
1150 | | PKIX_Boolean abortOnLeak = |
1151 | | (PR_GetEnvSecure("PKIX_OBJECT_LEAK_TEST_ABORT_ON_LEAK") == NULL) ? PKIX_FALSE |
1152 | | : PKIX_TRUE; |
1153 | | runningLeakTest = PKIX_TRUE; |
1154 | | |
1155 | | /* Prevent multi-threaded run of object leak test */ |
1156 | | fnInvLocalCount = PR_ATOMIC_INCREMENT(¶llelFnInvocationCount); |
1157 | | PORT_Assert(fnInvLocalCount == 1); |
1158 | | |
1159 | | do { |
1160 | | rv = SECFailure; |
1161 | | plContext = NULL; |
1162 | | procParams = NULL; |
1163 | | result = NULL; |
1164 | | verifyNode = NULL; |
1165 | | error = NULL; |
1166 | | errorGenerated = PKIX_FALSE; |
1167 | | stackPosition = 0; |
1168 | | |
1169 | | if (leakedObjNum) { |
1170 | | pkix_pl_lifecycle_ObjectTableUpdate(objCountTable); |
1171 | | } |
1172 | | memLeakLoopCount += 1; |
1173 | | #endif /* PKIX_OBJECT_LEAK_TEST */ |
1174 | | |
1175 | | error = |
1176 | | cert_CreatePkixProcessingParams(cert, checkSig, time, wincx, |
1177 | | PR_FALSE /*use arena*/, |
1178 | | requiredUsage == certUsageStatusResponder, |
1179 | | &procParams, &plContext); |
1180 | | if (error) { |
1181 | | goto cleanup; |
1182 | | } |
1183 | | |
1184 | | error = |
1185 | | cert_ProcessingParamsSetKeyAndCertUsage(procParams, requiredUsage, 0, |
1186 | | plContext); |
1187 | | if (error) { |
1188 | | goto cleanup; |
1189 | | } |
1190 | | |
1191 | | error = |
1192 | | cert_BuildAndValidateChain(procParams, &result, &verifyNode, plContext); |
1193 | | if (error) { |
1194 | | goto cleanup; |
1195 | | } |
1196 | | |
1197 | | if (pRevoked) { |
1198 | | /* Currently always PR_FALSE. Will be fixed as a part of 394077 */ |
1199 | | *pRevoked = PR_FALSE; |
1200 | | } |
1201 | | if (pSigerror) { |
1202 | | /* Currently always PR_FALSE. Will be fixed as a part of 394077 */ |
1203 | | *pSigerror = PR_FALSE; |
1204 | | } |
1205 | | rv = SECSuccess; |
1206 | | |
1207 | | cleanup: |
1208 | | error = cert_GetBuildResults(result, verifyNode, error, log, NULL, NULL, |
1209 | | plContext); |
1210 | | if (error) { |
1211 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); |
1212 | | } |
1213 | | if (procParams) { |
1214 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext); |
1215 | | } |
1216 | | if (plContext) { |
1217 | | PKIX_PL_NssContext_Destroy(plContext); |
1218 | | } |
1219 | | |
1220 | | #ifdef PKIX_OBJECT_LEAK_TEST |
1221 | | leakedObjNum = |
1222 | | pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL); |
1223 | | |
1224 | | if (pkixLog && leakedObjNum) { |
1225 | | PR_LOG(pkixLog, 1, ("The generated error caused an object leaks. Loop %d." |
1226 | | "Stack %s\n", |
1227 | | memLeakLoopCount, errorFnStackString)); |
1228 | | } |
1229 | | PR_Free(errorFnStackString); |
1230 | | errorFnStackString = NULL; |
1231 | | if (abortOnLeak) { |
1232 | | PORT_Assert(leakedObjNum == 0); |
1233 | | } |
1234 | | |
1235 | | } while (errorGenerated); |
1236 | | |
1237 | | runningLeakTest = PKIX_FALSE; |
1238 | | PR_ATOMIC_DECREMENT(¶llelFnInvocationCount); |
1239 | | usePKIXValidationEngine = savedUsePkixEngFlag; |
1240 | | #endif /* PKIX_OBJECT_LEAK_TEST */ |
1241 | | |
1242 | | return rv; |
1243 | | #endif /* NSS_DISABLE_LIBPKIX */ |
1244 | 0 | } |
1245 | | |
1246 | | #ifndef NSS_DISABLE_LIBPKIX |
1247 | | PKIX_CertSelector * |
1248 | | cert_GetTargetCertConstraints(CERTCertificate *target, void *plContext) |
1249 | | { |
1250 | | PKIX_ComCertSelParams *certSelParams = NULL; |
1251 | | PKIX_CertSelector *certSelector = NULL; |
1252 | | PKIX_CertSelector *r = NULL; |
1253 | | PKIX_PL_Cert *eeCert = NULL; |
1254 | | PKIX_Error *error = NULL; |
1255 | | |
1256 | | error = PKIX_PL_Cert_CreateFromCERTCertificate(target, &eeCert, plContext); |
1257 | | if (error != NULL) |
1258 | | goto cleanup; |
1259 | | |
1260 | | error = PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext); |
1261 | | if (error != NULL) |
1262 | | goto cleanup; |
1263 | | |
1264 | | error = PKIX_ComCertSelParams_Create(&certSelParams, plContext); |
1265 | | if (error != NULL) |
1266 | | goto cleanup; |
1267 | | |
1268 | | error = PKIX_ComCertSelParams_SetCertificate( |
1269 | | certSelParams, eeCert, plContext); |
1270 | | if (error != NULL) |
1271 | | goto cleanup; |
1272 | | |
1273 | | error = PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext); |
1274 | | if (error != NULL) |
1275 | | goto cleanup; |
1276 | | |
1277 | | error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certSelector, plContext); |
1278 | | if (error == NULL) |
1279 | | r = certSelector; |
1280 | | |
1281 | | cleanup: |
1282 | | if (certSelParams != NULL) |
1283 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelParams, plContext); |
1284 | | |
1285 | | if (eeCert != NULL) |
1286 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)eeCert, plContext); |
1287 | | |
1288 | | if (certSelector != NULL) |
1289 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext); |
1290 | | |
1291 | | if (error != NULL) { |
1292 | | SECErrorCodes nssErr; |
1293 | | |
1294 | | cert_PkixErrorToNssCode(error, &nssErr, plContext); |
1295 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); |
1296 | | PORT_SetError(nssErr); |
1297 | | } |
1298 | | |
1299 | | return r; |
1300 | | } |
1301 | | |
1302 | | static PKIX_List * |
1303 | | cert_GetCertStores(void *plContext) |
1304 | | { |
1305 | | PKIX_CertStore *certStore = NULL; |
1306 | | PKIX_List *certStores = NULL; |
1307 | | PKIX_List *r = NULL; |
1308 | | PKIX_Error *error = NULL; |
1309 | | |
1310 | | error = PKIX_PL_Pk11CertStore_Create(&certStore, plContext); |
1311 | | if (error != NULL) |
1312 | | goto cleanup; |
1313 | | |
1314 | | error = PKIX_List_Create(&certStores, plContext); |
1315 | | if (error != NULL) |
1316 | | goto cleanup; |
1317 | | |
1318 | | error = PKIX_List_AppendItem(certStores, |
1319 | | (PKIX_PL_Object *)certStore, plContext); |
1320 | | if (error != NULL) |
1321 | | goto cleanup; |
1322 | | |
1323 | | error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certStores, plContext); |
1324 | | if (error == NULL) |
1325 | | r = certStores; |
1326 | | |
1327 | | cleanup: |
1328 | | if (certStores != NULL) |
1329 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext); |
1330 | | |
1331 | | if (certStore != NULL) |
1332 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStore, plContext); |
1333 | | |
1334 | | if (error != NULL) { |
1335 | | SECErrorCodes nssErr; |
1336 | | |
1337 | | cert_PkixErrorToNssCode(error, &nssErr, plContext); |
1338 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); |
1339 | | PORT_SetError(nssErr); |
1340 | | } |
1341 | | |
1342 | | return r; |
1343 | | } |
1344 | | |
1345 | | struct fake_PKIX_PL_CertStruct { |
1346 | | CERTCertificate *nssCert; |
1347 | | }; |
1348 | | |
1349 | | /* This needs to be part of the PKIX_PL_* */ |
1350 | | /* This definitely needs to go away, and be replaced with |
1351 | | a real accessor function in PKIX */ |
1352 | | static CERTCertificate * |
1353 | | cert_NSSCertFromPKIXCert(const PKIX_PL_Cert *pkix_cert) |
1354 | | { |
1355 | | struct fake_PKIX_PL_CertStruct *fcert = NULL; |
1356 | | |
1357 | | fcert = (struct fake_PKIX_PL_CertStruct *)pkix_cert; |
1358 | | |
1359 | | return CERT_DupCertificate(fcert->nssCert); |
1360 | | } |
1361 | | |
1362 | | PKIX_List * |
1363 | | cert_PKIXMakeOIDList(const SECOidTag *oids, int oidCount, void *plContext) |
1364 | | { |
1365 | | PKIX_List *r = NULL; |
1366 | | PKIX_List *policyList = NULL; |
1367 | | PKIX_PL_OID *policyOID = NULL; |
1368 | | PKIX_Error *error = NULL; |
1369 | | int i; |
1370 | | |
1371 | | error = PKIX_List_Create(&policyList, plContext); |
1372 | | if (error != NULL) { |
1373 | | goto cleanup; |
1374 | | } |
1375 | | |
1376 | | for (i = 0; i < oidCount; i++) { |
1377 | | error = PKIX_PL_OID_Create(oids[i], &policyOID, plContext); |
1378 | | if (error) { |
1379 | | goto cleanup; |
1380 | | } |
1381 | | error = PKIX_List_AppendItem(policyList, |
1382 | | (PKIX_PL_Object *)policyOID, plContext); |
1383 | | if (error != NULL) { |
1384 | | goto cleanup; |
1385 | | } |
1386 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext); |
1387 | | policyOID = NULL; |
1388 | | } |
1389 | | |
1390 | | error = PKIX_List_SetImmutable(policyList, plContext); |
1391 | | if (error != NULL) |
1392 | | goto cleanup; |
1393 | | |
1394 | | error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)policyList, plContext); |
1395 | | if (error == NULL) |
1396 | | r = policyList; |
1397 | | |
1398 | | cleanup: |
1399 | | if (policyOID != NULL) { |
1400 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext); |
1401 | | } |
1402 | | if (policyList != NULL) { |
1403 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyList, plContext); |
1404 | | } |
1405 | | if (error != NULL) { |
1406 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); |
1407 | | } |
1408 | | |
1409 | | return r; |
1410 | | } |
1411 | | |
1412 | | CERTValOutParam * |
1413 | | cert_pkix_FindOutputParam(CERTValOutParam *params, const CERTValParamOutType t) |
1414 | | { |
1415 | | CERTValOutParam *i; |
1416 | | if (params == NULL) { |
1417 | | return NULL; |
1418 | | } |
1419 | | for (i = params; i->type != cert_po_end; i++) { |
1420 | | if (i->type == t) { |
1421 | | return i; |
1422 | | } |
1423 | | } |
1424 | | return NULL; |
1425 | | } |
1426 | | |
1427 | | static PKIX_Error * |
1428 | | setRevocationMethod(PKIX_RevocationChecker *revChecker, |
1429 | | PKIX_ProcessingParams *procParams, |
1430 | | const CERTRevocationTests *revTest, |
1431 | | CERTRevocationMethodIndex certRevMethod, |
1432 | | PKIX_RevocationMethodType pkixRevMethod, |
1433 | | PKIX_Boolean verifyResponderUsages, |
1434 | | PKIX_Boolean isLeafTest, |
1435 | | void *plContext) |
1436 | | { |
1437 | | PKIX_UInt32 methodFlags = 0; |
1438 | | PKIX_Error *error = NULL; |
1439 | | PKIX_UInt32 priority = 0; |
1440 | | |
1441 | | if (revTest->number_of_defined_methods <= (PRUint32)certRevMethod) { |
1442 | | return NULL; |
1443 | | } |
1444 | | if (revTest->preferred_methods) { |
1445 | | unsigned int i = 0; |
1446 | | for (; i < revTest->number_of_preferred_methods; i++) { |
1447 | | if (revTest->preferred_methods[i] == certRevMethod) |
1448 | | break; |
1449 | | } |
1450 | | priority = i; |
1451 | | } |
1452 | | methodFlags = revTest->cert_rev_flags_per_method[certRevMethod]; |
1453 | | if (verifyResponderUsages && |
1454 | | pkixRevMethod == PKIX_RevocationMethod_OCSP) { |
1455 | | methodFlags |= PKIX_REV_M_FORBID_NETWORK_FETCHING; |
1456 | | } |
1457 | | error = |
1458 | | PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams, |
1459 | | pkixRevMethod, methodFlags, |
1460 | | priority, NULL, |
1461 | | isLeafTest, plContext); |
1462 | | return error; |
1463 | | } |
1464 | | |
1465 | | SECStatus |
1466 | | cert_pkixSetParam(PKIX_ProcessingParams *procParams, |
1467 | | const CERTValInParam *param, void *plContext) |
1468 | | { |
1469 | | PKIX_Error *error = NULL; |
1470 | | SECStatus r = SECSuccess; |
1471 | | PKIX_PL_Date *date = NULL; |
1472 | | PKIX_List *policyOIDList = NULL; |
1473 | | PKIX_List *certListPkix = NULL; |
1474 | | const CERTRevocationFlags *flags; |
1475 | | SECErrorCodes errCode = SEC_ERROR_INVALID_ARGS; |
1476 | | const CERTCertList *certList = NULL; |
1477 | | CERTCertListNode *node; |
1478 | | PKIX_PL_Cert *certPkix = NULL; |
1479 | | PKIX_TrustAnchor *trustAnchor = NULL; |
1480 | | PKIX_RevocationChecker *revChecker = NULL; |
1481 | | PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext *)plContext; |
1482 | | |
1483 | | /* XXX we need a way to map generic PKIX error to generic NSS errors */ |
1484 | | |
1485 | | switch (param->type) { |
1486 | | |
1487 | | case cert_pi_policyOID: |
1488 | | |
1489 | | /* needed? */ |
1490 | | error = PKIX_ProcessingParams_SetExplicitPolicyRequired( |
1491 | | procParams, PKIX_TRUE, plContext); |
1492 | | |
1493 | | if (error != NULL) { |
1494 | | break; |
1495 | | } |
1496 | | |
1497 | | policyOIDList = cert_PKIXMakeOIDList(param->value.array.oids, |
1498 | | param->value.arraySize, plContext); |
1499 | | if (policyOIDList == NULL) { |
1500 | | r = SECFailure; |
1501 | | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
1502 | | break; |
1503 | | } |
1504 | | |
1505 | | error = PKIX_ProcessingParams_SetInitialPolicies( |
1506 | | procParams, policyOIDList, plContext); |
1507 | | break; |
1508 | | |
1509 | | case cert_pi_date: |
1510 | | if (param->value.scalar.time == 0) { |
1511 | | error = PKIX_PL_Date_Create_UTCTime(NULL, &date, plContext); |
1512 | | if (error != NULL) { |
1513 | | errCode = SEC_ERROR_INVALID_TIME; |
1514 | | break; |
1515 | | } |
1516 | | } else { |
1517 | | error = pkix_pl_Date_CreateFromPRTime(param->value.scalar.time, |
1518 | | &date, plContext); |
1519 | | if (error != NULL) { |
1520 | | errCode = SEC_ERROR_INVALID_TIME; |
1521 | | break; |
1522 | | } |
1523 | | } |
1524 | | |
1525 | | error = PKIX_ProcessingParams_SetDate(procParams, date, plContext); |
1526 | | if (error != NULL) { |
1527 | | errCode = SEC_ERROR_INVALID_TIME; |
1528 | | } |
1529 | | break; |
1530 | | |
1531 | | case cert_pi_revocationFlags: { |
1532 | | PKIX_UInt32 leafIMFlags = 0; |
1533 | | PKIX_UInt32 chainIMFlags = 0; |
1534 | | PKIX_Boolean validatingResponderCert = PKIX_FALSE; |
1535 | | |
1536 | | flags = param->value.pointer.revocation; |
1537 | | if (!flags) { |
1538 | | PORT_SetError(errCode); |
1539 | | r = SECFailure; |
1540 | | break; |
1541 | | } |
1542 | | |
1543 | | leafIMFlags = |
1544 | | flags->leafTests.cert_rev_method_independent_flags; |
1545 | | chainIMFlags = |
1546 | | flags->chainTests.cert_rev_method_independent_flags; |
1547 | | |
1548 | | error = |
1549 | | PKIX_RevocationChecker_Create(leafIMFlags, chainIMFlags, |
1550 | | &revChecker, plContext); |
1551 | | if (error) { |
1552 | | break; |
1553 | | } |
1554 | | |
1555 | | error = |
1556 | | PKIX_ProcessingParams_SetRevocationChecker(procParams, |
1557 | | revChecker, plContext); |
1558 | | if (error) { |
1559 | | break; |
1560 | | } |
1561 | | |
1562 | | if (((PKIX_PL_NssContext *)plContext)->certificateUsage & |
1563 | | certificateUsageStatusResponder) { |
1564 | | validatingResponderCert = PKIX_TRUE; |
1565 | | } |
1566 | | |
1567 | | error = setRevocationMethod(revChecker, |
1568 | | procParams, &flags->leafTests, |
1569 | | cert_revocation_method_crl, |
1570 | | PKIX_RevocationMethod_CRL, |
1571 | | validatingResponderCert, |
1572 | | PKIX_TRUE, plContext); |
1573 | | if (error) { |
1574 | | break; |
1575 | | } |
1576 | | |
1577 | | error = setRevocationMethod(revChecker, |
1578 | | procParams, &flags->leafTests, |
1579 | | cert_revocation_method_ocsp, |
1580 | | PKIX_RevocationMethod_OCSP, |
1581 | | validatingResponderCert, |
1582 | | PKIX_TRUE, plContext); |
1583 | | if (error) { |
1584 | | break; |
1585 | | } |
1586 | | |
1587 | | error = setRevocationMethod(revChecker, |
1588 | | procParams, &flags->chainTests, |
1589 | | cert_revocation_method_crl, |
1590 | | PKIX_RevocationMethod_CRL, |
1591 | | validatingResponderCert, |
1592 | | PKIX_FALSE, plContext); |
1593 | | if (error) { |
1594 | | break; |
1595 | | } |
1596 | | |
1597 | | error = setRevocationMethod(revChecker, |
1598 | | procParams, &flags->chainTests, |
1599 | | cert_revocation_method_ocsp, |
1600 | | PKIX_RevocationMethod_OCSP, |
1601 | | validatingResponderCert, |
1602 | | PKIX_FALSE, plContext); |
1603 | | if (error) { |
1604 | | break; |
1605 | | } |
1606 | | |
1607 | | } break; |
1608 | | |
1609 | | case cert_pi_trustAnchors: |
1610 | | certList = param->value.pointer.chain; |
1611 | | if (!certList) { |
1612 | | PORT_SetError(errCode); |
1613 | | r = SECFailure; |
1614 | | break; |
1615 | | } |
1616 | | error = PKIX_List_Create(&certListPkix, plContext); |
1617 | | if (error != NULL) { |
1618 | | break; |
1619 | | } |
1620 | | for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList); |
1621 | | node = CERT_LIST_NEXT(node)) { |
1622 | | error = PKIX_PL_Cert_CreateFromCERTCertificate(node->cert, |
1623 | | &certPkix, plContext); |
1624 | | if (error) { |
1625 | | break; |
1626 | | } |
1627 | | error = PKIX_TrustAnchor_CreateWithCert(certPkix, &trustAnchor, |
1628 | | plContext); |
1629 | | if (error) { |
1630 | | break; |
1631 | | } |
1632 | | error = PKIX_List_AppendItem(certListPkix, |
1633 | | (PKIX_PL_Object *)trustAnchor, plContext); |
1634 | | if (error) { |
1635 | | break; |
1636 | | } |
1637 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext); |
1638 | | trustAnchor = NULL; |
1639 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)certPkix, plContext); |
1640 | | certPkix = NULL; |
1641 | | } |
1642 | | error = |
1643 | | PKIX_ProcessingParams_SetTrustAnchors(procParams, certListPkix, |
1644 | | plContext); |
1645 | | break; |
1646 | | |
1647 | | case cert_pi_useAIACertFetch: |
1648 | | error = |
1649 | | PKIX_ProcessingParams_SetUseAIAForCertFetching(procParams, |
1650 | | (PRBool)(param->value.scalar.b != |
1651 | | 0), |
1652 | | plContext); |
1653 | | break; |
1654 | | |
1655 | | case cert_pi_chainVerifyCallback: { |
1656 | | const CERTChainVerifyCallback *chainVerifyCallback = |
1657 | | param->value.pointer.chainVerifyCallback; |
1658 | | if (!chainVerifyCallback || !chainVerifyCallback->isChainValid) { |
1659 | | PORT_SetError(errCode); |
1660 | | r = SECFailure; |
1661 | | break; |
1662 | | } |
1663 | | |
1664 | | nssContext->chainVerifyCallback = *chainVerifyCallback; |
1665 | | } break; |
1666 | | |
1667 | | case cert_pi_useOnlyTrustAnchors: |
1668 | | error = |
1669 | | PKIX_ProcessingParams_SetUseOnlyTrustAnchors(procParams, |
1670 | | (PRBool)(param->value.scalar.b != |
1671 | | 0), |
1672 | | plContext); |
1673 | | break; |
1674 | | |
1675 | | default: |
1676 | | PORT_SetError(errCode); |
1677 | | r = SECFailure; |
1678 | | break; |
1679 | | } |
1680 | | |
1681 | | if (policyOIDList != NULL) |
1682 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOIDList, plContext); |
1683 | | |
1684 | | if (date != NULL) |
1685 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)date, plContext); |
1686 | | |
1687 | | if (revChecker != NULL) |
1688 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)revChecker, plContext); |
1689 | | |
1690 | | if (certListPkix) |
1691 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)certListPkix, plContext); |
1692 | | |
1693 | | if (trustAnchor) |
1694 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext); |
1695 | | |
1696 | | if (certPkix) |
1697 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)certPkix, plContext); |
1698 | | |
1699 | | if (error != NULL) { |
1700 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); |
1701 | | PORT_SetError(errCode); |
1702 | | r = SECFailure; |
1703 | | } |
1704 | | |
1705 | | return r; |
1706 | | } |
1707 | | |
1708 | | void |
1709 | | cert_pkixDestroyValOutParam(CERTValOutParam *params) |
1710 | | { |
1711 | | CERTValOutParam *i; |
1712 | | |
1713 | | if (params == NULL) { |
1714 | | return; |
1715 | | } |
1716 | | for (i = params; i->type != cert_po_end; i++) { |
1717 | | switch (i->type) { |
1718 | | case cert_po_trustAnchor: |
1719 | | if (i->value.pointer.cert) { |
1720 | | CERT_DestroyCertificate(i->value.pointer.cert); |
1721 | | i->value.pointer.cert = NULL; |
1722 | | } |
1723 | | break; |
1724 | | |
1725 | | case cert_po_certList: |
1726 | | if (i->value.pointer.chain) { |
1727 | | CERT_DestroyCertList(i->value.pointer.chain); |
1728 | | i->value.pointer.chain = NULL; |
1729 | | } |
1730 | | break; |
1731 | | |
1732 | | default: |
1733 | | break; |
1734 | | } |
1735 | | } |
1736 | | } |
1737 | | |
1738 | | static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_LeafFlags[2] = { |
1739 | | /* crl */ |
1740 | | CERT_REV_M_TEST_USING_THIS_METHOD | |
1741 | | CERT_REV_M_FORBID_NETWORK_FETCHING | |
1742 | | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO, |
1743 | | /* ocsp */ |
1744 | | CERT_REV_M_TEST_USING_THIS_METHOD |
1745 | | }; |
1746 | | |
1747 | | static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_ChainFlags[2] = { |
1748 | | /* crl */ |
1749 | | CERT_REV_M_TEST_USING_THIS_METHOD | |
1750 | | CERT_REV_M_FORBID_NETWORK_FETCHING | |
1751 | | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO, |
1752 | | /* ocsp */ |
1753 | | 0 |
1754 | | }; |
1755 | | |
1756 | | static CERTRevocationMethodIndex |
1757 | | certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_Method_Preference = { |
1758 | | cert_revocation_method_crl |
1759 | | }; |
1760 | | |
1761 | | static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy = { |
1762 | | { /* leafTests */ |
1763 | | 2, |
1764 | | certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_LeafFlags, |
1765 | | 1, |
1766 | | &certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_Method_Preference, |
1767 | | 0 }, |
1768 | | { /* chainTests */ |
1769 | | 2, |
1770 | | certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_ChainFlags, |
1771 | | 0, |
1772 | | 0, |
1773 | | 0 } |
1774 | | }; |
1775 | | #endif /* NSS_DISABLE_LIBPKIX */ |
1776 | | |
1777 | | extern const CERTRevocationFlags * |
1778 | | CERT_GetClassicOCSPEnabledSoftFailurePolicy() |
1779 | 0 | { |
1780 | 0 | #ifdef NSS_DISABLE_LIBPKIX |
1781 | 0 | PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
1782 | 0 | return NULL; |
1783 | | #else |
1784 | | return &certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy; |
1785 | | #endif /* NSS_DISABLE_LIBPKIX */ |
1786 | 0 | } |
1787 | | |
1788 | | #ifndef NSS_DISABLE_LIBPKIX |
1789 | | static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_LeafFlags[2] = { |
1790 | | /* crl */ |
1791 | | CERT_REV_M_TEST_USING_THIS_METHOD | |
1792 | | CERT_REV_M_FORBID_NETWORK_FETCHING | |
1793 | | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO, |
1794 | | /* ocsp */ |
1795 | | CERT_REV_M_TEST_USING_THIS_METHOD | |
1796 | | CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO |
1797 | | }; |
1798 | | |
1799 | | static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_ChainFlags[2] = { |
1800 | | /* crl */ |
1801 | | CERT_REV_M_TEST_USING_THIS_METHOD | |
1802 | | CERT_REV_M_FORBID_NETWORK_FETCHING | |
1803 | | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO, |
1804 | | /* ocsp */ |
1805 | | 0 |
1806 | | }; |
1807 | | |
1808 | | static CERTRevocationMethodIndex |
1809 | | certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_Method_Preference = { |
1810 | | cert_revocation_method_crl |
1811 | | }; |
1812 | | |
1813 | | static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy = { |
1814 | | { /* leafTests */ |
1815 | | 2, |
1816 | | certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_LeafFlags, |
1817 | | 1, |
1818 | | &certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_Method_Preference, |
1819 | | 0 }, |
1820 | | { /* chainTests */ |
1821 | | 2, |
1822 | | certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_ChainFlags, |
1823 | | 0, |
1824 | | 0, |
1825 | | 0 } |
1826 | | }; |
1827 | | #endif /* NSS_DISABLE_LIBPKIX */ |
1828 | | |
1829 | | extern const CERTRevocationFlags * |
1830 | | CERT_GetClassicOCSPEnabledHardFailurePolicy() |
1831 | 0 | { |
1832 | 0 | #ifdef NSS_DISABLE_LIBPKIX |
1833 | 0 | PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
1834 | 0 | return NULL; |
1835 | | #else |
1836 | | return &certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy; |
1837 | | #endif /* NSS_DISABLE_LIBPKIX */ |
1838 | 0 | } |
1839 | | |
1840 | | #ifndef NSS_DISABLE_LIBPKIX |
1841 | | static PRUint64 certRev_NSS_3_11_Ocsp_Disabled_Policy_LeafFlags[2] = { |
1842 | | /* crl */ |
1843 | | CERT_REV_M_TEST_USING_THIS_METHOD | |
1844 | | CERT_REV_M_FORBID_NETWORK_FETCHING | |
1845 | | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO, |
1846 | | /* ocsp */ |
1847 | | 0 |
1848 | | }; |
1849 | | |
1850 | | static PRUint64 certRev_NSS_3_11_Ocsp_Disabled_Policy_ChainFlags[2] = { |
1851 | | /* crl */ |
1852 | | CERT_REV_M_TEST_USING_THIS_METHOD | |
1853 | | CERT_REV_M_FORBID_NETWORK_FETCHING | |
1854 | | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO, |
1855 | | /* ocsp */ |
1856 | | 0 |
1857 | | }; |
1858 | | |
1859 | | static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Disabled_Policy = { |
1860 | | { /* leafTests */ |
1861 | | 2, |
1862 | | certRev_NSS_3_11_Ocsp_Disabled_Policy_LeafFlags, |
1863 | | 0, |
1864 | | 0, |
1865 | | 0 }, |
1866 | | { /* chainTests */ |
1867 | | 2, |
1868 | | certRev_NSS_3_11_Ocsp_Disabled_Policy_ChainFlags, |
1869 | | 0, |
1870 | | 0, |
1871 | | 0 } |
1872 | | }; |
1873 | | #endif /* NSS_DISABLE_LIBPKIX */ |
1874 | | |
1875 | | extern const CERTRevocationFlags * |
1876 | | CERT_GetClassicOCSPDisabledPolicy() |
1877 | 0 | { |
1878 | 0 | #ifdef NSS_DISABLE_LIBPKIX |
1879 | 0 | PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
1880 | 0 | return NULL; |
1881 | | #else |
1882 | | return &certRev_NSS_3_11_Ocsp_Disabled_Policy; |
1883 | | #endif /* NSS_DISABLE_LIBPKIX */ |
1884 | 0 | } |
1885 | | |
1886 | | #ifndef NSS_DISABLE_LIBPKIX |
1887 | | static PRUint64 certRev_PKIX_Verify_Nist_Policy_LeafFlags[2] = { |
1888 | | /* crl */ |
1889 | | CERT_REV_M_TEST_USING_THIS_METHOD | |
1890 | | CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO | |
1891 | | CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE, |
1892 | | /* ocsp */ |
1893 | | 0 |
1894 | | }; |
1895 | | |
1896 | | static PRUint64 certRev_PKIX_Verify_Nist_Policy_ChainFlags[2] = { |
1897 | | /* crl */ |
1898 | | CERT_REV_M_TEST_USING_THIS_METHOD | |
1899 | | CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO | |
1900 | | CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE, |
1901 | | /* ocsp */ |
1902 | | 0 |
1903 | | }; |
1904 | | |
1905 | | static const CERTRevocationFlags certRev_PKIX_Verify_Nist_Policy = { |
1906 | | { /* leafTests */ |
1907 | | 2, |
1908 | | certRev_PKIX_Verify_Nist_Policy_LeafFlags, |
1909 | | 0, |
1910 | | 0, |
1911 | | 0 }, |
1912 | | { /* chainTests */ |
1913 | | 2, |
1914 | | certRev_PKIX_Verify_Nist_Policy_ChainFlags, |
1915 | | 0, |
1916 | | 0, |
1917 | | 0 } |
1918 | | }; |
1919 | | #endif /* NSS_DISABLE_LIBPKIX */ |
1920 | | |
1921 | | extern const CERTRevocationFlags * |
1922 | | CERT_GetPKIXVerifyNistRevocationPolicy() |
1923 | 0 | { |
1924 | 0 | #ifdef NSS_DISABLE_LIBPKIX |
1925 | 0 | PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
1926 | 0 | return NULL; |
1927 | | #else |
1928 | | return &certRev_PKIX_Verify_Nist_Policy; |
1929 | | #endif /* NSS_DISABLE_LIBPKIX */ |
1930 | 0 | } |
1931 | | |
1932 | | CERTRevocationFlags * |
1933 | | CERT_AllocCERTRevocationFlags( |
1934 | | PRUint32 number_leaf_methods, PRUint32 number_leaf_pref_methods, |
1935 | | PRUint32 number_chain_methods, PRUint32 number_chain_pref_methods) |
1936 | 0 | { |
1937 | 0 | #ifdef NSS_DISABLE_LIBPKIX |
1938 | 0 | PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
1939 | 0 | return NULL; |
1940 | | #else |
1941 | | CERTRevocationFlags *flags; |
1942 | | |
1943 | | flags = PORT_New(CERTRevocationFlags); |
1944 | | if (!flags) |
1945 | | return (NULL); |
1946 | | |
1947 | | flags->leafTests.number_of_defined_methods = number_leaf_methods; |
1948 | | flags->leafTests.cert_rev_flags_per_method = |
1949 | | PORT_NewArray(PRUint64, number_leaf_methods); |
1950 | | |
1951 | | flags->leafTests.number_of_preferred_methods = number_leaf_pref_methods; |
1952 | | flags->leafTests.preferred_methods = |
1953 | | PORT_NewArray(CERTRevocationMethodIndex, number_leaf_pref_methods); |
1954 | | |
1955 | | flags->chainTests.number_of_defined_methods = number_chain_methods; |
1956 | | flags->chainTests.cert_rev_flags_per_method = |
1957 | | PORT_NewArray(PRUint64, number_chain_methods); |
1958 | | |
1959 | | flags->chainTests.number_of_preferred_methods = number_chain_pref_methods; |
1960 | | flags->chainTests.preferred_methods = |
1961 | | PORT_NewArray(CERTRevocationMethodIndex, number_chain_pref_methods); |
1962 | | |
1963 | | if (!flags->leafTests.cert_rev_flags_per_method || |
1964 | | !flags->leafTests.preferred_methods || |
1965 | | !flags->chainTests.cert_rev_flags_per_method || |
1966 | | !flags->chainTests.preferred_methods) { |
1967 | | CERT_DestroyCERTRevocationFlags(flags); |
1968 | | return (NULL); |
1969 | | } |
1970 | | |
1971 | | return flags; |
1972 | | #endif /* NSS_DISABLE_LIBPKIX */ |
1973 | 0 | } |
1974 | | |
1975 | | void |
1976 | | CERT_DestroyCERTRevocationFlags(CERTRevocationFlags *flags) |
1977 | 0 | { |
1978 | 0 | #ifdef NSS_DISABLE_LIBPKIX |
1979 | 0 | PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
1980 | 0 | return; |
1981 | | #else |
1982 | | if (!flags) |
1983 | | return; |
1984 | | |
1985 | | if (flags->leafTests.cert_rev_flags_per_method) |
1986 | | PORT_Free(flags->leafTests.cert_rev_flags_per_method); |
1987 | | |
1988 | | if (flags->leafTests.preferred_methods) |
1989 | | PORT_Free(flags->leafTests.preferred_methods); |
1990 | | |
1991 | | if (flags->chainTests.cert_rev_flags_per_method) |
1992 | | PORT_Free(flags->chainTests.cert_rev_flags_per_method); |
1993 | | |
1994 | | if (flags->chainTests.preferred_methods) |
1995 | | PORT_Free(flags->chainTests.preferred_methods); |
1996 | | |
1997 | | PORT_Free(flags); |
1998 | | #endif /* NSS_DISABLE_LIBPKIX */ |
1999 | 0 | } |
2000 | | |
2001 | | /* |
2002 | | * CERT_PKIXVerifyCert |
2003 | | * |
2004 | | * Verify a Certificate using the PKIX library. |
2005 | | * |
2006 | | * Parameters: |
2007 | | * cert - the target certificate to verify. Must be non-null |
2008 | | * params - an array of type/value parameters which can be |
2009 | | * used to modify the behavior of the validation |
2010 | | * algorithm, or supply additional constraints. |
2011 | | * |
2012 | | * outputTrustAnchor - the trust anchor which the certificate |
2013 | | * chains to. The caller is responsible |
2014 | | * for freeing this. |
2015 | | * |
2016 | | * Example Usage: |
2017 | | * CERTValParam args[3]; |
2018 | | * args[0].type = cvpt_policyOID; |
2019 | | * args[0].value.si = oid; |
2020 | | * args[1].type = revCheckRequired; |
2021 | | * args[1].value.b = PR_TRUE; |
2022 | | * args[2].type = cvpt_end; |
2023 | | * |
2024 | | * CERT_PKIXVerifyCert(cert, &output, args |
2025 | | */ |
2026 | | SECStatus |
2027 | | CERT_PKIXVerifyCert( |
2028 | | CERTCertificate *cert, |
2029 | | SECCertificateUsage usages, |
2030 | | CERTValInParam *paramsIn, |
2031 | | CERTValOutParam *paramsOut, |
2032 | | void *wincx) |
2033 | 0 | { |
2034 | 0 | #ifdef NSS_DISABLE_LIBPKIX |
2035 | 0 | PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
2036 | 0 | return SECFailure; |
2037 | | #else |
2038 | | SECStatus r = SECFailure; |
2039 | | PKIX_Error *error = NULL; |
2040 | | PKIX_ProcessingParams *procParams = NULL; |
2041 | | PKIX_BuildResult *buildResult = NULL; |
2042 | | void *nbioContext = NULL; /* for non-blocking IO */ |
2043 | | void *buildState = NULL; /* for non-blocking IO */ |
2044 | | PKIX_CertSelector *certSelector = NULL; |
2045 | | PKIX_List *certStores = NULL; |
2046 | | PKIX_ValidateResult *valResult = NULL; |
2047 | | PKIX_VerifyNode *verifyNode = NULL; |
2048 | | PKIX_TrustAnchor *trustAnchor = NULL; |
2049 | | PKIX_PL_Cert *trustAnchorCert = NULL; |
2050 | | PKIX_List *builtCertList = NULL; |
2051 | | CERTValOutParam *oparam = NULL; |
2052 | | int i = 0; |
2053 | | |
2054 | | void *plContext = NULL; |
2055 | | |
2056 | | #ifdef PKIX_OBJECT_LEAK_TEST |
2057 | | int leakedObjNum = 0; |
2058 | | int memLeakLoopCount = 0; |
2059 | | int objCountTable[PKIX_NUMTYPES]; |
2060 | | int fnInvLocalCount = 0; |
2061 | | PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine; |
2062 | | |
2063 | | if (usePKIXValidationEngine) { |
2064 | | /* current memory leak testing implementation does not allow |
2065 | | * to run simultaneous tests one the same or a different threads. |
2066 | | * Setting the variable to false, to make additional chain |
2067 | | * validations be handled by old nss. */ |
2068 | | usePKIXValidationEngine = PR_FALSE; |
2069 | | } |
2070 | | testStartFnStackPosition = 1; |
2071 | | fnStackNameArr[0] = "CERT_PKIXVerifyCert"; |
2072 | | fnStackInvCountArr[0] = 0; |
2073 | | PKIX_Boolean abortOnLeak = |
2074 | | (PR_GetEnvSecure("PKIX_OBJECT_LEAK_TEST_ABORT_ON_LEAK") == NULL) ? PKIX_FALSE |
2075 | | : PKIX_TRUE; |
2076 | | runningLeakTest = PKIX_TRUE; |
2077 | | |
2078 | | /* Prevent multi-threaded run of object leak test */ |
2079 | | fnInvLocalCount = PR_ATOMIC_INCREMENT(¶llelFnInvocationCount); |
2080 | | PORT_Assert(fnInvLocalCount == 1); |
2081 | | |
2082 | | do { |
2083 | | r = SECFailure; |
2084 | | error = NULL; |
2085 | | procParams = NULL; |
2086 | | buildResult = NULL; |
2087 | | nbioContext = NULL; /* for non-blocking IO */ |
2088 | | buildState = NULL; /* for non-blocking IO */ |
2089 | | certSelector = NULL; |
2090 | | certStores = NULL; |
2091 | | valResult = NULL; |
2092 | | verifyNode = NULL; |
2093 | | trustAnchor = NULL; |
2094 | | trustAnchorCert = NULL; |
2095 | | builtCertList = NULL; |
2096 | | oparam = NULL; |
2097 | | i = 0; |
2098 | | errorGenerated = PKIX_FALSE; |
2099 | | stackPosition = 0; |
2100 | | |
2101 | | if (leakedObjNum) { |
2102 | | pkix_pl_lifecycle_ObjectTableUpdate(objCountTable); |
2103 | | } |
2104 | | memLeakLoopCount += 1; |
2105 | | #endif /* PKIX_OBJECT_LEAK_TEST */ |
2106 | | |
2107 | | error = PKIX_PL_NssContext_Create( |
2108 | | 0, PR_FALSE /*use arena*/, wincx, &plContext); |
2109 | | if (error != NULL) { /* need pkix->nss error map */ |
2110 | | PORT_SetError(SEC_ERROR_CERT_NOT_VALID); |
2111 | | goto cleanup; |
2112 | | } |
2113 | | |
2114 | | error = pkix_pl_NssContext_SetCertUsage(usages, plContext); |
2115 | | if (error != NULL) { |
2116 | | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
2117 | | goto cleanup; |
2118 | | } |
2119 | | |
2120 | | error = PKIX_ProcessingParams_Create(&procParams, plContext); |
2121 | | if (error != NULL) { /* need pkix->nss error map */ |
2122 | | PORT_SetError(SEC_ERROR_CERT_NOT_VALID); |
2123 | | goto cleanup; |
2124 | | } |
2125 | | |
2126 | | /* local cert store should be set into procParams before |
2127 | | * filling in revocation settings. */ |
2128 | | certStores = cert_GetCertStores(plContext); |
2129 | | if (certStores == NULL) { |
2130 | | goto cleanup; |
2131 | | } |
2132 | | error = PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext); |
2133 | | if (error != NULL) { |
2134 | | goto cleanup; |
2135 | | } |
2136 | | |
2137 | | /* now process the extensible input parameters structure */ |
2138 | | if (paramsIn != NULL) { |
2139 | | i = 0; |
2140 | | while (paramsIn[i].type != cert_pi_end) { |
2141 | | if (paramsIn[i].type >= cert_pi_max) { |
2142 | | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
2143 | | goto cleanup; |
2144 | | } |
2145 | | if (cert_pkixSetParam(procParams, |
2146 | | ¶msIn[i], plContext) != |
2147 | | SECSuccess) { |
2148 | | PORT_SetError(SEC_ERROR_INVALID_ARGS); |
2149 | | goto cleanup; |
2150 | | } |
2151 | | i++; |
2152 | | } |
2153 | | } |
2154 | | |
2155 | | certSelector = cert_GetTargetCertConstraints(cert, plContext); |
2156 | | if (certSelector == NULL) { |
2157 | | goto cleanup; |
2158 | | } |
2159 | | error = PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext); |
2160 | | if (error != NULL) { |
2161 | | goto cleanup; |
2162 | | } |
2163 | | |
2164 | | error = PKIX_BuildChain(procParams, &nbioContext, |
2165 | | &buildState, &buildResult, &verifyNode, |
2166 | | plContext); |
2167 | | if (error != NULL) { |
2168 | | goto cleanup; |
2169 | | } |
2170 | | |
2171 | | error = PKIX_BuildResult_GetValidateResult(buildResult, &valResult, |
2172 | | plContext); |
2173 | | if (error != NULL) { |
2174 | | goto cleanup; |
2175 | | } |
2176 | | |
2177 | | error = PKIX_ValidateResult_GetTrustAnchor(valResult, &trustAnchor, |
2178 | | plContext); |
2179 | | if (error != NULL) { |
2180 | | goto cleanup; |
2181 | | } |
2182 | | |
2183 | | if (trustAnchor != NULL) { |
2184 | | error = PKIX_TrustAnchor_GetTrustedCert(trustAnchor, &trustAnchorCert, |
2185 | | plContext); |
2186 | | if (error != NULL) { |
2187 | | goto cleanup; |
2188 | | } |
2189 | | } |
2190 | | |
2191 | | #ifdef PKIX_OBJECT_LEAK_TEST |
2192 | | /* Can not continue if error was generated but not returned. |
2193 | | * Jumping to cleanup. */ |
2194 | | if (errorGenerated) |
2195 | | goto cleanup; |
2196 | | #endif /* PKIX_OBJECT_LEAK_TEST */ |
2197 | | |
2198 | | oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_trustAnchor); |
2199 | | if (oparam != NULL) { |
2200 | | if (trustAnchorCert != NULL) { |
2201 | | oparam->value.pointer.cert = |
2202 | | cert_NSSCertFromPKIXCert(trustAnchorCert); |
2203 | | } else { |
2204 | | oparam->value.pointer.cert = NULL; |
2205 | | } |
2206 | | } |
2207 | | |
2208 | | error = PKIX_BuildResult_GetCertChain(buildResult, &builtCertList, |
2209 | | plContext); |
2210 | | if (error != NULL) { |
2211 | | goto cleanup; |
2212 | | } |
2213 | | |
2214 | | oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_certList); |
2215 | | if (oparam != NULL) { |
2216 | | error = cert_PkixToNssCertsChain(builtCertList, |
2217 | | &oparam->value.pointer.chain, |
2218 | | plContext); |
2219 | | if (error) |
2220 | | goto cleanup; |
2221 | | } |
2222 | | |
2223 | | r = SECSuccess; |
2224 | | |
2225 | | cleanup: |
2226 | | if (verifyNode) { |
2227 | | /* Return validation log only upon error. */ |
2228 | | oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_errorLog); |
2229 | | #ifdef PKIX_OBJECT_LEAK_TEST |
2230 | | if (!errorGenerated) |
2231 | | #endif /* PKIX_OBJECT_LEAK_TEST */ |
2232 | | if (r && oparam != NULL) { |
2233 | | PKIX_Error *tmpError = |
2234 | | cert_GetLogFromVerifyNode(oparam->value.pointer.log, |
2235 | | verifyNode, plContext); |
2236 | | if (tmpError) { |
2237 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext); |
2238 | | } |
2239 | | } |
2240 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)verifyNode, plContext); |
2241 | | } |
2242 | | |
2243 | | if (procParams != NULL) |
2244 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext); |
2245 | | |
2246 | | if (trustAnchorCert != NULL) |
2247 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchorCert, plContext); |
2248 | | |
2249 | | if (trustAnchor != NULL) |
2250 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext); |
2251 | | |
2252 | | if (valResult != NULL) |
2253 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)valResult, plContext); |
2254 | | |
2255 | | if (buildResult != NULL) |
2256 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)buildResult, plContext); |
2257 | | |
2258 | | if (certStores != NULL) |
2259 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext); |
2260 | | |
2261 | | if (certSelector != NULL) |
2262 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext); |
2263 | | |
2264 | | if (builtCertList != NULL) |
2265 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)builtCertList, plContext); |
2266 | | |
2267 | | if (error != NULL) { |
2268 | | SECErrorCodes nssErrorCode = 0; |
2269 | | |
2270 | | cert_PkixErrorToNssCode(error, &nssErrorCode, plContext); |
2271 | | cert_pkixDestroyValOutParam(paramsOut); |
2272 | | PORT_SetError(nssErrorCode); |
2273 | | PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext); |
2274 | | } |
2275 | | |
2276 | | PKIX_PL_NssContext_Destroy(plContext); |
2277 | | |
2278 | | #ifdef PKIX_OBJECT_LEAK_TEST |
2279 | | leakedObjNum = |
2280 | | pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL); |
2281 | | |
2282 | | if (pkixLog && leakedObjNum) { |
2283 | | PR_LOG(pkixLog, 1, ("The generated error caused an object leaks. Loop %d." |
2284 | | "Stack %s\n", |
2285 | | memLeakLoopCount, errorFnStackString)); |
2286 | | } |
2287 | | PR_Free(errorFnStackString); |
2288 | | errorFnStackString = NULL; |
2289 | | if (abortOnLeak) { |
2290 | | PORT_Assert(leakedObjNum == 0); |
2291 | | } |
2292 | | |
2293 | | } while (errorGenerated); |
2294 | | |
2295 | | runningLeakTest = PKIX_FALSE; |
2296 | | PR_ATOMIC_DECREMENT(¶llelFnInvocationCount); |
2297 | | usePKIXValidationEngine = savedUsePkixEngFlag; |
2298 | | #endif /* PKIX_OBJECT_LEAK_TEST */ |
2299 | | |
2300 | | return r; |
2301 | | #endif /* NSS_DISABLE_LIBPKIX */ |
2302 | 0 | } |