pkix_trustanchor.c (15678B)
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_trustanchor.c 6 * 7 * TrustAnchor Object Functions 8 * 9 */ 10 11 #include "pkix_trustanchor.h" 12 13 /* --Private-Functions-------------------------------------------- */ 14 15 /* 16 * FUNCTION: pkix_TrustAnchor_Destroy 17 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) 18 */ 19 static PKIX_Error * 20 pkix_TrustAnchor_Destroy( 21 PKIX_PL_Object *object, 22 void *plContext) 23 { 24 PKIX_TrustAnchor *anchor = NULL; 25 26 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Destroy"); 27 PKIX_NULLCHECK_ONE(object); 28 29 /* Check that this object is a trust anchor */ 30 PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext), 31 PKIX_OBJECTNOTTRUSTANCHOR); 32 33 anchor = (PKIX_TrustAnchor *)object; 34 35 PKIX_DECREF(anchor->trustedCert); 36 PKIX_DECREF(anchor->caName); 37 PKIX_DECREF(anchor->caPubKey); 38 PKIX_DECREF(anchor->nameConstraints); 39 40 cleanup: 41 42 PKIX_RETURN(TRUSTANCHOR); 43 } 44 45 /* 46 * FUNCTION: pkix_TrustAnchor_Equals 47 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h) 48 */ 49 static PKIX_Error * 50 pkix_TrustAnchor_Equals( 51 PKIX_PL_Object *first, 52 PKIX_PL_Object *second, 53 PKIX_Boolean *pResult, 54 void *plContext) 55 { 56 PKIX_UInt32 secondType; 57 PKIX_Boolean cmpResult; 58 PKIX_TrustAnchor *firstAnchor = NULL; 59 PKIX_TrustAnchor *secondAnchor = NULL; 60 PKIX_PL_Cert *firstCert = NULL; 61 PKIX_PL_Cert *secondCert = NULL; 62 63 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Equals"); 64 PKIX_NULLCHECK_THREE(first, second, pResult); 65 66 PKIX_CHECK(pkix_CheckType(first, PKIX_TRUSTANCHOR_TYPE, plContext), 67 PKIX_FIRSTOBJECTNOTTRUSTANCHOR); 68 69 PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext), 70 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); 71 72 *pResult = PKIX_FALSE; 73 74 if (secondType != PKIX_TRUSTANCHOR_TYPE) goto cleanup; 75 76 firstAnchor = (PKIX_TrustAnchor *)first; 77 secondAnchor = (PKIX_TrustAnchor *)second; 78 79 firstCert = firstAnchor->trustedCert; 80 secondCert = secondAnchor->trustedCert; 81 82 if ((firstCert && !secondCert) || (!firstCert && secondCert)){ 83 goto cleanup; 84 } 85 86 if (firstCert && secondCert){ 87 PKIX_CHECK(PKIX_PL_Object_Equals 88 ((PKIX_PL_Object *)firstCert, 89 (PKIX_PL_Object *)secondCert, 90 &cmpResult, 91 plContext), 92 PKIX_OBJECTEQUALSFAILED); 93 } else { 94 PKIX_CHECK(PKIX_PL_Object_Equals 95 ((PKIX_PL_Object *)firstAnchor->caName, 96 (PKIX_PL_Object *)secondAnchor->caName, 97 &cmpResult, 98 plContext), 99 PKIX_OBJECTEQUALSFAILED); 100 101 if (!cmpResult) goto cleanup; 102 103 PKIX_CHECK(PKIX_PL_Object_Equals 104 ((PKIX_PL_Object *)firstAnchor->caPubKey, 105 (PKIX_PL_Object *)secondAnchor->caPubKey, 106 &cmpResult, 107 plContext), 108 PKIX_OBJECTEQUALSFAILED); 109 110 if (!cmpResult) goto cleanup; 111 112 PKIX_EQUALS 113 (firstAnchor->nameConstraints, 114 secondAnchor->nameConstraints, 115 &cmpResult, 116 plContext, 117 PKIX_OBJECTEQUALSFAILED); 118 119 if (!cmpResult) goto cleanup; 120 121 } 122 123 *pResult = cmpResult; 124 125 cleanup: 126 127 PKIX_RETURN(TRUSTANCHOR); 128 } 129 130 /* 131 * FUNCTION: pkix_TrustAnchor_Hashcode 132 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) 133 */ 134 static PKIX_Error * 135 pkix_TrustAnchor_Hashcode( 136 PKIX_PL_Object *object, 137 PKIX_UInt32 *pHashcode, 138 void *plContext) 139 { 140 PKIX_TrustAnchor *anchor = NULL; 141 PKIX_PL_Cert *cert = NULL; 142 PKIX_UInt32 hash = 0; 143 PKIX_UInt32 certHash = 0; 144 PKIX_UInt32 nameHash = 0; 145 PKIX_UInt32 pubKeyHash = 0; 146 PKIX_UInt32 ncHash = 0; 147 148 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Hashcode"); 149 PKIX_NULLCHECK_TWO(object, pHashcode); 150 151 PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext), 152 PKIX_OBJECTNOTTRUSTANCHOR); 153 154 anchor = (PKIX_TrustAnchor*)object; 155 cert = anchor->trustedCert; 156 157 if (cert){ 158 PKIX_CHECK(PKIX_PL_Object_Hashcode 159 ((PKIX_PL_Object *)cert, 160 &certHash, 161 plContext), 162 PKIX_OBJECTHASHCODEFAILED); 163 164 hash = certHash; 165 166 } else { 167 PKIX_CHECK(PKIX_PL_Object_Hashcode 168 ((PKIX_PL_Object *)anchor->caName, 169 &nameHash, 170 plContext), 171 PKIX_OBJECTHASHCODEFAILED); 172 173 PKIX_CHECK(PKIX_PL_Object_Hashcode 174 ((PKIX_PL_Object *)anchor->caPubKey, 175 &pubKeyHash, 176 plContext), 177 PKIX_OBJECTHASHCODEFAILED); 178 179 PKIX_HASHCODE(anchor->nameConstraints, &ncHash, plContext, 180 PKIX_OBJECTHASHCODEFAILED); 181 182 hash = 31 * nameHash + pubKeyHash + ncHash; 183 184 } 185 186 *pHashcode = hash; 187 188 cleanup: 189 190 PKIX_RETURN(TRUSTANCHOR); 191 } 192 193 /* 194 * FUNCTION: pkix_TrustAnchor_ToString 195 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) 196 */ 197 static PKIX_Error * 198 pkix_TrustAnchor_ToString( 199 PKIX_PL_Object *object, 200 PKIX_PL_String **pString, 201 void *plContext) 202 { 203 PKIX_TrustAnchor *anchor = NULL; 204 char *asciiFormat = NULL; 205 PKIX_PL_String *formatString = NULL; 206 PKIX_PL_String *anchorString = NULL; 207 PKIX_PL_String *certString = NULL; 208 PKIX_PL_String *nameString = NULL; 209 PKIX_PL_String *pubKeyString = NULL; 210 PKIX_PL_String *nameConstraintsString = NULL; 211 212 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_ToString"); 213 PKIX_NULLCHECK_TWO(object, pString); 214 215 PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext), 216 PKIX_OBJECTNOTTRUSTANCHOR); 217 218 anchor = (PKIX_TrustAnchor*)object; 219 220 if (anchor->trustedCert){ 221 asciiFormat = 222 "[\n" 223 "\tTrusted Cert: %s\n" 224 "]\n"; 225 226 PKIX_CHECK(PKIX_PL_String_Create 227 (PKIX_ESCASCII, 228 asciiFormat, 229 0, 230 &formatString, 231 plContext), 232 PKIX_STRINGCREATEFAILED); 233 234 PKIX_CHECK(PKIX_PL_Object_ToString 235 ((PKIX_PL_Object *)anchor->trustedCert, 236 &certString, 237 plContext), 238 PKIX_OBJECTTOSTRINGFAILED); 239 240 PKIX_CHECK(PKIX_PL_Sprintf 241 (&anchorString, 242 plContext, 243 formatString, 244 certString), 245 PKIX_SPRINTFFAILED); 246 } else { 247 asciiFormat = 248 "[\n" 249 "\tTrusted CA Name: %s\n" 250 "\tTrusted CA PublicKey: %s\n" 251 "\tInitial Name Constraints:%s\n" 252 "]\n"; 253 254 PKIX_CHECK(PKIX_PL_String_Create 255 (PKIX_ESCASCII, 256 asciiFormat, 257 0, 258 &formatString, 259 plContext), 260 PKIX_STRINGCREATEFAILED); 261 262 PKIX_CHECK(PKIX_PL_Object_ToString 263 ((PKIX_PL_Object *)anchor->caName, 264 &nameString, 265 plContext), 266 PKIX_OBJECTTOSTRINGFAILED); 267 268 PKIX_CHECK(PKIX_PL_Object_ToString 269 ((PKIX_PL_Object *)anchor->caPubKey, 270 &pubKeyString, 271 plContext), 272 PKIX_OBJECTTOSTRINGFAILED); 273 274 PKIX_TOSTRING 275 (anchor->nameConstraints, 276 &nameConstraintsString, 277 plContext, 278 PKIX_OBJECTTOSTRINGFAILED); 279 280 PKIX_CHECK(PKIX_PL_Sprintf 281 (&anchorString, 282 plContext, 283 formatString, 284 nameString, 285 pubKeyString, 286 nameConstraintsString), 287 PKIX_SPRINTFFAILED); 288 } 289 290 *pString = anchorString; 291 292 cleanup: 293 294 PKIX_DECREF(formatString); 295 PKIX_DECREF(certString); 296 PKIX_DECREF(nameString); 297 PKIX_DECREF(pubKeyString); 298 PKIX_DECREF(nameConstraintsString); 299 300 PKIX_RETURN(TRUSTANCHOR); 301 } 302 303 /* 304 * FUNCTION: pkix_TrustAnchor_RegisterSelf 305 * DESCRIPTION: 306 * Registers PKIX_TRUSTANCHOR_TYPE and its related functions with 307 * systemClasses[] 308 * THREAD SAFETY: 309 * Not Thread Safe - for performance and complexity reasons 310 * 311 * Since this function is only called by PKIX_PL_Initialize, which should 312 * only be called once, it is acceptable that this function is not 313 * thread-safe. 314 */ 315 PKIX_Error * 316 pkix_TrustAnchor_RegisterSelf(void *plContext) 317 { 318 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; 319 pkix_ClassTable_Entry entry; 320 321 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_RegisterSelf"); 322 323 entry.description = "TrustAnchor"; 324 entry.objCounter = 0; 325 entry.typeObjectSize = sizeof(PKIX_TrustAnchor); 326 entry.destructor = pkix_TrustAnchor_Destroy; 327 entry.equalsFunction = pkix_TrustAnchor_Equals; 328 entry.hashcodeFunction = pkix_TrustAnchor_Hashcode; 329 entry.toStringFunction = pkix_TrustAnchor_ToString; 330 entry.comparator = NULL; 331 entry.duplicateFunction = pkix_duplicateImmutable; 332 333 systemClasses[PKIX_TRUSTANCHOR_TYPE] = entry; 334 335 PKIX_RETURN(TRUSTANCHOR); 336 } 337 338 /* --Public-Functions--------------------------------------------- */ 339 340 341 /* 342 * FUNCTION: PKIX_TrustAnchor_CreateWithCert (see comments in pkix_params.h) 343 */ 344 PKIX_Error * 345 PKIX_TrustAnchor_CreateWithCert( 346 PKIX_PL_Cert *cert, 347 PKIX_TrustAnchor **pAnchor, 348 void *plContext) 349 { 350 PKIX_TrustAnchor *anchor = NULL; 351 352 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_CreateWithCert"); 353 PKIX_NULLCHECK_TWO(cert, pAnchor); 354 355 PKIX_CHECK(PKIX_PL_Object_Alloc 356 (PKIX_TRUSTANCHOR_TYPE, 357 sizeof (PKIX_TrustAnchor), 358 (PKIX_PL_Object **)&anchor, 359 plContext), 360 PKIX_COULDNOTCREATETRUSTANCHOROBJECT); 361 362 /* initialize fields */ 363 PKIX_CHECK( 364 PKIX_PL_Cert_SetAsTrustAnchor(cert, plContext), 365 PKIX_CERTSETASTRUSTANCHORFAILED); 366 367 PKIX_INCREF(cert); 368 anchor->trustedCert = cert; 369 370 anchor->caName = NULL; 371 anchor->caPubKey = NULL; 372 373 PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints 374 (anchor->trustedCert, &anchor->nameConstraints, plContext), 375 PKIX_CERTGETNAMECONSTRAINTSFAILED); 376 377 378 *pAnchor = anchor; 379 anchor = NULL; 380 381 cleanup: 382 383 PKIX_DECREF(anchor); 384 385 PKIX_RETURN(TRUSTANCHOR); 386 387 } 388 389 /* 390 * FUNCTION: PKIX_TrustAnchor_CreateWithNameKeyPair 391 * (see comments in pkix_params.h) 392 */ 393 PKIX_Error * 394 PKIX_TrustAnchor_CreateWithNameKeyPair( 395 PKIX_PL_X500Name *name, 396 PKIX_PL_PublicKey *pubKey, 397 PKIX_PL_CertNameConstraints *nameConstraints, 398 PKIX_TrustAnchor **pAnchor, 399 void *plContext) 400 { 401 PKIX_TrustAnchor *anchor = NULL; 402 403 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_CreateWithNameKeyPair"); 404 405 #ifndef BUILD_LIBPKIX_TESTS 406 /* Nss creates trust anchors by using PKIX_TrustAnchor_CreateWithCert 407 * function as the complete trusted cert structure, and not only cert 408 * public key, is required for chain building and validation processes. 409 * Restricting this function for been used only in libpkix unit 410 * tests. */ 411 PKIX_ERROR(PKIX_FUNCTIONMUSTNOTBEUSED); 412 #endif 413 414 PKIX_NULLCHECK_THREE(name, pubKey, pAnchor); 415 416 PKIX_CHECK(PKIX_PL_Object_Alloc 417 (PKIX_TRUSTANCHOR_TYPE, 418 sizeof (PKIX_TrustAnchor), 419 (PKIX_PL_Object **)&anchor, 420 plContext), 421 PKIX_COULDNOTCREATETRUSTANCHOROBJECT); 422 423 /* initialize fields */ 424 anchor->trustedCert = NULL; 425 426 PKIX_INCREF(name); 427 anchor->caName = name; 428 429 PKIX_INCREF(pubKey); 430 anchor->caPubKey = pubKey; 431 432 PKIX_INCREF(nameConstraints); 433 anchor->nameConstraints = nameConstraints; 434 435 *pAnchor = anchor; 436 anchor = NULL; 437 cleanup: 438 439 PKIX_DECREF(anchor); 440 441 PKIX_RETURN(TRUSTANCHOR); 442 } 443 444 /* 445 * FUNCTION: PKIX_TrustAnchor_GetTrustedCert (see comments in pkix_params.h) 446 */ 447 PKIX_Error * 448 PKIX_TrustAnchor_GetTrustedCert( 449 PKIX_TrustAnchor *anchor, 450 PKIX_PL_Cert **pCert, 451 void *plContext) 452 { 453 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetTrustedCert"); 454 PKIX_NULLCHECK_TWO(anchor, pCert); 455 456 PKIX_INCREF(anchor->trustedCert); 457 458 *pCert = anchor->trustedCert; 459 460 cleanup: 461 PKIX_RETURN(TRUSTANCHOR); 462 463 } 464 465 /* 466 * FUNCTION: PKIX_TrustAnchor_GetCAName (see comments in pkix_params.h) 467 */ 468 PKIX_Error * 469 PKIX_TrustAnchor_GetCAName( 470 PKIX_TrustAnchor *anchor, 471 PKIX_PL_X500Name **pCAName, 472 void *plContext) 473 { 474 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetCAName"); 475 PKIX_NULLCHECK_TWO(anchor, pCAName); 476 477 PKIX_INCREF(anchor->caName); 478 479 *pCAName = anchor->caName; 480 481 cleanup: 482 PKIX_RETURN(TRUSTANCHOR); 483 484 } 485 486 /* 487 * FUNCTION: PKIX_TrustAnchor_GetCAPublicKey (see comments in pkix_params.h) 488 */ 489 PKIX_Error * 490 PKIX_TrustAnchor_GetCAPublicKey( 491 PKIX_TrustAnchor *anchor, 492 PKIX_PL_PublicKey **pPubKey, 493 void *plContext) 494 { 495 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetCAPublicKey"); 496 PKIX_NULLCHECK_TWO(anchor, pPubKey); 497 498 PKIX_INCREF(anchor->caPubKey); 499 500 *pPubKey = anchor->caPubKey; 501 502 cleanup: 503 PKIX_RETURN(TRUSTANCHOR); 504 } 505 506 /* 507 * FUNCTION: PKIX_TrustAnchor_GetNameConstraints 508 * (see comments in pkix_params.h) 509 */ 510 PKIX_Error * 511 PKIX_TrustAnchor_GetNameConstraints( 512 PKIX_TrustAnchor *anchor, 513 PKIX_PL_CertNameConstraints **pNameConstraints, 514 void *plContext) 515 { 516 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetNameConstraints"); 517 PKIX_NULLCHECK_TWO(anchor, pNameConstraints); 518 519 PKIX_INCREF(anchor->nameConstraints); 520 521 *pNameConstraints = anchor->nameConstraints; 522 523 cleanup: 524 PKIX_RETURN(TRUSTANCHOR); 525 }