1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,308 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +/* 1.8 + * pkix_nameconstraintschecker.c 1.9 + * 1.10 + * Functions for Name Constraints Checkers 1.11 + * 1.12 + */ 1.13 + 1.14 +#include "pkix_nameconstraintschecker.h" 1.15 + 1.16 +/* --Private-NameConstraintsCheckerState-Functions---------------------- */ 1.17 + 1.18 +/* 1.19 + * FUNCTION: pkix_NameConstraintsCheckerstate_Destroy 1.20 + * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) 1.21 + */ 1.22 +static PKIX_Error * 1.23 +pkix_NameConstraintsCheckerState_Destroy( 1.24 + PKIX_PL_Object *object, 1.25 + void *plContext) 1.26 +{ 1.27 + pkix_NameConstraintsCheckerState *state = NULL; 1.28 + 1.29 + PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE, 1.30 + "pkix_NameConstraintsCheckerState_Destroy"); 1.31 + PKIX_NULLCHECK_ONE(object); 1.32 + 1.33 + /* Check that object type */ 1.34 + PKIX_CHECK(pkix_CheckType 1.35 + (object, PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE, plContext), 1.36 + PKIX_OBJECTNOTNAMECONSTRAINTSCHECKERSTATE); 1.37 + 1.38 + state = (pkix_NameConstraintsCheckerState *)object; 1.39 + 1.40 + PKIX_DECREF(state->nameConstraints); 1.41 + PKIX_DECREF(state->nameConstraintsOID); 1.42 + 1.43 +cleanup: 1.44 + 1.45 + PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE); 1.46 +} 1.47 + 1.48 +/* 1.49 + * FUNCTION: pkix_NameConstraintsCheckerState_RegisterSelf 1.50 + * 1.51 + * DESCRIPTION: 1.52 + * Registers PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE and its related 1.53 + * functions with systemClasses[] 1.54 + * 1.55 + * THREAD SAFETY: 1.56 + * Not Thread Safe - for performance and complexity reasons 1.57 + * 1.58 + * Since this function is only called by PKIX_PL_Initialize, which should 1.59 + * only be called once, it is acceptable that this function is not 1.60 + * thread-safe. 1.61 + */ 1.62 +PKIX_Error * 1.63 +pkix_NameConstraintsCheckerState_RegisterSelf(void *plContext) 1.64 +{ 1.65 + extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; 1.66 + pkix_ClassTable_Entry entry; 1.67 + 1.68 + PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE, 1.69 + "pkix_NameConstraintsCheckerState_RegisterSelf"); 1.70 + 1.71 + entry.description = "NameConstraintsCheckerState"; 1.72 + entry.objCounter = 0; 1.73 + entry.typeObjectSize = sizeof(pkix_NameConstraintsCheckerState); 1.74 + entry.destructor = pkix_NameConstraintsCheckerState_Destroy; 1.75 + entry.equalsFunction = NULL; 1.76 + entry.hashcodeFunction = NULL; 1.77 + entry.toStringFunction = NULL; 1.78 + entry.comparator = NULL; 1.79 + entry.duplicateFunction = NULL; 1.80 + 1.81 + systemClasses[PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE] = entry; 1.82 + 1.83 + PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE); 1.84 +} 1.85 + 1.86 +/* 1.87 + * FUNCTION: pkix_NameConstraintsCheckerState_Create 1.88 + * 1.89 + * DESCRIPTION: 1.90 + * Allocate and initialize NameConstraintsChecker state data. 1.91 + * 1.92 + * PARAMETERS 1.93 + * "nameConstraints" 1.94 + * Address of NameConstraints to be stored in state. May be NULL. 1.95 + * "numCerts" 1.96 + * Number of certificates in the validation chain. This data is used 1.97 + * to identify end-entity. 1.98 + * "pCheckerState" 1.99 + * Address of NameConstraintsCheckerState that is returned. Must be 1.100 + * non-NULL. 1.101 + * "plContext" - Platform-specific context pointer. 1.102 + * 1.103 + * THREAD SAFETY: 1.104 + * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1.105 + * 1.106 + * RETURNS: 1.107 + * Returns NULL if the function succeeds. 1.108 + * Returns a CERTNAMECONSTRAINTSCHECKERSTATE Error if the function fails in 1.109 + * a non-fatal way. 1.110 + * Returns a Fatal Error 1.111 + */ 1.112 +static PKIX_Error * 1.113 +pkix_NameConstraintsCheckerState_Create( 1.114 + PKIX_PL_CertNameConstraints *nameConstraints, 1.115 + PKIX_UInt32 numCerts, 1.116 + pkix_NameConstraintsCheckerState **pCheckerState, 1.117 + void *plContext) 1.118 +{ 1.119 + pkix_NameConstraintsCheckerState *state = NULL; 1.120 + 1.121 + PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE, 1.122 + "pkix_NameConstraintsCheckerState_Create"); 1.123 + PKIX_NULLCHECK_ONE(pCheckerState); 1.124 + 1.125 + PKIX_CHECK(PKIX_PL_Object_Alloc 1.126 + (PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE, 1.127 + sizeof (pkix_NameConstraintsCheckerState), 1.128 + (PKIX_PL_Object **)&state, 1.129 + plContext), 1.130 + PKIX_COULDNOTCREATENAMECONSTRAINTSCHECKERSTATEOBJECT); 1.131 + 1.132 + /* Initialize fields */ 1.133 + 1.134 + PKIX_CHECK(PKIX_PL_OID_Create 1.135 + (PKIX_NAMECONSTRAINTS_OID, 1.136 + &state->nameConstraintsOID, 1.137 + plContext), 1.138 + PKIX_OIDCREATEFAILED); 1.139 + 1.140 + PKIX_INCREF(nameConstraints); 1.141 + 1.142 + state->nameConstraints = nameConstraints; 1.143 + state->certsRemaining = numCerts; 1.144 + 1.145 + *pCheckerState = state; 1.146 + state = NULL; 1.147 + 1.148 +cleanup: 1.149 + 1.150 + PKIX_DECREF(state); 1.151 + 1.152 + PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE); 1.153 +} 1.154 + 1.155 +/* --Private-NameConstraintsChecker-Functions------------------------- */ 1.156 + 1.157 +/* 1.158 + * FUNCTION: pkix_NameConstraintsChecker_Check 1.159 + * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h) 1.160 + */ 1.161 +static PKIX_Error * 1.162 +pkix_NameConstraintsChecker_Check( 1.163 + PKIX_CertChainChecker *checker, 1.164 + PKIX_PL_Cert *cert, 1.165 + PKIX_List *unresolvedCriticalExtensions, 1.166 + void **pNBIOContext, 1.167 + void *plContext) 1.168 +{ 1.169 + pkix_NameConstraintsCheckerState *state = NULL; 1.170 + PKIX_PL_CertNameConstraints *nameConstraints = NULL; 1.171 + PKIX_PL_CertNameConstraints *mergedNameConstraints = NULL; 1.172 + PKIX_Boolean selfIssued = PKIX_FALSE; 1.173 + PKIX_Boolean lastCert = PKIX_FALSE; 1.174 + 1.175 + PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameConstraintsChecker_Check"); 1.176 + PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext); 1.177 + 1.178 + *pNBIOContext = NULL; /* we never block on pending I/O */ 1.179 + 1.180 + PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState 1.181 + (checker, (PKIX_PL_Object **)&state, plContext), 1.182 + PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED); 1.183 + 1.184 + state->certsRemaining--; 1.185 + lastCert = state->certsRemaining == 0; 1.186 + 1.187 + /* Get status of self issued */ 1.188 + PKIX_CHECK(pkix_IsCertSelfIssued(cert, &selfIssued, plContext), 1.189 + PKIX_ISCERTSELFISSUEDFAILED); 1.190 + 1.191 + /* Check on non self-issued and if so only for last cert */ 1.192 + if (selfIssued == PKIX_FALSE || 1.193 + (selfIssued == PKIX_TRUE && lastCert)) { 1.194 + PKIX_CHECK(PKIX_PL_Cert_CheckNameConstraints 1.195 + (cert, state->nameConstraints, lastCert, 1.196 + plContext), 1.197 + PKIX_CERTCHECKNAMECONSTRAINTSFAILED); 1.198 + } 1.199 + 1.200 + if (!lastCert) { 1.201 + 1.202 + PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints 1.203 + (cert, &nameConstraints, plContext), 1.204 + PKIX_CERTGETNAMECONSTRAINTSFAILED); 1.205 + 1.206 + /* Merge with previous name constraints kept in state */ 1.207 + 1.208 + if (nameConstraints != NULL) { 1.209 + 1.210 + if (state->nameConstraints == NULL) { 1.211 + 1.212 + state->nameConstraints = nameConstraints; 1.213 + 1.214 + } else { 1.215 + 1.216 + PKIX_CHECK(PKIX_PL_Cert_MergeNameConstraints 1.217 + (nameConstraints, 1.218 + state->nameConstraints, 1.219 + &mergedNameConstraints, 1.220 + plContext), 1.221 + PKIX_CERTMERGENAMECONSTRAINTSFAILED); 1.222 + 1.223 + PKIX_DECREF(nameConstraints); 1.224 + PKIX_DECREF(state->nameConstraints); 1.225 + 1.226 + state->nameConstraints = mergedNameConstraints; 1.227 + } 1.228 + 1.229 + /* Remove Name Constraints Extension OID from list */ 1.230 + if (unresolvedCriticalExtensions != NULL) { 1.231 + PKIX_CHECK(pkix_List_Remove 1.232 + (unresolvedCriticalExtensions, 1.233 + (PKIX_PL_Object *)state->nameConstraintsOID, 1.234 + plContext), 1.235 + PKIX_LISTREMOVEFAILED); 1.236 + } 1.237 + } 1.238 + } 1.239 + 1.240 + PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState 1.241 + (checker, (PKIX_PL_Object *)state, plContext), 1.242 + PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED); 1.243 + 1.244 +cleanup: 1.245 + 1.246 + PKIX_DECREF(state); 1.247 + 1.248 + PKIX_RETURN(CERTCHAINCHECKER); 1.249 +} 1.250 + 1.251 +/* 1.252 + * FUNCTION: pkix_NameConstraintsChecker_Initialize 1.253 + * 1.254 + * DESCRIPTION: 1.255 + * Create a CertChainChecker with a NameConstraintsCheckerState. The 1.256 + * NameConstraintsCheckerState is created with "trustedNC" and "numCerts" 1.257 + * as its initial state. The CertChainChecker for the NameConstraints is 1.258 + * returned at address of "pChecker". 1.259 + * 1.260 + * PARAMETERS 1.261 + * "trustedNC" 1.262 + * The NameConstraints from trusted anchor Cert is stored at "trustedNC" 1.263 + * for initialization. May be NULL. 1.264 + * "numCerts" 1.265 + * Number of certificates in the validation chain. This data is used 1.266 + * to identify end-entity. 1.267 + * "pChecker" 1.268 + * Address of CertChainChecker to bo created and returned. 1.269 + * Must be non-NULL. 1.270 + * "plContext" - Platform-specific context pointer. 1.271 + * 1.272 + * THREAD SAFETY: 1.273 + * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1.274 + * 1.275 + * RETURNS: 1.276 + * Returns NULL if the function succeeds. 1.277 + * Returns a CERTCHAINCHECKER Error if the function fails in a non-fatal way. 1.278 + * Returns a Fatal Error 1.279 + */ 1.280 +PKIX_Error * 1.281 +pkix_NameConstraintsChecker_Initialize( 1.282 + PKIX_PL_CertNameConstraints *trustedNC, 1.283 + PKIX_UInt32 numCerts, 1.284 + PKIX_CertChainChecker **pChecker, 1.285 + void *plContext) 1.286 +{ 1.287 + pkix_NameConstraintsCheckerState *state = NULL; 1.288 + 1.289 + PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameConstraintsChecker_Initialize"); 1.290 + PKIX_NULLCHECK_ONE(pChecker); 1.291 + 1.292 + PKIX_CHECK(pkix_NameConstraintsCheckerState_Create 1.293 + (trustedNC, numCerts, &state, plContext), 1.294 + PKIX_NAMECONSTRAINTSCHECKERSTATECREATEFAILED); 1.295 + 1.296 + PKIX_CHECK(PKIX_CertChainChecker_Create 1.297 + (pkix_NameConstraintsChecker_Check, 1.298 + PKIX_FALSE, 1.299 + PKIX_FALSE, 1.300 + NULL, 1.301 + (PKIX_PL_Object *) state, 1.302 + pChecker, 1.303 + plContext), 1.304 + PKIX_CERTCHAINCHECKERCREATEFAILED); 1.305 + 1.306 +cleanup: 1.307 + 1.308 + PKIX_DECREF(state); 1.309 + 1.310 + PKIX_RETURN(CERTCHAINCHECKER); 1.311 +}