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 ***** */
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_OUTOFMEMORY
);
331 nssMatchName
= nssSubjectNames
;
332 nssNameConstraintsList
= nameConstraints
->nssNameConstraintsList
;
335 * CERTNameConstraint items in each permitted or excluded list
336 * is verified as OR condition. That means, if one item matched,
337 * then the checking on the remaining items on the list is skipped.
338 * (see NSS cert_CompareNameWithConstraints(...)).
339 * Items on PKIX_PL_NameConstraint's nssNameConstraints are verified
340 * as AND condition. PKIX_PL_NameConstraint keeps an array of pointers
341 * of CERTNameConstraints resulting from merging multiple
342 * PKIX_PL_NameConstraints. Since each CERTNameConstraint are created
343 * for different entity, a union condition of these entities then is
349 numItems
= nameConstraints
->numNssNameConstraints
;
351 for (i
= 0; i
< numItems
; i
++) {
353 PKIX_NULLCHECK_ONE(nssNameConstraintsList
);
354 nssNameConstraints
= *(nssNameConstraintsList
+ i
);
355 PKIX_NULLCHECK_ONE(nssNameConstraints
);
357 PKIX_CERTNAMECONSTRAINTS_DEBUG
358 ("\t\tCalling CERT_CheckNameSpace\n");
359 status
= CERT_CheckNameSpace
360 (arena
, nssNameConstraints
, nssMatchName
);
361 if (status
!= SECSuccess
) {
367 if (status
!= SECSuccess
) {
371 PKIX_CERTNAMECONSTRAINTS_DEBUG
372 ("\t\tCalling CERT_GetNextGeneralName\n");
373 nssMatchName
= CERT_GetNextGeneralName(nssMatchName
);
375 } while (nssMatchName
!= nssSubjectNames
);
377 if (status
== SECFailure
) {
379 *pCheckPass
= PKIX_FALSE
;
385 PKIX_CERTNAMECONSTRAINTS_DEBUG
386 ("\t\tCalling PORT_FreeArena).\n");
387 PORT_FreeArena(arena
, PR_FALSE
);
390 PKIX_RETURN(CERTNAMECONSTRAINTS
);
394 * FUNCTION: pkix_pl_NameConstraints_Destroy
395 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
398 pkix_pl_CertNameConstraints_Destroy(
399 PKIX_PL_Object
*object
,
402 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
404 PKIX_ENTER(CERTNAMECONSTRAINTS
, "pkix_pl_CertNameConstraints_Destroy");
405 PKIX_NULLCHECK_ONE(object
);
407 PKIX_CHECK(pkix_CheckType
408 (object
, PKIX_CERTNAMECONSTRAINTS_TYPE
, plContext
),
409 PKIX_OBJECTNOTCERTNAMECONSTRAINTS
);
411 nameConstraints
= (PKIX_PL_CertNameConstraints
*)object
;
413 PKIX_CHECK(PKIX_PL_Free
414 (nameConstraints
->nssNameConstraintsList
, plContext
),
417 if (nameConstraints
->arena
){
418 PKIX_CERTNAMECONSTRAINTS_DEBUG
419 ("\t\tCalling PORT_FreeArena).\n");
420 PORT_FreeArena(nameConstraints
->arena
, PR_FALSE
);
421 nameConstraints
->arena
= NULL
;
424 PKIX_DECREF(nameConstraints
->permittedList
);
425 PKIX_DECREF(nameConstraints
->excludedList
);
429 PKIX_RETURN(CERTNAMECONSTRAINTS
);
433 * FUNCTION: pkix_pl_CertNameConstraints_ToString_Helper
436 * Helper function that creates a string representation of the object
437 * NameConstraints and stores it at "pString".
441 * Address of CertNameConstraints whose string representation is
442 * desired. Must be non-NULL.
444 * Address where string object pointer will be stored. Must be non-NULL.
445 * "plContext" - Platform-specific context pointer.
447 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
449 * Returns NULL if the function succeeds.
450 * Returns a NameConstraints Error if the function fails in a
452 * Returns a Fatal Error if the function fails in an unrecoverable way.
455 pkix_pl_CertNameConstraints_ToString_Helper(
456 PKIX_PL_CertNameConstraints
*nameConstraints
,
457 PKIX_PL_String
**pString
,
460 char *asciiFormat
= NULL
;
461 PKIX_PL_String
*formatString
= NULL
;
462 PKIX_List
*permittedList
= NULL
;
463 PKIX_List
*excludedList
= NULL
;
464 PKIX_PL_String
*permittedListString
= NULL
;
465 PKIX_PL_String
*excludedListString
= NULL
;
466 PKIX_PL_String
*nameConstraintsString
= NULL
;
468 PKIX_ENTER(CERTNAMECONSTRAINTS
,
469 "pkix_pl_CertNameConstraints_ToString_Helper");
470 PKIX_NULLCHECK_TWO(nameConstraints
, pString
);
474 "\t\tPermitted Name: %s\n"
475 "\t\tExcluded Name: %s\n"
478 PKIX_CHECK(PKIX_PL_String_Create
484 PKIX_STRINGCREATEFAILED
);
486 PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
487 (nameConstraints
, &permittedList
, plContext
),
488 PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED
);
490 PKIX_TOSTRING(permittedList
, &permittedListString
, plContext
,
491 PKIX_LISTTOSTRINGFAILED
);
493 PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
494 (nameConstraints
, &excludedList
, plContext
),
495 PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED
);
497 PKIX_TOSTRING(excludedList
, &excludedListString
, plContext
,
498 PKIX_LISTTOSTRINGFAILED
);
500 PKIX_CHECK(PKIX_PL_Sprintf
501 (&nameConstraintsString
,
508 *pString
= nameConstraintsString
;
512 PKIX_DECREF(formatString
);
513 PKIX_DECREF(permittedList
);
514 PKIX_DECREF(excludedList
);
515 PKIX_DECREF(permittedListString
);
516 PKIX_DECREF(excludedListString
);
518 PKIX_RETURN(CERTNAMECONSTRAINTS
);
522 * FUNCTION: pkix_pl_CertNameConstraints_ToString
523 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
526 pkix_pl_CertNameConstraints_ToString(
527 PKIX_PL_Object
*object
,
528 PKIX_PL_String
**pString
,
531 PKIX_PL_String
*nameConstraintsString
= NULL
;
532 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
534 PKIX_ENTER(CERTNAMECONSTRAINTS
, "pkix_pl_CertNameConstraints_ToString");
535 PKIX_NULLCHECK_TWO(object
, pString
);
537 PKIX_CHECK(pkix_CheckType(
538 object
, PKIX_CERTNAMECONSTRAINTS_TYPE
, plContext
),
539 PKIX_OBJECTNOTCERTNAMECONSTRAINTS
);
541 nameConstraints
= (PKIX_PL_CertNameConstraints
*)object
;
543 PKIX_CHECK(pkix_pl_CertNameConstraints_ToString_Helper
544 (nameConstraints
, &nameConstraintsString
, plContext
),
545 PKIX_CERTNAMECONSTRAINTSTOSTRINGHELPERFAILED
);
547 *pString
= nameConstraintsString
;
551 PKIX_RETURN(CERTNAMECONSTRAINTS
);
555 * FUNCTION: pkix_pl_CertNameConstraints_Hashcode
556 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
559 pkix_pl_CertNameConstraints_Hashcode(
560 PKIX_PL_Object
*object
,
561 PKIX_UInt32
*pHashcode
,
564 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
565 PKIX_List
*permittedList
= NULL
;
566 PKIX_List
*excludedList
= NULL
;
567 PKIX_UInt32 permitHash
= 0;
568 PKIX_UInt32 excludeHash
= 0;
570 PKIX_ENTER(CERTNAMECONSTRAINTS
, "pkix_pl_CertNameConstraints_Hashcode");
571 PKIX_NULLCHECK_TWO(object
, pHashcode
);
573 PKIX_CHECK(pkix_CheckType
574 (object
, PKIX_CERTNAMECONSTRAINTS_TYPE
, plContext
),
575 PKIX_OBJECTNOTCERTNAMECONSTRAINTS
);
577 nameConstraints
= (PKIX_PL_CertNameConstraints
*)object
;
579 PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
580 (nameConstraints
, &permittedList
, plContext
),
581 PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED
);
583 PKIX_HASHCODE(permittedList
, &permitHash
, plContext
,
584 PKIX_OBJECTHASHCODEFAILED
);
586 PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
587 (nameConstraints
, &excludedList
, plContext
),
588 PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED
);
590 PKIX_HASHCODE(excludedList
, &excludeHash
, plContext
,
591 PKIX_OBJECTHASHCODEFAILED
);
593 *pHashcode
= (((permitHash
<< 7) + excludeHash
) << 7) +
594 nameConstraints
->numNssNameConstraints
;
598 PKIX_DECREF(permittedList
);
599 PKIX_DECREF(excludedList
);
600 PKIX_RETURN(CERTNAMECONSTRAINTS
);
604 * FUNCTION: pkix_pl_CertNameConstraints_Equals
605 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
608 pkix_pl_CertNameConstraints_Equals(
609 PKIX_PL_Object
*firstObject
,
610 PKIX_PL_Object
*secondObject
,
611 PKIX_Boolean
*pResult
,
614 PKIX_PL_CertNameConstraints
*firstNC
= NULL
;
615 PKIX_PL_CertNameConstraints
*secondNC
= NULL
;
616 PKIX_List
*firstPermittedList
= NULL
;
617 PKIX_List
*secondPermittedList
= NULL
;
618 PKIX_List
*firstExcludedList
= NULL
;
619 PKIX_List
*secondExcludedList
= NULL
;
620 PKIX_UInt32 secondType
;
621 PKIX_Boolean cmpResult
= PKIX_FALSE
;
623 PKIX_ENTER(CERTNAMECONSTRAINTS
, "pkix_pl_CertNameConstraints_Equals");
624 PKIX_NULLCHECK_THREE(firstObject
, secondObject
, pResult
);
626 /* test that firstObject is a CertNameConstraints */
627 PKIX_CHECK(pkix_CheckType
628 (firstObject
, PKIX_CERTNAMECONSTRAINTS_TYPE
, plContext
),
629 PKIX_FIRSTOBJECTNOTCERTNAMECONSTRAINTS
);
631 firstNC
= (PKIX_PL_CertNameConstraints
*)firstObject
;
632 secondNC
= (PKIX_PL_CertNameConstraints
*)secondObject
;
635 * Since we know firstObject is a CertNameConstraints, if both
636 * references are identical, they must be equal
638 if (firstNC
== secondNC
){
639 *pResult
= PKIX_TRUE
;
644 * If secondNC isn't a CertNameConstraints, we don't throw an error.
645 * We simply return a Boolean result of FALSE
647 *pResult
= PKIX_FALSE
;
649 PKIX_CHECK(PKIX_PL_Object_GetType
650 ((PKIX_PL_Object
*)secondNC
, &secondType
, plContext
),
651 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT
);
653 if (secondType
!= PKIX_CERTNAMECONSTRAINTS_TYPE
) {
657 PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
658 (firstNC
, &firstPermittedList
, plContext
),
659 PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED
);
661 PKIX_CHECK(pkix_pl_CertNameConstraints_GetPermitted
662 (secondNC
, &secondPermittedList
, plContext
),
663 PKIX_CERTNAMECONSTRAINTSGETPERMITTEDFAILED
);
666 (firstPermittedList
, secondPermittedList
, &cmpResult
, plContext
,
667 PKIX_OBJECTEQUALSFAILED
);
669 if (cmpResult
!= PKIX_TRUE
) {
673 PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
674 (firstNC
, &firstExcludedList
, plContext
),
675 PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED
);
677 PKIX_CHECK(pkix_pl_CertNameConstraints_GetExcluded
678 (secondNC
, &secondExcludedList
, plContext
),
679 PKIX_CERTNAMECONSTRAINTSGETEXCLUDEDFAILED
);
682 (firstExcludedList
, secondExcludedList
, &cmpResult
, plContext
,
683 PKIX_OBJECTEQUALSFAILED
);
685 if (cmpResult
!= PKIX_TRUE
) {
690 * numNssNameConstraints is not checked because it is basically a
691 * merge count, it cannot determine the data equality.
694 *pResult
= PKIX_TRUE
;
698 PKIX_DECREF(firstPermittedList
);
699 PKIX_DECREF(secondPermittedList
);
700 PKIX_DECREF(firstExcludedList
);
701 PKIX_DECREF(secondExcludedList
);
703 PKIX_RETURN(CERTNAMECONSTRAINTS
);
707 * FUNCTION: pkix_pl_CertNameConstraints_RegisterSelf
709 * Registers PKIX_CERTNAMECONSTRAINTS_TYPE and its related functions with
712 * Not Thread Safe - for performance and complexity reasons
714 * Since this function is only called by PKIX_PL_Initialize, which should
715 * only be called once, it is acceptable that this function is not
719 pkix_pl_CertNameConstraints_RegisterSelf(void *plContext
)
721 extern pkix_ClassTable_Entry systemClasses
[PKIX_NUMTYPES
];
722 pkix_ClassTable_Entry entry
;
724 PKIX_ENTER(CERTNAMECONSTRAINTS
,
725 "pkix_pl_CertNameConstraints_RegisterSelf");
727 entry
.description
= "CertNameConstraints";
728 entry
.objCounter
= 0;
729 entry
.typeObjectSize
= sizeof(PKIX_PL_CertNameConstraints
);
730 entry
.destructor
= pkix_pl_CertNameConstraints_Destroy
;
731 entry
.equalsFunction
= pkix_pl_CertNameConstraints_Equals
;
732 entry
.hashcodeFunction
= pkix_pl_CertNameConstraints_Hashcode
;
733 entry
.toStringFunction
= pkix_pl_CertNameConstraints_ToString
;
734 entry
.comparator
= NULL
;
735 entry
.duplicateFunction
= pkix_duplicateImmutable
;
737 systemClasses
[PKIX_CERTNAMECONSTRAINTS_TYPE
] = entry
;
739 PKIX_RETURN(CERTNAMECONSTRAINTS
);
743 * FUNCTION: pkix_pl_CertNameConstraints_Create_Helper
746 * This function retrieves name constraints in "nssNameConstraints",
747 * converts and stores the result in a PKIX_PL_CertNameConstraints object.
750 * "nssNameConstraints"
751 * Address of CERTNameConstraints that contains this object's data.
754 * Address where object pointer will be stored. Must be non-NULL.
755 * A NULL value will be returned if there is no Name Constraints extension.
756 * "plContext" - Platform-specific context pointer.
759 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
762 * Returns NULL if the function succeeds.
763 * Returns a NameConstraints Error if the function fails in a non-fatal way.
764 * Returns a Fatal Error if the function fails in an unrecoverable way.
767 pkix_pl_CertNameConstraints_Create_Helper(
768 CERTNameConstraints
*nssNameConstraints
,
769 PKIX_PL_CertNameConstraints
**pNameConstraints
,
772 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
773 CERTNameConstraints
**nssNameConstraintPtr
= NULL
;
775 PKIX_ENTER(CERTNAMECONSTRAINTS
,
776 "pkix_pl_CertNameConstraints_Create_Helper");
777 PKIX_NULLCHECK_TWO(nssNameConstraints
, pNameConstraints
);
779 PKIX_CHECK(PKIX_PL_Object_Alloc
780 (PKIX_CERTNAMECONSTRAINTS_TYPE
,
781 sizeof (PKIX_PL_CertNameConstraints
),
782 (PKIX_PL_Object
**)&nameConstraints
,
784 PKIX_COULDNOTCREATECERTNAMECONSTRAINTSOBJECT
);
786 PKIX_CHECK(PKIX_PL_Malloc
787 (sizeof (CERTNameConstraint
*),
788 (void *)&nssNameConstraintPtr
,
792 nameConstraints
->numNssNameConstraints
= 1;
793 nameConstraints
->nssNameConstraintsList
= nssNameConstraintPtr
;
794 *nssNameConstraintPtr
= nssNameConstraints
;
796 nameConstraints
->permittedList
= NULL
;
797 nameConstraints
->excludedList
= NULL
;
798 nameConstraints
->arena
= NULL
;
800 *pNameConstraints
= nameConstraints
;
804 if (PKIX_ERROR_RECEIVED
){
805 PKIX_DECREF(nameConstraints
);
808 PKIX_RETURN(CERTNAMECONSTRAINTS
);
812 * FUNCTION: pkix_pl_CertNameConstraints_Create
815 * function that allocates and initialize the object CertNameConstraints.
819 * Address of CERT that contains this object's data.
822 * Address where object pointer will be stored. Must be non-NULL.
823 * A NULL value will be returned if there is no Name Constraints extension.
824 * "plContext" - Platform-specific context pointer.
827 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
830 * Returns NULL if the function succeeds.
831 * Returns a NameConstraints Error if the function fails in a non-fatal way.
832 * Returns a Fatal Error if the function fails in an unrecoverable way.
835 pkix_pl_CertNameConstraints_Create(
836 CERTCertificate
*nssCert
,
837 PKIX_PL_CertNameConstraints
**pNameConstraints
,
840 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
841 CERTNameConstraints
*nssNameConstraints
= NULL
;
842 PLArenaPool
*arena
= NULL
;
845 PKIX_ENTER(CERTNAMECONSTRAINTS
, "pkix_pl_CertNameConstraints_Create");
846 PKIX_NULLCHECK_THREE(nssCert
, pNameConstraints
, nssCert
->arena
);
848 PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena).\n");
849 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
851 PKIX_ERROR(PKIX_OUTOFMEMORY
);
854 PKIX_CERTNAMECONSTRAINTS_DEBUG
855 ("\t\tCalling CERT_FindNameConstraintsExten\n");
856 status
= CERT_FindNameConstraintsExten
857 (arena
, nssCert
, &nssNameConstraints
);
859 if (status
!= SECSuccess
) {
860 PKIX_ERROR(PKIX_DECODINGCERTNAMECONSTRAINTSFAILED
);
863 if (nssNameConstraints
== NULL
) {
864 *pNameConstraints
= NULL
;
866 PKIX_CERTNAMECONSTRAINTS_DEBUG
867 ("\t\tCalling PORT_FreeArena).\n");
868 PORT_FreeArena(arena
, PR_FALSE
);
873 PKIX_CHECK(pkix_pl_CertNameConstraints_Create_Helper
874 (nssNameConstraints
, &nameConstraints
, plContext
),
875 PKIX_CERTNAMECONSTRAINTSCREATEHELPERFAILED
);
877 nameConstraints
->arena
= arena
;
879 *pNameConstraints
= nameConstraints
;
883 if (PKIX_ERROR_RECEIVED
){
885 PKIX_CERTNAMECONSTRAINTS_DEBUG
886 ("\t\tCalling PORT_FreeArena).\n");
887 PORT_FreeArena(arena
, PR_FALSE
);
891 PKIX_RETURN(CERTNAMECONSTRAINTS
);
895 * FUNCTION: pkix_pl_CertNameConstraints_CreateByMerge
899 * This function allocates and creates a PKIX_PL_NameConstraint object
900 * for merging. It also allocates CERTNameConstraints data space for the
901 * merged NSS NameConstraints data.
905 * Address where object pointer will be stored and returned.
907 * "plContext" - Platform-specific context pointer.
910 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
913 * Returns NULL if the function succeeds.
914 * Returns a NameConstraints Error if the function fails in a non-fatal way.
915 * Returns a Fatal Error if the function fails in an unrecoverable way.
918 pkix_pl_CertNameConstraints_CreateByMerge(
919 PKIX_PL_CertNameConstraints
**pNameConstraints
,
922 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
923 CERTNameConstraints
*nssNameConstraints
= NULL
;
924 PLArenaPool
*arena
= NULL
;
926 PKIX_ENTER(CERTNAMECONSTRAINTS
,
927 "pkix_pl_CertNameConstraints_CreateByMerge");
928 PKIX_NULLCHECK_ONE(pNameConstraints
);
930 PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena).\n");
931 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
933 PKIX_ERROR(PKIX_OUTOFMEMORY
);
936 PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_ArenaZNew).\n");
937 nssNameConstraints
= PORT_ArenaZNew(arena
, CERTNameConstraints
);
938 if (nssNameConstraints
== NULL
) {
939 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED
);
942 nssNameConstraints
->permited
= NULL
;
943 nssNameConstraints
->excluded
= NULL
;
944 nssNameConstraints
->DERPermited
= NULL
;
945 nssNameConstraints
->DERExcluded
= NULL
;
947 PKIX_CHECK(pkix_pl_CertNameConstraints_Create_Helper
948 (nssNameConstraints
, &nameConstraints
, plContext
),
949 PKIX_CERTNAMECONSTRAINTSCREATEHELPERFAILED
);
951 nameConstraints
->arena
= arena
;
953 *pNameConstraints
= nameConstraints
;
957 if (PKIX_ERROR_RECEIVED
){
959 PKIX_CERTNAMECONSTRAINTS_DEBUG
960 ("\t\tCalling PORT_FreeArena).\n");
961 PORT_FreeArena(arena
, PR_FALSE
);
965 PKIX_RETURN(CERTNAMECONSTRAINTS
);
969 * FUNCTION: pkix_pl_CertNameConstraints_CopyNssNameConstraints
973 * This function allocates and copies data to a NSS CERTNameConstraints from
974 * the NameConstraints given by "srcNC" and stores the result at "pDestNC". It
975 * copies items on both the permitted and excluded lists, but not the
976 * DERPermited and DERExcluded.
980 * Memory pool where object data is allocated from. Must be non-NULL.
982 * Address of the NameConstraints to copy from. Must be non-NULL.
984 * Address where new copied object is stored and returned.
986 * "plContext" - Platform-specific context pointer.
989 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
992 * Returns NULL if the function succeeds.
993 * Returns a NameConstraints Error if the function fails in a non-fatal way.
994 * Returns a Fatal Error if the function fails in an unrecoverable way.
997 pkix_pl_CertNameConstraints_CopyNssNameConstraints(
999 CERTNameConstraints
*srcNC
,
1000 CERTNameConstraints
**pDestNC
,
1003 CERTNameConstraints
*nssNameConstraints
= NULL
;
1004 CERTNameConstraint
*nssNameConstraintHead
= NULL
;
1005 CERTNameConstraint
*nssCurrent
= NULL
;
1006 CERTNameConstraint
*nssCopyTo
= NULL
;
1007 CERTNameConstraint
*nssCopyFrom
= NULL
;
1009 PKIX_ENTER(CERTNAMECONSTRAINTS
,
1010 "pkix_pl_CertNameConstraints_CopyNssNameConstraints");
1011 PKIX_NULLCHECK_THREE(arena
, srcNC
, pDestNC
);
1013 PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_ArenaZNew).\n");
1014 nssNameConstraints
= PORT_ArenaZNew(arena
, CERTNameConstraints
);
1015 if (nssNameConstraints
== NULL
) {
1016 PKIX_ERROR(PKIX_PORTARENAALLOCFAILED
);
1019 if (srcNC
->permited
) {
1021 nssCopyFrom
= srcNC
->permited
;
1026 PKIX_CERTNAMECONSTRAINTS_DEBUG
1027 ("\t\tCalling CERT_CopyNameConstraint).\n");
1028 nssCopyTo
= CERT_CopyNameConstraint
1029 (arena
, nssCopyTo
, nssCopyFrom
);
1030 if (nssCopyTo
== NULL
) {
1031 PKIX_ERROR(PKIX_CERTCOPYNAMECONSTRAINTFAILED
);
1033 if (nssCurrent
== NULL
) {
1034 nssCurrent
= nssNameConstraintHead
= nssCopyTo
;
1036 PKIX_CERTNAMECONSTRAINTS_DEBUG
1037 ("\t\tCalling CERT_AddNameConstraint).\n");
1038 nssCurrent
= CERT_AddNameConstraint
1039 (nssCurrent
, nssCopyTo
);
1042 PKIX_CERTNAMECONSTRAINTS_DEBUG
1043 ("\t\tCalling CERT_GetNextNameConstrain).\n");
1044 nssCopyFrom
= CERT_GetNextNameConstraint(nssCopyFrom
);
1046 } while (nssCopyFrom
!= srcNC
->permited
);
1048 nssNameConstraints
->permited
= nssNameConstraintHead
;
1051 if (srcNC
->excluded
) {
1054 nssCopyFrom
= srcNC
->excluded
;
1059 * Cannot use CERT_DupGeneralNameList, which just increments
1060 * refcount. We need our own copy since arena is for each
1061 * PKIX_PL_NameConstraints. Perhaps contribute this code
1062 * as CERT_CopyGeneralNameList (in the future).
1065 PKIX_CERTNAMECONSTRAINTS_DEBUG
1066 ("\t\tCalling CERT_CopyNameConstraint).\n");
1067 nssCopyTo
= CERT_CopyNameConstraint
1068 (arena
, nssCopyTo
, nssCopyFrom
);
1069 if (nssCopyTo
== NULL
) {
1070 PKIX_ERROR(PKIX_CERTCOPYNAMECONSTRAINTFAILED
);
1072 if (nssCurrent
== NULL
) {
1073 nssCurrent
= nssNameConstraintHead
= nssCopyTo
;
1075 PKIX_CERTNAMECONSTRAINTS_DEBUG
1076 ("\t\tCalling CERT_AddNameConstraint).\n");
1077 nssCurrent
= CERT_AddNameConstraint
1078 (nssCurrent
, nssCopyTo
);
1081 PKIX_CERTNAMECONSTRAINTS_DEBUG
1082 ("\t\tCalling CERT_GetNextNameConstrain).\n");
1083 nssCopyFrom
= CERT_GetNextNameConstraint(nssCopyFrom
);
1085 } while (nssCopyFrom
!= srcNC
->excluded
);
1087 nssNameConstraints
->excluded
= nssNameConstraintHead
;
1090 *pDestNC
= nssNameConstraints
;
1094 PKIX_RETURN(CERTNAMECONSTRAINTS
);
1098 * FUNCTION: pkix_pl_CertNameConstraints_Merge
1102 * This function merges two NameConstraints pointed to by "firstNC" and
1103 * "secondNC" and stores the result in "pMergedNC".
1107 * Address of the first NameConstraints to be merged. Must be non-NULL.
1109 * Address of the second NameConstraints to be merged. Must be non-NULL.
1111 * Address where the merge result is stored and returned. Must be non-NULL.
1112 * "plContext" - Platform-specific context pointer.
1115 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
1118 * Returns NULL if the function succeeds.
1119 * Returns a NameConstraints Error if the function fails in a non-fatal way.
1120 * Returns a Fatal Error if the function fails in an unrecoverable way.
1123 pkix_pl_CertNameConstraints_Merge(
1124 PKIX_PL_CertNameConstraints
*firstNC
,
1125 PKIX_PL_CertNameConstraints
*secondNC
,
1126 PKIX_PL_CertNameConstraints
**pMergedNC
,
1129 PKIX_PL_CertNameConstraints
*nameConstraints
= NULL
;
1130 CERTNameConstraints
**nssNCto
= NULL
;
1131 CERTNameConstraints
**nssNCfrom
= NULL
;
1132 CERTNameConstraints
*nssNameConstraints
= NULL
;
1133 PKIX_UInt32 numNssItems
= 0;
1136 PKIX_ENTER(CERTNAMECONSTRAINTS
, "pkix_pl_CertNameConstraints_Merge");
1137 PKIX_NULLCHECK_THREE(firstNC
, secondNC
, pMergedNC
);
1139 PKIX_CHECK(pkix_pl_CertNameConstraints_CreateByMerge
1140 (&nameConstraints
, plContext
),
1141 PKIX_CERTNAMECONSTRAINTSCREATEBYMERGEFAILED
);
1143 /* Merge NSSCertConstraint lists */
1145 numNssItems
= firstNC
->numNssNameConstraints
+
1146 secondNC
->numNssNameConstraints
;
1148 /* Free the default space (only one entry) allocated by create */
1149 PKIX_CHECK(PKIX_PL_Free
1150 (nameConstraints
->nssNameConstraintsList
, plContext
),
1153 /* Reallocate the size we need */
1154 PKIX_CHECK(PKIX_PL_Malloc
1155 (numNssItems
* sizeof (CERTNameConstraint
*),
1160 nameConstraints
->nssNameConstraintsList
= nssNCto
;
1162 nssNCfrom
= firstNC
->nssNameConstraintsList
;
1164 for (i
= 0; i
< firstNC
->numNssNameConstraints
; i
++) {
1166 PKIX_CHECK(pkix_pl_CertNameConstraints_CopyNssNameConstraints
1167 (nameConstraints
->arena
,
1169 &nssNameConstraints
,
1171 PKIX_CERTNAMECONSTRAINTSCOPYNSSNAMECONSTRAINTSFAILED
);
1173 *nssNCto
= nssNameConstraints
;
1179 nssNCfrom
= secondNC
->nssNameConstraintsList
;
1181 for (i
= 0; i
< secondNC
->numNssNameConstraints
; i
++) {
1183 PKIX_CHECK(pkix_pl_CertNameConstraints_CopyNssNameConstraints
1184 (nameConstraints
->arena
,
1186 &nssNameConstraints
,
1188 PKIX_CERTNAMECONSTRAINTSCOPYNSSNAMECONSTRAINTSFAILED
);
1190 *nssNCto
= nssNameConstraints
;
1196 nameConstraints
->numNssNameConstraints
= numNssItems
;
1197 nameConstraints
->permittedList
= NULL
;
1198 nameConstraints
->excludedList
= NULL
;
1200 *pMergedNC
= nameConstraints
;
1204 if (PKIX_ERROR_RECEIVED
){
1205 PKIX_DECREF(nameConstraints
);
1208 PKIX_RETURN(CERTNAMECONSTRAINTS
);
1211 /* --Public-NameConstraints-Functions-------------------------------- */
1214 * FUNCTION: PKIX_PL_CertNameConstraints_CheckNamesInNameSpace
1215 * (see comments in pkix_pl_system.h)
1218 PKIX_PL_CertNameConstraints_CheckNamesInNameSpace(
1219 PKIX_List
*nameList
, /* List of PKIX_PL_GeneralName */
1220 PKIX_PL_CertNameConstraints
*nameConstraints
,
1221 PKIX_Boolean
*pCheckPass
,
1224 CERTNameConstraints
**nssNameConstraintsList
= NULL
;
1225 CERTNameConstraints
*nssNameConstraints
= NULL
;
1226 CERTGeneralName
*nssMatchName
= NULL
;
1227 PRArenaPool
*arena
= NULL
;
1228 PKIX_PL_GeneralName
*name
= NULL
;
1229 PKIX_UInt32 numNameItems
= 0;
1230 PKIX_UInt32 numNCItems
= 0;
1232 SECStatus status
= SECSuccess
;
1234 PKIX_ENTER(CERTNAMECONSTRAINTS
,
1235 "PKIX_PL_CertNameConstraints_CheckNamesInNameSpace");
1236 PKIX_NULLCHECK_TWO(nameConstraints
, pCheckPass
);
1238 *pCheckPass
= PKIX_TRUE
;
1240 if (nameList
!= NULL
) {
1242 PKIX_CERTNAMECONSTRAINTS_DEBUG("\t\tCalling PORT_NewArena\n");
1243 arena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
1244 if (arena
== NULL
) {
1245 PKIX_ERROR(PKIX_OUTOFMEMORY
);
1248 nssNameConstraintsList
=
1249 nameConstraints
->nssNameConstraintsList
;
1250 PKIX_NULLCHECK_ONE(nssNameConstraintsList
);
1251 numNCItems
= nameConstraints
->numNssNameConstraints
;
1253 PKIX_CHECK(PKIX_List_GetLength
1254 (nameList
, &numNameItems
, plContext
),
1255 PKIX_LISTGETLENGTHFAILED
);
1257 for (i
= 0; i
< numNameItems
; i
++) {
1259 PKIX_CHECK(PKIX_List_GetItem
1262 (PKIX_PL_Object
**) &name
,
1264 PKIX_LISTGETITEMFAILED
);
1266 PKIX_CHECK(pkix_pl_GeneralName_GetNssGeneralName
1267 (name
, &nssMatchName
, plContext
),
1268 PKIX_GENERALNAMEGETNSSGENERALNAMEFAILED
);
1272 for (j
= 0; j
< numNCItems
; j
++) {
1274 nssNameConstraints
= *(nssNameConstraintsList
+ j
);
1275 PKIX_NULLCHECK_ONE(nssNameConstraints
);
1277 PKIX_CERTNAMECONSTRAINTS_DEBUG
1278 ("\t\tCalling CERT_CheckNameSpace\n");
1279 status
= CERT_CheckNameSpace
1280 (arena
, nssNameConstraints
, nssMatchName
);
1281 if (status
!= SECSuccess
) {
1287 if (status
!= SECSuccess
) {
1294 if (status
== SECFailure
) {
1295 *pCheckPass
= PKIX_FALSE
;
1301 PKIX_CERTNAMECONSTRAINTS_DEBUG
1302 ("\t\tCalling PORT_FreeArena).\n");
1303 PORT_FreeArena(arena
, PR_FALSE
);
1306 PKIX_RETURN(CERTNAMECONSTRAINTS
);