pkix_pl_x500name.c (19535B)
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_x500name.c 6 * 7 * X500Name Object Functions 8 * 9 */ 10 11 #include "pkix_pl_x500name.h" 12 13 /* --Private-X500Name-Functions------------------------------------- */ 14 15 /* 16 * FUNCTION: pkix_pl_X500Name_Destroy 17 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) 18 */ 19 static PKIX_Error * 20 pkix_pl_X500Name_Destroy( 21 PKIX_PL_Object *object, 22 void *plContext) 23 { 24 PKIX_PL_X500Name *name = NULL; 25 26 PKIX_ENTER(X500NAME, "pkix_pl_X500Name_Destroy"); 27 PKIX_NULLCHECK_ONE(object); 28 29 PKIX_CHECK(pkix_CheckType(object, PKIX_X500NAME_TYPE, plContext), 30 PKIX_OBJECTNOTANX500NAME); 31 32 name = (PKIX_PL_X500Name *)object; 33 34 /* PORT_FreeArena will destroy arena, and, allocated on it, CERTName 35 * and SECItem */ 36 if (name->arena) { 37 PORT_FreeArena(name->arena, PR_FALSE); 38 name->arena = NULL; 39 } 40 41 cleanup: 42 43 PKIX_RETURN(X500NAME); 44 } 45 46 /* 47 * FUNCTION: pkix_pl_X500Name_ToString 48 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) 49 */ 50 static PKIX_Error * 51 pkix_pl_X500Name_ToString( 52 PKIX_PL_Object *object, 53 PKIX_PL_String **pString, 54 void *plContext) 55 { 56 PKIX_PL_X500Name *name = NULL; 57 char *string = NULL; 58 PKIX_UInt32 strLength = 0; 59 60 PKIX_ENTER(X500NAME, "pkix_pl_X500Name_toString"); 61 PKIX_NULLCHECK_TWO(object, pString); 62 63 PKIX_CHECK(pkix_CheckType(object, PKIX_X500NAME_TYPE, plContext), 64 PKIX_OBJECTNOTANX500NAME); 65 66 name = (PKIX_PL_X500Name *)object; 67 string = CERT_NameToAscii(&name->nssDN); 68 if (!string){ 69 PKIX_ERROR(PKIX_CERTNAMETOASCIIFAILED); 70 } 71 strLength = PL_strlen(string); 72 73 PKIX_CHECK(PKIX_PL_String_Create 74 (PKIX_ESCASCII, string, strLength, pString, plContext), 75 PKIX_STRINGCREATEFAILED); 76 77 cleanup: 78 79 PKIX_RETURN(X500NAME); 80 } 81 82 /* 83 * FUNCTION: pkix_pl_X500Name_Hashcode 84 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) 85 */ 86 static PKIX_Error * 87 pkix_pl_X500Name_Hashcode( 88 PKIX_PL_Object *object, 89 PKIX_UInt32 *pHashcode, 90 void *plContext) 91 { 92 PKIX_PL_X500Name *name = NULL; 93 SECItem *derBytes = NULL; 94 PKIX_UInt32 nameHash; 95 96 PKIX_ENTER(X500NAME, "pkix_pl_X500Name_Hashcode"); 97 PKIX_NULLCHECK_TWO(object, pHashcode); 98 99 PKIX_CHECK(pkix_CheckType(object, PKIX_X500NAME_TYPE, plContext), 100 PKIX_OBJECTNOTANX500NAME); 101 102 name = (PKIX_PL_X500Name *)object; 103 104 /* we hash over the bytes in the DER encoding */ 105 106 derBytes = &name->derName; 107 108 PKIX_CHECK(pkix_hash 109 (derBytes->data, derBytes->len, &nameHash, plContext), 110 PKIX_HASHFAILED); 111 112 *pHashcode = nameHash; 113 114 cleanup: 115 116 PKIX_RETURN(X500NAME); 117 } 118 119 120 /* 121 * FUNCTION: pkix_pl_X500Name_Equals 122 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) 123 */ 124 static PKIX_Error * 125 pkix_pl_X500Name_Equals( 126 PKIX_PL_Object *firstObject, 127 PKIX_PL_Object *secondObject, 128 PKIX_Boolean *pResult, 129 void *plContext) 130 { 131 PKIX_UInt32 secondType; 132 133 PKIX_ENTER(X500NAME, "pkix_pl_X500Name_Equals"); 134 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); 135 136 /* test that firstObject is an X500Name */ 137 PKIX_CHECK(pkix_CheckType(firstObject, PKIX_X500NAME_TYPE, plContext), 138 PKIX_FIRSTOBJECTARGUMENTNOTANX500NAME); 139 140 /* 141 * Since we know firstObject is an X500Name, if both references are 142 * identical, they must be equal 143 */ 144 if (firstObject == secondObject){ 145 *pResult = PKIX_TRUE; 146 goto cleanup; 147 } 148 149 /* 150 * If secondObject isn't an X500Name, we don't throw an error. 151 * We simply return a Boolean result of FALSE 152 */ 153 *pResult = PKIX_FALSE; 154 PKIX_CHECK(PKIX_PL_Object_GetType 155 (secondObject, &secondType, plContext), 156 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); 157 if (secondType != PKIX_X500NAME_TYPE) goto cleanup; 158 159 PKIX_CHECK( 160 PKIX_PL_X500Name_Match((PKIX_PL_X500Name *)firstObject, 161 (PKIX_PL_X500Name *)secondObject, 162 pResult, plContext), 163 PKIX_X500NAMEMATCHFAILED); 164 165 cleanup: 166 167 PKIX_RETURN(X500NAME); 168 } 169 170 /* 171 * FUNCTION: pkix_pl_X500Name_RegisterSelf 172 * DESCRIPTION: 173 * Registers PKIX_X500NAME_TYPE and its related functions with systemClasses[] 174 * THREAD SAFETY: 175 * Not Thread Safe - for performance and complexity reasons 176 * 177 * Since this function is only called by PKIX_PL_Initialize, which should 178 * only be called once, it is acceptable that this function is not 179 * thread-safe. 180 */ 181 PKIX_Error * 182 pkix_pl_X500Name_RegisterSelf(void *plContext) 183 { 184 185 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; 186 pkix_ClassTable_Entry entry; 187 188 PKIX_ENTER(X500NAME, "pkix_pl_X500Name_RegisterSelf"); 189 190 entry.description = "X500Name"; 191 entry.objCounter = 0; 192 entry.typeObjectSize = sizeof(PKIX_PL_X500Name); 193 entry.destructor = pkix_pl_X500Name_Destroy; 194 entry.equalsFunction = pkix_pl_X500Name_Equals; 195 entry.hashcodeFunction = pkix_pl_X500Name_Hashcode; 196 entry.toStringFunction = pkix_pl_X500Name_ToString; 197 entry.comparator = NULL; 198 entry.duplicateFunction = pkix_duplicateImmutable; 199 200 systemClasses[PKIX_X500NAME_TYPE] = entry; 201 202 PKIX_RETURN(X500NAME); 203 } 204 205 #ifdef BUILD_LIBPKIX_TESTS 206 /* 207 * FUNCTION: pkix_pl_X500Name_CreateFromUtf8 208 * 209 * DESCRIPTION: 210 * Creates an X500Name object from the RFC1485 string representation pointed 211 * to by "stringRep", and stores the result at "pName". If the string cannot 212 * be successfully converted, a non-fatal error is returned. 213 * 214 * NOTE: ifdefed BUILD_LIBPKIX_TESTS function: this function is allowed to be 215 * called only by pkix tests programs. 216 * 217 * PARAMETERS: 218 * "stringRep" 219 * Address of the RFC1485 string to be converted. Must be non-NULL. 220 * "pName" 221 * Address where the X500Name result will be stored. Must be non-NULL. 222 * "plContext" 223 * Platform-specific context pointer. 224 * 225 * THREAD SAFETY: 226 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 227 * 228 * RETURNS: 229 * Returns NULL if the function succeeds. 230 * Returns an X500NAME Error if the function fails in a non-fatal way. 231 * Returns a Fatal Error if the function fails in an unrecoverable way. 232 */ 233 PKIX_Error * 234 pkix_pl_X500Name_CreateFromUtf8( 235 char *stringRep, 236 PKIX_PL_X500Name **pName, 237 void *plContext) 238 { 239 PKIX_PL_X500Name *x500Name = NULL; 240 PLArenaPool *arena = NULL; 241 CERTName *nssDN = NULL; 242 SECItem *resultSecItem = NULL; 243 244 PKIX_ENTER(X500NAME, "pkix_pl_X500Name_CreateFromUtf8"); 245 PKIX_NULLCHECK_TWO(pName, stringRep); 246 247 nssDN = CERT_AsciiToName(stringRep); 248 if (nssDN == NULL) { 249 PKIX_ERROR(PKIX_COULDNOTCREATENSSDN); 250 } 251 252 arena = nssDN->arena; 253 254 /* create a PKIX_PL_X500Name object */ 255 PKIX_CHECK(PKIX_PL_Object_Alloc 256 (PKIX_X500NAME_TYPE, 257 sizeof (PKIX_PL_X500Name), 258 (PKIX_PL_Object **)&x500Name, 259 plContext), 260 PKIX_COULDNOTCREATEX500NAMEOBJECT); 261 262 /* populate the nssDN field */ 263 x500Name->arena = arena; 264 x500Name->nssDN.arena = arena; 265 x500Name->nssDN.rdns = nssDN->rdns; 266 267 resultSecItem = 268 SEC_ASN1EncodeItem(arena, &x500Name->derName, nssDN, 269 CERT_NameTemplate); 270 271 if (resultSecItem == NULL){ 272 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED); 273 } 274 275 *pName = x500Name; 276 277 cleanup: 278 279 if (PKIX_ERROR_RECEIVED){ 280 if (x500Name) { 281 PKIX_PL_Object_DecRef((PKIX_PL_Object*)x500Name, 282 plContext); 283 } else if (nssDN) { 284 CERT_DestroyName(nssDN); 285 } 286 } 287 288 PKIX_RETURN(X500NAME); 289 } 290 #endif /* BUILD_LIBPKIX_TESTS */ 291 292 /* 293 * FUNCTION: pkix_pl_X500Name_GetCERTName 294 * 295 * DESCRIPTION: 296 * 297 * Returns the pointer to CERTName member of X500Name structure. 298 * 299 * Returned pointed should not be freed.2 300 * 301 * PARAMETERS: 302 * "xname" 303 * Address of X500Name whose OrganizationName is to be extracted. Must be 304 * non-NULL. 305 * "pCERTName" 306 * Address where result will be stored. Must be non-NULL. 307 * "plContext" 308 * Platform-specific context pointer. 309 * 310 * THREAD SAFETY: 311 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 312 * 313 * RETURNS: 314 * Returns NULL if the function succeeds. 315 * Returns a Fatal Error if the function fails in an unrecoverable way. 316 */ 317 PKIX_Error * 318 pkix_pl_X500Name_GetCERTName( 319 PKIX_PL_X500Name *xname, 320 CERTName **pCERTName, 321 void *plContext) 322 { 323 PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetCERTName"); 324 PKIX_NULLCHECK_TWO(xname, pCERTName); 325 326 *pCERTName = &xname->nssDN; 327 328 PKIX_RETURN(X500NAME); 329 } 330 331 /* --Public-Functions------------------------------------------------------- */ 332 333 /* 334 * FUNCTION: PKIX_PL_X500Name_CreateFromCERTName (see comments in pkix_pl_pki.h) 335 */ 336 337 PKIX_Error * 338 PKIX_PL_X500Name_CreateFromCERTName( 339 SECItem *derName, 340 CERTName *name, 341 PKIX_PL_X500Name **pName, 342 void *plContext) 343 { 344 PLArenaPool *arena = NULL; 345 SECStatus rv = SECFailure; 346 PKIX_PL_X500Name *x500Name = NULL; 347 348 PKIX_ENTER(X500NAME, "PKIX_PL_X500Name_CreateFromCERTName"); 349 PKIX_NULLCHECK_ONE(pName); 350 if (derName == NULL && name == NULL) { 351 PKIX_ERROR(PKIX_NULLARGUMENT); 352 } 353 354 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 355 if (arena == NULL) { 356 PKIX_ERROR(PKIX_OUTOFMEMORY); 357 } 358 359 PKIX_CHECK(PKIX_PL_Object_Alloc 360 (PKIX_X500NAME_TYPE, 361 sizeof (PKIX_PL_X500Name), 362 (PKIX_PL_Object **)&x500Name, 363 plContext), 364 PKIX_COULDNOTCREATEX500NAMEOBJECT); 365 366 x500Name->arena = arena; 367 x500Name->nssDN.arena = NULL; 368 369 if (derName != NULL) { 370 rv = SECITEM_CopyItem(arena, &x500Name->derName, derName); 371 if (rv == SECFailure) { 372 PKIX_ERROR(PKIX_OUTOFMEMORY); 373 } 374 } 375 376 if (name != NULL) { 377 rv = CERT_CopyName(arena, &x500Name->nssDN, name); 378 if (rv == SECFailure) { 379 PKIX_ERROR(PKIX_CERTCOPYNAMEFAILED); 380 } 381 } else { 382 rv = SEC_QuickDERDecodeItem(arena, &x500Name->nssDN, 383 CERT_NameTemplate, 384 &x500Name->derName); 385 if (rv == SECFailure) { 386 PKIX_ERROR(PKIX_SECQUICKDERDECODERFAILED); 387 } 388 } 389 390 *pName = x500Name; 391 392 cleanup: 393 if (PKIX_ERROR_RECEIVED) { 394 if (x500Name) { 395 PKIX_PL_Object_DecRef((PKIX_PL_Object*)x500Name, 396 plContext); 397 } else if (arena) { 398 PORT_FreeArena(arena, PR_FALSE); 399 } 400 } 401 402 PKIX_RETURN(X500NAME); 403 } 404 405 #ifdef BUILD_LIBPKIX_TESTS 406 /* 407 * FUNCTION: PKIX_PL_X500Name_Create (see comments in pkix_pl_pki.h) 408 * 409 * NOTE: ifdefed BUILD_LIBPKIX_TESTS function: this function is allowed 410 * to be called only by pkix tests programs. 411 */ 412 PKIX_Error * 413 PKIX_PL_X500Name_Create( 414 PKIX_PL_String *stringRep, 415 PKIX_PL_X500Name **pName, 416 void *plContext) 417 { 418 char *utf8String = NULL; 419 PKIX_UInt32 utf8Length = 0; 420 421 PKIX_ENTER(X500NAME, "PKIX_PL_X500Name_Create"); 422 PKIX_NULLCHECK_TWO(pName, stringRep); 423 424 /* 425 * convert the input PKIX_PL_String to PKIX_UTF8_NULL_TERM. 426 * we need to use this format specifier because 427 * CERT_AsciiToName expects a NULL-terminated UTF8 string. 428 * Since UTF8 allow NUL characters in the middle of the 429 * string, this is buggy. However, as a workaround, using 430 * PKIX_UTF8_NULL_TERM gives us a NULL-terminated UTF8 string. 431 */ 432 433 PKIX_CHECK(PKIX_PL_String_GetEncoded 434 (stringRep, 435 PKIX_UTF8_NULL_TERM, 436 (void **)&utf8String, 437 &utf8Length, 438 plContext), 439 PKIX_STRINGGETENCODEDFAILED); 440 441 PKIX_CHECK( 442 pkix_pl_X500Name_CreateFromUtf8(utf8String, 443 pName, plContext), 444 PKIX_X500NAMECREATEFROMUTF8FAILED); 445 446 cleanup: 447 PKIX_FREE(utf8String); 448 449 PKIX_RETURN(X500NAME); 450 } 451 #endif /* BUILD_LIBPKIX_TESTS */ 452 453 /* 454 * FUNCTION: PKIX_PL_X500Name_Match (see comments in pkix_pl_pki.h) 455 */ 456 PKIX_Error * 457 PKIX_PL_X500Name_Match( 458 PKIX_PL_X500Name *firstX500Name, 459 PKIX_PL_X500Name *secondX500Name, 460 PKIX_Boolean *pResult, 461 void *plContext) 462 { 463 SECItem *firstDerName = NULL; 464 SECItem *secondDerName = NULL; 465 SECComparison cmpResult; 466 467 PKIX_ENTER(X500NAME, "PKIX_PL_X500Name_Match"); 468 PKIX_NULLCHECK_THREE(firstX500Name, secondX500Name, pResult); 469 470 if (firstX500Name == secondX500Name){ 471 *pResult = PKIX_TRUE; 472 goto cleanup; 473 } 474 475 firstDerName = &firstX500Name->derName; 476 secondDerName = &secondX500Name->derName; 477 478 PKIX_NULLCHECK_TWO(firstDerName->data, secondDerName->data); 479 480 cmpResult = SECITEM_CompareItem(firstDerName, secondDerName); 481 if (cmpResult != SECEqual) { 482 cmpResult = CERT_CompareName(&firstX500Name->nssDN, 483 &secondX500Name->nssDN); 484 } 485 486 *pResult = (cmpResult == SECEqual); 487 488 cleanup: 489 490 PKIX_RETURN(X500NAME); 491 } 492 493 /* 494 * FUNCTION: pkix_pl_X500Name_GetSECName 495 * 496 * DESCRIPTION: 497 * Returns a copy of CERTName DER representation allocated on passed in arena. 498 * If allocation on arena can not be done, NULL is stored at "pSECName". 499 * 500 * PARAMETERS: 501 * "xname" 502 * Address of X500Name whose CERTName flag is to be encoded. Must be 503 * non-NULL. 504 * "arena" 505 * Address of the PLArenaPool to be used in the encoding, and in which 506 * "pSECName" will be allocated. Must be non-NULL. 507 * "pSECName" 508 * Address where result will be stored. Must be non-NULL. 509 * "plContext" 510 * Platform-specific context pointer. 511 * 512 * THREAD SAFETY: 513 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 514 * 515 * RETURNS: 516 * Returns NULL if the function succeeds. 517 * Returns a Fatal Error if the function fails in an unrecoverable way. 518 */ 519 PKIX_Error * 520 pkix_pl_X500Name_GetDERName( 521 PKIX_PL_X500Name *xname, 522 PLArenaPool *arena, 523 SECItem **pDERName, 524 void *plContext) 525 { 526 SECItem *derName = NULL; 527 528 PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetDERName"); 529 530 PKIX_NULLCHECK_THREE(xname, arena, pDERName); 531 532 /* Return NULL is X500Name was not created from DER */ 533 if (xname->derName.data == NULL) { 534 *pDERName = NULL; 535 goto cleanup; 536 } 537 538 derName = SECITEM_ArenaDupItem(arena, &xname->derName); 539 if (derName == NULL) { 540 PKIX_ERROR(PKIX_OUTOFMEMORY); 541 } 542 543 *pDERName = derName; 544 cleanup: 545 546 PKIX_RETURN(X500NAME); 547 } 548 549 /* 550 * FUNCTION: pkix_pl_X500Name_GetCommonName 551 * 552 * DESCRIPTION: 553 * Extracts the CommonName component of the X500Name object pointed to by 554 * "xname", and stores the result at "pCommonName". If the CommonName cannot 555 * be successfully extracted, NULL is stored at "pCommonName". 556 * 557 * The returned string must be freed with PORT_Free. 558 * 559 * PARAMETERS: 560 * "xname" 561 * Address of X500Name whose CommonName is to be extracted. Must be 562 * non-NULL. 563 * "pCommonName" 564 * Address where result will be stored. Must be non-NULL. 565 * "plContext" 566 * Platform-specific context pointer. 567 * 568 * THREAD SAFETY: 569 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 570 * 571 * RETURNS: 572 * Returns NULL if the function succeeds. 573 * Returns a Fatal Error if the function fails in an unrecoverable way. 574 */ 575 PKIX_Error * 576 pkix_pl_X500Name_GetCommonName( 577 PKIX_PL_X500Name *xname, 578 unsigned char **pCommonName, 579 void *plContext) 580 { 581 PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetCommonName"); 582 PKIX_NULLCHECK_TWO(xname, pCommonName); 583 584 *pCommonName = (unsigned char *)CERT_GetCommonName(&xname->nssDN); 585 586 PKIX_RETURN(X500NAME); 587 } 588 589 /* 590 * FUNCTION: pkix_pl_X500Name_GetCountryName 591 * 592 * DESCRIPTION: 593 * Extracts the CountryName component of the X500Name object pointed to by 594 * "xname", and stores the result at "pCountryName". If the CountryName cannot 595 * be successfully extracted, NULL is stored at "pCountryName". 596 * 597 * The returned string must be freed with PORT_Free. 598 * 599 * PARAMETERS: 600 * "xname" 601 * Address of X500Name whose CountryName is to be extracted. Must be 602 * non-NULL. 603 * "pCountryName" 604 * Address where result will be stored. Must be non-NULL. 605 * "plContext" 606 * Platform-specific context pointer. 607 * 608 * THREAD SAFETY: 609 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 610 * 611 * RETURNS: 612 * Returns NULL if the function succeeds. 613 * Returns a Fatal Error if the function fails in an unrecoverable way. 614 */ 615 PKIX_Error * 616 pkix_pl_X500Name_GetCountryName( 617 PKIX_PL_X500Name *xname, 618 unsigned char **pCountryName, 619 void *plContext) 620 { 621 PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetCountryName"); 622 PKIX_NULLCHECK_TWO(xname, pCountryName); 623 624 *pCountryName = (unsigned char*)CERT_GetCountryName(&xname->nssDN); 625 626 PKIX_RETURN(X500NAME); 627 } 628 629 /* 630 * FUNCTION: pkix_pl_X500Name_GetOrgName 631 * 632 * DESCRIPTION: 633 * Extracts the OrganizationName component of the X500Name object pointed to by 634 * "xname", and stores the result at "pOrgName". If the OrganizationName cannot 635 * be successfully extracted, NULL is stored at "pOrgName". 636 * 637 * The returned string must be freed with PORT_Free. 638 * 639 * PARAMETERS: 640 * "xname" 641 * Address of X500Name whose OrganizationName is to be extracted. Must be 642 * non-NULL. 643 * "pOrgName" 644 * Address where result will be stored. Must be non-NULL. 645 * "plContext" 646 * Platform-specific context pointer. 647 * 648 * THREAD SAFETY: 649 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 650 * 651 * RETURNS: 652 * Returns NULL if the function succeeds. 653 * Returns a Fatal Error if the function fails in an unrecoverable way. 654 */ 655 PKIX_Error * 656 pkix_pl_X500Name_GetOrgName( 657 PKIX_PL_X500Name *xname, 658 unsigned char **pOrgName, 659 void *plContext) 660 { 661 PKIX_ENTER(X500NAME, "pkix_pl_X500Name_GetOrgName"); 662 PKIX_NULLCHECK_TWO(xname, pOrgName); 663 664 *pOrgName = (unsigned char*)CERT_GetOrgName(&xname->nssDN); 665 666 PKIX_RETURN(X500NAME); 667 }