Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
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 * pkix_targetcertchecker.c | |
6 * | |
7 * Functions for target cert validation | |
8 * | |
9 */ | |
10 | |
11 | |
12 #include "pkix_targetcertchecker.h" | |
13 | |
14 /* --Private-TargetCertCheckerState-Functions------------------------------- */ | |
15 | |
16 /* | |
17 * FUNCTION: pkix_TargetCertCheckerState_Destroy | |
18 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |
19 */ | |
20 static PKIX_Error * | |
21 pkix_TargetCertCheckerState_Destroy( | |
22 PKIX_PL_Object *object, | |
23 void *plContext) | |
24 { | |
25 pkix_TargetCertCheckerState *state = NULL; | |
26 | |
27 PKIX_ENTER(TARGETCERTCHECKERSTATE, | |
28 "pkix_TargetCertCheckerState_Destroy"); | |
29 PKIX_NULLCHECK_ONE(object); | |
30 | |
31 /* Check that this object is a target cert checker state */ | |
32 PKIX_CHECK(pkix_CheckType | |
33 (object, PKIX_TARGETCERTCHECKERSTATE_TYPE, plContext), | |
34 PKIX_OBJECTNOTTARGETCERTCHECKERSTATE); | |
35 | |
36 state = (pkix_TargetCertCheckerState *)object; | |
37 | |
38 PKIX_DECREF(state->certSelector); | |
39 PKIX_DECREF(state->extKeyUsageOID); | |
40 PKIX_DECREF(state->subjAltNameOID); | |
41 PKIX_DECREF(state->pathToNameList); | |
42 PKIX_DECREF(state->extKeyUsageList); | |
43 PKIX_DECREF(state->subjAltNameList); | |
44 | |
45 cleanup: | |
46 | |
47 PKIX_RETURN(TARGETCERTCHECKERSTATE); | |
48 } | |
49 | |
50 /* | |
51 * FUNCTION: pkix_TargetCertCheckerState_RegisterSelf | |
52 * DESCRIPTION: | |
53 * Registers PKIX_TARGETCERTCHECKERSTATE_TYPE and its related functions with | |
54 * systemClasses[] | |
55 * THREAD SAFETY: | |
56 * Not Thread Safe - for performance and complexity reasons | |
57 * | |
58 * Since this function is only called by PKIX_PL_Initialize, which should | |
59 * only be called once, it is acceptable that this function is not | |
60 * thread-safe. | |
61 */ | |
62 PKIX_Error * | |
63 pkix_TargetCertCheckerState_RegisterSelf(void *plContext) | |
64 { | |
65 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |
66 pkix_ClassTable_Entry entry; | |
67 | |
68 PKIX_ENTER(TARGETCERTCHECKERSTATE, | |
69 "pkix_TargetCertCheckerState_RegisterSelf"); | |
70 | |
71 entry.description = "TargetCertCheckerState"; | |
72 entry.objCounter = 0; | |
73 entry.typeObjectSize = sizeof(pkix_TargetCertCheckerState); | |
74 entry.destructor = pkix_TargetCertCheckerState_Destroy; | |
75 entry.equalsFunction = NULL; | |
76 entry.hashcodeFunction = NULL; | |
77 entry.toStringFunction = NULL; | |
78 entry.comparator = NULL; | |
79 entry.duplicateFunction = NULL; | |
80 | |
81 systemClasses[PKIX_TARGETCERTCHECKERSTATE_TYPE] = entry; | |
82 | |
83 PKIX_RETURN(TARGETCERTCHECKERSTATE); | |
84 } | |
85 | |
86 /* | |
87 * FUNCTION: pkix_TargetCertCheckerState_Create | |
88 * DESCRIPTION: | |
89 * | |
90 * Creates a new TargetCertCheckerState using the CertSelector pointed to | |
91 * by "certSelector" and the number of certs represented by "certsRemaining" | |
92 * and stores it at "pState". | |
93 * | |
94 * PARAMETERS: | |
95 * "certSelector" | |
96 * Address of CertSelector representing the criteria against which the | |
97 * final certificate in a chain is to be matched. Must be non-NULL. | |
98 * "certsRemaining" | |
99 * Number of certificates remaining in the chain. | |
100 * "pState" | |
101 * Address where object pointer will be stored. Must be non-NULL. | |
102 * "plContext" | |
103 * Platform-specific context pointer. | |
104 * THREAD SAFETY: | |
105 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
106 * RETURNS: | |
107 * Returns NULL if the function succeeds. | |
108 * Returns a TargetCertCheckerState Error if the function fails in a | |
109 * non-fatal way. | |
110 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
111 */ | |
112 PKIX_Error * | |
113 pkix_TargetCertCheckerState_Create( | |
114 PKIX_CertSelector *certSelector, | |
115 PKIX_UInt32 certsRemaining, | |
116 pkix_TargetCertCheckerState **pState, | |
117 void *plContext) | |
118 { | |
119 pkix_TargetCertCheckerState *state = NULL; | |
120 PKIX_ComCertSelParams *certSelectorParams = NULL; | |
121 PKIX_List *pathToNameList = NULL; | |
122 PKIX_List *extKeyUsageList = NULL; | |
123 PKIX_List *subjAltNameList = NULL; | |
124 PKIX_PL_OID *extKeyUsageOID = NULL; | |
125 PKIX_PL_OID *subjAltNameOID = NULL; | |
126 PKIX_Boolean subjAltNameMatchAll = PKIX_TRUE; | |
127 | |
128 PKIX_ENTER(TARGETCERTCHECKERSTATE, | |
129 "pkix_TargetCertCheckerState_Create"); | |
130 PKIX_NULLCHECK_ONE(pState); | |
131 | |
132 PKIX_CHECK(PKIX_PL_OID_Create | |
133 (PKIX_EXTENDEDKEYUSAGE_OID, | |
134 &extKeyUsageOID, | |
135 plContext), | |
136 PKIX_OIDCREATEFAILED); | |
137 | |
138 PKIX_CHECK(PKIX_PL_OID_Create | |
139 (PKIX_CERTSUBJALTNAME_OID, | |
140 &subjAltNameOID, | |
141 plContext), | |
142 PKIX_OIDCREATEFAILED); | |
143 | |
144 PKIX_CHECK(PKIX_PL_Object_Alloc | |
145 (PKIX_TARGETCERTCHECKERSTATE_TYPE, | |
146 sizeof (pkix_TargetCertCheckerState), | |
147 (PKIX_PL_Object **)&state, | |
148 plContext), | |
149 PKIX_COULDNOTCREATETARGETCERTCHECKERSTATEOBJECT); | |
150 | |
151 /* initialize fields */ | |
152 | |
153 if (certSelector != NULL) { | |
154 | |
155 PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams | |
156 (certSelector, &certSelectorParams, plContext), | |
157 PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMFAILED); | |
158 | |
159 if (certSelectorParams != NULL) { | |
160 | |
161 PKIX_CHECK(PKIX_ComCertSelParams_GetPathToNames | |
162 (certSelectorParams, | |
163 &pathToNameList, | |
164 plContext), | |
165 PKIX_COMCERTSELPARAMSGETPATHTONAMESFAILED); | |
166 | |
167 PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage | |
168 (certSelectorParams, | |
169 &extKeyUsageList, | |
170 plContext), | |
171 PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED); | |
172 | |
173 PKIX_CHECK(PKIX_ComCertSelParams_GetSubjAltNames | |
174 (certSelectorParams, | |
175 &subjAltNameList, | |
176 plContext), | |
177 PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED); | |
178 | |
179 PKIX_CHECK(PKIX_ComCertSelParams_GetMatchAllSubjAltNames | |
180 (certSelectorParams, | |
181 &subjAltNameMatchAll, | |
182 plContext), | |
183 PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED); | |
184 } | |
185 } | |
186 | |
187 state->certsRemaining = certsRemaining; | |
188 state->subjAltNameMatchAll = subjAltNameMatchAll; | |
189 | |
190 PKIX_INCREF(certSelector); | |
191 state->certSelector = certSelector; | |
192 | |
193 state->pathToNameList = pathToNameList; | |
194 pathToNameList = NULL; | |
195 | |
196 state->extKeyUsageList = extKeyUsageList; | |
197 extKeyUsageList = NULL; | |
198 | |
199 state->subjAltNameList = subjAltNameList; | |
200 subjAltNameList = NULL; | |
201 | |
202 state->extKeyUsageOID = extKeyUsageOID; | |
203 extKeyUsageOID = NULL; | |
204 | |
205 state->subjAltNameOID = subjAltNameOID; | |
206 subjAltNameOID = NULL; | |
207 | |
208 *pState = state; | |
209 state = NULL; | |
210 | |
211 cleanup: | |
212 | |
213 PKIX_DECREF(extKeyUsageOID); | |
214 PKIX_DECREF(subjAltNameOID); | |
215 PKIX_DECREF(pathToNameList); | |
216 PKIX_DECREF(extKeyUsageList); | |
217 PKIX_DECREF(subjAltNameList); | |
218 PKIX_DECREF(state); | |
219 | |
220 PKIX_DECREF(certSelectorParams); | |
221 | |
222 PKIX_RETURN(TARGETCERTCHECKERSTATE); | |
223 | |
224 } | |
225 | |
226 /* --Private-TargetCertChecker-Functions------------------------------- */ | |
227 | |
228 /* | |
229 * FUNCTION: pkix_TargetCertChecker_Check | |
230 * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h) | |
231 */ | |
232 PKIX_Error * | |
233 pkix_TargetCertChecker_Check( | |
234 PKIX_CertChainChecker *checker, | |
235 PKIX_PL_Cert *cert, | |
236 PKIX_List *unresolvedCriticalExtensions, | |
237 void **pNBIOContext, | |
238 void *plContext) | |
239 { | |
240 pkix_TargetCertCheckerState *state = NULL; | |
241 PKIX_CertSelector_MatchCallback certSelectorMatch = NULL; | |
242 PKIX_PL_CertNameConstraints *nameConstraints = NULL; | |
243 PKIX_List *certSubjAltNames = NULL; | |
244 PKIX_List *certExtKeyUsageList = NULL; | |
245 PKIX_PL_GeneralName *name = NULL; | |
246 PKIX_PL_X500Name *certSubjectName = NULL; | |
247 PKIX_Boolean checkPassed = PKIX_FALSE; | |
248 PKIX_UInt32 numItems, i; | |
249 PKIX_UInt32 matchCount = 0; | |
250 | |
251 PKIX_ENTER(CERTCHAINCHECKER, "pkix_TargetCertChecker_Check"); | |
252 PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext); | |
253 | |
254 *pNBIOContext = NULL; /* we never block on pending I/O */ | |
255 | |
256 PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState | |
257 (checker, (PKIX_PL_Object **)&state, plContext), | |
258 PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED); | |
259 | |
260 (state->certsRemaining)--; | |
261 | |
262 if (state->pathToNameList != NULL) { | |
263 | |
264 PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints | |
265 (cert, &nameConstraints, plContext), | |
266 PKIX_CERTGETNAMECONSTRAINTSFAILED); | |
267 | |
268 /* | |
269 * XXX We should either make the following call a public one | |
270 * so it is legal to call from the portability layer or we | |
271 * should try to create pathToNameList as CertNameConstraints | |
272 * then call the existing check function. | |
273 */ | |
274 PKIX_CHECK(PKIX_PL_CertNameConstraints_CheckNamesInNameSpace | |
275 (state->pathToNameList, | |
276 nameConstraints, | |
277 &checkPassed, | |
278 plContext), | |
279 PKIX_CERTNAMECONSTRAINTSCHECKNAMEINNAMESPACEFAILED); | |
280 | |
281 if (checkPassed != PKIX_TRUE) { | |
282 PKIX_ERROR(PKIX_VALIDATIONFAILEDPATHTONAMECHECKFAILED); | |
283 } | |
284 | |
285 } | |
286 | |
287 PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames | |
288 (cert, &certSubjAltNames, plContext), | |
289 PKIX_CERTGETSUBJALTNAMESFAILED); | |
290 | |
291 if (state->subjAltNameList != NULL && certSubjAltNames != NULL) { | |
292 | |
293 PKIX_CHECK(PKIX_List_GetLength | |
294 (state->subjAltNameList, &numItems, plContext), | |
295 PKIX_LISTGETLENGTHFAILED); | |
296 | |
297 for (i = 0; i < numItems; i++) { | |
298 | |
299 PKIX_CHECK(PKIX_List_GetItem | |
300 (state->subjAltNameList, | |
301 i, | |
302 (PKIX_PL_Object **) &name, | |
303 plContext), | |
304 PKIX_LISTGETITEMFAILED); | |
305 | |
306 PKIX_CHECK(pkix_List_Contains | |
307 (certSubjAltNames, | |
308 (PKIX_PL_Object *) name, | |
309 &checkPassed, | |
310 plContext), | |
311 PKIX_LISTCONTAINSFAILED); | |
312 | |
313 PKIX_DECREF(name); | |
314 | |
315 if (checkPassed == PKIX_TRUE) { | |
316 | |
317 if (state->subjAltNameMatchAll == PKIX_FALSE) { | |
318 matchCount = numItems; | |
319 break; | |
320 } else { | |
321 /* else continue checking next */ | |
322 matchCount++; | |
323 } | |
324 | |
325 } | |
326 } | |
327 | |
328 if (matchCount != numItems) { | |
329 PKIX_ERROR(PKIX_SUBJALTNAMECHECKFAILED); | |
330 | |
331 } | |
332 } | |
333 | |
334 if (state->certsRemaining == 0) { | |
335 | |
336 if (state->certSelector != NULL) { | |
337 PKIX_CHECK(PKIX_CertSelector_GetMatchCallback | |
338 (state->certSelector, | |
339 &certSelectorMatch, | |
340 plContext), | |
341 PKIX_CERTSELECTORGETMATCHCALLBACKFAILED); | |
342 | |
343 PKIX_CHECK(certSelectorMatch | |
344 (state->certSelector, | |
345 cert, | |
346 plContext), | |
347 PKIX_CERTSELECTORMATCHFAILED); | |
348 } else { | |
349 /* Check at least cert/key usages if target cert selector | |
350 * is not set. */ | |
351 PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, | |
352 PKIX_FALSE /* is chain cert*/, | |
353 plContext), | |
354 PKIX_CERTVERIFYCERTTYPEFAILED); | |
355 } | |
356 /* | |
357 * There are two Extended Key Usage Checkings | |
358 * available : | |
359 * 1) here at the targetcertchecker where we | |
360 * verify the Extended Key Usage OIDs application | |
361 * specifies via ComCertSelParams are included | |
362 * in Cert's Extended Key Usage OID's. Note, | |
363 * this is an OID to OID comparison and only last | |
364 * Cert is checked. | |
365 * 2) at user defined ekuchecker where checking | |
366 * is applied to all Certs on the chain and | |
367 * the NSS Extended Key Usage algorithm is | |
368 * used. In order to invoke this checking, not | |
369 * only does the ComCertSelparams needs to be | |
370 * set, the EKU initialize call is required to | |
371 * activate the checking. | |
372 * | |
373 * XXX We use the same ComCertSelParams Set/Get | |
374 * functions to set the parameters for both cases. | |
375 * We may want to separate them in the future. | |
376 */ | |
377 | |
378 PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage | |
379 (cert, &certExtKeyUsageList, plContext), | |
380 PKIX_CERTGETEXTENDEDKEYUSAGEFAILED); | |
381 | |
382 | |
383 if (state->extKeyUsageList != NULL && | |
384 certExtKeyUsageList != NULL) { | |
385 | |
386 PKIX_CHECK(PKIX_List_GetLength | |
387 (state->extKeyUsageList, &numItems, plContext), | |
388 PKIX_LISTGETLENGTHFAILED); | |
389 | |
390 for (i = 0; i < numItems; i++) { | |
391 | |
392 PKIX_CHECK(PKIX_List_GetItem | |
393 (state->extKeyUsageList, | |
394 i, | |
395 (PKIX_PL_Object **) &name, | |
396 plContext), | |
397 PKIX_LISTGETITEMFAILED); | |
398 | |
399 PKIX_CHECK(pkix_List_Contains | |
400 (certExtKeyUsageList, | |
401 (PKIX_PL_Object *) name, | |
402 &checkPassed, | |
403 plContext), | |
404 PKIX_LISTCONTAINSFAILED); | |
405 | |
406 PKIX_DECREF(name); | |
407 | |
408 if (checkPassed != PKIX_TRUE) { | |
409 PKIX_ERROR | |
410 (PKIX_EXTENDEDKEYUSAGECHECKINGFAILED); | |
411 | |
412 } | |
413 } | |
414 } | |
415 } else { | |
416 /* Check key usage and cert type based on certificate usage. */ | |
417 PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, PKIX_TRUE, | |
418 plContext), | |
419 PKIX_CERTVERIFYCERTTYPEFAILED); | |
420 } | |
421 | |
422 /* Remove Critical Extension OID from list */ | |
423 if (unresolvedCriticalExtensions != NULL) { | |
424 | |
425 PKIX_CHECK(pkix_List_Remove | |
426 (unresolvedCriticalExtensions, | |
427 (PKIX_PL_Object *) state->extKeyUsageOID, | |
428 plContext), | |
429 PKIX_LISTREMOVEFAILED); | |
430 | |
431 PKIX_CHECK(PKIX_PL_Cert_GetSubject | |
432 (cert, &certSubjectName, plContext), | |
433 PKIX_CERTGETSUBJECTFAILED); | |
434 | |
435 if (certSubjAltNames != NULL) { | |
436 PKIX_CHECK(pkix_List_Remove | |
437 (unresolvedCriticalExtensions, | |
438 (PKIX_PL_Object *) state->subjAltNameOID, | |
439 plContext), | |
440 PKIX_LISTREMOVEFAILED); | |
441 } | |
442 | |
443 } | |
444 | |
445 cleanup: | |
446 | |
447 PKIX_DECREF(name); | |
448 PKIX_DECREF(nameConstraints); | |
449 PKIX_DECREF(certSubjAltNames); | |
450 PKIX_DECREF(certExtKeyUsageList); | |
451 PKIX_DECREF(certSubjectName); | |
452 PKIX_DECREF(state); | |
453 | |
454 PKIX_RETURN(CERTCHAINCHECKER); | |
455 | |
456 } | |
457 | |
458 /* | |
459 * FUNCTION: pkix_TargetCertChecker_Initialize | |
460 * DESCRIPTION: | |
461 * | |
462 * Creates a new CertChainChecker and stores it at "pChecker", where it will | |
463 * used by pkix_TargetCertChecker_Check to check that the final certificate | |
464 * of a chain meets the criteria of the CertSelector pointed to by | |
465 * "certSelector". The number of certs remaining in the chain, represented by | |
466 * "certsRemaining" is used to initialize the checker's state. | |
467 * | |
468 * PARAMETERS: | |
469 * "certSelector" | |
470 * Address of CertSelector representing the criteria against which the | |
471 * final certificate in a chain is to be matched. May be NULL. | |
472 * "certsRemaining" | |
473 * Number of certificates remaining in the chain. | |
474 * "pChecker" | |
475 * Address where object pointer will be stored. Must be non-NULL. | |
476 * "plContext" | |
477 * Platform-specific context pointer. | |
478 * THREAD SAFETY: | |
479 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
480 * RETURNS: | |
481 * Returns NULL if the function succeeds. | |
482 * Returns a CertChainChecker Error if the function fails in a non-fatal way. | |
483 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
484 */ | |
485 PKIX_Error * | |
486 pkix_TargetCertChecker_Initialize( | |
487 PKIX_CertSelector *certSelector, | |
488 PKIX_UInt32 certsRemaining, | |
489 PKIX_CertChainChecker **pChecker, | |
490 void *plContext) | |
491 { | |
492 pkix_TargetCertCheckerState *state = NULL; | |
493 | |
494 PKIX_ENTER(CERTCHAINCHECKER, "pkix_TargetCertChecker_Initialize"); | |
495 PKIX_NULLCHECK_ONE(pChecker); | |
496 | |
497 PKIX_CHECK(pkix_TargetCertCheckerState_Create | |
498 (certSelector, certsRemaining, &state, plContext), | |
499 PKIX_TARGETCERTCHECKERSTATECREATEFAILED); | |
500 | |
501 PKIX_CHECK(PKIX_CertChainChecker_Create | |
502 (pkix_TargetCertChecker_Check, | |
503 PKIX_FALSE, | |
504 PKIX_FALSE, | |
505 NULL, | |
506 (PKIX_PL_Object *)state, | |
507 pChecker, | |
508 plContext), | |
509 PKIX_CERTCHAINCHECKERCREATEFAILED); | |
510 | |
511 cleanup: | |
512 | |
513 PKIX_DECREF(state); | |
514 | |
515 PKIX_RETURN(CERTCHAINCHECKER); | |
516 } |