security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rwxr-xr-x

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial