1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the PKIX-C library.
16 * The Initial Developer of the Original Code is
17 * Sun Microsystems, Inc.
18 * Portions created by the Initial Developer are
19 * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
22 * Sun Microsystems, Inc.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 * pkix_basicconstraintschecker.c
40 * Functions for basic constraints validation
44 #include "pkix_basicconstraintschecker.h"
46 /* --Private-BasicConstraintsCheckerState-Functions------------------------- */
49 * FUNCTION: pkix_BasicConstraintsCheckerState_Destroy
50 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
53 pkix_BasicConstraintsCheckerState_Destroy(
54 PKIX_PL_Object *object,
57 pkix_BasicConstraintsCheckerState *state = NULL;
59 PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE,
60 "pkix_BasicConstraintsCheckerState_Destroy");
62 PKIX_NULLCHECK_ONE(object);
64 /* Check that this object is a basic constraints checker state */
65 PKIX_CHECK(pkix_CheckType
66 (object, PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE, plContext),
67 PKIX_OBJECTNOTBASICCONSTRAINTSCHECKERSTATE);
69 state = (pkix_BasicConstraintsCheckerState *)object;
71 PKIX_DECREF(state->basicConstraintsOID);
75 PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE);
79 * FUNCTION: pkix_BasicConstraintsCheckerState_RegisterSelf
81 * Registers PKIX_CERT_TYPE and its related functions with systemClasses[]
83 * Not Thread Safe - for performance and complexity reasons
85 * Since this function is only called by PKIX_PL_Initialize, which should
86 * only be called once, it is acceptable that this function is not
90 pkix_BasicConstraintsCheckerState_RegisterSelf(void *plContext)
92 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
93 pkix_ClassTable_Entry entry;
95 PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE,
96 "pkix_BasicConstraintsCheckerState_RegisterSelf");
98 entry.description = "BasicConstraintsCheckerState";
100 entry.typeObjectSize = sizeof(pkix_BasicConstraintsCheckerState);
101 entry.destructor = pkix_BasicConstraintsCheckerState_Destroy;
102 entry.equalsFunction = NULL;
103 entry.hashcodeFunction = NULL;
104 entry.toStringFunction = NULL;
105 entry.comparator = NULL;
106 entry.duplicateFunction = NULL;
108 systemClasses[PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE] = entry;
110 PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE);
114 * FUNCTION: pkix_BasicConstraintsCheckerState_Create
117 * Creates a new BasicConstraintsCheckerState using the number of certs in
118 * the chain represented by "certsRemaining" and stores it at "pState".
122 * Number of certificates in the chain.
124 * Address where object pointer will be stored. Must be non-NULL.
126 * Platform-specific context pointer.
128 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
130 * Returns NULL if the function succeeds.
131 * Returns a BasicConstraintsCheckerState Error if the function fails in a
133 * Returns a Fatal Error if the function fails in an unrecoverable way.
136 pkix_BasicConstraintsCheckerState_Create(
137 PKIX_UInt32 certsRemaining,
138 pkix_BasicConstraintsCheckerState **pState,
141 pkix_BasicConstraintsCheckerState *state = NULL;
143 PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE,
144 "pkix_BasicConstraintsCheckerState_Create");
146 PKIX_NULLCHECK_ONE(pState);
148 PKIX_CHECK(PKIX_PL_Object_Alloc
149 (PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE,
150 sizeof (pkix_BasicConstraintsCheckerState),
151 (PKIX_PL_Object **)&state,
153 PKIX_COULDNOTCREATEBASICCONSTRAINTSSTATEOBJECT);
155 /* initialize fields */
156 state->certsRemaining = certsRemaining;
157 state->maxPathLength = PKIX_UNLIMITED_PATH_CONSTRAINT;
159 PKIX_CHECK(PKIX_PL_OID_Create
160 (PKIX_BASICCONSTRAINTS_OID,
161 &state->basicConstraintsOID,
163 PKIX_OIDCREATEFAILED);
172 PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE);
175 /* --Private-BasicConstraintsChecker-Functions------------------------------ */
178 * FUNCTION: pkix_BasicConstraintsChecker_Check
179 * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h)
182 pkix_BasicConstraintsChecker_Check(
183 PKIX_CertChainChecker *checker,
185 PKIX_List *unresolvedCriticalExtensions, /* list of PKIX_PL_OID */
189 PKIX_PL_CertBasicConstraints *basicConstraints = NULL;
190 pkix_BasicConstraintsCheckerState *state = NULL;
191 PKIX_Boolean caFlag = PKIX_FALSE;
192 PKIX_Int32 pathLength = 0;
193 PKIX_Int32 maxPathLength_now;
194 PKIX_Boolean isSelfIssued = PKIX_FALSE;
196 PKIX_ENTER(CERTCHAINCHECKER, "pkix_BasicConstraintsChecker_Check");
197 PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext);
199 *pNBIOContext = NULL; /* we never block on pending I/O */
201 PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState
202 (checker, (PKIX_PL_Object **)&state, plContext),
203 PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED);
205 state->certsRemaining--;
207 if (state->certsRemaining != 0) {
209 PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints
210 (cert, &basicConstraints, plContext),
211 PKIX_CERTGETBASICCONSTRAINTSFAILED);
213 /* get CA Flag and path length */
214 if (basicConstraints != NULL) {
215 PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag
219 PKIX_BASICCONSTRAINTSGETCAFLAGFAILED);
221 if (caFlag == PKIX_TRUE) {
223 (PKIX_PL_BasicConstraints_GetPathLenConstraint
227 PKIX_BASICCONSTRAINTSGETPATHLENCONSTRAINTFAILED);
232 pathLength = PKIX_UNLIMITED_PATH_CONSTRAINT;
235 PKIX_CHECK(pkix_IsCertSelfIssued
239 PKIX_ISCERTSELFISSUEDFAILED);
241 maxPathLength_now = state->maxPathLength;
243 if (isSelfIssued != PKIX_TRUE) {
245 /* Not last CA Cert, but maxPathLength is down to zero */
246 if (maxPathLength_now == 0) {
247 PKIX_ERROR(PKIX_BASICCONSTRAINTSVALIDATIONFAILEDLN);
250 if (caFlag == PKIX_FALSE) {
251 PKIX_ERROR(PKIX_BASICCONSTRAINTSVALIDATIONFAILEDCA);
254 if (maxPathLength_now > 0) { /* can be unlimited (-1) */
260 if (caFlag == PKIX_TRUE) {
261 if (maxPathLength_now == PKIX_UNLIMITED_PATH_CONSTRAINT){
262 maxPathLength_now = pathLength;
264 /* If pathLength is not specified, don't set */
265 if (pathLength != PKIX_UNLIMITED_PATH_CONSTRAINT) {
267 (maxPathLength_now > pathLength)?
268 pathLength:maxPathLength_now;
273 state->maxPathLength = maxPathLength_now;
276 /* Remove Basic Constraints Extension OID from list */
277 if (unresolvedCriticalExtensions != NULL) {
279 PKIX_CHECK(pkix_List_Remove
280 (unresolvedCriticalExtensions,
281 (PKIX_PL_Object *) state->basicConstraintsOID,
283 PKIX_LISTREMOVEFAILED);
287 PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState
288 (checker, (PKIX_PL_Object *)state, plContext),
289 PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED);
294 PKIX_DECREF(basicConstraints);
295 PKIX_RETURN(CERTCHAINCHECKER);
300 * FUNCTION: pkix_BasicConstraintsChecker_Initialize
302 * Registers PKIX_CERT_TYPE and its related functions with systemClasses[]
304 * Not Thread Safe - for performance and complexity reasons
306 * Since this function is only called by PKIX_PL_Initialize, which should
307 * only be called once, it is acceptable that this function is not
311 pkix_BasicConstraintsChecker_Initialize(
312 PKIX_UInt32 certsRemaining,
313 PKIX_CertChainChecker **pChecker,
316 pkix_BasicConstraintsCheckerState *state = NULL;
318 PKIX_ENTER(CERTCHAINCHECKER, "pkix_BasicConstraintsChecker_Initialize");
319 PKIX_NULLCHECK_ONE(pChecker);
321 PKIX_CHECK(pkix_BasicConstraintsCheckerState_Create
322 (certsRemaining, &state, plContext),
323 PKIX_BASICCONSTRAINTSCHECKERSTATECREATEFAILED);
325 PKIX_CHECK(PKIX_CertChainChecker_Create
326 (pkix_BasicConstraintsChecker_Check,
330 (PKIX_PL_Object *)state,
333 PKIX_CERTCHAINCHECKERCHECKFAILED);
338 PKIX_RETURN(CERTCHAINCHECKER);