Imported Upstream version 3.13.6
[platform/upstream/nss.git] / mozilla / security / nss / lib / libpkix / pkix_pl_nss / pki / pkix_pl_basicconstraints.c
1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
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/
8  *
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.
13  *
14  * The Original Code is the PKIX-C library.
15  *
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.
20  *
21  * Contributor(s):
22  *   Sun Microsystems, Inc.
23  *
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.
35  *
36  * ***** END LICENSE BLOCK ***** */
37 /*
38  * pkix_pl_basicconstraints.c
39  *
40  * BasicConstraints Object Functions
41  *
42  */
43
44 #include "pkix_pl_basicconstraints.h"
45
46 /*
47  * FUNCTION: pkix_pl_CertBasicConstraints_Create
48  * DESCRIPTION:
49  *
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".
53  *
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.
69  */
70 PKIX_Error *
71 pkix_pl_CertBasicConstraints_Create(
72         PKIX_Boolean isCA,
73         PKIX_Int32 pathLen,
74         PKIX_PL_CertBasicConstraints **pObject,
75         void *plContext)
76 {
77         PKIX_PL_CertBasicConstraints *basic = NULL;
78
79         PKIX_ENTER(CERTBASICCONSTRAINTS,
80                     "pkix_pl_CertBasicConstraints_Create");
81         PKIX_NULLCHECK_ONE(pObject);
82
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);
89
90         basic->isCA = isCA;
91
92         /* pathLen has meaning only for CAs, but it's not worth checking */
93         basic->pathLen = pathLen;
94
95         *pObject = basic;
96
97 cleanup:
98
99         PKIX_RETURN(CERTBASICCONSTRAINTS);
100 }
101
102 /*
103  * FUNCTION: pkix_pl_CertBasicConstraints_Destroy
104  * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
105  */
106 static PKIX_Error *
107 pkix_pl_CertBasicConstraints_Destroy(
108         PKIX_PL_Object *object,
109         void *plContext)
110 {
111         PKIX_PL_CertBasicConstraints *certB = NULL;
112
113         PKIX_ENTER(CERTBASICCONSTRAINTS,
114                 "pkix_pl_CertBasicConstraints_Destroy");
115         PKIX_NULLCHECK_ONE(object);
116
117         PKIX_CHECK(pkix_CheckType
118                     (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
119                     PKIX_OBJECTNOTCERTBASICCONSTRAINTS);
120
121         certB = (PKIX_PL_CertBasicConstraints*)object;
122
123         certB->isCA = PKIX_FALSE;
124         certB->pathLen = 0;
125
126 cleanup:
127
128         PKIX_RETURN(CERTBASICCONSTRAINTS);
129 }
130
131 /*
132  * FUNCTION: pkix_pl_CertBasicConstraints_ToString
133  * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
134  */
135 static PKIX_Error *
136 pkix_pl_CertBasicConstraints_ToString(
137         PKIX_PL_Object *object,
138         PKIX_PL_String **pString,
139         void *plContext)
140 {
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;
148
149         PKIX_ENTER(CERTBASICCONSTRAINTS,
150                 "pkix_pl_CertBasicConstraints_toString");
151         PKIX_NULLCHECK_TWO(object, pString);
152
153         PKIX_CHECK(pkix_CheckType
154                     (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
155                     PKIX_FIRSTARGUMENTNOTCERTBASICCONSTRAINTSOBJECT);
156
157         certB = (PKIX_PL_CertBasicConstraints *)object;
158
159         /*
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"
165          */
166
167         isCA = certB->isCA;
168
169         if (isCA) {
170                 pathLen = certB->pathLen;
171
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;
180                 }
181         } else {
182                 /* print "~CA" */
183                 fmtString = "~CA";
184                 pathlenArg = PKIX_FALSE;
185         }
186
187         PKIX_CHECK(PKIX_PL_String_Create
188                     (PKIX_ESCASCII,
189                     fmtString,
190                     0,
191                     &certBasicConstraintsString,
192                     plContext),
193                     PKIX_STRINGCREATEFAILED);
194
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);
208         }
209
210         *pString = outString;
211
212 cleanup:
213
214         PKIX_DECREF(certBasicConstraintsString);
215
216         PKIX_RETURN(CERTBASICCONSTRAINTS);
217 }
218
219 /*
220  * FUNCTION: pkix_pl_CertBasicConstraints_Hashcode
221  * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
222  */
223 static PKIX_Error *
224 pkix_pl_CertBasicConstraints_Hashcode(
225         PKIX_PL_Object *object,
226         PKIX_UInt32 *pHashcode,
227         void *plContext)
228 {
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;
234
235         PKIX_ENTER(CERTBASICCONSTRAINTS,
236                 "pkix_pl_CertBasicConstraints_Hashcode");
237         PKIX_NULLCHECK_TWO(object, pHashcode);
238
239         PKIX_CHECK(pkix_CheckType
240                     (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
241                     PKIX_OBJECTNOTCERTBASICCONSTRAINTS);
242
243         certB = (PKIX_PL_CertBasicConstraints *)object;
244
245         /*
246          * if CA == TRUE
247          *      hash(pathLen + 1 - PKIX_UNLIMITED_PATH_CONSTRAINT)
248          * if CA == FALSE, hash(0)
249          */
250
251         isCA = certB->isCA;
252
253         if (isCA) {
254                 pathLen = certB->pathLen;
255
256                 hashInput = pathLen + 1 - PKIX_UNLIMITED_PATH_CONSTRAINT;
257         }
258
259         PKIX_CHECK(pkix_hash
260                     ((const unsigned char *)&hashInput,
261                     sizeof (hashInput),
262                     &cbcHash,
263                     plContext),
264                     PKIX_HASHFAILED);
265
266         *pHashcode = cbcHash;
267
268 cleanup:
269
270         PKIX_RETURN(CERTBASICCONSTRAINTS);
271 }
272
273
274 /*
275  * FUNCTION: pkix_pl_CertBasicConstraints_Equals
276  * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
277  */
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)
284 {
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;
292
293         PKIX_ENTER(CERTBASICCONSTRAINTS,
294                 "pkix_pl_CertBasicConstraints_Equals");
295         PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
296
297         /* test that firstObject is a CertBasicConstraints */
298         PKIX_CHECK(pkix_CheckType
299                     (firstObject, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
300                     PKIX_FIRSTOBJECTNOTCERTBASICCONSTRAINTS);
301
302         /*
303          * Since we know firstObject is a CertBasicConstraints,
304          * if both references are identical, they must be equal
305          */
306         if (firstObject == secondObject){
307                 *pResult = PKIX_TRUE;
308                 goto cleanup;
309         }
310
311         /*
312          * If secondObject isn't a CertBasicConstraints, we
313          * don't throw an error. We simply return FALSE.
314          */
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;
321         }
322
323         firstCBC = (PKIX_PL_CertBasicConstraints *)firstObject;
324         secondCBC = (PKIX_PL_CertBasicConstraints *)secondObject;
325
326         /*
327          * Compare the value of the CAFlag components
328          */
329
330         firstIsCA = firstCBC->isCA;
331
332         /*
333          * Failure here would be an error, not merely a miscompare,
334          * since we know second is a CertBasicConstraints.
335          */
336         secondIsCA = secondCBC->isCA;
337
338         /*
339          * If isCA flags differ, the objects are not equal.
340          */
341         if (secondIsCA != firstIsCA) {
342                 *pResult = PKIX_FALSE;
343                 goto cleanup;
344         }
345
346         /*
347          * If isCA was FALSE, the objects are equal, because
348          * pathLen is meaningless in that case.
349          */
350         if (!firstIsCA) {
351                 *pResult = PKIX_TRUE;
352                 goto cleanup;
353         }
354
355         firstPathLen = firstCBC->pathLen;
356         secondPathLen = secondCBC->pathLen;
357
358         *pResult = (secondPathLen == firstPathLen);
359
360 cleanup:
361
362         PKIX_RETURN(CERTBASICCONSTRAINTS);
363 }
364
365 /*
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
372  *
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.
376  */
377 PKIX_Error *
378 pkix_pl_CertBasicConstraints_RegisterSelf(void *plContext)
379 {
380
381         extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
382         pkix_ClassTable_Entry entry;
383
384         PKIX_ENTER(CERTBASICCONSTRAINTS,
385                 "pkix_pl_CertBasicConstraints_RegisterSelf");
386
387         entry.description = "CertBasicConstraints";
388         entry.objCounter = 0;
389         entry.typeObjectSize = sizeof(PKIX_PL_CertBasicConstraints);
390         entry.destructor = pkix_pl_CertBasicConstraints_Destroy;
391         entry.equalsFunction = pkix_pl_CertBasicConstraints_Equals;
392         entry.hashcodeFunction = pkix_pl_CertBasicConstraints_Hashcode;
393         entry.toStringFunction = pkix_pl_CertBasicConstraints_ToString;
394         entry.comparator = NULL;
395         entry.duplicateFunction = pkix_duplicateImmutable;
396
397         systemClasses[PKIX_CERTBASICCONSTRAINTS_TYPE] = entry;
398
399         PKIX_RETURN(CERTBASICCONSTRAINTS);
400 }
401
402 /* --Public-Functions------------------------------------------------------- */
403
404 /*
405  * FUNCTION: PKIX_PL_BasicConstraints_GetCAFlag
406  * (see comments in pkix_pl_pki.h)
407  */
408 PKIX_Error *
409 PKIX_PL_BasicConstraints_GetCAFlag(
410         PKIX_PL_CertBasicConstraints *basicConstraints,
411         PKIX_Boolean *pResult,
412         void *plContext)
413 {
414         PKIX_ENTER(CERTBASICCONSTRAINTS,
415                 "PKIX_PL_BasicConstraintsGetCAFlag");
416         PKIX_NULLCHECK_TWO(basicConstraints, pResult);
417
418         *pResult = basicConstraints->isCA;
419
420         PKIX_RETURN(CERTBASICCONSTRAINTS);
421 }
422
423 /*
424  * FUNCTION: PKIX_PL_BasicConstraints_GetPathLenConstraint
425  * (see comments in pkix_pl_pki.h)
426  */
427 PKIX_Error *
428 PKIX_PL_BasicConstraints_GetPathLenConstraint(
429         PKIX_PL_CertBasicConstraints *basicConstraints,
430         PKIX_Int32 *pPathLenConstraint,
431         void *plContext)
432 {
433         PKIX_ENTER(CERTBASICCONSTRAINTS,
434                 "PKIX_PL_BasicConstraintsGetPathLenConstraint");
435         PKIX_NULLCHECK_TWO(basicConstraints, pPathLenConstraint);
436
437         *pPathLenConstraint = basicConstraints->pathLen;
438
439         PKIX_RETURN(CERTBASICCONSTRAINTS);
440 }