|
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_nameconstraintschecker.c |
|
6 * |
|
7 * Functions for Name Constraints Checkers |
|
8 * |
|
9 */ |
|
10 |
|
11 #include "pkix_nameconstraintschecker.h" |
|
12 |
|
13 /* --Private-NameConstraintsCheckerState-Functions---------------------- */ |
|
14 |
|
15 /* |
|
16 * FUNCTION: pkix_NameConstraintsCheckerstate_Destroy |
|
17 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) |
|
18 */ |
|
19 static PKIX_Error * |
|
20 pkix_NameConstraintsCheckerState_Destroy( |
|
21 PKIX_PL_Object *object, |
|
22 void *plContext) |
|
23 { |
|
24 pkix_NameConstraintsCheckerState *state = NULL; |
|
25 |
|
26 PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE, |
|
27 "pkix_NameConstraintsCheckerState_Destroy"); |
|
28 PKIX_NULLCHECK_ONE(object); |
|
29 |
|
30 /* Check that object type */ |
|
31 PKIX_CHECK(pkix_CheckType |
|
32 (object, PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE, plContext), |
|
33 PKIX_OBJECTNOTNAMECONSTRAINTSCHECKERSTATE); |
|
34 |
|
35 state = (pkix_NameConstraintsCheckerState *)object; |
|
36 |
|
37 PKIX_DECREF(state->nameConstraints); |
|
38 PKIX_DECREF(state->nameConstraintsOID); |
|
39 |
|
40 cleanup: |
|
41 |
|
42 PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE); |
|
43 } |
|
44 |
|
45 /* |
|
46 * FUNCTION: pkix_NameConstraintsCheckerState_RegisterSelf |
|
47 * |
|
48 * DESCRIPTION: |
|
49 * Registers PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE and its related |
|
50 * functions with systemClasses[] |
|
51 * |
|
52 * THREAD SAFETY: |
|
53 * Not Thread Safe - for performance and complexity reasons |
|
54 * |
|
55 * Since this function is only called by PKIX_PL_Initialize, which should |
|
56 * only be called once, it is acceptable that this function is not |
|
57 * thread-safe. |
|
58 */ |
|
59 PKIX_Error * |
|
60 pkix_NameConstraintsCheckerState_RegisterSelf(void *plContext) |
|
61 { |
|
62 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; |
|
63 pkix_ClassTable_Entry entry; |
|
64 |
|
65 PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE, |
|
66 "pkix_NameConstraintsCheckerState_RegisterSelf"); |
|
67 |
|
68 entry.description = "NameConstraintsCheckerState"; |
|
69 entry.objCounter = 0; |
|
70 entry.typeObjectSize = sizeof(pkix_NameConstraintsCheckerState); |
|
71 entry.destructor = pkix_NameConstraintsCheckerState_Destroy; |
|
72 entry.equalsFunction = NULL; |
|
73 entry.hashcodeFunction = NULL; |
|
74 entry.toStringFunction = NULL; |
|
75 entry.comparator = NULL; |
|
76 entry.duplicateFunction = NULL; |
|
77 |
|
78 systemClasses[PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE] = entry; |
|
79 |
|
80 PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE); |
|
81 } |
|
82 |
|
83 /* |
|
84 * FUNCTION: pkix_NameConstraintsCheckerState_Create |
|
85 * |
|
86 * DESCRIPTION: |
|
87 * Allocate and initialize NameConstraintsChecker state data. |
|
88 * |
|
89 * PARAMETERS |
|
90 * "nameConstraints" |
|
91 * Address of NameConstraints to be stored in state. May be NULL. |
|
92 * "numCerts" |
|
93 * Number of certificates in the validation chain. This data is used |
|
94 * to identify end-entity. |
|
95 * "pCheckerState" |
|
96 * Address of NameConstraintsCheckerState that is returned. Must be |
|
97 * non-NULL. |
|
98 * "plContext" - Platform-specific context pointer. |
|
99 * |
|
100 * THREAD SAFETY: |
|
101 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
|
102 * |
|
103 * RETURNS: |
|
104 * Returns NULL if the function succeeds. |
|
105 * Returns a CERTNAMECONSTRAINTSCHECKERSTATE Error if the function fails in |
|
106 * a non-fatal way. |
|
107 * Returns a Fatal Error |
|
108 */ |
|
109 static PKIX_Error * |
|
110 pkix_NameConstraintsCheckerState_Create( |
|
111 PKIX_PL_CertNameConstraints *nameConstraints, |
|
112 PKIX_UInt32 numCerts, |
|
113 pkix_NameConstraintsCheckerState **pCheckerState, |
|
114 void *plContext) |
|
115 { |
|
116 pkix_NameConstraintsCheckerState *state = NULL; |
|
117 |
|
118 PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE, |
|
119 "pkix_NameConstraintsCheckerState_Create"); |
|
120 PKIX_NULLCHECK_ONE(pCheckerState); |
|
121 |
|
122 PKIX_CHECK(PKIX_PL_Object_Alloc |
|
123 (PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE, |
|
124 sizeof (pkix_NameConstraintsCheckerState), |
|
125 (PKIX_PL_Object **)&state, |
|
126 plContext), |
|
127 PKIX_COULDNOTCREATENAMECONSTRAINTSCHECKERSTATEOBJECT); |
|
128 |
|
129 /* Initialize fields */ |
|
130 |
|
131 PKIX_CHECK(PKIX_PL_OID_Create |
|
132 (PKIX_NAMECONSTRAINTS_OID, |
|
133 &state->nameConstraintsOID, |
|
134 plContext), |
|
135 PKIX_OIDCREATEFAILED); |
|
136 |
|
137 PKIX_INCREF(nameConstraints); |
|
138 |
|
139 state->nameConstraints = nameConstraints; |
|
140 state->certsRemaining = numCerts; |
|
141 |
|
142 *pCheckerState = state; |
|
143 state = NULL; |
|
144 |
|
145 cleanup: |
|
146 |
|
147 PKIX_DECREF(state); |
|
148 |
|
149 PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE); |
|
150 } |
|
151 |
|
152 /* --Private-NameConstraintsChecker-Functions------------------------- */ |
|
153 |
|
154 /* |
|
155 * FUNCTION: pkix_NameConstraintsChecker_Check |
|
156 * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h) |
|
157 */ |
|
158 static PKIX_Error * |
|
159 pkix_NameConstraintsChecker_Check( |
|
160 PKIX_CertChainChecker *checker, |
|
161 PKIX_PL_Cert *cert, |
|
162 PKIX_List *unresolvedCriticalExtensions, |
|
163 void **pNBIOContext, |
|
164 void *plContext) |
|
165 { |
|
166 pkix_NameConstraintsCheckerState *state = NULL; |
|
167 PKIX_PL_CertNameConstraints *nameConstraints = NULL; |
|
168 PKIX_PL_CertNameConstraints *mergedNameConstraints = NULL; |
|
169 PKIX_Boolean selfIssued = PKIX_FALSE; |
|
170 PKIX_Boolean lastCert = PKIX_FALSE; |
|
171 |
|
172 PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameConstraintsChecker_Check"); |
|
173 PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext); |
|
174 |
|
175 *pNBIOContext = NULL; /* we never block on pending I/O */ |
|
176 |
|
177 PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState |
|
178 (checker, (PKIX_PL_Object **)&state, plContext), |
|
179 PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED); |
|
180 |
|
181 state->certsRemaining--; |
|
182 lastCert = state->certsRemaining == 0; |
|
183 |
|
184 /* Get status of self issued */ |
|
185 PKIX_CHECK(pkix_IsCertSelfIssued(cert, &selfIssued, plContext), |
|
186 PKIX_ISCERTSELFISSUEDFAILED); |
|
187 |
|
188 /* Check on non self-issued and if so only for last cert */ |
|
189 if (selfIssued == PKIX_FALSE || |
|
190 (selfIssued == PKIX_TRUE && lastCert)) { |
|
191 PKIX_CHECK(PKIX_PL_Cert_CheckNameConstraints |
|
192 (cert, state->nameConstraints, lastCert, |
|
193 plContext), |
|
194 PKIX_CERTCHECKNAMECONSTRAINTSFAILED); |
|
195 } |
|
196 |
|
197 if (!lastCert) { |
|
198 |
|
199 PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints |
|
200 (cert, &nameConstraints, plContext), |
|
201 PKIX_CERTGETNAMECONSTRAINTSFAILED); |
|
202 |
|
203 /* Merge with previous name constraints kept in state */ |
|
204 |
|
205 if (nameConstraints != NULL) { |
|
206 |
|
207 if (state->nameConstraints == NULL) { |
|
208 |
|
209 state->nameConstraints = nameConstraints; |
|
210 |
|
211 } else { |
|
212 |
|
213 PKIX_CHECK(PKIX_PL_Cert_MergeNameConstraints |
|
214 (nameConstraints, |
|
215 state->nameConstraints, |
|
216 &mergedNameConstraints, |
|
217 plContext), |
|
218 PKIX_CERTMERGENAMECONSTRAINTSFAILED); |
|
219 |
|
220 PKIX_DECREF(nameConstraints); |
|
221 PKIX_DECREF(state->nameConstraints); |
|
222 |
|
223 state->nameConstraints = mergedNameConstraints; |
|
224 } |
|
225 |
|
226 /* Remove Name Constraints Extension OID from list */ |
|
227 if (unresolvedCriticalExtensions != NULL) { |
|
228 PKIX_CHECK(pkix_List_Remove |
|
229 (unresolvedCriticalExtensions, |
|
230 (PKIX_PL_Object *)state->nameConstraintsOID, |
|
231 plContext), |
|
232 PKIX_LISTREMOVEFAILED); |
|
233 } |
|
234 } |
|
235 } |
|
236 |
|
237 PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState |
|
238 (checker, (PKIX_PL_Object *)state, plContext), |
|
239 PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED); |
|
240 |
|
241 cleanup: |
|
242 |
|
243 PKIX_DECREF(state); |
|
244 |
|
245 PKIX_RETURN(CERTCHAINCHECKER); |
|
246 } |
|
247 |
|
248 /* |
|
249 * FUNCTION: pkix_NameConstraintsChecker_Initialize |
|
250 * |
|
251 * DESCRIPTION: |
|
252 * Create a CertChainChecker with a NameConstraintsCheckerState. The |
|
253 * NameConstraintsCheckerState is created with "trustedNC" and "numCerts" |
|
254 * as its initial state. The CertChainChecker for the NameConstraints is |
|
255 * returned at address of "pChecker". |
|
256 * |
|
257 * PARAMETERS |
|
258 * "trustedNC" |
|
259 * The NameConstraints from trusted anchor Cert is stored at "trustedNC" |
|
260 * for initialization. May be NULL. |
|
261 * "numCerts" |
|
262 * Number of certificates in the validation chain. This data is used |
|
263 * to identify end-entity. |
|
264 * "pChecker" |
|
265 * Address of CertChainChecker to bo created and returned. |
|
266 * Must be non-NULL. |
|
267 * "plContext" - Platform-specific context pointer. |
|
268 * |
|
269 * THREAD SAFETY: |
|
270 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
|
271 * |
|
272 * RETURNS: |
|
273 * Returns NULL if the function succeeds. |
|
274 * Returns a CERTCHAINCHECKER Error if the function fails in a non-fatal way. |
|
275 * Returns a Fatal Error |
|
276 */ |
|
277 PKIX_Error * |
|
278 pkix_NameConstraintsChecker_Initialize( |
|
279 PKIX_PL_CertNameConstraints *trustedNC, |
|
280 PKIX_UInt32 numCerts, |
|
281 PKIX_CertChainChecker **pChecker, |
|
282 void *plContext) |
|
283 { |
|
284 pkix_NameConstraintsCheckerState *state = NULL; |
|
285 |
|
286 PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameConstraintsChecker_Initialize"); |
|
287 PKIX_NULLCHECK_ONE(pChecker); |
|
288 |
|
289 PKIX_CHECK(pkix_NameConstraintsCheckerState_Create |
|
290 (trustedNC, numCerts, &state, plContext), |
|
291 PKIX_NAMECONSTRAINTSCHECKERSTATECREATEFAILED); |
|
292 |
|
293 PKIX_CHECK(PKIX_CertChainChecker_Create |
|
294 (pkix_NameConstraintsChecker_Check, |
|
295 PKIX_FALSE, |
|
296 PKIX_FALSE, |
|
297 NULL, |
|
298 (PKIX_PL_Object *) state, |
|
299 pChecker, |
|
300 plContext), |
|
301 PKIX_CERTCHAINCHECKERCREATEFAILED); |
|
302 |
|
303 cleanup: |
|
304 |
|
305 PKIX_DECREF(state); |
|
306 |
|
307 PKIX_RETURN(CERTCHAINCHECKER); |
|
308 } |