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 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)