Import from 1.9a8 tarball
[mozilla-nss.git] / security / nss / lib / libpkix / pkix_pl_nss / pki / pkix_pl_basicconstraints.c
blob80ac31201298a68930e9ed0a5fc16f6c0d0e4b2e
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 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.
21 * Contributor(s):
22 * Sun Microsystems
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_basicconstraints.c
40 * BasicConstraints Object Functions
44 #include "pkix_pl_basicconstraints.h"
47 * FUNCTION: pkix_pl_CertBasicConstraints_Create
48 * DESCRIPTION:
50 * Creates a new CertBasicConstraints object whose CA Flag has the value
51 * given by the Boolean value of "isCA" and whose path length field has the
52 * value given by the "pathLen" argument and stores it at "pObject".
54 * PARAMETERS
55 * "isCA"
56 * Boolean value with the desired value of CA Flag.
57 * "pathLen"
58 * a PKIX_Int32 with the desired value of path length
59 * "pObject"
60 * Address of object pointer's destination. 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 CertBasicConstraints Error if the function fails
67 * in a non-fatal way.
68 * Returns a Fatal Error if the function fails in an unrecoverable way.
70 PKIX_Error *
71 pkix_pl_CertBasicConstraints_Create(
72 PKIX_Boolean isCA,
73 PKIX_Int32 pathLen,
74 PKIX_PL_CertBasicConstraints **pObject,
75 void *plContext)
77 PKIX_PL_CertBasicConstraints *basic = NULL;
79 PKIX_ENTER(CERTBASICCONSTRAINTS,
80 "pkix_pl_CertBasicConstraints_Create");
81 PKIX_NULLCHECK_ONE(pObject);
83 PKIX_CHECK(PKIX_PL_Object_Alloc
84 (PKIX_CERTBASICCONSTRAINTS_TYPE,
85 sizeof (PKIX_PL_CertBasicConstraints),
86 (PKIX_PL_Object **)&basic,
87 plContext),
88 PKIX_COULDNOTCREATECERTBASICCONSTRAINTSOBJECT);
90 basic->isCA = isCA;
92 /* pathLen has meaning only for CAs, but it's not worth checking */
93 basic->pathLen = pathLen;
95 *pObject = basic;
97 cleanup:
99 PKIX_RETURN(CERTBASICCONSTRAINTS);
103 * FUNCTION: pkix_pl_CertBasicConstraints_Destroy
104 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
106 static PKIX_Error *
107 pkix_pl_CertBasicConstraints_Destroy(
108 PKIX_PL_Object *object,
109 void *plContext)
111 PKIX_PL_CertBasicConstraints *certB = NULL;
113 PKIX_ENTER(CERTBASICCONSTRAINTS,
114 "pkix_pl_CertBasicConstraints_Destroy");
115 PKIX_NULLCHECK_ONE(object);
117 PKIX_CHECK(pkix_CheckType
118 (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
119 PKIX_OBJECTNOTCERTBASICCONSTRAINTS);
121 certB = (PKIX_PL_CertBasicConstraints*)object;
123 certB->isCA = PKIX_FALSE;
124 certB->pathLen = 0;
126 cleanup:
128 PKIX_RETURN(CERTBASICCONSTRAINTS);
132 * FUNCTION: pkix_pl_CertBasicConstraints_ToString
133 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
135 static PKIX_Error *
136 pkix_pl_CertBasicConstraints_ToString(
137 PKIX_PL_Object *object,
138 PKIX_PL_String **pString,
139 void *plContext)
141 PKIX_PL_String *certBasicConstraintsString = NULL;
142 PKIX_PL_CertBasicConstraints *certB = NULL;
143 PKIX_Boolean isCA = PKIX_FALSE;
144 PKIX_Int32 pathLen = 0;
145 PKIX_PL_String *outString = NULL;
146 char *fmtString = NULL;
147 PKIX_Boolean pathlenArg = PKIX_FALSE;
149 PKIX_ENTER(CERTBASICCONSTRAINTS,
150 "pkix_pl_CertBasicConstraints_toString");
151 PKIX_NULLCHECK_TWO(object, pString);
153 PKIX_CHECK(pkix_CheckType
154 (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
155 PKIX_FIRSTARGUMENTNOTCERTBASICCONSTRAINTSOBJECT);
157 certB = (PKIX_PL_CertBasicConstraints *)object;
160 * if CA == TRUE
161 * if pathLen == CERT_UNLIMITED_PATH_CONSTRAINT
162 * print "CA(-1)"
163 * else print "CA(nnn)"
164 * if CA == FALSE, print "~CA"
167 isCA = certB->isCA;
169 if (isCA) {
170 pathLen = certB->pathLen;
172 if (pathLen == CERT_UNLIMITED_PATH_CONSTRAINT) {
173 /* print "CA(-1)" */
174 fmtString = "CA(-1)";
175 pathlenArg = PKIX_FALSE;
176 } else {
177 /* print "CA(pathLen)" */
178 fmtString = "CA(%d)";
179 pathlenArg = PKIX_TRUE;
181 } else {
182 /* print "~CA" */
183 fmtString = "~CA";
184 pathlenArg = PKIX_FALSE;
187 PKIX_CHECK(PKIX_PL_String_Create
188 (PKIX_ESCASCII,
189 fmtString,
191 &certBasicConstraintsString,
192 plContext),
193 PKIX_STRINGCREATEFAILED);
195 if (pathlenArg) {
196 PKIX_CHECK(PKIX_PL_Sprintf
197 (&outString,
198 plContext,
199 certBasicConstraintsString,
200 pathLen),
201 PKIX_SPRINTFFAILED);
202 } else {
203 PKIX_CHECK(PKIX_PL_Sprintf
204 (&outString,
205 plContext,
206 certBasicConstraintsString),
207 PKIX_SPRINTFFAILED);
210 *pString = outString;
212 cleanup:
214 PKIX_DECREF(certBasicConstraintsString);
216 PKIX_RETURN(CERTBASICCONSTRAINTS);
220 * FUNCTION: pkix_pl_CertBasicConstraints_Hashcode
221 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
223 static PKIX_Error *
224 pkix_pl_CertBasicConstraints_Hashcode(
225 PKIX_PL_Object *object,
226 PKIX_UInt32 *pHashcode,
227 void *plContext)
229 PKIX_PL_CertBasicConstraints *certB = NULL;
230 PKIX_Boolean isCA = PKIX_FALSE;
231 PKIX_Int32 pathLen = 0;
232 PKIX_Int32 hashInput = 0;
233 PKIX_UInt32 cbcHash = 0;
235 PKIX_ENTER(CERTBASICCONSTRAINTS,
236 "pkix_pl_CertBasicConstraints_Hashcode");
237 PKIX_NULLCHECK_TWO(object, pHashcode);
239 PKIX_CHECK(pkix_CheckType
240 (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
241 PKIX_OBJECTNOTCERTBASICCONSTRAINTS);
243 certB = (PKIX_PL_CertBasicConstraints *)object;
246 * if CA == TRUE
247 * hash(pathLen + 1 - PKIX_UNLIMITED_PATH_CONSTRAINT)
248 * if CA == FALSE, hash(0)
251 isCA = certB->isCA;
253 if (isCA) {
254 pathLen = certB->pathLen;
256 hashInput = pathLen + 1 - PKIX_UNLIMITED_PATH_CONSTRAINT;
259 PKIX_CHECK(pkix_hash
260 ((const unsigned char *)&hashInput,
261 sizeof (hashInput),
262 &cbcHash,
263 plContext),
264 PKIX_HASHFAILED);
266 *pHashcode = cbcHash;
268 cleanup:
270 PKIX_RETURN(CERTBASICCONSTRAINTS);
275 * FUNCTION: pkix_pl_CertBasicConstraints_Equals
276 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
278 static PKIX_Error *
279 pkix_pl_CertBasicConstraints_Equals(
280 PKIX_PL_Object *firstObject,
281 PKIX_PL_Object *secondObject,
282 PKIX_Boolean *pResult,
283 void *plContext)
285 PKIX_PL_CertBasicConstraints *firstCBC = NULL;
286 PKIX_PL_CertBasicConstraints *secondCBC = NULL;
287 PKIX_UInt32 secondType;
288 PKIX_Boolean firstIsCA = PKIX_FALSE;
289 PKIX_Boolean secondIsCA = PKIX_FALSE;
290 PKIX_Int32 firstPathLen = 0;
291 PKIX_Int32 secondPathLen = 0;
293 PKIX_ENTER(CERTBASICCONSTRAINTS,
294 "pkix_pl_CertBasicConstraints_Equals");
295 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
297 /* test that firstObject is a CertBasicConstraints */
298 PKIX_CHECK(pkix_CheckType
299 (firstObject, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
300 PKIX_FIRSTOBJECTNOTCERTBASICCONSTRAINTS);
303 * Since we know firstObject is a CertBasicConstraints,
304 * if both references are identical, they must be equal
306 if (firstObject == secondObject){
307 *pResult = PKIX_TRUE;
308 goto cleanup;
312 * If secondObject isn't a CertBasicConstraints, we
313 * don't throw an error. We simply return FALSE.
315 PKIX_CHECK(PKIX_PL_Object_GetType
316 (secondObject, &secondType, plContext),
317 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
318 if (secondType != PKIX_CERTBASICCONSTRAINTS_TYPE) {
319 *pResult = PKIX_FALSE;
320 goto cleanup;
323 firstCBC = (PKIX_PL_CertBasicConstraints *)firstObject;
324 secondCBC = (PKIX_PL_CertBasicConstraints *)secondObject;
327 * Compare the value of the CAFlag components
330 firstIsCA = firstCBC->isCA;
333 * Failure here would be an error, not merely a miscompare,
334 * since we know second is a CertBasicConstraints.
336 secondIsCA = secondCBC->isCA;
339 * If isCA flags differ, the objects are not equal.
341 if (secondIsCA != firstIsCA) {
342 *pResult = PKIX_FALSE;
343 goto cleanup;
347 * If isCA was FALSE, the objects are equal, because
348 * pathLen is meaningless in that case.
350 if (!firstIsCA) {
351 *pResult = PKIX_TRUE;
352 goto cleanup;
355 firstPathLen = firstCBC->pathLen;
356 secondPathLen = secondCBC->pathLen;
358 *pResult = (secondPathLen == firstPathLen);
360 cleanup:
362 PKIX_RETURN(CERTBASICCONSTRAINTS);
366 * FUNCTION: pkix_pl_CertBasicConstraints_RegisterSelf
367 * DESCRIPTION:
368 * Registers PKIX_CERTBASICCONSTRAINTS_TYPE and its related
369 * functions with systemClasses[]
370 * THREAD SAFETY:
371 * Not Thread Safe - for performance and complexity reasons
373 * Since this function is only called by PKIX_PL_Initialize,
374 * which should only be called once, it is acceptable that
375 * this function is not thread-safe.
377 PKIX_Error *
378 pkix_pl_CertBasicConstraints_RegisterSelf(void *plContext)
381 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
382 pkix_ClassTable_Entry entry;
384 PKIX_ENTER(CERTBASICCONSTRAINTS,
385 "pkix_pl_CertBasicConstraints_RegisterSelf");
387 entry.description = "CertBasicConstraints";
388 entry.destructor = pkix_pl_CertBasicConstraints_Destroy;
389 entry.equalsFunction = pkix_pl_CertBasicConstraints_Equals;
390 entry.hashcodeFunction = pkix_pl_CertBasicConstraints_Hashcode;
391 entry.toStringFunction = pkix_pl_CertBasicConstraints_ToString;
392 entry.comparator = NULL;
393 entry.duplicateFunction = pkix_duplicateImmutable;
395 systemClasses[PKIX_CERTBASICCONSTRAINTS_TYPE] = entry;
397 PKIX_RETURN(CERTBASICCONSTRAINTS);
400 /* --Public-Functions------------------------------------------------------- */
403 * FUNCTION: PKIX_PL_BasicConstraints_GetCAFlag
404 * (see comments in pkix_pl_pki.h)
406 PKIX_Error *
407 PKIX_PL_BasicConstraints_GetCAFlag(
408 PKIX_PL_CertBasicConstraints *basicConstraints,
409 PKIX_Boolean *pResult,
410 void *plContext)
412 PKIX_ENTER(CERTBASICCONSTRAINTS,
413 "PKIX_PL_BasicConstraintsGetCAFlag");
414 PKIX_NULLCHECK_TWO(basicConstraints, pResult);
416 *pResult = basicConstraints->isCA;
418 PKIX_RETURN(CERTBASICCONSTRAINTS);
422 * FUNCTION: PKIX_PL_BasicConstraints_GetPathLenConstraint
423 * (see comments in pkix_pl_pki.h)
425 PKIX_Error *
426 PKIX_PL_BasicConstraints_GetPathLenConstraint(
427 PKIX_PL_CertBasicConstraints *basicConstraints,
428 PKIX_Int32 *pPathLenConstraint,
429 void *plContext)
431 PKIX_ENTER(CERTBASICCONSTRAINTS,
432 "PKIX_PL_BasicConstraintsGetPathLenConstraint");
433 PKIX_NULLCHECK_TWO(basicConstraints, pPathLenConstraint);
435 *pPathLenConstraint = basicConstraints->pathLen;
437 PKIX_RETURN(CERTBASICCONSTRAINTS);