Blame nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.c

Packit 40b132
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit 40b132
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit 40b132
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit 40b132
/*
Packit 40b132
 * pkix_pl_basicconstraints.c
Packit 40b132
 *
Packit 40b132
 * BasicConstraints Object Functions
Packit 40b132
 *
Packit 40b132
 */
Packit 40b132
Packit 40b132
#include "pkix_pl_basicconstraints.h"
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CertBasicConstraints_Create
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *
Packit 40b132
 *  Creates a new CertBasicConstraints object whose CA Flag has the value
Packit 40b132
 *  given by the Boolean value of "isCA" and whose path length field has the
Packit 40b132
 *  value given by the "pathLen" argument and stores it at "pObject".
Packit 40b132
 *
Packit 40b132
 * PARAMETERS
Packit 40b132
 *  "isCA"
Packit 40b132
 *      Boolean value with the desired value of CA Flag.
Packit 40b132
 *  "pathLen"
Packit 40b132
 *      a PKIX_Int32 with the desired value of path length
Packit 40b132
 *  "pObject"
Packit 40b132
 *      Address of object pointer's destination. Must be non-NULL.
Packit 40b132
 *  "plContext" - Platform-specific context pointer.
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
Packit 40b132
 * RETURNS:
Packit 40b132
 *  Returns NULL if the function succeeds.
Packit 40b132
 *  Returns a CertBasicConstraints Error if the function fails
Packit 40b132
 *  in a non-fatal way.
Packit 40b132
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
pkix_pl_CertBasicConstraints_Create(
Packit 40b132
        PKIX_Boolean isCA,
Packit 40b132
        PKIX_Int32 pathLen,
Packit 40b132
        PKIX_PL_CertBasicConstraints **pObject,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_CertBasicConstraints *basic = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTBASICCONSTRAINTS,
Packit 40b132
                    "pkix_pl_CertBasicConstraints_Create");
Packit 40b132
        PKIX_NULLCHECK_ONE(pObject);
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_PL_Object_Alloc
Packit 40b132
                    (PKIX_CERTBASICCONSTRAINTS_TYPE,
Packit 40b132
                    sizeof (PKIX_PL_CertBasicConstraints),
Packit 40b132
                    (PKIX_PL_Object **)&basic,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_COULDNOTCREATECERTBASICCONSTRAINTSOBJECT);
Packit 40b132
Packit 40b132
        basic->isCA = isCA;
Packit 40b132
Packit 40b132
        /* pathLen has meaning only for CAs, but it's not worth checking */
Packit 40b132
        basic->pathLen = pathLen;
Packit 40b132
Packit 40b132
        *pObject = basic;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTBASICCONSTRAINTS);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CertBasicConstraints_Destroy
Packit 40b132
 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
Packit 40b132
 */
Packit 40b132
static PKIX_Error *
Packit 40b132
pkix_pl_CertBasicConstraints_Destroy(
Packit 40b132
        PKIX_PL_Object *object,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_CertBasicConstraints *certB = NULL;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTBASICCONSTRAINTS,
Packit 40b132
                "pkix_pl_CertBasicConstraints_Destroy");
Packit 40b132
        PKIX_NULLCHECK_ONE(object);
Packit 40b132
Packit 40b132
        PKIX_CHECK(pkix_CheckType
Packit 40b132
                    (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
Packit 40b132
                    PKIX_OBJECTNOTCERTBASICCONSTRAINTS);
Packit 40b132
Packit 40b132
        certB = (PKIX_PL_CertBasicConstraints*)object;
Packit 40b132
Packit 40b132
        certB->isCA = PKIX_FALSE;
Packit 40b132
        certB->pathLen = 0;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTBASICCONSTRAINTS);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CertBasicConstraints_ToString
Packit 40b132
 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
Packit 40b132
 */
Packit 40b132
static PKIX_Error *
Packit 40b132
pkix_pl_CertBasicConstraints_ToString(
Packit 40b132
        PKIX_PL_Object *object,
Packit 40b132
        PKIX_PL_String **pString,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_String *certBasicConstraintsString = NULL;
Packit 40b132
        PKIX_PL_CertBasicConstraints *certB = NULL;
Packit 40b132
        PKIX_Boolean isCA = PKIX_FALSE;
Packit 40b132
        PKIX_Int32 pathLen = 0;
Packit 40b132
        PKIX_PL_String *outString = NULL;
Packit 40b132
        char *fmtString = NULL;
Packit 40b132
        PKIX_Boolean pathlenArg = PKIX_FALSE;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTBASICCONSTRAINTS,
Packit 40b132
                "pkix_pl_CertBasicConstraints_toString");
Packit 40b132
        PKIX_NULLCHECK_TWO(object, pString);
Packit 40b132
Packit 40b132
        PKIX_CHECK(pkix_CheckType
Packit 40b132
                    (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
Packit 40b132
                    PKIX_FIRSTARGUMENTNOTCERTBASICCONSTRAINTSOBJECT);
Packit 40b132
Packit 40b132
        certB = (PKIX_PL_CertBasicConstraints *)object;
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * if CA == TRUE
Packit 40b132
         *      if pathLen == CERT_UNLIMITED_PATH_CONSTRAINT
Packit 40b132
         *              print "CA(-1)"
Packit 40b132
         *      else print "CA(nnn)"
Packit 40b132
         * if CA == FALSE, print "~CA"
Packit 40b132
         */
Packit 40b132
Packit 40b132
        isCA = certB->isCA;
Packit 40b132
Packit 40b132
        if (isCA) {
Packit 40b132
                pathLen = certB->pathLen;
Packit 40b132
Packit 40b132
                if (pathLen == CERT_UNLIMITED_PATH_CONSTRAINT) {
Packit 40b132
                        /* print "CA(-1)" */
Packit 40b132
                        fmtString = "CA(-1)";
Packit 40b132
                        pathlenArg = PKIX_FALSE;
Packit 40b132
                } else {
Packit 40b132
                        /* print "CA(pathLen)" */
Packit 40b132
                        fmtString = "CA(%d)";
Packit 40b132
                        pathlenArg = PKIX_TRUE;
Packit 40b132
                }
Packit 40b132
        } else {
Packit 40b132
                /* print "~CA" */
Packit 40b132
                fmtString = "~CA";
Packit 40b132
                pathlenArg = PKIX_FALSE;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_CHECK(PKIX_PL_String_Create
Packit 40b132
                    (PKIX_ESCASCII,
Packit 40b132
                    fmtString,
Packit 40b132
                    0,
Packit 40b132
                    &certBasicConstraintsString,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_STRINGCREATEFAILED);
Packit 40b132
Packit 40b132
        if (pathlenArg) {
Packit 40b132
                PKIX_CHECK(PKIX_PL_Sprintf
Packit 40b132
                            (&outString,
Packit 40b132
                            plContext,
Packit 40b132
                            certBasicConstraintsString,
Packit 40b132
                            pathLen),
Packit 40b132
                            PKIX_SPRINTFFAILED);
Packit 40b132
        } else {
Packit 40b132
                PKIX_CHECK(PKIX_PL_Sprintf
Packit 40b132
                            (&outString,
Packit 40b132
                            plContext,
Packit 40b132
                            certBasicConstraintsString),
Packit 40b132
                            PKIX_SPRINTFFAILED);
Packit 40b132
        }
Packit 40b132
Packit 40b132
        *pString = outString;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
Packit 40b132
        PKIX_DECREF(certBasicConstraintsString);
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTBASICCONSTRAINTS);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CertBasicConstraints_Hashcode
Packit 40b132
 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
Packit 40b132
 */
Packit 40b132
static PKIX_Error *
Packit 40b132
pkix_pl_CertBasicConstraints_Hashcode(
Packit 40b132
        PKIX_PL_Object *object,
Packit 40b132
        PKIX_UInt32 *pHashcode,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_CertBasicConstraints *certB = NULL;
Packit 40b132
        PKIX_Boolean isCA = PKIX_FALSE;
Packit 40b132
        PKIX_Int32 pathLen = 0;
Packit 40b132
        PKIX_Int32 hashInput = 0;
Packit 40b132
        PKIX_UInt32 cbcHash = 0;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTBASICCONSTRAINTS,
Packit 40b132
                "pkix_pl_CertBasicConstraints_Hashcode");
Packit 40b132
        PKIX_NULLCHECK_TWO(object, pHashcode);
Packit 40b132
Packit 40b132
        PKIX_CHECK(pkix_CheckType
Packit 40b132
                    (object, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
Packit 40b132
                    PKIX_OBJECTNOTCERTBASICCONSTRAINTS);
Packit 40b132
Packit 40b132
        certB = (PKIX_PL_CertBasicConstraints *)object;
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * if CA == TRUE
Packit 40b132
         *      hash(pathLen + 1 - PKIX_UNLIMITED_PATH_CONSTRAINT)
Packit 40b132
         * if CA == FALSE, hash(0)
Packit 40b132
         */
Packit 40b132
Packit 40b132
        isCA = certB->isCA;
Packit 40b132
Packit 40b132
        if (isCA) {
Packit 40b132
                pathLen = certB->pathLen;
Packit 40b132
Packit 40b132
                hashInput = pathLen + 1 - PKIX_UNLIMITED_PATH_CONSTRAINT;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        PKIX_CHECK(pkix_hash
Packit 40b132
                    ((const unsigned char *)&hashInput,
Packit 40b132
                    sizeof (hashInput),
Packit 40b132
                    &cbcHash,
Packit 40b132
                    plContext),
Packit 40b132
                    PKIX_HASHFAILED);
Packit 40b132
Packit 40b132
        *pHashcode = cbcHash;
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTBASICCONSTRAINTS);
Packit 40b132
}
Packit 40b132
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CertBasicConstraints_Equals
Packit 40b132
 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
Packit 40b132
 */
Packit 40b132
static PKIX_Error *
Packit 40b132
pkix_pl_CertBasicConstraints_Equals(
Packit 40b132
        PKIX_PL_Object *firstObject,
Packit 40b132
        PKIX_PL_Object *secondObject,
Packit 40b132
        PKIX_Boolean *pResult,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_PL_CertBasicConstraints *firstCBC = NULL;
Packit 40b132
        PKIX_PL_CertBasicConstraints *secondCBC = NULL;
Packit 40b132
        PKIX_UInt32 secondType;
Packit 40b132
        PKIX_Boolean firstIsCA = PKIX_FALSE;
Packit 40b132
        PKIX_Boolean secondIsCA = PKIX_FALSE;
Packit 40b132
        PKIX_Int32 firstPathLen = 0;
Packit 40b132
        PKIX_Int32 secondPathLen = 0;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTBASICCONSTRAINTS,
Packit 40b132
                "pkix_pl_CertBasicConstraints_Equals");
Packit 40b132
        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
Packit 40b132
Packit 40b132
        /* test that firstObject is a CertBasicConstraints */
Packit 40b132
        PKIX_CHECK(pkix_CheckType
Packit 40b132
                    (firstObject, PKIX_CERTBASICCONSTRAINTS_TYPE, plContext),
Packit 40b132
                    PKIX_FIRSTOBJECTNOTCERTBASICCONSTRAINTS);
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * Since we know firstObject is a CertBasicConstraints,
Packit 40b132
         * if both references are identical, they must be equal
Packit 40b132
         */
Packit 40b132
        if (firstObject == secondObject){
Packit 40b132
                *pResult = PKIX_TRUE;
Packit 40b132
                goto cleanup;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * If secondObject isn't a CertBasicConstraints, we
Packit 40b132
         * don't throw an error. We simply return FALSE.
Packit 40b132
         */
Packit 40b132
        PKIX_CHECK(PKIX_PL_Object_GetType
Packit 40b132
                    (secondObject, &secondType, plContext),
Packit 40b132
                    PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
Packit 40b132
        if (secondType != PKIX_CERTBASICCONSTRAINTS_TYPE) {
Packit 40b132
                *pResult = PKIX_FALSE;
Packit 40b132
                goto cleanup;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        firstCBC = (PKIX_PL_CertBasicConstraints *)firstObject;
Packit 40b132
        secondCBC = (PKIX_PL_CertBasicConstraints *)secondObject;
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * Compare the value of the CAFlag components
Packit 40b132
         */
Packit 40b132
Packit 40b132
        firstIsCA = firstCBC->isCA;
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * Failure here would be an error, not merely a miscompare,
Packit 40b132
         * since we know second is a CertBasicConstraints.
Packit 40b132
         */
Packit 40b132
        secondIsCA = secondCBC->isCA;
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * If isCA flags differ, the objects are not equal.
Packit 40b132
         */
Packit 40b132
        if (secondIsCA != firstIsCA) {
Packit 40b132
                *pResult = PKIX_FALSE;
Packit 40b132
                goto cleanup;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        /*
Packit 40b132
         * If isCA was FALSE, the objects are equal, because
Packit 40b132
         * pathLen is meaningless in that case.
Packit 40b132
         */
Packit 40b132
        if (!firstIsCA) {
Packit 40b132
                *pResult = PKIX_TRUE;
Packit 40b132
                goto cleanup;
Packit 40b132
        }
Packit 40b132
Packit 40b132
        firstPathLen = firstCBC->pathLen;
Packit 40b132
        secondPathLen = secondCBC->pathLen;
Packit 40b132
Packit 40b132
        *pResult = (secondPathLen == firstPathLen);
Packit 40b132
Packit 40b132
cleanup:
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTBASICCONSTRAINTS);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: pkix_pl_CertBasicConstraints_RegisterSelf
Packit 40b132
 * DESCRIPTION:
Packit 40b132
 *  Registers PKIX_CERTBASICCONSTRAINTS_TYPE and its related
Packit 40b132
 *  functions with systemClasses[]
Packit 40b132
 * THREAD SAFETY:
Packit 40b132
 *  Not Thread Safe - for performance and complexity reasons
Packit 40b132
 *
Packit 40b132
 *  Since this function is only called by PKIX_PL_Initialize,
Packit 40b132
 *  which should only be called once, it is acceptable that
Packit 40b132
 *  this function is not thread-safe.
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
pkix_pl_CertBasicConstraints_RegisterSelf(void *plContext)
Packit 40b132
{
Packit 40b132
Packit 40b132
        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
Packit 40b132
        pkix_ClassTable_Entry entry;
Packit 40b132
Packit 40b132
        PKIX_ENTER(CERTBASICCONSTRAINTS,
Packit 40b132
                "pkix_pl_CertBasicConstraints_RegisterSelf");
Packit 40b132
Packit 40b132
        entry.description = "CertBasicConstraints";
Packit 40b132
        entry.objCounter = 0;
Packit 40b132
        entry.typeObjectSize = sizeof(PKIX_PL_CertBasicConstraints);
Packit 40b132
        entry.destructor = pkix_pl_CertBasicConstraints_Destroy;
Packit 40b132
        entry.equalsFunction = pkix_pl_CertBasicConstraints_Equals;
Packit 40b132
        entry.hashcodeFunction = pkix_pl_CertBasicConstraints_Hashcode;
Packit 40b132
        entry.toStringFunction = pkix_pl_CertBasicConstraints_ToString;
Packit 40b132
        entry.comparator = NULL;
Packit 40b132
        entry.duplicateFunction = pkix_duplicateImmutable;
Packit 40b132
Packit 40b132
        systemClasses[PKIX_CERTBASICCONSTRAINTS_TYPE] = entry;
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTBASICCONSTRAINTS);
Packit 40b132
}
Packit 40b132
Packit 40b132
/* --Public-Functions------------------------------------------------------- */
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: PKIX_PL_BasicConstraints_GetCAFlag
Packit 40b132
 * (see comments in pkix_pl_pki.h)
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
PKIX_PL_BasicConstraints_GetCAFlag(
Packit 40b132
        PKIX_PL_CertBasicConstraints *basicConstraints,
Packit 40b132
        PKIX_Boolean *pResult,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_ENTER(CERTBASICCONSTRAINTS,
Packit 40b132
                "PKIX_PL_BasicConstraintsGetCAFlag");
Packit 40b132
        PKIX_NULLCHECK_TWO(basicConstraints, pResult);
Packit 40b132
Packit 40b132
        *pResult = basicConstraints->isCA;
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTBASICCONSTRAINTS);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*
Packit 40b132
 * FUNCTION: PKIX_PL_BasicConstraints_GetPathLenConstraint
Packit 40b132
 * (see comments in pkix_pl_pki.h)
Packit 40b132
 */
Packit 40b132
PKIX_Error *
Packit 40b132
PKIX_PL_BasicConstraints_GetPathLenConstraint(
Packit 40b132
        PKIX_PL_CertBasicConstraints *basicConstraints,
Packit 40b132
        PKIX_Int32 *pPathLenConstraint,
Packit 40b132
        void *plContext)
Packit 40b132
{
Packit 40b132
        PKIX_ENTER(CERTBASICCONSTRAINTS,
Packit 40b132
                "PKIX_PL_BasicConstraintsGetPathLenConstraint");
Packit 40b132
        PKIX_NULLCHECK_TWO(basicConstraints, pPathLenConstraint);
Packit 40b132
Packit 40b132
        *pPathLenConstraint = basicConstraints->pathLen;
Packit 40b132
Packit 40b132
        PKIX_RETURN(CERTBASICCONSTRAINTS);
Packit 40b132
}