pkix_pl_basicconstraints.c (12385B)
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_pl_basicconstraints.c 6 * 7 * BasicConstraints Object Functions 8 * 9 */ 10 11 #include "pkix_pl_basicconstraints.h" 12 13 /* 14 * FUNCTION: pkix_pl_CertBasicConstraints_Create 15 * DESCRIPTION: 16 * 17 * Creates a new CertBasicConstraints object whose CA Flag has the value 18 * given by the Boolean value of "isCA" and whose path length field has the 19 * value given by the "pathLen" argument and stores it at "pObject". 20 * 21 * PARAMETERS 22 * "isCA" 23 * Boolean value with the desired value of CA Flag. 24 * "pathLen" 25 * a PKIX_Int32 with the desired value of path length 26 * "pObject" 27 * Address of object pointer's destination. Must be non-NULL. 28 * "plContext" - Platform-specific context pointer. 29 * THREAD SAFETY: 30 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 31 * RETURNS: 32 * Returns NULL if the function succeeds. 33 * Returns a CertBasicConstraints Error if the function fails 34 * in a non-fatal way. 35 * Returns a Fatal Error if the function fails in an unrecoverable way. 36 */ 37 PKIX_Error * 38 pkix_pl_CertBasicConstraints_Create( 39 PKIX_Boolean isCA, 40 PKIX_Int32 pathLen, 41 PKIX_PL_CertBasicConstraints **pObject, 42 void *plContext) 43 { 44 PKIX_PL_CertBasicConstraints *basic = NULL; 45 46 PKIX_ENTER(CERTBASICCONSTRAINTS, 47 "pkix_pl_CertBasicConstraints_Create"); 48 PKIX_NULLCHECK_ONE(pObject); 49 50 PKIX_CHECK(PKIX_PL_Object_Alloc 51 (PKIX_CERTBASICCONSTRAINTS_TYPE, 52 sizeof (PKIX_PL_CertBasicConstraints), 53 (PKIX_PL_Object **)&basic, 54 plContext), 55 PKIX_COULDNOTCREATECERTBASICCONSTRAINTSOBJECT); 56 57 basic->isCA = isCA; 58 59 /* pathLen has meaning only for CAs, but it's not worth checking */ 60 basic->pathLen = pathLen; 61 62 *pObject = basic; 63 64 cleanup: 65 66 PKIX_RETURN(CERTBASICCONSTRAINTS); 67 } 68 69 /* 70 * FUNCTION: pkix_pl_CertBasicConstraints_Destroy 71 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) 72 */ 73 static PKIX_Error * 74 pkix_pl_CertBasicConstraints_Destroy( 75 PKIX_PL_Object *object, 76 void *plContext) 77 { 78 PKIX_PL_CertBasicConstraints *certB = NULL; 79 80 PKIX_ENTER(CERTBASICCONSTRAINTS, 81 "pkix_pl_CertBasicConstraints_Destroy"); 82 PKIX_NULLCHECK_ONE(object); 83 84 PKIX_CHECK(pkix_CheckType 85 (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext), 86 PKIX_OBJECTNOTCERTBASICCONSTRAINTS); 87 88 certB = (PKIX_PL_CertBasicConstraints*)object; 89 90 certB->isCA = PKIX_FALSE; 91 certB->pathLen = 0; 92 93 cleanup: 94 95 PKIX_RETURN(CERTBASICCONSTRAINTS); 96 } 97 98 /* 99 * FUNCTION: pkix_pl_CertBasicConstraints_ToString 100 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) 101 */ 102 static PKIX_Error * 103 pkix_pl_CertBasicConstraints_ToString( 104 PKIX_PL_Object *object, 105 PKIX_PL_String **pString, 106 void *plContext) 107 { 108 PKIX_PL_String *certBasicConstraintsString = NULL; 109 PKIX_PL_CertBasicConstraints *certB = NULL; 110 PKIX_Boolean isCA = PKIX_FALSE; 111 PKIX_Int32 pathLen = 0; 112 PKIX_PL_String *outString = NULL; 113 char *fmtString = NULL; 114 PKIX_Boolean pathlenArg = PKIX_FALSE; 115 116 PKIX_ENTER(CERTBASICCONSTRAINTS, 117 "pkix_pl_CertBasicConstraints_toString"); 118 PKIX_NULLCHECK_TWO(object, pString); 119 120 PKIX_CHECK(pkix_CheckType 121 (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext), 122 PKIX_FIRSTARGUMENTNOTCERTBASICCONSTRAINTSOBJECT); 123 124 certB = (PKIX_PL_CertBasicConstraints *)object; 125 126 /* 127 * if CA == TRUE 128 * if pathLen == CERT_UNLIMITED_PATH_CONSTRAINT 129 * print "CA(-1)" 130 * else print "CA(nnn)" 131 * if CA == FALSE, print "~CA" 132 */ 133 134 isCA = certB->isCA; 135 136 if (isCA) { 137 pathLen = certB->pathLen; 138 139 if (pathLen == CERT_UNLIMITED_PATH_CONSTRAINT) { 140 /* print "CA(-1)" */ 141 fmtString = "CA(-1)"; 142 pathlenArg = PKIX_FALSE; 143 } else { 144 /* print "CA(pathLen)" */ 145 fmtString = "CA(%d)"; 146 pathlenArg = PKIX_TRUE; 147 } 148 } else { 149 /* print "~CA" */ 150 fmtString = "~CA"; 151 pathlenArg = PKIX_FALSE; 152 } 153 154 PKIX_CHECK(PKIX_PL_String_Create 155 (PKIX_ESCASCII, 156 fmtString, 157 0, 158 &certBasicConstraintsString, 159 plContext), 160 PKIX_STRINGCREATEFAILED); 161 162 if (pathlenArg) { 163 PKIX_CHECK(PKIX_PL_Sprintf 164 (&outString, 165 plContext, 166 certBasicConstraintsString, 167 pathLen), 168 PKIX_SPRINTFFAILED); 169 } else { 170 PKIX_CHECK(PKIX_PL_Sprintf 171 (&outString, 172 plContext, 173 certBasicConstraintsString), 174 PKIX_SPRINTFFAILED); 175 } 176 177 *pString = outString; 178 179 cleanup: 180 181 PKIX_DECREF(certBasicConstraintsString); 182 183 PKIX_RETURN(CERTBASICCONSTRAINTS); 184 } 185 186 /* 187 * FUNCTION: pkix_pl_CertBasicConstraints_Hashcode 188 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) 189 */ 190 static PKIX_Error * 191 pkix_pl_CertBasicConstraints_Hashcode( 192 PKIX_PL_Object *object, 193 PKIX_UInt32 *pHashcode, 194 void *plContext) 195 { 196 PKIX_PL_CertBasicConstraints *certB = NULL; 197 PKIX_Boolean isCA = PKIX_FALSE; 198 PKIX_Int32 pathLen = 0; 199 PKIX_Int32 hashInput = 0; 200 PKIX_UInt32 cbcHash = 0; 201 202 PKIX_ENTER(CERTBASICCONSTRAINTS, 203 "pkix_pl_CertBasicConstraints_Hashcode"); 204 PKIX_NULLCHECK_TWO(object, pHashcode); 205 206 PKIX_CHECK(pkix_CheckType 207 (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext), 208 PKIX_OBJECTNOTCERTBASICCONSTRAINTS); 209 210 certB = (PKIX_PL_CertBasicConstraints *)object; 211 212 /* 213 * if CA == TRUE 214 * hash(pathLen + 1 - PKIX_UNLIMITED_PATH_CONSTRAINT) 215 * if CA == FALSE, hash(0) 216 */ 217 218 isCA = certB->isCA; 219 220 if (isCA) { 221 pathLen = certB->pathLen; 222 223 hashInput = pathLen + 1 - PKIX_UNLIMITED_PATH_CONSTRAINT; 224 } 225 226 PKIX_CHECK(pkix_hash 227 ((const unsigned char *)&hashInput, 228 sizeof (hashInput), 229 &cbcHash, 230 plContext), 231 PKIX_HASHFAILED); 232 233 *pHashcode = cbcHash; 234 235 cleanup: 236 237 PKIX_RETURN(CERTBASICCONSTRAINTS); 238 } 239 240 241 /* 242 * FUNCTION: pkix_pl_CertBasicConstraints_Equals 243 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) 244 */ 245 static PKIX_Error * 246 pkix_pl_CertBasicConstraints_Equals( 247 PKIX_PL_Object *firstObject, 248 PKIX_PL_Object *secondObject, 249 PKIX_Boolean *pResult, 250 void *plContext) 251 { 252 PKIX_PL_CertBasicConstraints *firstCBC = NULL; 253 PKIX_PL_CertBasicConstraints *secondCBC = NULL; 254 PKIX_UInt32 secondType; 255 PKIX_Boolean firstIsCA = PKIX_FALSE; 256 PKIX_Boolean secondIsCA = PKIX_FALSE; 257 PKIX_Int32 firstPathLen = 0; 258 PKIX_Int32 secondPathLen = 0; 259 260 PKIX_ENTER(CERTBASICCONSTRAINTS, 261 "pkix_pl_CertBasicConstraints_Equals"); 262 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); 263 264 /* test that firstObject is a CertBasicConstraints */ 265 PKIX_CHECK(pkix_CheckType 266 (firstObject, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext), 267 PKIX_FIRSTOBJECTNOTCERTBASICCONSTRAINTS); 268 269 /* 270 * Since we know firstObject is a CertBasicConstraints, 271 * if both references are identical, they must be equal 272 */ 273 if (firstObject == secondObject){ 274 *pResult = PKIX_TRUE; 275 goto cleanup; 276 } 277 278 /* 279 * If secondObject isn't a CertBasicConstraints, we 280 * don't throw an error. We simply return FALSE. 281 */ 282 PKIX_CHECK(PKIX_PL_Object_GetType 283 (secondObject, &secondType, plContext), 284 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); 285 if (secondType != PKIX_CERTBASICCONSTRAINTS_TYPE) { 286 *pResult = PKIX_FALSE; 287 goto cleanup; 288 } 289 290 firstCBC = (PKIX_PL_CertBasicConstraints *)firstObject; 291 secondCBC = (PKIX_PL_CertBasicConstraints *)secondObject; 292 293 /* 294 * Compare the value of the CAFlag components 295 */ 296 297 firstIsCA = firstCBC->isCA; 298 299 /* 300 * Failure here would be an error, not merely a miscompare, 301 * since we know second is a CertBasicConstraints. 302 */ 303 secondIsCA = secondCBC->isCA; 304 305 /* 306 * If isCA flags differ, the objects are not equal. 307 */ 308 if (secondIsCA != firstIsCA) { 309 *pResult = PKIX_FALSE; 310 goto cleanup; 311 } 312 313 /* 314 * If isCA was FALSE, the objects are equal, because 315 * pathLen is meaningless in that case. 316 */ 317 if (!firstIsCA) { 318 *pResult = PKIX_TRUE; 319 goto cleanup; 320 } 321 322 firstPathLen = firstCBC->pathLen; 323 secondPathLen = secondCBC->pathLen; 324 325 *pResult = (secondPathLen == firstPathLen); 326 327 cleanup: 328 329 PKIX_RETURN(CERTBASICCONSTRAINTS); 330 } 331 332 /* 333 * FUNCTION: pkix_pl_CertBasicConstraints_RegisterSelf 334 * DESCRIPTION: 335 * Registers PKIX_CERTBASICCONSTRAINTS_TYPE and its related 336 * functions with systemClasses[] 337 * THREAD SAFETY: 338 * Not Thread Safe - for performance and complexity reasons 339 * 340 * Since this function is only called by PKIX_PL_Initialize, 341 * which should only be called once, it is acceptable that 342 * this function is not thread-safe. 343 */ 344 PKIX_Error * 345 pkix_pl_CertBasicConstraints_RegisterSelf(void *plContext) 346 { 347 348 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; 349 pkix_ClassTable_Entry entry; 350 351 PKIX_ENTER(CERTBASICCONSTRAINTS, 352 "pkix_pl_CertBasicConstraints_RegisterSelf"); 353 354 entry.description = "CertBasicConstraints"; 355 entry.objCounter = 0; 356 entry.typeObjectSize = sizeof(PKIX_PL_CertBasicConstraints); 357 entry.destructor = pkix_pl_CertBasicConstraints_Destroy; 358 entry.equalsFunction = pkix_pl_CertBasicConstraints_Equals; 359 entry.hashcodeFunction = pkix_pl_CertBasicConstraints_Hashcode; 360 entry.toStringFunction = pkix_pl_CertBasicConstraints_ToString; 361 entry.comparator = NULL; 362 entry.duplicateFunction = pkix_duplicateImmutable; 363 364 systemClasses[PKIX_CERTBASICCONSTRAINTS_TYPE] = entry; 365 366 PKIX_RETURN(CERTBASICCONSTRAINTS); 367 } 368 369 /* --Public-Functions------------------------------------------------------- */ 370 371 /* 372 * FUNCTION: PKIX_PL_BasicConstraints_GetCAFlag 373 * (see comments in pkix_pl_pki.h) 374 */ 375 PKIX_Error * 376 PKIX_PL_BasicConstraints_GetCAFlag( 377 PKIX_PL_CertBasicConstraints *basicConstraints, 378 PKIX_Boolean *pResult, 379 void *plContext) 380 { 381 PKIX_ENTER(CERTBASICCONSTRAINTS, 382 "PKIX_PL_BasicConstraintsGetCAFlag"); 383 PKIX_NULLCHECK_TWO(basicConstraints, pResult); 384 385 *pResult = basicConstraints->isCA; 386 387 PKIX_RETURN(CERTBASICCONSTRAINTS); 388 } 389 390 /* 391 * FUNCTION: PKIX_PL_BasicConstraints_GetPathLenConstraint 392 * (see comments in pkix_pl_pki.h) 393 */ 394 PKIX_Error * 395 PKIX_PL_BasicConstraints_GetPathLenConstraint( 396 PKIX_PL_CertBasicConstraints *basicConstraints, 397 PKIX_Int32 *pPathLenConstraint, 398 void *plContext) 399 { 400 PKIX_ENTER(CERTBASICCONSTRAINTS, 401 "PKIX_PL_BasicConstraintsGetPathLenConstraint"); 402 PKIX_NULLCHECK_TWO(basicConstraints, pPathLenConstraint); 403 404 *pPathLenConstraint = basicConstraints->pathLen; 405 406 PKIX_RETURN(CERTBASICCONSTRAINTS); 407 }