pkix_pl_generalname.c (30025B)
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_generalname.c 6 * 7 * GeneralName Object Definitions 8 * 9 */ 10 11 #include "pkix_pl_generalname.h" 12 13 /* --Private-GeneralName-Functions------------------------------------- */ 14 15 /* 16 * FUNCTION: pkix_pl_GeneralName_GetNssGeneralName 17 * DESCRIPTION: 18 * 19 * Retrieves the NSS representation of the PKIX_PL_GeneralName pointed by 20 * "genName" and stores it at "pNssGenName". The NSS data type CERTGeneralName 21 * is stored in this object when the object was created. 22 * 23 * PARAMETERS: 24 * "genName" 25 * Address of PKIX_PL_GeneralName. Must be non-NULL. 26 * "pNssGenName" 27 * Address where CERTGeneralName will be stored. 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 GeneralName Error if the function fails in a non-fatal way. 34 * Returns a Fatal Error if the function fails in an unrecoverable way. 35 */ 36 PKIX_Error * 37 pkix_pl_GeneralName_GetNssGeneralName( 38 PKIX_PL_GeneralName *genName, 39 CERTGeneralName **pNssGenName, 40 void *plContext) 41 { 42 CERTGeneralName *nssGenName = NULL; 43 44 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_GetNssGeneralName"); 45 PKIX_NULLCHECK_THREE(genName, pNssGenName, genName->nssGeneralNameList); 46 47 nssGenName = genName->nssGeneralNameList->name; 48 49 *pNssGenName = nssGenName; 50 51 PKIX_RETURN(GENERALNAME); 52 } 53 54 /* 55 * FUNCTION: pkix_pl_OtherName_Create 56 * DESCRIPTION: 57 * 58 * Creates new OtherName which represents the CERTGeneralName pointed to by 59 * "nssAltName" and stores it at "pOtherName". 60 * 61 * PARAMETERS: 62 * "nssAltName" 63 * Address of CERTGeneralName. Must be non-NULL. 64 * "pOtherName" 65 * Address where object pointer will be stored. Must be non-NULL. 66 * "plContext" - Platform-specific context pointer. 67 * THREAD SAFETY: 68 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 69 * RETURNS: 70 * Returns NULL if the function succeeds. 71 * Returns a GeneralName Error if the function fails in a non-fatal way. 72 * Returns a Fatal Error if the function fails in an unrecoverable way. 73 */ 74 static PKIX_Error * 75 pkix_pl_OtherName_Create( 76 CERTGeneralName *nssAltName, 77 OtherName **pOtherName, 78 void *plContext) 79 { 80 OtherName *otherName = NULL; 81 SECItem secItemName; 82 SECItem secItemOID; 83 SECStatus rv; 84 85 PKIX_ENTER(GENERALNAME, "pkix_pl_OtherName_Create"); 86 PKIX_NULLCHECK_TWO(nssAltName, pOtherName); 87 88 PKIX_CHECK(PKIX_PL_Malloc 89 (sizeof (OtherName), (void **)&otherName, plContext), 90 PKIX_MALLOCFAILED); 91 92 /* make a copy of the name field */ 93 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CopyItem).\n"); 94 rv = SECITEM_CopyItem 95 (NULL, &otherName->name, &nssAltName->name.OthName.name); 96 if (rv != SECSuccess) { 97 PKIX_ERROR(PKIX_OUTOFMEMORY); 98 } 99 100 /* make a copy of the oid field */ 101 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CopyItem).\n"); 102 rv = SECITEM_CopyItem 103 (NULL, &otherName->oid, &nssAltName->name.OthName.oid); 104 if (rv != SECSuccess) { 105 PKIX_ERROR(PKIX_OUTOFMEMORY); 106 } 107 108 *pOtherName = otherName; 109 110 cleanup: 111 112 if (otherName && PKIX_ERROR_RECEIVED){ 113 secItemName = otherName->name; 114 secItemOID = otherName->oid; 115 116 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n"); 117 SECITEM_FreeItem(&secItemName, PR_FALSE); 118 119 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n"); 120 SECITEM_FreeItem(&secItemOID, PR_FALSE); 121 122 PKIX_FREE(otherName); 123 otherName = NULL; 124 } 125 126 PKIX_RETURN(GENERALNAME); 127 } 128 129 /* 130 * FUNCTION: pkix_pl_DirectoryName_Create 131 * DESCRIPTION: 132 * 133 * Creates a new X500Name which represents the directoryName component of the 134 * CERTGeneralName pointed to by "nssAltName" and stores it at "pX500Name". 135 * 136 * PARAMETERS: 137 * "nssAltName" 138 * Address of CERTGeneralName. Must be non-NULL. 139 * "pX500Name" 140 * Address where object pointer will be stored. Must be non-NULL. 141 * "plContext" - Platform-specific context pointer. 142 * THREAD SAFETY: 143 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 144 * RETURNS: 145 * Returns NULL if the function succeeds. 146 * Returns a GeneralName Error if the function fails in a non-fatal way. 147 * Returns a Fatal Error if the function fails in an unrecoverable way. 148 */ 149 static PKIX_Error * 150 pkix_pl_DirectoryName_Create( 151 CERTGeneralName *nssAltName, 152 PKIX_PL_X500Name **pX500Name, 153 void *plContext) 154 { 155 PKIX_PL_X500Name *pkixDN = NULL; 156 CERTName *dirName = NULL; 157 PKIX_PL_String *pkixDNString = NULL; 158 char *utf8String = NULL; 159 160 PKIX_ENTER(GENERALNAME, "pkix_pl_DirectoryName_Create"); 161 PKIX_NULLCHECK_TWO(nssAltName, pX500Name); 162 163 dirName = &nssAltName->name.directoryName; 164 165 PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName(NULL, dirName, 166 &pkixDN, plContext), 167 PKIX_X500NAMECREATEFROMCERTNAMEFAILED); 168 169 *pX500Name = pkixDN; 170 171 cleanup: 172 173 PR_Free(utf8String); 174 PKIX_DECREF(pkixDNString); 175 176 PKIX_RETURN(GENERALNAME); 177 } 178 179 /* 180 * FUNCTION: pkix_pl_GeneralName_Create 181 * DESCRIPTION: 182 * 183 * Creates new GeneralName which represents the CERTGeneralName pointed to by 184 * "nssAltName" and stores it at "pGenName". 185 * 186 * PARAMETERS: 187 * "nssAltName" 188 * Address of CERTGeneralName. Must be non-NULL. 189 * "pGenName" 190 * Address where object pointer will be stored. Must be non-NULL. 191 * "plContext" - Platform-specific context pointer. 192 * THREAD SAFETY: 193 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 194 * RETURNS: 195 * Returns NULL if the function succeeds. 196 * Returns a GeneralName Error if the function fails in a non-fatal way. 197 * Returns a Fatal Error if the function fails in an unrecoverable way. 198 */ 199 PKIX_Error * 200 pkix_pl_GeneralName_Create( 201 CERTGeneralName *nssAltName, 202 PKIX_PL_GeneralName **pGenName, 203 void *plContext) 204 { 205 PKIX_PL_GeneralName *genName = NULL; 206 PKIX_PL_X500Name *pkixDN = NULL; 207 PKIX_PL_OID *pkixOID = NULL; 208 OtherName *otherName = NULL; 209 CERTGeneralNameList *nssGenNameList = NULL; 210 CERTGeneralNameType nameType; 211 212 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Create"); 213 PKIX_NULLCHECK_TWO(nssAltName, pGenName); 214 215 /* create a PKIX_PL_GeneralName object */ 216 PKIX_CHECK(PKIX_PL_Object_Alloc 217 (PKIX_GENERALNAME_TYPE, 218 sizeof (PKIX_PL_GeneralName), 219 (PKIX_PL_Object **)&genName, 220 plContext), 221 PKIX_COULDNOTCREATEOBJECT); 222 223 nameType = nssAltName->type; 224 225 /* 226 * We use CERT_CreateGeneralNameList to create just one CERTGeneralName 227 * item for memory allocation reason. If we want to just create one 228 * item, we have to use the calling path CERT_NewGeneralName, then 229 * CERT_CopyOneGeneralName. With this calling path, if we pass 230 * the arena argument as NULL, in CERT_CopyOneGeneralName's subsequent 231 * call to CERT_CopyName, it assumes arena should be valid, hence 232 * segmentation error (not sure this is a NSS bug, certainly it is 233 * not consistent). But on the other hand, we don't want to keep an 234 * arena record here explicitely for every PKIX_PL_GeneralName. 235 * So I concluded it is better to use CERT_CreateGeneralNameList, 236 * which keeps an arena pointer in its data structure and also masks 237 * out details calls from this libpkix level. 238 */ 239 240 PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_CreateGeneralNameList).\n"); 241 nssGenNameList = CERT_CreateGeneralNameList(nssAltName); 242 243 if (nssGenNameList == NULL) { 244 PKIX_ERROR(PKIX_CERTCREATEGENERALNAMELISTFAILED); 245 } 246 247 genName->nssGeneralNameList = nssGenNameList; 248 249 /* initialize fields */ 250 genName->type = nameType; 251 genName->directoryName = NULL; 252 genName->OthName = NULL; 253 genName->other = NULL; 254 genName->oid = NULL; 255 256 switch (nameType){ 257 case certOtherName: 258 259 PKIX_CHECK(pkix_pl_OtherName_Create 260 (nssAltName, &otherName, plContext), 261 PKIX_OTHERNAMECREATEFAILED); 262 263 genName->OthName = otherName; 264 break; 265 266 case certDirectoryName: 267 268 PKIX_CHECK(pkix_pl_DirectoryName_Create 269 (nssAltName, &pkixDN, plContext), 270 PKIX_DIRECTORYNAMECREATEFAILED); 271 272 genName->directoryName = pkixDN; 273 break; 274 case certRegisterID: 275 PKIX_CHECK(PKIX_PL_OID_CreateBySECItem(&nssAltName->name.other, 276 &pkixOID, plContext), 277 PKIX_OIDCREATEFAILED); 278 279 genName->oid = pkixOID; 280 break; 281 case certDNSName: 282 case certEDIPartyName: 283 case certIPAddress: 284 case certRFC822Name: 285 case certX400Address: 286 case certURI: 287 genName->other = SECITEM_DupItem(&nssAltName->name.other); 288 if (!genName->other) { 289 PKIX_ERROR(PKIX_OUTOFMEMORY); 290 } 291 break; 292 default: 293 PKIX_ERROR(PKIX_NAMETYPENOTSUPPORTED); 294 } 295 296 *pGenName = genName; 297 genName = NULL; 298 299 cleanup: 300 PKIX_DECREF(genName); 301 302 PKIX_RETURN(GENERALNAME); 303 } 304 305 /* 306 * FUNCTION: pkix_pl_GeneralName_ToString_Helper 307 * DESCRIPTION: 308 * 309 * Helper function that creates a string representation of the GeneralName 310 * pointed to by "name" and stores it at "pString" Different mechanisms are 311 * used to create the string, depending on the type of the GeneralName. 312 * 313 * PARAMETERS 314 * "name" 315 * Address of GeneralName whose string representation is desired. 316 * Must be non-NULL. 317 * "pString" 318 * Address where object pointer will be stored. Must be non-NULL. 319 * "plContext" - Platform-specific context pointer. 320 * THREAD SAFETY: 321 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 322 * RETURNS: 323 * Returns NULL if the function succeeds. 324 * Returns a GeneralName Error if the function fails in a non-fatal way. 325 * Returns a Fatal Error if the function fails in an unrecoverable way. 326 */ 327 static PKIX_Error * 328 pkix_pl_GeneralName_ToString_Helper( 329 PKIX_PL_GeneralName *name, 330 PKIX_PL_String **pString, 331 void *plContext) 332 { 333 PKIX_PL_X500Name *pkixDN = NULL; 334 PKIX_PL_OID *pkixOID = NULL; 335 char *x400AsciiName = NULL; 336 char *ediPartyName = NULL; 337 char *asciiName = NULL; 338 339 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_ToString_Helper"); 340 PKIX_NULLCHECK_TWO(name, pString); 341 342 switch (name->type) { 343 case certRFC822Name: 344 case certDNSName: 345 case certURI: 346 /* 347 * Note that we can't use PKIX_ESCASCII here because 348 * name->other->data is not guaranteed to be null-terminated. 349 */ 350 351 PKIX_NULLCHECK_ONE(name->other); 352 353 PKIX_CHECK(PKIX_PL_String_Create(PKIX_UTF8, 354 (name->other)->data, 355 (name->other)->len, 356 pString, 357 plContext), 358 PKIX_STRINGCREATEFAILED); 359 break; 360 case certEDIPartyName: 361 /* XXX print out the actual bytes */ 362 ediPartyName = "EDIPartyName: <DER-encoded value>"; 363 PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII, 364 ediPartyName, 365 0, 366 pString, 367 plContext), 368 PKIX_STRINGCREATEFAILED); 369 break; 370 case certX400Address: 371 /* XXX print out the actual bytes */ 372 x400AsciiName = "X400Address: <DER-encoded value>"; 373 PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII, 374 x400AsciiName, 375 0, 376 pString, 377 plContext), 378 PKIX_STRINGCREATEFAILED); 379 break; 380 case certIPAddress: 381 PKIX_CHECK(pkix_pl_ipAddrBytes2Ascii 382 (name->other, &asciiName, plContext), 383 PKIX_IPADDRBYTES2ASCIIFAILED); 384 385 PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII, 386 asciiName, 387 0, 388 pString, 389 plContext), 390 PKIX_STRINGCREATEFAILED); 391 break; 392 case certOtherName: 393 PKIX_NULLCHECK_ONE(name->OthName); 394 395 /* we only print type-id - don't know how to print value */ 396 /* XXX print out the bytes of the value */ 397 PKIX_CHECK(pkix_pl_oidBytes2Ascii 398 (&name->OthName->oid, &asciiName, plContext), 399 PKIX_OIDBYTES2ASCIIFAILED); 400 401 PKIX_CHECK(PKIX_PL_String_Create 402 (PKIX_ESCASCII, 403 asciiName, 404 0, 405 pString, 406 plContext), 407 PKIX_STRINGCREATEFAILED); 408 break; 409 case certRegisterID: 410 pkixOID = name->oid; 411 PKIX_CHECK(PKIX_PL_Object_ToString 412 ((PKIX_PL_Object *)pkixOID, pString, plContext), 413 PKIX_OIDTOSTRINGFAILED); 414 break; 415 case certDirectoryName: 416 pkixDN = name->directoryName; 417 PKIX_CHECK(PKIX_PL_Object_ToString 418 ((PKIX_PL_Object *)pkixDN, pString, plContext), 419 PKIX_X500NAMETOSTRINGFAILED); 420 break; 421 default: 422 PKIX_ERROR 423 (PKIX_TOSTRINGFORTHISGENERALNAMETYPENOTSUPPORTED); 424 } 425 426 cleanup: 427 428 PKIX_FREE(asciiName); 429 430 PKIX_RETURN(GENERALNAME); 431 } 432 433 /* 434 * FUNCTION: pkix_pl_GeneralName_Destroy 435 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) 436 */ 437 static PKIX_Error * 438 pkix_pl_GeneralName_Destroy( 439 PKIX_PL_Object *object, 440 void *plContext) 441 { 442 PKIX_PL_GeneralName *name = NULL; 443 SECItem secItemName; 444 SECItem secItemOID; 445 446 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Destroy"); 447 PKIX_NULLCHECK_ONE(object); 448 449 PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext), 450 PKIX_OBJECTNOTGENERALNAME); 451 452 name = (PKIX_PL_GeneralName *)object; 453 454 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n"); 455 SECITEM_FreeItem(name->other, PR_TRUE); 456 name->other = NULL; 457 458 if (name->OthName){ 459 secItemName = name->OthName->name; 460 secItemOID = name->OthName->oid; 461 462 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n"); 463 SECITEM_FreeItem(&secItemName, PR_FALSE); 464 465 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n"); 466 SECITEM_FreeItem(&secItemOID, PR_FALSE); 467 468 PKIX_FREE(name->OthName); 469 name->OthName = NULL; 470 } 471 472 if (name->nssGeneralNameList != NULL) { 473 PKIX_GENERALNAME_DEBUG 474 ("\t\tCalling CERT_DestroyGeneralNameList).\n"); 475 CERT_DestroyGeneralNameList(name->nssGeneralNameList); 476 } 477 478 PKIX_DECREF(name->directoryName); 479 PKIX_DECREF(name->oid); 480 481 cleanup: 482 483 PKIX_RETURN(GENERALNAME); 484 } 485 486 /* 487 * FUNCTION: pkix_pl_GeneralName_ToString 488 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) 489 */ 490 static PKIX_Error * 491 pkix_pl_GeneralName_ToString( 492 PKIX_PL_Object *object, 493 PKIX_PL_String **pString, 494 void *plContext) 495 { 496 PKIX_PL_String *nameString = NULL; 497 PKIX_PL_GeneralName *name = NULL; 498 499 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_toString"); 500 PKIX_NULLCHECK_TWO(object, pString); 501 502 PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext), 503 PKIX_OBJECTNOTGENERALNAME); 504 505 name = (PKIX_PL_GeneralName *)object; 506 507 PKIX_CHECK(pkix_pl_GeneralName_ToString_Helper 508 (name, &nameString, plContext), 509 PKIX_GENERALNAMETOSTRINGHELPERFAILED); 510 511 *pString = nameString; 512 513 cleanup: 514 515 516 517 PKIX_RETURN(GENERALNAME); 518 } 519 520 /* 521 * FUNCTION: pkix_pl_GeneralName_Hashcode 522 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) 523 */ 524 static PKIX_Error * 525 pkix_pl_GeneralName_Hashcode( 526 PKIX_PL_Object *object, 527 PKIX_UInt32 *pHashcode, 528 void *plContext) 529 { 530 PKIX_PL_GeneralName *name = NULL; 531 PKIX_UInt32 firstHash, secondHash, nameHash; 532 533 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Hashcode"); 534 PKIX_NULLCHECK_TWO(object, pHashcode); 535 536 PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext), 537 PKIX_OBJECTNOTGENERALNAME); 538 539 name = (PKIX_PL_GeneralName *)object; 540 541 switch (name->type) { 542 case certRFC822Name: 543 case certDNSName: 544 case certX400Address: 545 case certEDIPartyName: 546 case certURI: 547 case certIPAddress: 548 PKIX_NULLCHECK_ONE(name->other); 549 PKIX_CHECK(pkix_hash 550 ((const unsigned char *) 551 name->other->data, 552 name->other->len, 553 &nameHash, 554 plContext), 555 PKIX_HASHFAILED); 556 break; 557 case certRegisterID: 558 PKIX_CHECK(PKIX_PL_Object_Hashcode 559 ((PKIX_PL_Object *)name->oid, 560 &nameHash, 561 plContext), 562 PKIX_OIDHASHCODEFAILED); 563 break; 564 case certOtherName: 565 PKIX_NULLCHECK_ONE(name->OthName); 566 PKIX_CHECK(pkix_hash 567 ((const unsigned char *) 568 name->OthName->oid.data, 569 name->OthName->oid.len, 570 &firstHash, 571 plContext), 572 PKIX_HASHFAILED); 573 574 PKIX_CHECK(pkix_hash 575 ((const unsigned char *) 576 name->OthName->name.data, 577 name->OthName->name.len, 578 &secondHash, 579 plContext), 580 PKIX_HASHFAILED); 581 582 nameHash = firstHash + secondHash; 583 break; 584 case certDirectoryName: 585 PKIX_CHECK(PKIX_PL_Object_Hashcode 586 ((PKIX_PL_Object *) 587 name->directoryName, 588 &nameHash, 589 plContext), 590 PKIX_X500NAMEHASHCODEFAILED); 591 break; 592 } 593 594 *pHashcode = nameHash; 595 596 cleanup: 597 598 PKIX_RETURN(GENERALNAME); 599 600 } 601 602 /* 603 * FUNCTION: pkix_pl_GeneralName_Equals 604 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) 605 */ 606 static PKIX_Error * 607 pkix_pl_GeneralName_Equals( 608 PKIX_PL_Object *firstObject, 609 PKIX_PL_Object *secondObject, 610 PKIX_Boolean *pResult, 611 void *plContext) 612 { 613 PKIX_PL_GeneralName *firstName = NULL; 614 PKIX_PL_GeneralName *secondName = NULL; 615 PKIX_UInt32 secondType; 616 617 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Equals"); 618 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); 619 620 /* test that firstObject is a GeneralName */ 621 PKIX_CHECK(pkix_CheckType 622 (firstObject, PKIX_GENERALNAME_TYPE, plContext), 623 PKIX_FIRSTOBJECTNOTGENERALNAME); 624 625 /* 626 * Since we know firstObject is a GeneralName, if both references are 627 * identical, they must be equal 628 */ 629 if (firstObject == secondObject){ 630 *pResult = PKIX_TRUE; 631 goto cleanup; 632 } 633 634 /* 635 * If secondObject isn't a GeneralName, we don't throw an error. 636 * We simply return a Boolean result of FALSE 637 */ 638 *pResult = PKIX_FALSE; 639 PKIX_CHECK(PKIX_PL_Object_GetType 640 (secondObject, &secondType, plContext), 641 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); 642 if (secondType != PKIX_GENERALNAME_TYPE){ 643 goto cleanup; 644 } 645 646 firstName = (PKIX_PL_GeneralName *)firstObject; 647 secondName = (PKIX_PL_GeneralName *)secondObject; 648 649 if (firstName->type != secondName->type){ 650 goto cleanup; 651 } 652 653 switch (firstName->type) { 654 case certRFC822Name: 655 case certDNSName: 656 case certX400Address: 657 case certEDIPartyName: 658 case certURI: 659 case certIPAddress: 660 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CompareItem).\n"); 661 if (SECITEM_CompareItem(firstName->other, 662 secondName->other) != SECEqual) { 663 goto cleanup; 664 } 665 break; 666 case certRegisterID: 667 PKIX_CHECK(PKIX_PL_Object_Equals 668 ((PKIX_PL_Object *)firstName->oid, 669 (PKIX_PL_Object *)secondName->oid, 670 pResult, 671 plContext), 672 PKIX_OIDEQUALSFAILED); 673 goto cleanup; 674 case certOtherName: 675 PKIX_NULLCHECK_TWO(firstName->OthName, secondName->OthName); 676 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CompareItem).\n"); 677 if (SECITEM_CompareItem(&firstName->OthName->oid, 678 &secondName->OthName->oid) 679 != SECEqual || 680 SECITEM_CompareItem(&firstName->OthName->name, 681 &secondName->OthName->name) 682 != SECEqual) { 683 goto cleanup; 684 } 685 break; 686 case certDirectoryName: 687 PKIX_CHECK(PKIX_PL_Object_Equals 688 ((PKIX_PL_Object *)firstName->directoryName, 689 (PKIX_PL_Object *)secondName->directoryName, 690 pResult, 691 plContext), 692 PKIX_X500NAMEEQUALSFAILED); 693 goto cleanup; 694 } 695 696 *pResult = PKIX_TRUE; 697 698 cleanup: 699 700 PKIX_RETURN(GENERALNAME); 701 } 702 703 /* 704 * FUNCTION: pkix_pl_GeneralName_RegisterSelf 705 * DESCRIPTION: 706 * Registers PKIX_GENERALNAME_TYPE and related functions with systemClasses[] 707 * THREAD SAFETY: 708 * Not Thread Safe - for performance and complexity reasons 709 * 710 * Since this function is only called by PKIX_PL_Initialize, which should 711 * only be called once, it is acceptable that this function is not 712 * thread-safe. 713 */ 714 PKIX_Error * 715 pkix_pl_GeneralName_RegisterSelf(void *plContext) 716 { 717 718 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; 719 pkix_ClassTable_Entry entry; 720 721 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_RegisterSelf"); 722 723 entry.description = "GeneralName"; 724 entry.objCounter = 0; 725 entry.typeObjectSize = sizeof(PKIX_PL_GeneralName); 726 entry.destructor = pkix_pl_GeneralName_Destroy; 727 entry.equalsFunction = pkix_pl_GeneralName_Equals; 728 entry.hashcodeFunction = pkix_pl_GeneralName_Hashcode; 729 entry.toStringFunction = pkix_pl_GeneralName_ToString; 730 entry.comparator = NULL; 731 entry.duplicateFunction = pkix_duplicateImmutable; 732 733 systemClasses[PKIX_GENERALNAME_TYPE] = entry; 734 735 PKIX_RETURN(GENERALNAME); 736 } 737 738 /* --Public-Functions------------------------------------------------------- */ 739 740 #ifdef BUILD_LIBPKIX_TESTS 741 /* 742 * FUNCTION: PKIX_PL_GeneralName_Create (see comments in pkix_pl_pki.h) 743 */ 744 PKIX_Error * 745 PKIX_PL_GeneralName_Create( 746 PKIX_UInt32 nameType, 747 PKIX_PL_String *stringRep, 748 PKIX_PL_GeneralName **pGName, 749 void *plContext) 750 { 751 PKIX_PL_X500Name *pkixDN = NULL; 752 PKIX_PL_OID *pkixOID = NULL; 753 SECItem *secItem = NULL; 754 char *asciiString = NULL; 755 PKIX_UInt32 length = 0; 756 PKIX_PL_GeneralName *genName = NULL; 757 CERTGeneralName *nssGenName = NULL; 758 CERTGeneralNameList *nssGenNameList = NULL; 759 CERTName *nssCertName = NULL; 760 PLArenaPool *arena = NULL; 761 762 PKIX_ENTER(GENERALNAME, "PKIX_PL_GeneralName_Create"); 763 PKIX_NULLCHECK_TWO(pGName, stringRep); 764 765 PKIX_CHECK(PKIX_PL_String_GetEncoded 766 (stringRep, 767 PKIX_ESCASCII, 768 (void **)&asciiString, 769 &length, 770 plContext), 771 PKIX_STRINGGETENCODEDFAILED); 772 773 /* Create a temporary CERTGeneralName */ 774 PKIX_GENERALNAME_DEBUG("\t\tCalling PL_strlen).\n"); 775 length = PL_strlen(asciiString); 776 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_AllocItem).\n"); 777 secItem = SECITEM_AllocItem(NULL, NULL, length); 778 PKIX_GENERALNAME_DEBUG("\t\tCalling PORT_Memcpy).\n"); 779 (void) PORT_Memcpy(secItem->data, asciiString, length); 780 PKIX_CERT_DEBUG("\t\tCalling PORT_NewArena).\n"); 781 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 782 if (arena == NULL) { 783 PKIX_ERROR(PKIX_OUTOFMEMORY); 784 } 785 PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_NewGeneralName).\n"); 786 nssGenName = CERT_NewGeneralName(arena, nameType); 787 if (nssGenName == NULL) { 788 PKIX_ERROR(PKIX_ALLOCATENEWCERTGENERALNAMEFAILED); 789 } 790 791 switch (nameType) { 792 case certRFC822Name: 793 case certDNSName: 794 case certURI: 795 nssGenName->name.other = *secItem; 796 break; 797 798 case certDirectoryName: 799 800 PKIX_CHECK(PKIX_PL_X500Name_Create 801 (stringRep, &pkixDN, plContext), 802 PKIX_X500NAMECREATEFAILED); 803 804 PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_AsciiToName).\n"); 805 nssCertName = CERT_AsciiToName(asciiString); 806 nssGenName->name.directoryName = *nssCertName; 807 break; 808 809 case certRegisterID: 810 PKIX_CHECK(PKIX_PL_OID_Create 811 (asciiString, &pkixOID, plContext), 812 PKIX_OIDCREATEFAILED); 813 nssGenName->name.other = *secItem; 814 break; 815 default: 816 /* including IPAddress, EDIPartyName, OtherName, X400Address */ 817 PKIX_ERROR(PKIX_UNABLETOCREATEGENERALNAMEOFTHISTYPE); 818 } 819 820 /* create a PKIX_PL_GeneralName object */ 821 PKIX_CHECK(PKIX_PL_Object_Alloc 822 (PKIX_GENERALNAME_TYPE, 823 sizeof (PKIX_PL_GeneralName), 824 (PKIX_PL_Object **)&genName, 825 plContext), 826 PKIX_COULDNOTCREATEOBJECT); 827 828 /* create a CERTGeneralNameList */ 829 nssGenName->type = nameType; 830 PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_CreateGeneralNameList).\n"); 831 nssGenNameList = CERT_CreateGeneralNameList(nssGenName); 832 if (nssGenNameList == NULL) { 833 PKIX_ERROR(PKIX_CERTCREATEGENERALNAMELISTFAILED); 834 } 835 genName->nssGeneralNameList = nssGenNameList; 836 837 /* initialize fields */ 838 genName->type = nameType; 839 genName->directoryName = pkixDN; 840 genName->OthName = NULL; 841 genName->other = secItem; 842 genName->oid = pkixOID; 843 844 *pGName = genName; 845 cleanup: 846 847 PKIX_FREE(asciiString); 848 849 if (nssCertName != NULL) { 850 PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyName).\n"); 851 CERT_DestroyName(nssCertName); 852 } 853 854 if (arena){ /* will free nssGenName */ 855 PKIX_CERT_DEBUG("\t\tCalling PORT_FreeArena).\n"); 856 PORT_FreeArena(arena, PR_FALSE); 857 } 858 859 if (PKIX_ERROR_RECEIVED){ 860 PKIX_DECREF(pkixDN); 861 PKIX_DECREF(pkixOID); 862 863 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n"); 864 if (secItem){ 865 SECITEM_FreeItem(secItem, PR_TRUE); 866 secItem = NULL; 867 } 868 } 869 870 PKIX_RETURN(GENERALNAME); 871 } 872 873 #endif /* BUILD_LIBPKIX_TESTS */