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
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.
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 ***** */
40 * X500Name Object Functions
44 #include "pkix_pl_x500name.h"
46 /* --Private-X500Name-Functions------------------------------------- */
49 * FUNCTION: pkix_pl_X500Name_ToString_Helper
52 * Helper function that creates a string representation of the X500Name
53 * pointed to by "name" and stores it at "pString".
57 * Address of X500Name whose string representation is desired.
60 * Address where object pointer will be stored. Must be non-NULL.
61 * "plContext" - Platform-specific context pointer.
63 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
65 * Returns NULL if the function succeeds.
66 * Returns a X500Name Error if the function fails in a non-fatal way.
67 * Returns a Fatal Error if the function fails in an unrecoverable way.
70 pkix_pl_X500Name_ToString_Helper(
71 PKIX_PL_X500Name
*name
,
72 PKIX_PL_String
**pString
,
75 CERTName
*nssDN
= NULL
;
76 char *utf8String
= NULL
;
77 PKIX_UInt32 utf8Length
;
79 PKIX_ENTER(X500NAME
, "pkix_pl_X500Name_ToString_Helper");
80 PKIX_NULLCHECK_TWO(name
, pString
);
83 PKIX_X500NAME_DEBUG("\t\tCalling CERT_NameToAscii).\n");
84 /* this should really be called CERT_NameToUTF8 */
85 utf8String
= CERT_NameToAscii(nssDN
);
87 PKIX_ERROR(PKIX_CERTNAMETOASCIIFAILED
);
90 PKIX_X500NAME_DEBUG("\t\tCalling PL_strlen).\n");
91 utf8Length
= PL_strlen(utf8String
);
93 PKIX_CHECK(PKIX_PL_String_Create
94 (PKIX_UTF8
, utf8String
, utf8Length
, pString
, plContext
),
95 PKIX_STRINGCREATEFAILED
);
101 PKIX_RETURN(X500NAME
);
105 * FUNCTION: pkix_pl_X500Name_Destroy
106 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
109 pkix_pl_X500Name_Destroy(
110 PKIX_PL_Object
*object
,
113 PKIX_PL_X500Name
*name
= NULL
;
115 PKIX_ENTER(X500NAME
, "pkix_pl_X500Name_Destroy");
116 PKIX_NULLCHECK_ONE(object
);
118 PKIX_CHECK(pkix_CheckType(object
, PKIX_X500NAME_TYPE
, plContext
),
119 PKIX_OBJECTNOTANX500NAME
);
121 name
= (PKIX_PL_X500Name
*)object
;
123 /* PORT_FreeArena will destroy arena, and, allocated on it, CERTName
126 PORT_FreeArena(name
->arena
, PR_FALSE
);
132 PKIX_RETURN(X500NAME
);
136 * FUNCTION: pkix_pl_X500Name_ToString
137 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
140 pkix_pl_X500Name_ToString(
141 PKIX_PL_Object
*object
,
142 PKIX_PL_String
**pString
,
145 PKIX_PL_String
*nameString
= NULL
;
146 PKIX_PL_X500Name
*name
= NULL
;
148 PKIX_ENTER(X500NAME
, "pkix_pl_X500Name_toString");
149 PKIX_NULLCHECK_TWO(object
, pString
);
151 PKIX_CHECK(pkix_CheckType(object
, PKIX_X500NAME_TYPE
, plContext
),
152 PKIX_OBJECTNOTANX500NAME
);
154 name
= (PKIX_PL_X500Name
*)object
;
156 PKIX_CHECK(pkix_pl_X500Name_ToString_Helper
157 (name
, &nameString
, plContext
),
158 PKIX_X500NAMETOSTRINGHELPERFAILED
);
160 *pString
= nameString
;
164 PKIX_RETURN(X500NAME
);
168 * FUNCTION: pkix_pl_X500Name_Hashcode
169 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
172 pkix_pl_X500Name_Hashcode(
173 PKIX_PL_Object
*object
,
174 PKIX_UInt32
*pHashcode
,
177 PKIX_PL_X500Name
*name
= NULL
;
178 SECItem
*derBytes
= NULL
;
179 PKIX_UInt32 nameHash
;
181 PKIX_ENTER(X500NAME
, "pkix_pl_X500Name_Hashcode");
182 PKIX_NULLCHECK_TWO(object
, pHashcode
);
184 PKIX_CHECK(pkix_CheckType(object
, PKIX_X500NAME_TYPE
, plContext
),
185 PKIX_OBJECTNOTANX500NAME
);
187 name
= (PKIX_PL_X500Name
*)object
;
189 /* we hash over the bytes in the DER encoding */
191 derBytes
= &name
->derName
;
194 (derBytes
->data
, derBytes
->len
, &nameHash
, plContext
),
197 *pHashcode
= nameHash
;
201 PKIX_RETURN(X500NAME
);
206 * FUNCTION: pkix_pl_X500Name_Equals
207 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
210 pkix_pl_X500Name_Equals(
211 PKIX_PL_Object
*firstObject
,
212 PKIX_PL_Object
*secondObject
,
213 PKIX_Boolean
*pResult
,
216 PKIX_UInt32 secondType
;
218 PKIX_ENTER(X500NAME
, "pkix_pl_X500Name_Equals");
219 PKIX_NULLCHECK_THREE(firstObject
, secondObject
, pResult
);
221 /* test that firstObject is an X500Name */
222 PKIX_CHECK(pkix_CheckType(firstObject
, PKIX_X500NAME_TYPE
, plContext
),
223 PKIX_FIRSTOBJECTARGUMENTNOTANX500NAME
);
226 * Since we know firstObject is an X500Name, if both references are
227 * identical, they must be equal
229 if (firstObject
== secondObject
){
230 *pResult
= PKIX_TRUE
;
235 * If secondObject isn't an X500Name, we don't throw an error.
236 * We simply return a Boolean result of FALSE
238 *pResult
= PKIX_FALSE
;
239 PKIX_CHECK(PKIX_PL_Object_GetType
240 (secondObject
, &secondType
, plContext
),
241 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT
);
242 if (secondType
!= PKIX_X500NAME_TYPE
) goto cleanup
;
245 PKIX_PL_X500Name_Match((PKIX_PL_X500Name
*)firstObject
,
246 (PKIX_PL_X500Name
*)secondObject
,
248 PKIX_X500NAMEMATCHFAILED
);
252 PKIX_RETURN(X500NAME
);
256 * FUNCTION: pkix_pl_X500Name_RegisterSelf
258 * Registers PKIX_X500NAME_TYPE and its related functions with systemClasses[]
260 * Not Thread Safe - for performance and complexity reasons
262 * Since this function is only called by PKIX_PL_Initialize, which should
263 * only be called once, it is acceptable that this function is not
267 pkix_pl_X500Name_RegisterSelf(void *plContext
)
270 extern pkix_ClassTable_Entry systemClasses
[PKIX_NUMTYPES
];
271 pkix_ClassTable_Entry entry
;
273 PKIX_ENTER(X500NAME
, "pkix_pl_X500Name_RegisterSelf");
275 entry
.description
= "X500Name";
276 entry
.objCounter
= 0;
277 entry
.typeObjectSize
= sizeof(PKIX_PL_X500Name
);
278 entry
.destructor
= pkix_pl_X500Name_Destroy
;
279 entry
.equalsFunction
= pkix_pl_X500Name_Equals
;
280 entry
.hashcodeFunction
= pkix_pl_X500Name_Hashcode
;
281 entry
.toStringFunction
= pkix_pl_X500Name_ToString
;
282 entry
.comparator
= NULL
;
283 entry
.duplicateFunction
= pkix_duplicateImmutable
;
285 systemClasses
[PKIX_X500NAME_TYPE
] = entry
;
287 PKIX_RETURN(X500NAME
);
290 #ifdef BUILD_LIBPKIX_TESTS
292 * FUNCTION: pkix_pl_X500Name_CreateFromUtf8
295 * Creates an X500Name object from the RFC1485 string representation pointed
296 * to by "stringRep", and stores the result at "pName". If the string cannot
297 * be successfully converted, a non-fatal error is returned.
299 * NOTE: ifdefed BUILD_LIBPKIX_TESTS function: this function is allowed to be
300 * called only by pkix tests programs.
304 * Address of the RFC1485 string to be converted. Must be non-NULL.
306 * Address where the X500Name result will be stored. Must be non-NULL.
308 * Platform-specific context pointer.
311 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
314 * Returns NULL if the function succeeds.
315 * Returns an X500NAME Error if the function fails in a non-fatal way.
316 * Returns a Fatal Error if the function fails in an unrecoverable way.
319 pkix_pl_X500Name_CreateFromUtf8(
321 PKIX_PL_X500Name
**pName
,
324 PKIX_PL_X500Name
*x500Name
= NULL
;
325 PRArenaPool
*arena
= NULL
;
326 CERTName
*nssDN
= NULL
;
327 SECItem
*resultSecItem
= NULL
;
329 PKIX_ENTER(X500NAME
, "pkix_pl_X500Name_CreateFromUtf8");
330 PKIX_NULLCHECK_TWO(pName
, stringRep
);
332 nssDN
= CERT_AsciiToName(stringRep
);
334 PKIX_ERROR(PKIX_COULDNOTCREATENSSDN
);
337 arena
= nssDN
->arena
;
339 /* create a PKIX_PL_X500Name object */
340 PKIX_CHECK(PKIX_PL_Object_Alloc
342 sizeof (PKIX_PL_X500Name
),
343 (PKIX_PL_Object
**)&x500Name
,
345 PKIX_COULDNOTCREATEX500NAMEOBJECT
);
347 /* populate the nssDN field */
348 x500Name
->arena
= arena
;
349 x500Name
->nssDN
.arena
= arena
;
350 x500Name
->nssDN
.rdns
= nssDN
->rdns
;
353 SEC_ASN1EncodeItem(arena
, &x500Name
->derName
, nssDN
,
356 if (resultSecItem
== NULL
){
357 PKIX_ERROR(PKIX_SECASN1ENCODEITEMFAILED
);
364 if (PKIX_ERROR_RECEIVED
){
366 PKIX_PL_Object_DecRef((PKIX_PL_Object
*)x500Name
,
369 CERT_DestroyName(nssDN
);
373 PKIX_RETURN(X500NAME
);
375 #endif /* BUILD_LIBPKIX_TESTS */
378 * FUNCTION: pkix_pl_X500Name_GetCERTName
382 * Returns the pointer to CERTName member of X500Name structure.
384 * Returned pointed should not be freed.2
388 * Address of X500Name whose OrganizationName is to be extracted. Must be
391 * Address where result will be stored. Must be non-NULL.
393 * Platform-specific context pointer.
396 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
399 * Returns NULL if the function succeeds.
400 * Returns a Fatal Error if the function fails in an unrecoverable way.
403 pkix_pl_X500Name_GetCERTName(
404 PKIX_PL_X500Name
*xname
,
405 CERTName
**pCERTName
,
408 PKIX_ENTER(X500NAME
, "pkix_pl_X500Name_GetCERTName");
409 PKIX_NULLCHECK_TWO(xname
, pCERTName
);
411 *pCERTName
= &xname
->nssDN
;
413 PKIX_RETURN(X500NAME
);
416 /* --Public-Functions------------------------------------------------------- */
419 * FUNCTION: PKIX_PL_X500Name_CreateFromCERTName (see comments in pkix_pl_pki.h)
423 PKIX_PL_X500Name_CreateFromCERTName(
426 PKIX_PL_X500Name
**pName
,
429 PRArenaPool
*arena
= NULL
;
430 SECStatus rv
= SECFailure
;
431 PKIX_PL_X500Name
*x500Name
= NULL
;
433 PKIX_ENTER(X500NAME
, "PKIX_PL_X500Name_CreateFromCERTName");
434 PKIX_NULLCHECK_ONE(pName
);
435 if (derName
== NULL
&& name
== NULL
) {
436 PKIX_ERROR(PKIX_NULLARGUMENT
);
439 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
441 PKIX_ERROR(PKIX_OUTOFMEMORY
);
444 PKIX_CHECK(PKIX_PL_Object_Alloc
446 sizeof (PKIX_PL_X500Name
),
447 (PKIX_PL_Object
**)&x500Name
,
449 PKIX_COULDNOTCREATEX500NAMEOBJECT
);
451 x500Name
->arena
= arena
;
452 x500Name
->nssDN
.arena
= NULL
;
454 if (derName
!= NULL
) {
455 rv
= SECITEM_CopyItem(arena
, &x500Name
->derName
, derName
);
456 if (rv
== SECFailure
) {
457 PKIX_ERROR(PKIX_OUTOFMEMORY
);
462 rv
= CERT_CopyName(arena
, &x500Name
->nssDN
, name
);
463 if (rv
== SECFailure
) {
464 PKIX_ERROR(PKIX_CERTCOPYNAMEFAILED
);
467 rv
= SEC_QuickDERDecodeItem(arena
, &x500Name
->nssDN
,
470 if (rv
== SECFailure
) {
471 PKIX_ERROR(PKIX_SECQUICKDERDECODERFAILED
);
478 if (PKIX_ERROR_RECEIVED
) {
480 PKIX_PL_Object_DecRef((PKIX_PL_Object
*)x500Name
,
483 PORT_FreeArena(arena
, PR_FALSE
);
487 PKIX_RETURN(X500NAME
);
490 #ifdef BUILD_LIBPKIX_TESTS
492 * FUNCTION: PKIX_PL_X500Name_Create (see comments in pkix_pl_pki.h)
494 * NOTE: ifdefed BUILD_LIBPKIX_TESTS function: this function is allowed
495 * to be called only by pkix tests programs.
498 PKIX_PL_X500Name_Create(
499 PKIX_PL_String
*stringRep
,
500 PKIX_PL_X500Name
**pName
,
503 char *utf8String
= NULL
;
504 PKIX_UInt32 utf8Length
= 0;
506 PKIX_ENTER(X500NAME
, "PKIX_PL_X500Name_Create");
507 PKIX_NULLCHECK_TWO(pName
, stringRep
);
510 * convert the input PKIX_PL_String to PKIX_UTF8_NULL_TERM.
511 * we need to use this format specifier because
512 * CERT_AsciiToName expects a NULL-terminated UTF8 string.
513 * Since UTF8 allow NUL characters in the middle of the
514 * string, this is buggy. However, as a workaround, using
515 * PKIX_UTF8_NULL_TERM gives us a NULL-terminated UTF8 string.
518 PKIX_CHECK(PKIX_PL_String_GetEncoded
521 (void **)&utf8String
,
524 PKIX_STRINGGETENCODEDFAILED
);
527 pkix_pl_X500Name_CreateFromUtf8(utf8String
,
529 PKIX_X500NAMECREATEFROMUTF8FAILED
);
532 PKIX_FREE(utf8String
);
534 PKIX_RETURN(X500NAME
);
536 #endif /* BUILD_LIBPKIX_TESTS */
539 * FUNCTION: PKIX_PL_X500Name_Match (see comments in pkix_pl_pki.h)
542 PKIX_PL_X500Name_Match(
543 PKIX_PL_X500Name
*firstX500Name
,
544 PKIX_PL_X500Name
*secondX500Name
,
545 PKIX_Boolean
*pResult
,
548 SECItem
*firstDerName
= NULL
;
549 SECItem
*secondDerName
= NULL
;
550 SECComparison cmpResult
;
552 PKIX_ENTER(X500NAME
, "PKIX_PL_X500Name_Match");
553 PKIX_NULLCHECK_THREE(firstX500Name
, secondX500Name
, pResult
);
555 if (firstX500Name
== secondX500Name
){
556 *pResult
= PKIX_TRUE
;
560 firstDerName
= &firstX500Name
->derName
;
561 secondDerName
= &secondX500Name
->derName
;
563 PKIX_NULLCHECK_TWO(firstDerName
->data
, secondDerName
->data
);
565 cmpResult
= SECITEM_CompareItem(firstDerName
, secondDerName
);
566 if (cmpResult
!= SECEqual
) {
567 cmpResult
= CERT_CompareName(&firstX500Name
->nssDN
,
568 &secondX500Name
->nssDN
);
571 *pResult
= (cmpResult
== SECEqual
);
575 PKIX_RETURN(X500NAME
);
579 * FUNCTION: pkix_pl_X500Name_GetSECName
582 * Returns a copy of CERTName DER representation allocated on passed in arena.
583 * If allocation on arena can not be done, NULL is stored at "pSECName".
587 * Address of X500Name whose CERTName flag is to be encoded. Must be
590 * Address of the PRArenaPool to be used in the encoding, and in which
591 * "pSECName" will be allocated. Must be non-NULL.
593 * Address where result will be stored. Must be non-NULL.
595 * Platform-specific context pointer.
598 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
601 * Returns NULL if the function succeeds.
602 * Returns a Fatal Error if the function fails in an unrecoverable way.
605 pkix_pl_X500Name_GetDERName(
606 PKIX_PL_X500Name
*xname
,
611 SECItem
*derName
= NULL
;
613 PKIX_ENTER(X500NAME
, "pkix_pl_X500Name_GetDERName");
615 PKIX_NULLCHECK_THREE(xname
, arena
, pDERName
);
617 /* Return NULL is X500Name was not created from DER */
618 if (xname
->derName
.data
== NULL
) {
623 derName
= SECITEM_ArenaDupItem(arena
, &xname
->derName
);
624 if (derName
== NULL
) {
625 PKIX_ERROR(PKIX_OUTOFMEMORY
);
631 PKIX_RETURN(X500NAME
);
635 * FUNCTION: pkix_pl_X500Name_GetCommonName
638 * Extracts the CommonName component of the X500Name object pointed to by
639 * "xname", and stores the result at "pCommonName". If the CommonName cannot
640 * be successfully extracted, NULL is stored at "pCommonName".
642 * The returned string must be freed with PORT_Free.
646 * Address of X500Name whose CommonName is to be extracted. Must be
649 * Address where result will be stored. Must be non-NULL.
651 * Platform-specific context pointer.
654 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
657 * Returns NULL if the function succeeds.
658 * Returns a Fatal Error if the function fails in an unrecoverable way.
661 pkix_pl_X500Name_GetCommonName(
662 PKIX_PL_X500Name
*xname
,
663 unsigned char **pCommonName
,
666 PKIX_ENTER(X500NAME
, "pkix_pl_X500Name_GetCommonName");
667 PKIX_NULLCHECK_TWO(xname
, pCommonName
);
669 *pCommonName
= (unsigned char *)CERT_GetCommonName(&xname
->nssDN
);
671 PKIX_RETURN(X500NAME
);
675 * FUNCTION: pkix_pl_X500Name_GetCountryName
678 * Extracts the CountryName component of the X500Name object pointed to by
679 * "xname", and stores the result at "pCountryName". If the CountryName cannot
680 * be successfully extracted, NULL is stored at "pCountryName".
682 * The returned string must be freed with PORT_Free.
686 * Address of X500Name whose CountryName is to be extracted. Must be
689 * Address where result will be stored. Must be non-NULL.
691 * Platform-specific context pointer.
694 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
697 * Returns NULL if the function succeeds.
698 * Returns a Fatal Error if the function fails in an unrecoverable way.
701 pkix_pl_X500Name_GetCountryName(
702 PKIX_PL_X500Name
*xname
,
703 unsigned char **pCountryName
,
706 PKIX_ENTER(X500NAME
, "pkix_pl_X500Name_GetCountryName");
707 PKIX_NULLCHECK_TWO(xname
, pCountryName
);
709 *pCountryName
= (unsigned char*)CERT_GetCountryName(&xname
->nssDN
);
711 PKIX_RETURN(X500NAME
);
715 * FUNCTION: pkix_pl_X500Name_GetOrgName
718 * Extracts the OrganizationName component of the X500Name object pointed to by
719 * "xname", and stores the result at "pOrgName". If the OrganizationName cannot
720 * be successfully extracted, NULL is stored at "pOrgName".
722 * The returned string must be freed with PORT_Free.
726 * Address of X500Name whose OrganizationName is to be extracted. Must be
729 * Address where result will be stored. Must be non-NULL.
731 * Platform-specific context pointer.
734 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
737 * Returns NULL if the function succeeds.
738 * Returns a Fatal Error if the function fails in an unrecoverable way.
741 pkix_pl_X500Name_GetOrgName(
742 PKIX_PL_X500Name
*xname
,
743 unsigned char **pOrgName
,
746 PKIX_ENTER(X500NAME
, "pkix_pl_X500Name_GetOrgName");
747 PKIX_NULLCHECK_TWO(xname
, pOrgName
);
749 *pOrgName
= (unsigned char*)CERT_GetOrgName(&xname
->nssDN
);
751 PKIX_RETURN(X500NAME
);