nss: import at 3.0.1 beta 1
[mozilla-nss.git] / security / nss / lib / libpkix / pkix_pl_nss / pki / pkix_pl_generalname.c
blob859c0df12d073dfb77cbe28c6c351ff20c5354f1
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the PKIX-C library.
16 * The Initial Developer of the Original Code is
17 * Sun Microsystems, Inc.
18 * Portions created by the Initial Developer are
19 * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
21 * Contributor(s):
22 * Sun Microsystems, Inc.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 * pkix_pl_generalname.c
40 * GeneralName Object Definitions
44 #include "pkix_pl_generalname.h"
46 /* --Private-GeneralName-Functions------------------------------------- */
49 * FUNCTION: pkix_pl_GeneralName_GetNssGeneralName
50 * DESCRIPTION:
52 * Retrieves the NSS representation of the PKIX_PL_GeneralName pointed by
53 * "genName" and stores it at "pNssGenName". The NSS data type CERTGeneralName
54 * is stored in this object when the object was created.
56 * PARAMETERS:
57 * "genName"
58 * Address of PKIX_PL_GeneralName. Must be non-NULL.
59 * "pNssGenName"
60 * Address where CERTGeneralName will be stored. Must be non-NULL.
61 * "plContext" - Platform-specific context pointer.
62 * THREAD SAFETY:
63 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
64 * RETURNS:
65 * Returns NULL if the function succeeds.
66 * Returns a GeneralName Error if the function fails in a non-fatal way.
67 * Returns a Fatal Error if the function fails in an unrecoverable way.
69 PKIX_Error *
70 pkix_pl_GeneralName_GetNssGeneralName(
71 PKIX_PL_GeneralName *genName,
72 CERTGeneralName **pNssGenName,
73 void *plContext)
75 CERTGeneralName *nssGenName = NULL;
77 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_GetNssGeneralName");
78 PKIX_NULLCHECK_THREE(genName, pNssGenName, genName->nssGeneralNameList);
80 nssGenName = genName->nssGeneralNameList->name;
82 *pNssGenName = nssGenName;
84 PKIX_RETURN(GENERALNAME);
88 * FUNCTION: pkix_pl_OtherName_Create
89 * DESCRIPTION:
91 * Creates new OtherName which represents the CERTGeneralName pointed to by
92 * "nssAltName" and stores it at "pOtherName".
94 * PARAMETERS:
95 * "nssAltName"
96 * Address of CERTGeneralName. Must be non-NULL.
97 * "pOtherName"
98 * Address where object pointer will be stored. Must be non-NULL.
99 * "plContext" - Platform-specific context pointer.
100 * THREAD SAFETY:
101 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
102 * RETURNS:
103 * Returns NULL if the function succeeds.
104 * Returns a GeneralName Error if the function fails in a non-fatal way.
105 * Returns a Fatal Error if the function fails in an unrecoverable way.
107 static PKIX_Error *
108 pkix_pl_OtherName_Create(
109 CERTGeneralName *nssAltName,
110 OtherName **pOtherName,
111 void *plContext)
113 OtherName *otherName = NULL;
114 SECItem secItemName;
115 SECItem secItemOID;
116 SECStatus rv;
118 PKIX_ENTER(GENERALNAME, "pkix_pl_OtherName_Create");
119 PKIX_NULLCHECK_TWO(nssAltName, pOtherName);
121 PKIX_CHECK(PKIX_PL_Malloc
122 (sizeof (OtherName), (void **)&otherName, plContext),
123 PKIX_MALLOCFAILED);
125 /* make a copy of the name field */
126 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CopyItem).\n");
127 rv = SECITEM_CopyItem
128 (NULL, &otherName->name, &nssAltName->name.OthName.name);
129 if (rv != SECSuccess) {
130 PKIX_ERROR(PKIX_OUTOFMEMORY);
133 /* make a copy of the oid field */
134 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CopyItem).\n");
135 rv = SECITEM_CopyItem
136 (NULL, &otherName->oid, &nssAltName->name.OthName.oid);
137 if (rv != SECSuccess) {
138 PKIX_ERROR(PKIX_OUTOFMEMORY);
141 *pOtherName = otherName;
143 cleanup:
145 if (otherName && PKIX_ERROR_RECEIVED){
146 secItemName = otherName->name;
147 secItemOID = otherName->oid;
149 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
150 SECITEM_FreeItem(&secItemName, PR_FALSE);
152 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
153 SECITEM_FreeItem(&secItemOID, PR_FALSE);
155 PKIX_FREE(otherName);
156 otherName = NULL;
159 PKIX_RETURN(GENERALNAME);
163 * FUNCTION: pkix_pl_DirectoryName_Create
164 * DESCRIPTION:
166 * Creates a new X500Name which represents the directoryName component of the
167 * CERTGeneralName pointed to by "nssAltName" and stores it at "pX500Name".
169 * PARAMETERS:
170 * "nssAltName"
171 * Address of CERTGeneralName. Must be non-NULL.
172 * "pX500Name"
173 * Address where object pointer will be stored. Must be non-NULL.
174 * "plContext" - Platform-specific context pointer.
175 * THREAD SAFETY:
176 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
177 * RETURNS:
178 * Returns NULL if the function succeeds.
179 * Returns a GeneralName Error if the function fails in a non-fatal way.
180 * Returns a Fatal Error if the function fails in an unrecoverable way.
182 static PKIX_Error *
183 pkix_pl_DirectoryName_Create(
184 CERTGeneralName *nssAltName,
185 PKIX_PL_X500Name **pX500Name,
186 void *plContext)
188 PKIX_PL_X500Name *pkixDN = NULL;
189 CERTName *dirName = NULL;
190 PKIX_PL_String *pkixDNString = NULL;
191 char *utf8String = NULL;
192 PKIX_UInt32 utf8Length;
194 PKIX_ENTER(GENERALNAME, "pkix_pl_DirectoryName_Create");
195 PKIX_NULLCHECK_TWO(nssAltName, pX500Name);
197 dirName = &nssAltName->name.directoryName;
199 PKIX_CHECK(PKIX_PL_X500Name_CreateFromCERTName(NULL, dirName,
200 &pkixDN, plContext),
201 PKIX_X500NAMECREATEFROMCERTNAMEFAILED);
203 *pX500Name = pkixDN;
205 cleanup:
207 PR_Free(utf8String);
208 PKIX_DECREF(pkixDNString);
210 PKIX_RETURN(GENERALNAME);
214 * FUNCTION: pkix_pl_GeneralName_Create
215 * DESCRIPTION:
217 * Creates new GeneralName which represents the CERTGeneralName pointed to by
218 * "nssAltName" and stores it at "pGenName".
220 * PARAMETERS:
221 * "nssAltName"
222 * Address of CERTGeneralName. Must be non-NULL.
223 * "pGenName"
224 * Address where object pointer will be stored. Must be non-NULL.
225 * "plContext" - Platform-specific context pointer.
226 * THREAD SAFETY:
227 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
228 * RETURNS:
229 * Returns NULL if the function succeeds.
230 * Returns a GeneralName Error if the function fails in a non-fatal way.
231 * Returns a Fatal Error if the function fails in an unrecoverable way.
233 PKIX_Error *
234 pkix_pl_GeneralName_Create(
235 CERTGeneralName *nssAltName,
236 PKIX_PL_GeneralName **pGenName,
237 void *plContext)
239 PKIX_PL_GeneralName *genName = NULL;
240 PKIX_PL_X500Name *pkixDN = NULL;
241 PKIX_PL_OID *pkixOID = NULL;
242 OtherName *otherName = NULL;
243 CERTGeneralNameList *nssGenNameList = NULL;
244 CERTGeneralNameType nameType;
245 SECItem *secItem = NULL;
246 char *asciiName = NULL;
247 SECStatus rv;
249 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Create");
250 PKIX_NULLCHECK_TWO(nssAltName, pGenName);
252 /* create a PKIX_PL_GeneralName object */
253 PKIX_CHECK(PKIX_PL_Object_Alloc
254 (PKIX_GENERALNAME_TYPE,
255 sizeof (PKIX_PL_GeneralName),
256 (PKIX_PL_Object **)&genName,
257 plContext),
258 PKIX_COULDNOTCREATEOBJECT);
260 nameType = nssAltName->type;
263 * We use CERT_CreateGeneralNameList to create just one CERTGeneralName
264 * item for memory allocation reason. If we want to just create one
265 * item, we have to use the calling path CERT_NewGeneralName, then
266 * CERT_CopyOneGeneralName. With this calling path, if we pass
267 * the arena argument as NULL, in CERT_CopyOneGeneralName's subsequent
268 * call to CERT_CopyName, it assumes arena should be valid, hence
269 * segmentation error (not sure this is a NSS bug, certainly it is
270 * not consistent). But on the other hand, we don't want to keep an
271 * arena record here explicitely for every PKIX_PL_GeneralName.
272 * So I concluded it is better to use CERT_CreateGeneralNameList,
273 * which keeps an arena pointer in its data structure and also masks
274 * out details calls from this libpkix level.
277 PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_CreateGeneralNameList).\n");
278 nssGenNameList = CERT_CreateGeneralNameList(nssAltName);
280 if (nssGenNameList == NULL) {
281 PKIX_ERROR(PKIX_CERTCREATEGENERALNAMELISTFAILED);
284 genName->nssGeneralNameList = nssGenNameList;
286 /* initialize fields */
287 genName->type = nameType;
288 genName->directoryName = NULL;
289 genName->OthName = NULL;
290 genName->other = NULL;
291 genName->oid = NULL;
293 switch (nameType){
294 case certOtherName:
296 PKIX_CHECK(pkix_pl_OtherName_Create
297 (nssAltName, &otherName, plContext),
298 PKIX_OTHERNAMECREATEFAILED);
300 genName->OthName = otherName;
301 break;
303 case certDirectoryName:
305 PKIX_CHECK(pkix_pl_DirectoryName_Create
306 (nssAltName, &pkixDN, plContext),
307 PKIX_DIRECTORYNAMECREATEFAILED);
309 genName->directoryName = pkixDN;
310 break;
311 case certRegisterID:
313 PKIX_CHECK(pkix_pl_oidBytes2Ascii
314 (&nssAltName->name.other, &asciiName, plContext),
315 PKIX_OIDBYTES2ASCIIFAILED);
317 PKIX_CHECK(PKIX_PL_OID_Create(asciiName, &pkixOID, plContext),
318 PKIX_OIDCREATEFAILED);
320 genName->oid = pkixOID;
321 break;
322 case certDNSName:
323 case certEDIPartyName:
324 case certIPAddress:
325 case certRFC822Name:
326 case certX400Address:
327 case certURI:
329 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_AllocItem).\n");
330 secItem = SECITEM_AllocItem(NULL, NULL, 0);
331 if (secItem == NULL){
332 PKIX_ERROR(PKIX_OUTOFMEMORY);
335 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CopyItem).\n");
336 rv = SECITEM_CopyItem(NULL, secItem, &nssAltName->name.other);
337 if (rv != SECSuccess) {
338 PKIX_ERROR(PKIX_OUTOFMEMORY);
341 genName->other = secItem;
342 break;
343 default:
344 PKIX_ERROR(PKIX_NAMETYPENOTSUPPORTED);
347 *pGenName = genName;
348 cleanup:
350 PKIX_FREE(asciiName);
352 if (PKIX_ERROR_RECEIVED){
353 PKIX_DECREF(genName);
354 if (secItem){
355 PKIX_GENERALNAME_DEBUG
356 ("\t\tCalling SECITEM_FreeItem).\n");
357 SECITEM_FreeItem(secItem, PR_TRUE);
358 secItem = NULL;
362 PKIX_RETURN(GENERALNAME);
366 * FUNCTION: pkix_pl_GeneralName_ToString_Helper
367 * DESCRIPTION:
369 * Helper function that creates a string representation of the GeneralName
370 * pointed to by "name" and stores it at "pString" Different mechanisms are
371 * used to create the string, depending on the type of the GeneralName.
373 * PARAMETERS
374 * "name"
375 * Address of GeneralName whose string representation is desired.
376 * Must be non-NULL.
377 * "pString"
378 * Address where object pointer will be stored. Must be non-NULL.
379 * "plContext" - Platform-specific context pointer.
380 * THREAD SAFETY:
381 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
382 * RETURNS:
383 * Returns NULL if the function succeeds.
384 * Returns a GeneralName Error if the function fails in a non-fatal way.
385 * Returns a Fatal Error if the function fails in an unrecoverable way.
387 static PKIX_Error *
388 pkix_pl_GeneralName_ToString_Helper(
389 PKIX_PL_GeneralName *name,
390 PKIX_PL_String **pString,
391 void *plContext)
393 PKIX_PL_X500Name *pkixDN = NULL;
394 PKIX_PL_OID *pkixOID = NULL;
395 char *x400AsciiName = NULL;
396 char *ediPartyName = NULL;
397 char *asciiName = NULL;
399 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_ToString_Helper");
400 PKIX_NULLCHECK_TWO(name, pString);
402 switch (name->type) {
403 case certRFC822Name:
404 case certDNSName:
405 case certURI:
407 * Note that we can't use PKIX_ESCASCII here because
408 * name->other->data is not guaranteed to be null-terminated.
411 PKIX_NULLCHECK_ONE(name->other);
413 PKIX_CHECK(PKIX_PL_String_Create(PKIX_UTF8,
414 (name->other)->data,
415 (name->other)->len,
416 pString,
417 plContext),
418 PKIX_STRINGCREATEFAILED);
419 break;
420 case certEDIPartyName:
421 /* XXX print out the actual bytes */
422 ediPartyName = "EDIPartyName: <DER-encoded value>";
423 PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII,
424 ediPartyName,
426 pString,
427 plContext),
428 PKIX_STRINGCREATEFAILED);
429 break;
430 case certX400Address:
431 /* XXX print out the actual bytes */
432 x400AsciiName = "X400Address: <DER-encoded value>";
433 PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII,
434 x400AsciiName,
436 pString,
437 plContext),
438 PKIX_STRINGCREATEFAILED);
439 break;
440 case certIPAddress:
441 PKIX_CHECK(pkix_pl_ipAddrBytes2Ascii
442 (name->other, &asciiName, plContext),
443 PKIX_IPADDRBYTES2ASCIIFAILED);
445 PKIX_CHECK(PKIX_PL_String_Create(PKIX_ESCASCII,
446 asciiName,
448 pString,
449 plContext),
450 PKIX_STRINGCREATEFAILED);
451 break;
452 case certOtherName:
453 PKIX_NULLCHECK_ONE(name->OthName);
455 /* we only print type-id - don't know how to print value */
456 /* XXX print out the bytes of the value */
457 PKIX_CHECK(pkix_pl_oidBytes2Ascii
458 (&name->OthName->oid, &asciiName, plContext),
459 PKIX_OIDBYTES2ASCIIFAILED);
461 PKIX_CHECK(PKIX_PL_String_Create
462 (PKIX_ESCASCII,
463 asciiName,
465 pString,
466 plContext),
467 PKIX_STRINGCREATEFAILED);
468 break;
469 case certRegisterID:
470 pkixOID = name->oid;
471 PKIX_CHECK(PKIX_PL_Object_ToString
472 ((PKIX_PL_Object *)pkixOID, pString, plContext),
473 PKIX_OIDTOSTRINGFAILED);
474 break;
475 case certDirectoryName:
476 pkixDN = name->directoryName;
477 PKIX_CHECK(PKIX_PL_Object_ToString
478 ((PKIX_PL_Object *)pkixDN, pString, plContext),
479 PKIX_X500NAMETOSTRINGFAILED);
480 break;
481 default:
482 PKIX_ERROR
483 (PKIX_TOSTRINGFORTHISGENERALNAMETYPENOTSUPPORTED);
486 cleanup:
488 PKIX_FREE(asciiName);
490 PKIX_RETURN(GENERALNAME);
494 * FUNCTION: pkix_pl_GeneralName_Destroy
495 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
497 static PKIX_Error *
498 pkix_pl_GeneralName_Destroy(
499 PKIX_PL_Object *object,
500 void *plContext)
502 PKIX_PL_GeneralName *name = NULL;
503 SECItem secItemName;
504 SECItem secItemOID;
506 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Destroy");
507 PKIX_NULLCHECK_ONE(object);
509 PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext),
510 PKIX_OBJECTNOTGENERALNAME);
512 name = (PKIX_PL_GeneralName *)object;
514 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
515 SECITEM_FreeItem(name->other, PR_TRUE);
516 name->other = NULL;
518 if (name->OthName){
519 secItemName = name->OthName->name;
520 secItemOID = name->OthName->oid;
522 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
523 SECITEM_FreeItem(&secItemName, PR_FALSE);
525 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
526 SECITEM_FreeItem(&secItemOID, PR_FALSE);
528 PKIX_FREE(name->OthName);
529 name->OthName = NULL;
532 if (name->nssGeneralNameList != NULL) {
533 PKIX_GENERALNAME_DEBUG
534 ("\t\tCalling CERT_DestroyGeneralNameList).\n");
535 CERT_DestroyGeneralNameList(name->nssGeneralNameList);
538 PKIX_DECREF(name->directoryName);
539 PKIX_DECREF(name->oid);
541 cleanup:
543 PKIX_RETURN(GENERALNAME);
547 * FUNCTION: pkix_pl_GeneralName_ToString
548 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
550 static PKIX_Error *
551 pkix_pl_GeneralName_ToString(
552 PKIX_PL_Object *object,
553 PKIX_PL_String **pString,
554 void *plContext)
556 PKIX_PL_String *nameString = NULL;
557 PKIX_PL_GeneralName *name = NULL;
559 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_toString");
560 PKIX_NULLCHECK_TWO(object, pString);
562 PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext),
563 PKIX_OBJECTNOTGENERALNAME);
565 name = (PKIX_PL_GeneralName *)object;
567 PKIX_CHECK(pkix_pl_GeneralName_ToString_Helper
568 (name, &nameString, plContext),
569 PKIX_GENERALNAMETOSTRINGHELPERFAILED);
571 *pString = nameString;
573 cleanup:
577 PKIX_RETURN(GENERALNAME);
581 * FUNCTION: pkix_pl_GeneralName_Hashcode
582 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
584 static PKIX_Error *
585 pkix_pl_GeneralName_Hashcode(
586 PKIX_PL_Object *object,
587 PKIX_UInt32 *pHashcode,
588 void *plContext)
590 PKIX_PL_GeneralName *name = NULL;
591 PKIX_UInt32 firstHash, secondHash, nameHash;
593 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Hashcode");
594 PKIX_NULLCHECK_TWO(object, pHashcode);
596 PKIX_CHECK(pkix_CheckType(object, PKIX_GENERALNAME_TYPE, plContext),
597 PKIX_OBJECTNOTGENERALNAME);
599 name = (PKIX_PL_GeneralName *)object;
601 switch (name->type) {
602 case certRFC822Name:
603 case certDNSName:
604 case certX400Address:
605 case certEDIPartyName:
606 case certURI:
607 case certIPAddress:
608 PKIX_NULLCHECK_ONE(name->other);
609 PKIX_CHECK(pkix_hash
610 ((const unsigned char *)
611 name->other->data,
612 name->other->len,
613 &nameHash,
614 plContext),
615 PKIX_HASHFAILED);
616 break;
617 case certRegisterID:
618 PKIX_CHECK(PKIX_PL_Object_Hashcode
619 ((PKIX_PL_Object *)name->oid,
620 &nameHash,
621 plContext),
622 PKIX_OIDHASHCODEFAILED);
623 break;
624 case certOtherName:
625 PKIX_NULLCHECK_ONE(name->OthName);
626 PKIX_CHECK(pkix_hash
627 ((const unsigned char *)
628 name->OthName->oid.data,
629 name->OthName->oid.len,
630 &firstHash,
631 plContext),
632 PKIX_HASHFAILED);
634 PKIX_CHECK(pkix_hash
635 ((const unsigned char *)
636 name->OthName->name.data,
637 name->OthName->name.len,
638 &secondHash,
639 plContext),
640 PKIX_HASHFAILED);
642 nameHash = firstHash + secondHash;
643 break;
644 case certDirectoryName:
645 PKIX_CHECK(PKIX_PL_Object_Hashcode
646 ((PKIX_PL_Object *)
647 name->directoryName,
648 &nameHash,
649 plContext),
650 PKIX_X500NAMEHASHCODEFAILED);
651 break;
654 *pHashcode = nameHash;
656 cleanup:
658 PKIX_RETURN(GENERALNAME);
663 * FUNCTION: pkix_pl_GeneralName_Equals
664 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
666 static PKIX_Error *
667 pkix_pl_GeneralName_Equals(
668 PKIX_PL_Object *firstObject,
669 PKIX_PL_Object *secondObject,
670 PKIX_Boolean *pResult,
671 void *plContext)
673 PKIX_PL_GeneralName *firstName = NULL;
674 PKIX_PL_GeneralName *secondName = NULL;
675 PKIX_UInt32 secondType;
677 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Equals");
678 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
680 /* test that firstObject is a GeneralName */
681 PKIX_CHECK(pkix_CheckType
682 (firstObject, PKIX_GENERALNAME_TYPE, plContext),
683 PKIX_FIRSTOBJECTNOTGENERALNAME);
686 * Since we know firstObject is a GeneralName, if both references are
687 * identical, they must be equal
689 if (firstObject == secondObject){
690 *pResult = PKIX_TRUE;
691 goto cleanup;
695 * If secondObject isn't a GeneralName, we don't throw an error.
696 * We simply return a Boolean result of FALSE
698 *pResult = PKIX_FALSE;
699 PKIX_CHECK(PKIX_PL_Object_GetType
700 (secondObject, &secondType, plContext),
701 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
702 if (secondType != PKIX_GENERALNAME_TYPE){
703 goto cleanup;
706 firstName = (PKIX_PL_GeneralName *)firstObject;
707 secondName = (PKIX_PL_GeneralName *)secondObject;
709 if (firstName->type != secondName->type){
710 goto cleanup;
713 switch (firstName->type) {
714 case certRFC822Name:
715 case certDNSName:
716 case certX400Address:
717 case certEDIPartyName:
718 case certURI:
719 case certIPAddress:
720 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CompareItem).\n");
721 if (SECITEM_CompareItem(firstName->other,
722 secondName->other) != SECEqual) {
723 goto cleanup;
725 break;
726 case certRegisterID:
727 PKIX_CHECK(PKIX_PL_Object_Equals
728 ((PKIX_PL_Object *)firstName->oid,
729 (PKIX_PL_Object *)secondName->oid,
730 pResult,
731 plContext),
732 PKIX_OIDEQUALSFAILED);
733 goto cleanup;
734 case certOtherName:
735 PKIX_NULLCHECK_TWO(firstName->OthName, secondName->OthName);
736 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CompareItem).\n");
737 if (SECITEM_CompareItem(&firstName->OthName->oid,
738 &secondName->OthName->oid)
739 != SECEqual ||
740 SECITEM_CompareItem(&firstName->OthName->name,
741 &secondName->OthName->name)
742 != SECEqual) {
743 goto cleanup;
745 break;
746 case certDirectoryName:
747 PKIX_CHECK(PKIX_PL_Object_Equals
748 ((PKIX_PL_Object *)firstName->directoryName,
749 (PKIX_PL_Object *)secondName->directoryName,
750 pResult,
751 plContext),
752 PKIX_X500NAMEEQUALSFAILED);
753 goto cleanup;
756 *pResult = PKIX_TRUE;
758 cleanup:
760 PKIX_RETURN(GENERALNAME);
764 * FUNCTION: pkix_pl_GeneralName_RegisterSelf
765 * DESCRIPTION:
766 * Registers PKIX_GENERALNAME_TYPE and related functions with systemClasses[]
767 * THREAD SAFETY:
768 * Not Thread Safe - for performance and complexity reasons
770 * Since this function is only called by PKIX_PL_Initialize, which should
771 * only be called once, it is acceptable that this function is not
772 * thread-safe.
774 PKIX_Error *
775 pkix_pl_GeneralName_RegisterSelf(void *plContext)
778 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
779 pkix_ClassTable_Entry entry;
781 PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_RegisterSelf");
783 entry.description = "GeneralName";
784 entry.objCounter = 0;
785 entry.typeObjectSize = sizeof(PKIX_PL_GeneralName);
786 entry.destructor = pkix_pl_GeneralName_Destroy;
787 entry.equalsFunction = pkix_pl_GeneralName_Equals;
788 entry.hashcodeFunction = pkix_pl_GeneralName_Hashcode;
789 entry.toStringFunction = pkix_pl_GeneralName_ToString;
790 entry.comparator = NULL;
791 entry.duplicateFunction = pkix_duplicateImmutable;
793 systemClasses[PKIX_GENERALNAME_TYPE] = entry;
795 PKIX_RETURN(GENERALNAME);
798 /* --Public-Functions------------------------------------------------------- */
800 #ifdef BUILD_LIBPKIX_TESTS
802 * FUNCTION: PKIX_PL_GeneralName_Create (see comments in pkix_pl_pki.h)
804 PKIX_Error *
805 PKIX_PL_GeneralName_Create(
806 PKIX_UInt32 nameType,
807 PKIX_PL_String *stringRep,
808 PKIX_PL_GeneralName **pGName,
809 void *plContext)
811 PKIX_PL_X500Name *pkixDN = NULL;
812 PKIX_PL_OID *pkixOID = NULL;
813 SECItem *secItem = NULL;
814 char *asciiString = NULL;
815 PKIX_UInt32 length = 0;
816 PKIX_PL_GeneralName *genName = NULL;
817 CERTGeneralName *nssGenName = NULL;
818 CERTGeneralNameList *nssGenNameList = NULL;
819 CERTName *nssCertName = NULL;
820 PLArenaPool *arena = NULL;
822 PKIX_ENTER(GENERALNAME, "PKIX_PL_GeneralName_Create");
823 PKIX_NULLCHECK_TWO(pGName, stringRep);
825 PKIX_CHECK(PKIX_PL_String_GetEncoded
826 (stringRep,
827 PKIX_ESCASCII,
828 (void **)&asciiString,
829 &length,
830 plContext),
831 PKIX_STRINGGETENCODEDFAILED);
833 /* Create a temporary CERTGeneralName */
834 PKIX_GENERALNAME_DEBUG("\t\tCalling PL_strlen).\n");
835 length = PL_strlen(asciiString);
836 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_AllocItem).\n");
837 secItem = SECITEM_AllocItem(NULL, NULL, length);
838 PKIX_GENERALNAME_DEBUG("\t\tCalling PORT_Memcpy).\n");
839 (void) PORT_Memcpy(secItem->data, asciiString, length);
840 PKIX_CERT_DEBUG("\t\tCalling PORT_NewArena).\n");
841 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
842 if (arena == NULL) {
843 PKIX_ERROR(PKIX_OUTOFMEMORY);
845 PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_NewGeneralName).\n");
846 nssGenName = CERT_NewGeneralName(arena, nameType);
847 if (nssGenName == NULL) {
848 PKIX_ERROR(PKIX_ALLOCATENEWCERTGENERALNAMEFAILED);
851 switch (nameType) {
852 case certRFC822Name:
853 case certDNSName:
854 case certURI:
855 nssGenName->name.other = *secItem;
856 break;
858 case certDirectoryName:
860 PKIX_CHECK(PKIX_PL_X500Name_Create
861 (stringRep, &pkixDN, plContext),
862 PKIX_X500NAMECREATEFAILED);
864 PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_AsciiToName).\n");
865 nssCertName = CERT_AsciiToName(asciiString);
866 nssGenName->name.directoryName = *nssCertName;
867 break;
869 case certRegisterID:
870 PKIX_CHECK(PKIX_PL_OID_Create
871 (asciiString, &pkixOID, plContext),
872 PKIX_OIDCREATEFAILED);
873 nssGenName->name.other = *secItem;
874 break;
875 default:
876 /* including IPAddress, EDIPartyName, OtherName, X400Address */
877 PKIX_ERROR(PKIX_UNABLETOCREATEGENERALNAMEOFTHISTYPE);
880 /* create a PKIX_PL_GeneralName object */
881 PKIX_CHECK(PKIX_PL_Object_Alloc
882 (PKIX_GENERALNAME_TYPE,
883 sizeof (PKIX_PL_GeneralName),
884 (PKIX_PL_Object **)&genName,
885 plContext),
886 PKIX_COULDNOTCREATEOBJECT);
888 /* create a CERTGeneralNameList */
889 nssGenName->type = nameType;
890 PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_CreateGeneralNameList).\n");
891 nssGenNameList = CERT_CreateGeneralNameList(nssGenName);
892 if (nssGenNameList == NULL) {
893 PKIX_ERROR(PKIX_CERTCREATEGENERALNAMELISTFAILED);
895 genName->nssGeneralNameList = nssGenNameList;
897 /* initialize fields */
898 genName->type = nameType;
899 genName->directoryName = pkixDN;
900 genName->OthName = NULL;
901 genName->other = secItem;
902 genName->oid = pkixOID;
904 *pGName = genName;
905 cleanup:
907 PKIX_FREE(asciiString);
909 if (nssCertName != NULL) {
910 PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyName).\n");
911 CERT_DestroyName(nssCertName);
914 if (arena){ /* will free nssGenName */
915 PKIX_CERT_DEBUG("\t\tCalling PORT_FreeArena).\n");
916 PORT_FreeArena(arena, PR_FALSE);
919 if (PKIX_ERROR_RECEIVED){
920 PKIX_DECREF(pkixDN);
921 PKIX_DECREF(pkixOID);
923 PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
924 if (secItem){
925 SECITEM_FreeItem(secItem, PR_TRUE);
926 secItem = NULL;
930 PKIX_RETURN(GENERALNAME);
933 #endif /* BUILD_LIBPKIX_TESTS */