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