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);