| OLD | NEW |
| (Empty) |
| 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_basicconstraintschecker.c | |
| 6 * | |
| 7 * Functions for basic constraints validation | |
| 8 * | |
| 9 */ | |
| 10 | |
| 11 #include "pkix_basicconstraintschecker.h" | |
| 12 | |
| 13 /* --Private-BasicConstraintsCheckerState-Functions------------------------- */ | |
| 14 | |
| 15 /* | |
| 16 * FUNCTION: pkix_BasicConstraintsCheckerState_Destroy | |
| 17 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |
| 18 */ | |
| 19 static PKIX_Error * | |
| 20 pkix_BasicConstraintsCheckerState_Destroy( | |
| 21 PKIX_PL_Object *object, | |
| 22 void *plContext) | |
| 23 { | |
| 24 pkix_BasicConstraintsCheckerState *state = NULL; | |
| 25 | |
| 26 PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE, | |
| 27 "pkix_BasicConstraintsCheckerState_Destroy"); | |
| 28 | |
| 29 PKIX_NULLCHECK_ONE(object); | |
| 30 | |
| 31 /* Check that this object is a basic constraints checker state */ | |
| 32 PKIX_CHECK(pkix_CheckType | |
| 33 (object, PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE, plContext), | |
| 34 PKIX_OBJECTNOTBASICCONSTRAINTSCHECKERSTATE); | |
| 35 | |
| 36 state = (pkix_BasicConstraintsCheckerState *)object; | |
| 37 | |
| 38 PKIX_DECREF(state->basicConstraintsOID); | |
| 39 | |
| 40 cleanup: | |
| 41 | |
| 42 PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE); | |
| 43 } | |
| 44 | |
| 45 /* | |
| 46 * FUNCTION: pkix_BasicConstraintsCheckerState_RegisterSelf | |
| 47 * DESCRIPTION: | |
| 48 * Registers PKIX_CERT_TYPE and its related functions with systemClasses[] | |
| 49 * THREAD SAFETY: | |
| 50 * Not Thread Safe - for performance and complexity reasons | |
| 51 * | |
| 52 * Since this function is only called by PKIX_PL_Initialize, which should | |
| 53 * only be called once, it is acceptable that this function is not | |
| 54 * thread-safe. | |
| 55 */ | |
| 56 PKIX_Error * | |
| 57 pkix_BasicConstraintsCheckerState_RegisterSelf(void *plContext) | |
| 58 { | |
| 59 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |
| 60 pkix_ClassTable_Entry entry; | |
| 61 | |
| 62 PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE, | |
| 63 "pkix_BasicConstraintsCheckerState_RegisterSelf"); | |
| 64 | |
| 65 entry.description = "BasicConstraintsCheckerState"; | |
| 66 entry.objCounter = 0; | |
| 67 entry.typeObjectSize = sizeof(pkix_BasicConstraintsCheckerState); | |
| 68 entry.destructor = pkix_BasicConstraintsCheckerState_Destroy; | |
| 69 entry.equalsFunction = NULL; | |
| 70 entry.hashcodeFunction = NULL; | |
| 71 entry.toStringFunction = NULL; | |
| 72 entry.comparator = NULL; | |
| 73 entry.duplicateFunction = NULL; | |
| 74 | |
| 75 systemClasses[PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE] = entry; | |
| 76 | |
| 77 PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE); | |
| 78 } | |
| 79 | |
| 80 /* | |
| 81 * FUNCTION: pkix_BasicConstraintsCheckerState_Create | |
| 82 * DESCRIPTION: | |
| 83 * | |
| 84 * Creates a new BasicConstraintsCheckerState using the number of certs in | |
| 85 * the chain represented by "certsRemaining" and stores it at "pState". | |
| 86 * | |
| 87 * PARAMETERS: | |
| 88 * "certsRemaining" | |
| 89 * Number of certificates in the chain. | |
| 90 * "pState" | |
| 91 * Address where object pointer will be stored. Must be non-NULL. | |
| 92 * "plContext" | |
| 93 * Platform-specific context pointer. | |
| 94 * THREAD SAFETY: | |
| 95 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
| 96 * RETURNS: | |
| 97 * Returns NULL if the function succeeds. | |
| 98 * Returns a BasicConstraintsCheckerState Error if the function fails in a | |
| 99 * non-fatal way. | |
| 100 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
| 101 */ | |
| 102 static PKIX_Error * | |
| 103 pkix_BasicConstraintsCheckerState_Create( | |
| 104 PKIX_UInt32 certsRemaining, | |
| 105 pkix_BasicConstraintsCheckerState **pState, | |
| 106 void *plContext) | |
| 107 { | |
| 108 pkix_BasicConstraintsCheckerState *state = NULL; | |
| 109 | |
| 110 PKIX_ENTER(BASICCONSTRAINTSCHECKERSTATE, | |
| 111 "pkix_BasicConstraintsCheckerState_Create"); | |
| 112 | |
| 113 PKIX_NULLCHECK_ONE(pState); | |
| 114 | |
| 115 PKIX_CHECK(PKIX_PL_Object_Alloc | |
| 116 (PKIX_BASICCONSTRAINTSCHECKERSTATE_TYPE, | |
| 117 sizeof (pkix_BasicConstraintsCheckerState), | |
| 118 (PKIX_PL_Object **)&state, | |
| 119 plContext), | |
| 120 PKIX_COULDNOTCREATEBASICCONSTRAINTSSTATEOBJECT); | |
| 121 | |
| 122 /* initialize fields */ | |
| 123 state->certsRemaining = certsRemaining; | |
| 124 state->maxPathLength = PKIX_UNLIMITED_PATH_CONSTRAINT; | |
| 125 | |
| 126 PKIX_CHECK(PKIX_PL_OID_Create | |
| 127 (PKIX_BASICCONSTRAINTS_OID, | |
| 128 &state->basicConstraintsOID, | |
| 129 plContext), | |
| 130 PKIX_OIDCREATEFAILED); | |
| 131 | |
| 132 *pState = state; | |
| 133 state = NULL; | |
| 134 | |
| 135 cleanup: | |
| 136 | |
| 137 PKIX_DECREF(state); | |
| 138 | |
| 139 PKIX_RETURN(BASICCONSTRAINTSCHECKERSTATE); | |
| 140 } | |
| 141 | |
| 142 /* --Private-BasicConstraintsChecker-Functions------------------------------ */ | |
| 143 | |
| 144 /* | |
| 145 * FUNCTION: pkix_BasicConstraintsChecker_Check | |
| 146 * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h) | |
| 147 */ | |
| 148 PKIX_Error * | |
| 149 pkix_BasicConstraintsChecker_Check( | |
| 150 PKIX_CertChainChecker *checker, | |
| 151 PKIX_PL_Cert *cert, | |
| 152 PKIX_List *unresolvedCriticalExtensions, /* list of PKIX_PL_OID */ | |
| 153 void **pNBIOContext, | |
| 154 void *plContext) | |
| 155 { | |
| 156 PKIX_PL_CertBasicConstraints *basicConstraints = NULL; | |
| 157 pkix_BasicConstraintsCheckerState *state = NULL; | |
| 158 PKIX_Boolean caFlag = PKIX_FALSE; | |
| 159 PKIX_Int32 pathLength = 0; | |
| 160 PKIX_Int32 maxPathLength_now; | |
| 161 PKIX_Boolean isSelfIssued = PKIX_FALSE; | |
| 162 | |
| 163 PKIX_ENTER(CERTCHAINCHECKER, "pkix_BasicConstraintsChecker_Check"); | |
| 164 PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext); | |
| 165 | |
| 166 *pNBIOContext = NULL; /* we never block on pending I/O */ | |
| 167 | |
| 168 PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState | |
| 169 (checker, (PKIX_PL_Object **)&state, plContext), | |
| 170 PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED); | |
| 171 | |
| 172 state->certsRemaining--; | |
| 173 | |
| 174 if (state->certsRemaining != 0) { | |
| 175 | |
| 176 PKIX_CHECK(PKIX_PL_Cert_GetBasicConstraints | |
| 177 (cert, &basicConstraints, plContext), | |
| 178 PKIX_CERTGETBASICCONSTRAINTSFAILED); | |
| 179 | |
| 180 /* get CA Flag and path length */ | |
| 181 if (basicConstraints != NULL) { | |
| 182 PKIX_CHECK(PKIX_PL_BasicConstraints_GetCAFlag | |
| 183 (basicConstraints, | |
| 184 &caFlag, | |
| 185 plContext), | |
| 186 PKIX_BASICCONSTRAINTSGETCAFLAGFAILED); | |
| 187 | |
| 188 if (caFlag == PKIX_TRUE) { | |
| 189 PKIX_CHECK | |
| 190 (PKIX_PL_BasicConstraints_GetPathLenConstraint | |
| 191 (basicConstraints, | |
| 192 &pathLength, | |
| 193 plContext), | |
| 194 PKIX_BASICCONSTRAINTSGETPATHLENCONSTRAINTFAILED); | |
| 195 } | |
| 196 | |
| 197 }else{ | |
| 198 caFlag = PKIX_FALSE; | |
| 199 pathLength = PKIX_UNLIMITED_PATH_CONSTRAINT; | |
| 200 } | |
| 201 | |
| 202 PKIX_CHECK(pkix_IsCertSelfIssued | |
| 203 (cert, | |
| 204 &isSelfIssued, | |
| 205 plContext), | |
| 206 PKIX_ISCERTSELFISSUEDFAILED); | |
| 207 | |
| 208 maxPathLength_now = state->maxPathLength; | |
| 209 | |
| 210 if (isSelfIssued != PKIX_TRUE) { | |
| 211 | |
| 212 /* Not last CA Cert, but maxPathLength is down to zero */ | |
| 213 if (maxPathLength_now == 0) { | |
| 214 PKIX_ERROR(PKIX_BASICCONSTRAINTSVALIDATIONFAILEDLN); | |
| 215 } | |
| 216 | |
| 217 if (caFlag == PKIX_FALSE) { | |
| 218 PKIX_ERROR(PKIX_BASICCONSTRAINTSVALIDATIONFAILEDCA); | |
| 219 } | |
| 220 | |
| 221 if (maxPathLength_now > 0) { /* can be unlimited (-1) */ | |
| 222 maxPathLength_now--; | |
| 223 } | |
| 224 | |
| 225 } | |
| 226 | |
| 227 if (caFlag == PKIX_TRUE) { | |
| 228 if (maxPathLength_now == PKIX_UNLIMITED_PATH_CONSTRAINT){ | |
| 229 maxPathLength_now = pathLength; | |
| 230 } else { | |
| 231 /* If pathLength is not specified, don't set */ | |
| 232 if (pathLength != PKIX_UNLIMITED_PATH_CONSTRAINT) { | |
| 233 maxPathLength_now = | |
| 234 (maxPathLength_now > pathLength)? | |
| 235 pathLength:maxPathLength_now; | |
| 236 } | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 state->maxPathLength = maxPathLength_now; | |
| 241 } | |
| 242 | |
| 243 /* Remove Basic Constraints Extension OID from list */ | |
| 244 if (unresolvedCriticalExtensions != NULL) { | |
| 245 | |
| 246 PKIX_CHECK(pkix_List_Remove | |
| 247 (unresolvedCriticalExtensions, | |
| 248 (PKIX_PL_Object *) state->basicConstraintsOID, | |
| 249 plContext), | |
| 250 PKIX_LISTREMOVEFAILED); | |
| 251 } | |
| 252 | |
| 253 | |
| 254 PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState | |
| 255 (checker, (PKIX_PL_Object *)state, plContext), | |
| 256 PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED); | |
| 257 | |
| 258 | |
| 259 cleanup: | |
| 260 PKIX_DECREF(state); | |
| 261 PKIX_DECREF(basicConstraints); | |
| 262 PKIX_RETURN(CERTCHAINCHECKER); | |
| 263 | |
| 264 } | |
| 265 | |
| 266 /* | |
| 267 * FUNCTION: pkix_BasicConstraintsChecker_Initialize | |
| 268 * DESCRIPTION: | |
| 269 * Registers PKIX_CERT_TYPE and its related functions with systemClasses[] | |
| 270 * THREAD SAFETY: | |
| 271 * Not Thread Safe - for performance and complexity reasons | |
| 272 * | |
| 273 * Since this function is only called by PKIX_PL_Initialize, which should | |
| 274 * only be called once, it is acceptable that this function is not | |
| 275 * thread-safe. | |
| 276 */ | |
| 277 PKIX_Error * | |
| 278 pkix_BasicConstraintsChecker_Initialize( | |
| 279 PKIX_UInt32 certsRemaining, | |
| 280 PKIX_CertChainChecker **pChecker, | |
| 281 void *plContext) | |
| 282 { | |
| 283 pkix_BasicConstraintsCheckerState *state = NULL; | |
| 284 | |
| 285 PKIX_ENTER(CERTCHAINCHECKER, "pkix_BasicConstraintsChecker_Initialize"); | |
| 286 PKIX_NULLCHECK_ONE(pChecker); | |
| 287 | |
| 288 PKIX_CHECK(pkix_BasicConstraintsCheckerState_Create | |
| 289 (certsRemaining, &state, plContext), | |
| 290 PKIX_BASICCONSTRAINTSCHECKERSTATECREATEFAILED); | |
| 291 | |
| 292 PKIX_CHECK(PKIX_CertChainChecker_Create | |
| 293 (pkix_BasicConstraintsChecker_Check, | |
| 294 PKIX_FALSE, | |
| 295 PKIX_FALSE, | |
| 296 NULL, | |
| 297 (PKIX_PL_Object *)state, | |
| 298 pChecker, | |
| 299 plContext), | |
| 300 PKIX_CERTCHAINCHECKERCHECKFAILED); | |
| 301 | |
| 302 cleanup: | |
| 303 PKIX_DECREF(state); | |
| 304 | |
| 305 PKIX_RETURN(CERTCHAINCHECKER); | |
| 306 } | |
| OLD | NEW |