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