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 Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
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_nameconstraints.c
40 * Name Constraints Object Functions Definitions
44 #include "pkix_pl_nameconstraints.h"
47 /* --Private-NameConstraints-Functions----------------------------- */
50 * FUNCTION: pkix_pl_CertNameConstraints_GetPermitted
53 * This function retrieve name constraints permitted list from NSS
54 * data in "nameConstraints" and returns a PKIX_PL_GeneralName list
55 * in "pPermittedList".
59 * Address of CertNameConstraints which has a pointer to
60 * CERTNameConstraints data. Must be non-NULL.
62 * Address where returned permitted name list is stored. Must be non-NULL.
63 * "plContext" - Platform-specific context pointer.
65 * Conditionally Thread Safe
66 * (see Thread Safety Definitions in Programmer's Guide)
68 * Returns NULL if the function succeeds.
69 * Returns a NameConstraints Error if the function fails in a
71 * Returns a Fatal Error if the function fails in an unrecoverable way.
74 pkix_pl_CertNameConstraints_GetPermitted(
75 PKIX_PL_CertNameConstraints
*nameConstraints
,
76 PKIX_List
**pPermittedList
,
79 CERTNameConstraints
*nssNameConstraints
= NULL
;
80 CERTNameConstraints
**nssNameConstraintsList
= NULL
;
81 CERTNameConstraint
*nssPermitted
= NULL
;
82 CERTNameConstraint
*firstPermitted
= NULL
;
83 PKIX_List
*permittedList
= NULL
;
84 PKIX_PL_GeneralName
*name
= NULL
;
85 PKIX_UInt32 numItems
= 0;
88 PKIX_ENTER(CERTNAMECONSTRAINTS
,
89 "pkix_pl_CertNameConstraints_GetPermitted");
90 PKIX_NULLCHECK_TWO(nameConstraints
, pPermittedList
);
93 * nssNameConstraints is an array of CERTNameConstraints
94 * pointers where CERTNameConstraints keep its permitted and excluded
95 * lists as pointer array of CERTNameConstraint.
98 if (nameConstraints
->permittedList
== NULL
) {
100 PKIX_OBJECT_LOCK(nameConstraints
);
102 if (nameConstraints
->permittedList
== NULL
) {
104 PKIX_CHECK(PKIX_List_Create(&permittedList
, plContext
),
105 PKIX_LISTCREATEFAILED
);
107 numItems
= nameConstraints
->numNssNameConstraints
;
108 nssNameConstraintsList
=
109 nameConstraints
->nssNameConstraintsList
;
111 for (i
= 0; i
< numItems
; i
++) {
113 PKIX_NULLCHECK_ONE(nssNameConstraintsList
);
114 nssNameConstraints
= *(nssNameConstraintsList
+ i
);
115 PKIX_NULLCHECK_ONE(nssNameConstraints
);
117 if (nssNameConstraints
->permited
!= NULL
) {
119 nssPermitted
= nssNameConstraints
->permited
;
120 firstPermitted
= nssPermitted
;
124 PKIX_CHECK(pkix_pl_GeneralName_Create
125 (&nssPermitted
->name
, &name
, plContext
),
126 PKIX_GENERALNAMECREATEFAILED
);
128 PKIX_CHECK(PKIX_List_AppendItem
130 (PKIX_PL_Object
*)name
,
132 PKIX_LISTAPPENDITEMFAILED
);
136 PKIX_CERTNAMECONSTRAINTS_DEBUG
137 ("\t\tCalling CERT_GetNextNameConstraint\n");
138 nssPermitted
= CERT_GetNextNameConstraint
141 } while (nssPermitted
!= firstPermitted
);
146 PKIX_CHECK(PKIX_List_SetImmutable(permittedList
, plContext
),
147 PKIX_LISTSETIMMUTABLEFAILED
);
149 nameConstraints
->permittedList
= permittedList
;
153 PKIX_OBJECT_UNLOCK(nameConstraints
);
157 PKIX_INCREF(nameConstraints
->permittedList
);
159 *pPermittedList
= nameConstraints
->permittedList
;
163 PKIX_RETURN(CERTNAMECONSTRAINTS
);
167 * FUNCTION: pkix_pl_CertNameConstraints_GetExcluded
170 * This function retrieve name constraints excluded list from NSS
171 * data in "nameConstraints" and returns a PKIX_PL_GeneralName list
172 * in "pExcludedList".
176 * Address of CertNameConstraints which has a pointer to NSS data.
179 * Address where returned excluded name list is stored. Must be non-NULL.
180 * "plContext" - Platform-specific context pointer.
182 * Conditionally Thread Safe
183 * (see Thread Safety Definitions in Programmer's Guide)
185 * Returns NULL if the function succeeds.
186 * Returns a NameConstraints Error if the function fails in a
188 * Returns a Fatal Error if the function fails in an unrecoverable way.
191 pkix_pl_CertNameConstraints_GetExcluded(
192 PKIX_PL_CertNameConstraints
*nameConstraints
,
193 PKIX_List
**pExcludedList
,
196 CERTNameConstraints
*nssNameConstraints
= NULL
;
197 CERTNameConstraints
**nssNameConstraintsList
= NULL
;
198 CERTNameConstraint
*nssExcluded
= NULL
;
199 CERTNameConstraint
*firstExcluded
= NULL
;
200 PKIX_List
*excludedList
= NULL
;
201 PKIX_PL_GeneralName
*name
= NULL
;
202 PKIX_UInt32 numItems
= 0;
205 PKIX_ENTER(CERTNAMECONSTRAINTS
,
206 "pkix_pl_CertNameConstraints_GetExcluded");
207 PKIX_NULLCHECK_TWO(nameConstraints
, pExcludedList
);
209 if (nameConstraints
->excludedList
== NULL
) {
211 PKIX_OBJECT_LOCK(nameConstraints
);
213 if (nameConstraints
->excludedList
== NULL
) {
215 PKIX_CHECK(PKIX_List_Create(&excludedList
, plContext
),
216 PKIX_LISTCREATEFAILED
);
218 numItems
= nameConstraints
->numNssNameConstraints
;
219 nssNameConstraintsList
=
220 nameConstraints
->nssNameConstraintsList
;
222 for (i
= 0; i
< numItems
; i
++) {
224 PKIX_NULLCHECK_ONE(nssNameConstraintsList
);
225 nssNameConstraints
= *(nssNameConstraintsList
+ i
);
226 PKIX_NULLCHECK_ONE(nssNameConstraints
);
228 if (nssNameConstraints
->excluded
!= NULL
) {
230 nssExcluded
= nssNameConstraints
->excluded
;
231 firstExcluded
= nssExcluded
;
235 PKIX_CHECK(pkix_pl_GeneralName_Create
236 (&nssExcluded
->name
, &name
, plContext
),
237 PKIX_GENERALNAMECREATEFAILED
);
239 PKIX_CHECK(PKIX_List_AppendItem
241 (PKIX_PL_Object
*)name
,
243 PKIX_LISTAPPENDITEMFAILED
);
247 PKIX_CERTNAMECONSTRAINTS_DEBUG
248 ("\t\tCalling CERT_GetNextNameConstraint\n");
249 nssExcluded
= CERT_GetNextNameConstraint
252 } while (nssExcluded
!= firstExcluded
);
257 PKIX_CHECK(PKIX_List_SetImmutable(excludedList
, plContext
),
258 PKIX_LISTSETIMMUTABLEFAILED
);
260 nameConstraints
->excludedList
= excludedList
;
264 PKIX_OBJECT_UNLOCK(nameConstraints
);
267 PKIX_INCREF(nameConstraints
->excludedList
);
269 *pExcludedList
= nameConstraints
->excludedList
;
273 PKIX_RETURN(CERTNAMECONSTRAINTS
);
277 * FUNCTION: pkix_pl_CertNameConstraints_CheckNameSpaceNssNames
280 * This function checks if CERTGeneral names in "nssSubjectNames" complies
281 * with the permitted and excluded names in "nameConstraints". It returns
282 * PKIX_TRUE in "pCheckPass", if the Names satify the name space of the
283 * permitted list and if the Names are not in the excluded list. Otherwise,
284 * it returns PKIX_FALSE.
288 * List of CERTGeneralName that nameConstraints verification is based on.
290 * Address of CertNameConstraints that provides lists of permitted
291 * and excluded names. Must be non-NULL.
293 * Address where PKIX_TRUE is returned if the all names in "nameList" are
295 * "plContext" - Platform-specific context pointer.
297 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
299 * Returns NULL if the function succeeds.
300 * Returns a NameConstraints Error if the function fails in a
302 * Returns a Fatal Error if the function fails in an unrecoverable way.
305 pkix_pl_CertNameConstraints_CheckNameSpaceNssNames(
306 CERTGeneralName
*nssSubjectNames
,
307 PKIX_PL_CertNameConstraints
*nameConstraints
,
308 PKIX_Boolean
*pCheckPass
,
311 CERTNameConstraints
**nssNameConstraintsList
= NULL
;
312 CERTNameConstraints
*nssNameConstraints
= NULL
;
313 CERTGeneralName
*nssMatchName
= NULL
;
314 PRArenaPool
*arena
= NULL
;
315 PKIX_UInt32 numItems
= 0;
317 SECStatus status
= SECSuccess
;
319 PKIX_ENTER(CERTNAMECONSTRAINTS
,
320 "pkix_pl_CertNameConstraints_CheckNameSpaceNssNames");
321 PKIX_NULLCHECK_THREE(nssSubjectNames
, nameConstraints
, pCheckPass
);
323 *pCheckPass
= PKIX_TRUE
;
325 PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena\n");
326 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
328 PKIX_ERROR(PKIX_PORTNEWARENAFAILED
);
331 if (nssSubjectNames
== NULL
) {
332 PKIX_ERROR(PKIX_CERTGETCERTIFICATENAMESRETURNNULL
);
335 nssMatchName
= nssSubjectNames
;
336 nssNameConstraintsList
= nameConstraints
->nssNameConstraintsList
;
339 * CERTNameConstraint items in each permitted or excluded list
340 * is verified as OR condition. That means, if one item matched,
341 * then the checking on the remaining items on the list is skipped.
342 * (see NSS cert_CompareNameWithConstraints(...)).
343 * Items on PKIX_PL_NameConstraint's nssNameConstraints are verified
344 * as AND condition. PKIX_PL_NameConstraint keeps an array of pointers
345 * of CERTNameConstraints resulting from merging multiple
346 * PKIX_PL_NameConstraints. Since each CERTNameConstraint are created
347 * for different entity, a union condition of these entities then is
353 numItems
= nameConstraints
->numNssNameConstraints
;
355 for (i
= 0; i
< numItems
; i
++) {
357 PKIX_NULLCHECK_ONE(nssNameConstraintsList
);
358 nssNameConstraints
= *(nssNameConstraintsList
+ i
);
359 PKIX_NULLCHECK_ONE(nssNameConstraints
);
361 PKIX_CERTNAMECONSTRAINTS_DEBUG
362 ("\t\tCalling CERT_CheckNameSpace\n");
363 status
= CERT_CheckNameSpace
364 (arena
, nssNameConstraints
, nssMatchName
);
365 if (status
!= SECSuccess
) {
371 if (status
!= SECSuccess
) {
375 PKIX_CERTNAMECONSTRAINTS_DEBUG
376 ("\t\tCalling CERT_GetNextGeneralName\n");
377 nssMatchName
= CERT_GetNextGeneralName(nssMatchName
);
379 } while (nssMatchName
!= nssSubjectNames
);
381 if (status
== SECFailure
) {
383 *pCheckPass
= PKIX_FALSE
;
389 PKIX_CERTNAMECONSTRAINTS_DEBUG
390 ("\t\tCalling PORT_FreeArena).\n");
391 PORT_FreeArena(arena
, PR_FALSE
);
394 PKIX_RETURN(CERTNAMECONSTRAINTS
);
398 * FUNCTION: pkix_pl_NameConstraints_Destroy
399 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
402 pkix_pl_CertNameConstraints_Destroy(
403 PKIX_PL_Object
*object
,
406 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
408 PKIX_ENTER(CERTNAMECONSTRAINTS
, "pkix_pl_CertNameConstraints_Destroy");
409 PKIX_NULLCHECK_ONE(object
);
411 PKIX_CHECK(pkix_CheckType
412 (object
, PKIX_CERTNAMECONSTRAINTS_TYPE
, plContext
),
413 PKIX_OBJECTNOTCERTNAMECONSTRAINTS
);
415 nameConstraints
= (PKIX_PL_CertNameConstraints
*)object
;
417 PKIX_CHECK(PKIX_PL_Free
418 (nameConstraints
->nssNameConstraintsList
, plContext
),
421 if (nameConstraints
->arena
){
422 PKIX_CERTNAMECONSTRAINTS_DEBUG
423 ("\t\tCalling PORT_FreeArena).\n");
424 PORT_FreeArena(nameConstraints
->arena
, PR_FALSE
);
425 nameConstraints
->arena
= NULL
;
428 PKIX_DECREF(nameConstraints
->permittedList
);
429 PKIX_DECREF(nameConstraints
->excludedList
);
433 PKIX_RETURN(CERTNAMECONSTRAINTS
);
437 * FUNCTION: pkix_pl_CertNameConstraints_ToString_Helper
440 * Helper function that creates a string representation of the object
441 * NameConstraints and stores it at "pString".
445 * Address of CertNameConstraints whose string representation is
446 * desired. Must be non-NULL.
448 * Address where string object pointer will be stored. Must be non-NULL.
449 * "plContext" - Platform-specific context pointer.
451 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
453 * Returns NULL if the function succeeds.
454 * Returns a NameConstraints Error if the function fails in a
456 * Returns a Fatal Error if the function fails in an unrecoverable way.
459 pkix_pl_CertNameConstraints_ToString_Helper(
460 PKIX_PL_CertNameConstraints
*nameConstraints
,
461 PKIX_PL_String
**pString
,
464 char *asciiFormat
= NULL
;
465 PKIX_PL_String
*formatString
= NULL
;
466 PKIX_List
*permittedList
= NULL
;
467 PKIX_List
*excludedList
= NULL
;
468 PKIX_PL_String
*permittedListString
= NULL
;
469 PKIX_PL_String
*excludedListString
= NULL
;
470 PKIX_PL_String
*nameConstraintsString
= NULL
;
472 PKIX_ENTER(CERTNAMECONSTRAINTS
,
473 "pkix_pl_CertNameConstraints_ToString_Helper");
474 PKIX_NULLCHECK_TWO(nameConstraints
, pString
);
478 "\t\tPermitted Name: %s\n"
479 "\t\tExcluded Name: %s\n"
482 PKIX_CHECK(PKIX_PL_String_Create
488 PKIX_STRINGCREATEFAILED
);
490 PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
491 (nameConstraints
, &permittedList
, plContext
),
492 PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED
);
494 PKIX_TOSTRING(permittedList
, &permittedListString
, plContext
,
495 PKIX_LISTTOSTRINGFAILED
);
497 PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
498 (nameConstraints
, &excludedList
, plContext
),
499 PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED
);
501 PKIX_TOSTRING(excludedList
, &excludedListString
, plContext
,
502 PKIX_LISTTOSTRINGFAILED
);
504 PKIX_CHECK(PKIX_PL_Sprintf
505 (&nameConstraintsString
,
512 *pString
= nameConstraintsString
;
516 PKIX_DECREF(formatString
);
517 PKIX_DECREF(permittedList
);
518 PKIX_DECREF(excludedList
);
519 PKIX_DECREF(permittedListString
);
520 PKIX_DECREF(excludedListString
);
522 PKIX_RETURN(CERTNAMECONSTRAINTS
);
526 * FUNCTION: pkix_pl_CertNameConstraints_ToString
527 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
530 pkix_pl_CertNameConstraints_ToString(
531 PKIX_PL_Object
*object
,
532 PKIX_PL_String
**pString
,
535 PKIX_PL_String
*nameConstraintsString
= NULL
;
536 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
538 PKIX_ENTER(CERTNAMECONSTRAINTS
, "pkix_pl_CertNameConstraints_ToString");
539 PKIX_NULLCHECK_TWO(object
, pString
);
541 PKIX_CHECK(pkix_CheckType(
542 object
, PKIX_CERTNAMECONSTRAINTS_TYPE
, plContext
),
543 PKIX_OBJECTNOTCERTNAMECONSTRAINTS
);
545 nameConstraints
= (PKIX_PL_CertNameConstraints
*)object
;
547 PKIX_CHECK(pkix_pl_CertNameConstraints_ToString_Helper
548 (nameConstraints
, &nameConstraintsString
, plContext
),
549 PKIX_CERTNAMECONSTRAINTSTOSTRINGHELPERFAILED
);
551 *pString
= nameConstraintsString
;
555 PKIX_RETURN(CERTNAMECONSTRAINTS
);
559 * FUNCTION: pkix_pl_CertNameConstraints_Hashcode
560 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
563 pkix_pl_CertNameConstraints_Hashcode(
564 PKIX_PL_Object
*object
,
565 PKIX_UInt32
*pHashcode
,
568 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
569 PKIX_List
*permittedList
= NULL
;
570 PKIX_List
*excludedList
= NULL
;
571 PKIX_UInt32 permitHash
= 0;
572 PKIX_UInt32 excludeHash
= 0;
574 PKIX_ENTER(CERTNAMECONSTRAINTS
, "pkix_pl_CertNameConstraints_Hashcode");
575 PKIX_NULLCHECK_TWO(object
, pHashcode
);
577 PKIX_CHECK(pkix_CheckType
578 (object
, PKIX_CERTNAMECONSTRAINTS_TYPE
, plContext
),
579 PKIX_OBJECTNOTCERTNAMECONSTRAINTS
);
581 nameConstraints
= (PKIX_PL_CertNameConstraints
*)object
;
583 PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
584 (nameConstraints
, &permittedList
, plContext
),
585 PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED
);
587 PKIX_HASHCODE(permittedList
, &permitHash
, plContext
,
588 PKIX_OBJECTHASHCODEFAILED
);
590 PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
591 (nameConstraints
, &excludedList
, plContext
),
592 PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED
);
594 PKIX_HASHCODE(excludedList
, &excludeHash
, plContext
,
595 PKIX_OBJECTHASHCODEFAILED
);
597 *pHashcode
= (((permitHash
<< 7) + excludeHash
) << 7) +
598 nameConstraints
->numNssNameConstraints
;
602 PKIX_DECREF(permittedList
);
603 PKIX_DECREF(excludedList
);
604 PKIX_RETURN(CERTNAMECONSTRAINTS
);
608 * FUNCTION: pkix_pl_CertNameConstraints_Equals
609 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
612 pkix_pl_CertNameConstraints_Equals(
613 PKIX_PL_Object
*firstObject
,
614 PKIX_PL_Object
*secondObject
,
615 PKIX_Boolean
*pResult
,
618 PKIX_PL_CertNameConstraints
*firstNC
= NULL
;
619 PKIX_PL_CertNameConstraints
*secondNC
= NULL
;
620 PKIX_List
*firstPermittedList
= NULL
;
621 PKIX_List
*secondPermittedList
= NULL
;
622 PKIX_List
*firstExcludedList
= NULL
;
623 PKIX_List
*secondExcludedList
= NULL
;
624 PKIX_UInt32 secondType
;
625 PKIX_Boolean cmpResult
= PKIX_FALSE
;
627 PKIX_ENTER(CERTNAMECONSTRAINTS
, "pkix_pl_CertNameConstraints_Equals");
628 PKIX_NULLCHECK_THREE(firstObject
, secondObject
, pResult
);
630 /* test that firstObject is a CertNameConstraints */
631 PKIX_CHECK(pkix_CheckType
632 (firstObject
, PKIX_CERTNAMECONSTRAINTS_TYPE
, plContext
),
633 PKIX_FIRSTOBJECTNOTCERTNAMECONSTRAINTS
);
635 firstNC
= (PKIX_PL_CertNameConstraints
*)firstObject
;
636 secondNC
= (PKIX_PL_CertNameConstraints
*)secondObject
;
639 * Since we know firstObject is a CertNameConstraints, if both
640 * references are identical, they must be equal
642 if (firstNC
== secondNC
){
643 *pResult
= PKIX_TRUE
;
648 * If secondNC isn't a CertNameConstraints, we don't throw an error.
649 * We simply return a Boolean result of FALSE
651 *pResult
= PKIX_FALSE
;
653 PKIX_CHECK(PKIX_PL_Object_GetType
654 ((PKIX_PL_Object
*)secondNC
, &secondType
, plContext
),
655 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT
);
657 if (secondType
!= PKIX_CERTNAMECONSTRAINTS_TYPE
) {
661 PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
662 (firstNC
, &firstPermittedList
, plContext
),
663 PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED
);
665 PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
666 (secondNC
, &secondPermittedList
, plContext
),
667 PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED
);
670 (firstPermittedList
, secondPermittedList
, &cmpResult
, plContext
,
671 PKIX_OBJECTEQUALSFAILED
);
673 if (cmpResult
!= PKIX_TRUE
) {
677 PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
678 (firstNC
, &firstExcludedList
, plContext
),
679 PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED
);
681 PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
682 (secondNC
, &secondExcludedList
, plContext
),
683 PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED
);
686 (firstExcludedList
, secondExcludedList
, &cmpResult
, plContext
,
687 PKIX_OBJECTEQUALSFAILED
);
689 if (cmpResult
!= PKIX_TRUE
) {
694 * numNssNameConstraints is not checked because it is basically a
695 * merge count, it cannot determine the data equality.
698 *pResult
= PKIX_TRUE
;
702 PKIX_DECREF(firstPermittedList
);
703 PKIX_DECREF(secondPermittedList
);
704 PKIX_DECREF(firstExcludedList
);
705 PKIX_DECREF(secondExcludedList
);
707 PKIX_RETURN(CERTNAMECONSTRAINTS
);
711 * FUNCTION: pkix_pl_CertNameConstraints_RegisterSelf
713 * Registers PKIX_CERTNAMECONSTRAINTS_TYPE and its related functions with
716 * Not Thread Safe - for performance and complexity reasons
718 * Since this function is only called by PKIX_PL_Initialize, which should
719 * only be called once, it is acceptable that this function is not
723 pkix_pl_CertNameConstraints_RegisterSelf(void *plContext
)
725 extern pkix_ClassTable_Entry systemClasses
[PKIX_NUMTYPES
];
726 pkix_ClassTable_Entry entry
;
728 PKIX_ENTER(CERTNAMECONSTRAINTS
,
729 "pkix_pl_CertNameConstraints_RegisterSelf");
731 entry
.description
= "CertNameConstraints";
732 entry
.destructor
= pkix_pl_CertNameConstraints_Destroy
;
733 entry
.equalsFunction
= pkix_pl_CertNameConstraints_Equals
;
734 entry
.hashcodeFunction
= pkix_pl_CertNameConstraints_Hashcode
;
735 entry
.toStringFunction
= pkix_pl_CertNameConstraints_ToString
;
736 entry
.comparator
= NULL
;
737 entry
.duplicateFunction
= pkix_duplicateImmutable
;
739 systemClasses
[PKIX_CERTNAMECONSTRAINTS_TYPE
] = entry
;
741 PKIX_RETURN(CERTNAMECONSTRAINTS
);
745 * FUNCTION: pkix_pl_CertNameConstraints_Create_Helper
748 * This function retrieves name constraints in "nssNameConstraints",
749 * converts and stores the result in a PKIX_PL_CertNameConstraints object.
752 * "nssNameConstraints"
753 * Address of CERTNameConstraints that contains this object's data.
756 * Address where object pointer will be stored. Must be non-NULL.
757 * A NULL value will be returned if there is no Name Constraints extension.
758 * "plContext" - Platform-specific context pointer.
761 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
764 * Returns NULL if the function succeeds.
765 * Returns a NameConstraints Error if the function fails in a non-fatal way.
766 * Returns a Fatal Error if the function fails in an unrecoverable way.
769 pkix_pl_CertNameConstraints_Create_Helper(
770 CERTNameConstraints
*nssNameConstraints
,
771 PKIX_PL_CertNameConstraints
**pNameConstraints
,
774 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
775 CERTNameConstraints
**nssNameConstraintPtr
= NULL
;
777 PKIX_ENTER(CERTNAMECONSTRAINTS
,
778 "pkix_pl_CertNameConstraints_Create_Helper");
779 PKIX_NULLCHECK_TWO(nssNameConstraints
, pNameConstraints
);
781 PKIX_CHECK(PKIX_PL_Object_Alloc
782 (PKIX_CERTNAMECONSTRAINTS_TYPE
,
783 sizeof (PKIX_PL_CertNameConstraints
),
784 (PKIX_PL_Object
**)&nameConstraints
,
786 PKIX_COULDNOTCREATECERTNAMECONSTRAINTSOBJECT
);
788 PKIX_CHECK(PKIX_PL_Malloc
789 (sizeof (CERTNameConstraint
*),
790 (void *)&nssNameConstraintPtr
,
794 nameConstraints
->numNssNameConstraints
= 1;
795 nameConstraints
->nssNameConstraintsList
= nssNameConstraintPtr
;
796 *nssNameConstraintPtr
= nssNameConstraints
;
798 nameConstraints
->permittedList
= NULL
;
799 nameConstraints
->excludedList
= NULL
;
800 nameConstraints
->arena
= NULL
;
802 *pNameConstraints
= nameConstraints
;
806 if (PKIX_ERROR_RECEIVED
){
807 PKIX_DECREF(nameConstraints
);
810 PKIX_RETURN(CERTNAMECONSTRAINTS
);
814 * FUNCTION: pkix_pl_CertNameConstraints_Create
817 * function that allocates and initialize the object CertNameConstraints.
821 * Address of CERT that contains this object's data.
824 * Address where object pointer will be stored. Must be non-NULL.
825 * A NULL value will be returned if there is no Name Constraints extension.
826 * "plContext" - Platform-specific context pointer.
829 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
832 * Returns NULL if the function succeeds.
833 * Returns a NameConstraints Error if the function fails in a non-fatal way.
834 * Returns a Fatal Error if the function fails in an unrecoverable way.
837 pkix_pl_CertNameConstraints_Create(
838 CERTCertificate
*nssCert
,
839 PKIX_PL_CertNameConstraints
**pNameConstraints
,
842 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
843 CERTNameConstraints
*nssNameConstraints
= NULL
;
844 PLArenaPool
*arena
= NULL
;
847 PKIX_ENTER(CERTNAMECONSTRAINTS
, "pkix_pl_CertNameConstraints_Create");
848 PKIX_NULLCHECK_THREE(nssCert
, pNameConstraints
, nssCert
->arena
);
850 PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena).\n");
851 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
853 PKIX_ERROR(PKIX_PORTNEWARENAFAILED
);
856 PKIX_CERTNAMECONSTRAINTS_DEBUG
857 ("\t\tCalling CERT_FindNameConstraintsExten\n");
858 status
= CERT_FindNameConstraintsExten
859 (arena
, nssCert
, &nssNameConstraints
);
861 if (status
!= SECSuccess
) {
862 PKIX_ERROR(PKIX_DECODINGCERTNAMECONSTRAINTSFAILED
);
865 if (nssNameConstraints
== NULL
) {
866 *pNameConstraints
= NULL
;
868 PKIX_CERTNAMECONSTRAINTS_DEBUG
869 ("\t\tCalling PORT_FreeArena).\n");
870 PORT_FreeArena(arena
, PR_FALSE
);
875 PKIX_CHECK(pkix_pl_CertNameConstraints_Create_Helper
876 (nssNameConstraints
, &nameConstraints
, plContext
),
877 PKIX_CERTNAMECONSTRAINTSCREATEHELPERFAILED
);
879 nameConstraints
->arena
= arena
;
881 *pNameConstraints
= nameConstraints
;
885 if (PKIX_ERROR_RECEIVED
){
887 PKIX_CERTNAMECONSTRAINTS_DEBUG
888 ("\t\tCalling PORT_FreeArena).\n");
889 PORT_FreeArena(arena
, PR_FALSE
);
893 PKIX_RETURN(CERTNAMECONSTRAINTS
);
897 * FUNCTION: pkix_pl_CertNameConstraints_CreateByMerge
901 * This function allocates and creates a PKIX_PL_NameConstraint object
902 * for merging. It also allocates CERTNameConstraints data space for the
903 * merged NSS NameConstraints data.
907 * Address where object pointer will be stored and returned.
909 * "plContext" - Platform-specific context pointer.
912 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
915 * Returns NULL if the function succeeds.
916 * Returns a NameConstraints Error if the function fails in a non-fatal way.
917 * Returns a Fatal Error if the function fails in an unrecoverable way.
920 pkix_pl_CertNameConstraints_CreateByMerge(
921 PKIX_PL_CertNameConstraints
**pNameConstraints
,
924 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
925 CERTNameConstraints
*nssNameConstraints
= NULL
;
926 PLArenaPool
*arena
= NULL
;
928 PKIX_ENTER(CERTNAMECONSTRAINTS
,
929 "pkix_pl_CertNameConstraints_CreateByMerge");
930 PKIX_NULLCHECK_ONE(pNameConstraints
);
932 PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena).\n");
933 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
935 PKIX_ERROR(PKIX_PORTNEWARENAFAILED
);
938 PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_ArenaZNew).\n");
939 nssNameConstraints
= PORT_ArenaZNew(arena
, CERTNameConstraints
);
940 if (nssNameConstraints
== NULL
) {
941 PKIX_ERROR(PKIX_ALLOCATESPACEFORCERTNAMECONSTRAINTSFAILED
);
944 nssNameConstraints
->permited
= NULL
;
945 nssNameConstraints
->excluded
= NULL
;
946 nssNameConstraints
->DERPermited
= NULL
;
947 nssNameConstraints
->DERExcluded
= NULL
;
949 PKIX_CHECK(pkix_pl_CertNameConstraints_Create_Helper
950 (nssNameConstraints
, &nameConstraints
, plContext
),
951 PKIX_CERTNAMECONSTRAINTSCREATEHELPERFAILED
);
953 nameConstraints
->arena
= arena
;
955 *pNameConstraints
= nameConstraints
;
959 if (PKIX_ERROR_RECEIVED
){
961 PKIX_CERTNAMECONSTRAINTS_DEBUG
962 ("\t\tCalling PORT_FreeArena).\n");
963 PORT_FreeArena(arena
, PR_FALSE
);
967 PKIX_RETURN(CERTNAMECONSTRAINTS
);
971 * FUNCTION: pkix_pl_CertNameConstraints_CopyNssNameConstraints
975 * This function allocates and copies data to a NSS CERTNameConstraints from
976 * the NameConstraints given by "srcNC" and stores the result at "pDestNC". It
977 * copies items on both the permitted and excluded lists, but not the
978 * DERPermited and DERExcluded.
982 * Memory pool where object data is allocated from. Must be non-NULL.
984 * Address of the NameConstraints to copy from. Must be non-NULL.
986 * Address where new copied object is stored and returned.
988 * "plContext" - Platform-specific context pointer.
991 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
994 * Returns NULL if the function succeeds.
995 * Returns a NameConstraints Error if the function fails in a non-fatal way.
996 * Returns a Fatal Error if the function fails in an unrecoverable way.
999 pkix_pl_CertNameConstraints_CopyNssNameConstraints(
1001 CERTNameConstraints
*srcNC
,
1002 CERTNameConstraints
**pDestNC
,
1005 CERTNameConstraints
*nssNameConstraints
= NULL
;
1006 CERTNameConstraint
*nssNameConstraintHead
= NULL
;
1007 CERTNameConstraint
*nssCurrent
= NULL
;
1008 CERTNameConstraint
*nssCopyTo
= NULL
;
1009 CERTNameConstraint
*nssCopyFrom
= NULL
;
1011 PKIX_ENTER(CERTNAMECONSTRAINTS
,
1012 "pkix_pl_CertNameConstraints_CopyNssNameConstraints");
1013 PKIX_NULLCHECK_THREE(arena
, srcNC
, pDestNC
);
1015 PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_ArenaZNew).\n");
1016 nssNameConstraints
= PORT_ArenaZNew(arena
, CERTNameConstraints
);
1017 if (nssNameConstraints
== NULL
) {
1018 PKIX_ERROR(PKIX_ALLOCATESPACEFORCERTNAMECONSTRAINTSFAILED
);
1021 if (srcNC
->permited
) {
1023 nssCopyFrom
= srcNC
->permited
;
1028 PKIX_CERTNAMECONSTRAINTS_DEBUG
1029 ("\t\tCalling CERT_CopyNameConstraint).\n");
1030 nssCopyTo
= CERT_CopyNameConstraint
1031 (arena
, nssCopyTo
, nssCopyFrom
);
1032 if (nssCopyTo
== NULL
) {
1033 PKIX_ERROR(PKIX_CERTCOPYNAMECONSTRAINTFAILED
);
1035 if (nssCurrent
== NULL
) {
1036 nssCurrent
= nssNameConstraintHead
= nssCopyTo
;
1038 PKIX_CERTNAMECONSTRAINTS_DEBUG
1039 ("\t\tCalling CERT_AddNameConstraint).\n");
1040 nssCurrent
= CERT_AddNameConstraint
1041 (nssCurrent
, nssCopyTo
);
1044 PKIX_CERTNAMECONSTRAINTS_DEBUG
1045 ("\t\tCalling CERT_GetNextNameConstrain).\n");
1046 nssCopyFrom
= CERT_GetNextNameConstraint(nssCopyFrom
);
1048 } while (nssCopyFrom
!= srcNC
->permited
);
1050 nssNameConstraints
->permited
= nssNameConstraintHead
;
1053 if (srcNC
->excluded
) {
1056 nssCopyFrom
= srcNC
->excluded
;
1061 * Cannot use CERT_DupGeneralNameList, which just increments
1062 * refcount. We need our own copy since arena is for each
1063 * PKIX_PL_NameConstraints. Perhaps contribute this code
1064 * as CERT_CopyGeneralNameList (in the future).
1067 PKIX_CERTNAMECONSTRAINTS_DEBUG
1068 ("\t\tCalling CERT_CopyNameConstraint).\n");
1069 nssCopyTo
= CERT_CopyNameConstraint
1070 (arena
, nssCopyTo
, nssCopyFrom
);
1071 if (nssCopyTo
== NULL
) {
1072 PKIX_ERROR(PKIX_CERTCOPYNAMECONSTRAINTFAILED
);
1074 if (nssCurrent
== NULL
) {
1075 nssCurrent
= nssNameConstraintHead
= nssCopyTo
;
1077 PKIX_CERTNAMECONSTRAINTS_DEBUG
1078 ("\t\tCalling CERT_AddNameConstraint).\n");
1079 nssCurrent
= CERT_AddNameConstraint
1080 (nssCurrent
, nssCopyTo
);
1083 PKIX_CERTNAMECONSTRAINTS_DEBUG
1084 ("\t\tCalling CERT_GetNextNameConstrain).\n");
1085 nssCopyFrom
= CERT_GetNextNameConstraint(nssCopyFrom
);
1087 } while (nssCopyFrom
!= srcNC
->excluded
);
1089 nssNameConstraints
->excluded
= nssNameConstraintHead
;
1092 *pDestNC
= nssNameConstraints
;
1096 PKIX_RETURN(CERTNAMECONSTRAINTS
);
1100 * FUNCTION: pkix_pl_CertNameConstraints_Merge
1104 * This function merges two NameConstraints pointed to by "firstNC" and
1105 * "secondNC" and stores the result in "pMergedNC".
1109 * Address of the first NameConstraints to be merged. Must be non-NULL.
1111 * Address of the second NameConstraints to be merged. Must be non-NULL.
1113 * Address where the merge result is stored and returned. Must be non-NULL.
1114 * "plContext" - Platform-specific context pointer.
1117 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1120 * Returns NULL if the function succeeds.
1121 * Returns a NameConstraints Error if the function fails in a non-fatal way.
1122 * Returns a Fatal Error if the function fails in an unrecoverable way.
1125 pkix_pl_CertNameConstraints_Merge(
1126 PKIX_PL_CertNameConstraints
*firstNC
,
1127 PKIX_PL_CertNameConstraints
*secondNC
,
1128 PKIX_PL_CertNameConstraints
**pMergedNC
,
1131 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
1132 CERTNameConstraints
**nssNCto
= NULL
;
1133 CERTNameConstraints
**nssNCfrom
= NULL
;
1134 CERTNameConstraints
*nssNameConstraints
= NULL
;
1135 PKIX_UInt32 numNssItems
= 0;
1138 PKIX_ENTER(CERTNAMECONSTRAINTS
, "pkix_pl_CertNameConstraints_Merge");
1139 PKIX_NULLCHECK_THREE(firstNC
, secondNC
, pMergedNC
);
1141 PKIX_CHECK(pkix_pl_CertNameConstraints_CreateByMerge
1142 (&nameConstraints
, plContext
),
1143 PKIX_CERTNAMECONSTRAINTSCREATEBYMERGEFAILED
);
1145 /* Merge NSSCertConstraint lists */
1147 numNssItems
= firstNC
->numNssNameConstraints
+
1148 secondNC
->numNssNameConstraints
;
1150 /* Free the default space (only one entry) allocated by create */
1151 PKIX_CHECK(PKIX_PL_Free
1152 (nameConstraints
->nssNameConstraintsList
, plContext
),
1155 /* Reallocate the size we need */
1156 PKIX_CHECK(PKIX_PL_Malloc
1157 (numNssItems
* sizeof (CERTNameConstraint
*),
1162 nameConstraints
->nssNameConstraintsList
= nssNCto
;
1164 nssNCfrom
= firstNC
->nssNameConstraintsList
;
1166 for (i
= 0; i
< firstNC
->numNssNameConstraints
; i
++) {
1168 PKIX_CHECK(pkix_pl_CertNameConstraints_CopyNssNameConstraints
1169 (nameConstraints
->arena
,
1171 &nssNameConstraints
,
1173 PKIX_CERTNAMECONSTRAINTSCOPYNSSNAMECONSTRAINTSFAILED
);
1175 *nssNCto
= nssNameConstraints
;
1181 nssNCfrom
= secondNC
->nssNameConstraintsList
;
1183 for (i
= 0; i
< secondNC
->numNssNameConstraints
; i
++) {
1185 PKIX_CHECK(pkix_pl_CertNameConstraints_CopyNssNameConstraints
1186 (nameConstraints
->arena
,
1188 &nssNameConstraints
,
1190 PKIX_CERTNAMECONSTRAINTSCOPYNSSNAMECONSTRAINTSFAILED
);
1192 *nssNCto
= nssNameConstraints
;
1198 nameConstraints
->numNssNameConstraints
= numNssItems
;
1199 nameConstraints
->permittedList
= NULL
;
1200 nameConstraints
->excludedList
= NULL
;
1202 *pMergedNC
= nameConstraints
;
1206 if (PKIX_ERROR_RECEIVED
){
1207 PKIX_DECREF(nameConstraints
);
1210 PKIX_RETURN(CERTNAMECONSTRAINTS
);
1213 /* --Public-NameConstraints-Functions-------------------------------- */
1216 * FUNCTION: PKIX_PL_CertNameConstraints_CheckNamesInNameSpace
1217 * (see comments in pkix_pl_system.h)
1220 PKIX_PL_CertNameConstraints_CheckNamesInNameSpace(
1221 PKIX_List
*nameList
, /* List of PKIX_PL_GeneralName */
1222 PKIX_PL_CertNameConstraints
*nameConstraints
,
1223 PKIX_Boolean
*pCheckPass
,
1226 CERTNameConstraints
**nssNameConstraintsList
= NULL
;
1227 CERTNameConstraints
*nssNameConstraints
= NULL
;
1228 CERTGeneralName
*nssMatchName
= NULL
;
1229 PRArenaPool
*arena
= NULL
;
1230 PKIX_PL_GeneralName
*name
= NULL
;
1231 PKIX_UInt32 numNameItems
= 0;
1232 PKIX_UInt32 numNCItems
= 0;
1234 SECStatus status
= SECSuccess
;
1236 PKIX_ENTER(CERTNAMECONSTRAINTS
,
1237 "PKIX_PL_CertNameConstraints_CheckNamesInNameSpace");
1238 PKIX_NULLCHECK_TWO(nameConstraints
, pCheckPass
);
1240 *pCheckPass
= PKIX_TRUE
;
1242 if (nameList
!= NULL
) {
1244 PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena\n");
1245 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
1246 if (arena
== NULL
) {
1247 PKIX_ERROR(PKIX_PORTNEWARENAFAILED
);
1250 nssNameConstraintsList
=
1251 nameConstraints
->nssNameConstraintsList
;
1252 PKIX_NULLCHECK_ONE(nssNameConstraintsList
);
1253 numNCItems
= nameConstraints
->numNssNameConstraints
;
1255 PKIX_CHECK(PKIX_List_GetLength
1256 (nameList
, &numNameItems
, plContext
),
1257 PKIX_LISTGETLENGTHFAILED
);
1259 for (i
= 0; i
< numNameItems
; i
++) {
1261 PKIX_CHECK(PKIX_List_GetItem
1264 (PKIX_PL_Object
**) &name
,
1266 PKIX_LISTGETITEMFAILED
);
1268 PKIX_CHECK(pkix_pl_GeneralName_GetNssGeneralName
1269 (name
, &nssMatchName
, plContext
),
1270 PKIX_GENERALNAMEGETNSSGENERALNAMEFAILED
);
1274 for (j
= 0; j
< numNCItems
; j
++) {
1276 nssNameConstraints
= *(nssNameConstraintsList
+ j
);
1277 PKIX_NULLCHECK_ONE(nssNameConstraints
);
1279 PKIX_CERTNAMECONSTRAINTS_DEBUG
1280 ("\t\tCalling CERT_CheckNameSpace\n");
1281 status
= CERT_CheckNameSpace
1282 (arena
, nssNameConstraints
, nssMatchName
);
1283 if (status
!= SECSuccess
) {
1289 if (status
!= SECSuccess
) {
1296 if (status
== SECFailure
) {
1297 *pCheckPass
= PKIX_FALSE
;
1303 PKIX_CERTNAMECONSTRAINTS_DEBUG
1304 ("\t\tCalling PORT_FreeArena).\n");
1305 PORT_FreeArena(arena
, PR_FALSE
);
1308 PKIX_RETURN(CERTNAMECONSTRAINTS
);