tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pkix_pl_basicconstraints.c (12385B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 /*
      5 * pkix_pl_basicconstraints.c
      6 *
      7 * BasicConstraints Object Functions
      8 *
      9 */
     10 
     11 #include "pkix_pl_basicconstraints.h"
     12 
     13 /*
     14 * FUNCTION: pkix_pl_CertBasicConstraints_Create
     15 * DESCRIPTION:
     16 *
     17 *  Creates a new CertBasicConstraints object whose CA Flag has the value
     18 *  given by the Boolean value of "isCA" and whose path length field has the
     19 *  value given by the "pathLen" argument and stores it at "pObject".
     20 *
     21 * PARAMETERS
     22 *  "isCA"
     23 *      Boolean value with the desired value of CA Flag.
     24 *  "pathLen"
     25 *      a PKIX_Int32 with the desired value of path length
     26 *  "pObject"
     27 *      Address of object pointer's destination. Must be non-NULL.
     28 *  "plContext" - Platform-specific context pointer.
     29 * THREAD SAFETY:
     30 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
     31 * RETURNS:
     32 *  Returns NULL if the function succeeds.
     33 *  Returns a CertBasicConstraints Error if the function fails
     34 *  in a non-fatal way.
     35 *  Returns a Fatal Error if the function fails in an unrecoverable way.
     36 */
     37 PKIX_Error *
     38 pkix_pl_CertBasicConstraints_Create(
     39        PKIX_Boolean isCA,
     40        PKIX_Int32 pathLen,
     41        PKIX_PL_CertBasicConstraints **pObject,
     42        void *plContext)
     43 {
     44        PKIX_PL_CertBasicConstraints *basic = NULL;
     45 
     46        PKIX_ENTER(CERTBASICCONSTRAINTS,
     47                    "pkix_pl_CertBasicConstraints_Create");
     48        PKIX_NULLCHECK_ONE(pObject);
     49 
     50        PKIX_CHECK(PKIX_PL_Object_Alloc
     51                    (PKIX_CERTBASICCONSTRAINTS_TYPE,
     52                    sizeof (PKIX_PL_CertBasicConstraints),
     53                    (PKIX_PL_Object **)&basic,
     54                    plContext),
     55                    PKIX_COULDNOTCREATECERTBASICCONSTRAINTSOBJECT);
     56 
     57        basic->isCA = isCA;
     58 
     59        /* pathLen has meaning only for CAs, but it's not worth checking */
     60        basic->pathLen = pathLen;
     61 
     62        *pObject = basic;
     63 
     64 cleanup:
     65 
     66        PKIX_RETURN(CERTBASICCONSTRAINTS);
     67 }
     68 
     69 /*
     70 * FUNCTION: pkix_pl_CertBasicConstraints_Destroy
     71 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
     72 */
     73 static PKIX_Error *
     74 pkix_pl_CertBasicConstraints_Destroy(
     75        PKIX_PL_Object *object,
     76        void *plContext)
     77 {
     78        PKIX_PL_CertBasicConstraints *certB = NULL;
     79 
     80        PKIX_ENTER(CERTBASICCONSTRAINTS,
     81                "pkix_pl_CertBasicConstraints_Destroy");
     82        PKIX_NULLCHECK_ONE(object);
     83 
     84        PKIX_CHECK(pkix_CheckType
     85                    (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
     86                    PKIX_OBJECTNOTCERTBASICCONSTRAINTS);
     87 
     88        certB = (PKIX_PL_CertBasicConstraints*)object;
     89 
     90        certB->isCA = PKIX_FALSE;
     91        certB->pathLen = 0;
     92 
     93 cleanup:
     94 
     95        PKIX_RETURN(CERTBASICCONSTRAINTS);
     96 }
     97 
     98 /*
     99 * FUNCTION: pkix_pl_CertBasicConstraints_ToString
    100 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
    101 */
    102 static PKIX_Error *
    103 pkix_pl_CertBasicConstraints_ToString(
    104        PKIX_PL_Object *object,
    105        PKIX_PL_String **pString,
    106        void *plContext)
    107 {
    108        PKIX_PL_String *certBasicConstraintsString = NULL;
    109        PKIX_PL_CertBasicConstraints *certB = NULL;
    110        PKIX_Boolean isCA = PKIX_FALSE;
    111        PKIX_Int32 pathLen = 0;
    112        PKIX_PL_String *outString = NULL;
    113        char *fmtString = NULL;
    114        PKIX_Boolean pathlenArg = PKIX_FALSE;
    115 
    116        PKIX_ENTER(CERTBASICCONSTRAINTS,
    117                "pkix_pl_CertBasicConstraints_toString");
    118        PKIX_NULLCHECK_TWO(object, pString);
    119 
    120        PKIX_CHECK(pkix_CheckType
    121                    (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
    122                    PKIX_FIRSTARGUMENTNOTCERTBASICCONSTRAINTSOBJECT);
    123 
    124        certB = (PKIX_PL_CertBasicConstraints *)object;
    125 
    126        /*
    127         * if CA == TRUE
    128         *      if pathLen == CERT_UNLIMITED_PATH_CONSTRAINT
    129         *              print "CA(-1)"
    130         *      else print "CA(nnn)"
    131         * if CA == FALSE, print "~CA"
    132         */
    133 
    134        isCA = certB->isCA;
    135 
    136        if (isCA) {
    137                pathLen = certB->pathLen;
    138 
    139                if (pathLen == CERT_UNLIMITED_PATH_CONSTRAINT) {
    140                        /* print "CA(-1)" */
    141                        fmtString = "CA(-1)";
    142                        pathlenArg = PKIX_FALSE;
    143                } else {
    144                        /* print "CA(pathLen)" */
    145                        fmtString = "CA(%d)";
    146                        pathlenArg = PKIX_TRUE;
    147                }
    148        } else {
    149                /* print "~CA" */
    150                fmtString = "~CA";
    151                pathlenArg = PKIX_FALSE;
    152        }
    153 
    154        PKIX_CHECK(PKIX_PL_String_Create
    155                    (PKIX_ESCASCII,
    156                    fmtString,
    157                    0,
    158                    &certBasicConstraintsString,
    159                    plContext),
    160                    PKIX_STRINGCREATEFAILED);
    161 
    162        if (pathlenArg) {
    163                PKIX_CHECK(PKIX_PL_Sprintf
    164                            (&outString,
    165                            plContext,
    166                            certBasicConstraintsString,
    167                            pathLen),
    168                            PKIX_SPRINTFFAILED);
    169        } else {
    170                PKIX_CHECK(PKIX_PL_Sprintf
    171                            (&outString,
    172                            plContext,
    173                            certBasicConstraintsString),
    174                            PKIX_SPRINTFFAILED);
    175        }
    176 
    177        *pString = outString;
    178 
    179 cleanup:
    180 
    181        PKIX_DECREF(certBasicConstraintsString);
    182 
    183        PKIX_RETURN(CERTBASICCONSTRAINTS);
    184 }
    185 
    186 /*
    187 * FUNCTION: pkix_pl_CertBasicConstraints_Hashcode
    188 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
    189 */
    190 static PKIX_Error *
    191 pkix_pl_CertBasicConstraints_Hashcode(
    192        PKIX_PL_Object *object,
    193        PKIX_UInt32 *pHashcode,
    194        void *plContext)
    195 {
    196        PKIX_PL_CertBasicConstraints *certB = NULL;
    197        PKIX_Boolean isCA = PKIX_FALSE;
    198        PKIX_Int32 pathLen = 0;
    199        PKIX_Int32 hashInput = 0;
    200        PKIX_UInt32 cbcHash = 0;
    201 
    202        PKIX_ENTER(CERTBASICCONSTRAINTS,
    203                "pkix_pl_CertBasicConstraints_Hashcode");
    204        PKIX_NULLCHECK_TWO(object, pHashcode);
    205 
    206        PKIX_CHECK(pkix_CheckType
    207                    (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
    208                    PKIX_OBJECTNOTCERTBASICCONSTRAINTS);
    209 
    210        certB = (PKIX_PL_CertBasicConstraints *)object;
    211 
    212        /*
    213         * if CA == TRUE
    214         *      hash(pathLen + 1 - PKIX_UNLIMITED_PATH_CONSTRAINT)
    215         * if CA == FALSE, hash(0)
    216         */
    217 
    218        isCA = certB->isCA;
    219 
    220        if (isCA) {
    221                pathLen = certB->pathLen;
    222 
    223                hashInput = pathLen + 1 - PKIX_UNLIMITED_PATH_CONSTRAINT;
    224        }
    225 
    226        PKIX_CHECK(pkix_hash
    227                    ((const unsigned char *)&hashInput,
    228                    sizeof (hashInput),
    229                    &cbcHash,
    230                    plContext),
    231                    PKIX_HASHFAILED);
    232 
    233        *pHashcode = cbcHash;
    234 
    235 cleanup:
    236 
    237        PKIX_RETURN(CERTBASICCONSTRAINTS);
    238 }
    239 
    240 
    241 /*
    242 * FUNCTION: pkix_pl_CertBasicConstraints_Equals
    243 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
    244 */
    245 static PKIX_Error *
    246 pkix_pl_CertBasicConstraints_Equals(
    247        PKIX_PL_Object *firstObject,
    248        PKIX_PL_Object *secondObject,
    249        PKIX_Boolean *pResult,
    250        void *plContext)
    251 {
    252        PKIX_PL_CertBasicConstraints *firstCBC = NULL;
    253        PKIX_PL_CertBasicConstraints *secondCBC = NULL;
    254        PKIX_UInt32 secondType;
    255        PKIX_Boolean firstIsCA = PKIX_FALSE;
    256        PKIX_Boolean secondIsCA = PKIX_FALSE;
    257        PKIX_Int32 firstPathLen = 0;
    258        PKIX_Int32 secondPathLen = 0;
    259 
    260        PKIX_ENTER(CERTBASICCONSTRAINTS,
    261                "pkix_pl_CertBasicConstraints_Equals");
    262        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
    263 
    264        /* test that firstObject is a CertBasicConstraints */
    265        PKIX_CHECK(pkix_CheckType
    266                    (firstObject, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
    267                    PKIX_FIRSTOBJECTNOTCERTBASICCONSTRAINTS);
    268 
    269        /*
    270         * Since we know firstObject is a CertBasicConstraints,
    271         * if both references are identical, they must be equal
    272         */
    273        if (firstObject == secondObject){
    274                *pResult = PKIX_TRUE;
    275                goto cleanup;
    276        }
    277 
    278        /*
    279         * If secondObject isn't a CertBasicConstraints, we
    280         * don't throw an error. We simply return FALSE.
    281         */
    282        PKIX_CHECK(PKIX_PL_Object_GetType
    283                    (secondObject, &secondType, plContext),
    284                    PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
    285        if (secondType != PKIX_CERTBASICCONSTRAINTS_TYPE) {
    286                *pResult = PKIX_FALSE;
    287                goto cleanup;
    288        }
    289 
    290        firstCBC = (PKIX_PL_CertBasicConstraints *)firstObject;
    291        secondCBC = (PKIX_PL_CertBasicConstraints *)secondObject;
    292 
    293        /*
    294         * Compare the value of the CAFlag components
    295         */
    296 
    297        firstIsCA = firstCBC->isCA;
    298 
    299        /*
    300         * Failure here would be an error, not merely a miscompare,
    301         * since we know second is a CertBasicConstraints.
    302         */
    303        secondIsCA = secondCBC->isCA;
    304 
    305        /*
    306         * If isCA flags differ, the objects are not equal.
    307         */
    308        if (secondIsCA != firstIsCA) {
    309                *pResult = PKIX_FALSE;
    310                goto cleanup;
    311        }
    312 
    313        /*
    314         * If isCA was FALSE, the objects are equal, because
    315         * pathLen is meaningless in that case.
    316         */
    317        if (!firstIsCA) {
    318                *pResult = PKIX_TRUE;
    319                goto cleanup;
    320        }
    321 
    322        firstPathLen = firstCBC->pathLen;
    323        secondPathLen = secondCBC->pathLen;
    324 
    325        *pResult = (secondPathLen == firstPathLen);
    326 
    327 cleanup:
    328 
    329        PKIX_RETURN(CERTBASICCONSTRAINTS);
    330 }
    331 
    332 /*
    333 * FUNCTION: pkix_pl_CertBasicConstraints_RegisterSelf
    334 * DESCRIPTION:
    335 *  Registers PKIX_CERTBASICCONSTRAINTS_TYPE and its related
    336 *  functions with systemClasses[]
    337 * THREAD SAFETY:
    338 *  Not Thread Safe - for performance and complexity reasons
    339 *
    340 *  Since this function is only called by PKIX_PL_Initialize,
    341 *  which should only be called once, it is acceptable that
    342 *  this function is not thread-safe.
    343 */
    344 PKIX_Error *
    345 pkix_pl_CertBasicConstraints_RegisterSelf(void *plContext)
    346 {
    347 
    348        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
    349        pkix_ClassTable_Entry entry;
    350 
    351        PKIX_ENTER(CERTBASICCONSTRAINTS,
    352                "pkix_pl_CertBasicConstraints_RegisterSelf");
    353 
    354        entry.description = "CertBasicConstraints";
    355        entry.objCounter = 0;
    356        entry.typeObjectSize = sizeof(PKIX_PL_CertBasicConstraints);
    357        entry.destructor = pkix_pl_CertBasicConstraints_Destroy;
    358        entry.equalsFunction = pkix_pl_CertBasicConstraints_Equals;
    359        entry.hashcodeFunction = pkix_pl_CertBasicConstraints_Hashcode;
    360        entry.toStringFunction = pkix_pl_CertBasicConstraints_ToString;
    361        entry.comparator = NULL;
    362        entry.duplicateFunction = pkix_duplicateImmutable;
    363 
    364        systemClasses[PKIX_CERTBASICCONSTRAINTS_TYPE] = entry;
    365 
    366        PKIX_RETURN(CERTBASICCONSTRAINTS);
    367 }
    368 
    369 /* --Public-Functions------------------------------------------------------- */
    370 
    371 /*
    372 * FUNCTION: PKIX_PL_BasicConstraints_GetCAFlag
    373 * (see comments in pkix_pl_pki.h)
    374 */
    375 PKIX_Error *
    376 PKIX_PL_BasicConstraints_GetCAFlag(
    377        PKIX_PL_CertBasicConstraints *basicConstraints,
    378        PKIX_Boolean *pResult,
    379        void *plContext)
    380 {
    381        PKIX_ENTER(CERTBASICCONSTRAINTS,
    382                "PKIX_PL_BasicConstraintsGetCAFlag");
    383        PKIX_NULLCHECK_TWO(basicConstraints, pResult);
    384 
    385        *pResult = basicConstraints->isCA;
    386 
    387        PKIX_RETURN(CERTBASICCONSTRAINTS);
    388 }
    389 
    390 /*
    391 * FUNCTION: PKIX_PL_BasicConstraints_GetPathLenConstraint
    392 * (see comments in pkix_pl_pki.h)
    393 */
    394 PKIX_Error *
    395 PKIX_PL_BasicConstraints_GetPathLenConstraint(
    396        PKIX_PL_CertBasicConstraints *basicConstraints,
    397        PKIX_Int32 *pPathLenConstraint,
    398        void *plContext)
    399 {
    400        PKIX_ENTER(CERTBASICCONSTRAINTS,
    401                "PKIX_PL_BasicConstraintsGetPathLenConstraint");
    402        PKIX_NULLCHECK_TWO(basicConstraints, pPathLenConstraint);
    403 
    404        *pPathLenConstraint = basicConstraints->pathLen;
    405 
    406        PKIX_RETURN(CERTBASICCONSTRAINTS);
    407 }