michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: /* michael@0: * pkix_buildresult.c michael@0: * michael@0: * BuildResult Object Functions michael@0: * michael@0: */ michael@0: michael@0: #include "pkix_buildresult.h" michael@0: michael@0: /* --Private-Functions-------------------------------------------- */ michael@0: michael@0: /* michael@0: * FUNCTION: pkix_BuildResult_Destroy michael@0: * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) michael@0: */ michael@0: static PKIX_Error * michael@0: pkix_BuildResult_Destroy( michael@0: PKIX_PL_Object *object, michael@0: void *plContext) michael@0: { michael@0: PKIX_BuildResult *result = NULL; michael@0: michael@0: PKIX_ENTER(BUILDRESULT, "pkix_BuildResult_Destroy"); michael@0: PKIX_NULLCHECK_ONE(object); michael@0: michael@0: /* Check that this object is a build result object */ michael@0: PKIX_CHECK(pkix_CheckType(object, PKIX_BUILDRESULT_TYPE, plContext), michael@0: PKIX_OBJECTNOTBUILDRESULT); michael@0: michael@0: result = (PKIX_BuildResult *)object; michael@0: michael@0: PKIX_DECREF(result->valResult); michael@0: PKIX_DECREF(result->certChain); michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_RETURN(BUILDRESULT); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: pkix_BuildResult_Equals michael@0: * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h) michael@0: */ michael@0: static PKIX_Error * michael@0: pkix_BuildResult_Equals( michael@0: PKIX_PL_Object *first, michael@0: PKIX_PL_Object *second, michael@0: PKIX_Boolean *pResult, michael@0: void *plContext) michael@0: { michael@0: PKIX_UInt32 secondType; michael@0: PKIX_Boolean cmpResult; michael@0: PKIX_BuildResult *firstBuildResult = NULL; michael@0: PKIX_BuildResult *secondBuildResult = NULL; michael@0: michael@0: PKIX_ENTER(BUILDRESULT, "pkix_BuildResult_Equals"); michael@0: PKIX_NULLCHECK_THREE(first, second, pResult); michael@0: michael@0: PKIX_CHECK(pkix_CheckType(first, PKIX_BUILDRESULT_TYPE, plContext), michael@0: PKIX_FIRSTOBJECTNOTBUILDRESULT); michael@0: michael@0: PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext), michael@0: PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); michael@0: michael@0: *pResult = PKIX_FALSE; michael@0: michael@0: if (secondType != PKIX_BUILDRESULT_TYPE) goto cleanup; michael@0: michael@0: firstBuildResult = (PKIX_BuildResult *)first; michael@0: secondBuildResult = (PKIX_BuildResult *)second; michael@0: michael@0: PKIX_CHECK(PKIX_PL_Object_Equals michael@0: ((PKIX_PL_Object *)firstBuildResult->valResult, michael@0: (PKIX_PL_Object *)secondBuildResult->valResult, michael@0: &cmpResult, michael@0: plContext), michael@0: PKIX_OBJECTEQUALSFAILED); michael@0: michael@0: if (!cmpResult) goto cleanup; michael@0: michael@0: PKIX_CHECK(PKIX_PL_Object_Equals michael@0: ((PKIX_PL_Object *)firstBuildResult->certChain, michael@0: (PKIX_PL_Object *)secondBuildResult->certChain, michael@0: &cmpResult, michael@0: plContext), michael@0: PKIX_OBJECTEQUALSFAILED); michael@0: michael@0: if (!cmpResult) goto cleanup; michael@0: michael@0: /* michael@0: * The remaining case is that both are null, michael@0: * which we consider equality. michael@0: * cmpResult = PKIX_TRUE; michael@0: */ michael@0: michael@0: *pResult = cmpResult; michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_RETURN(BUILDRESULT); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: pkix_BuildResult_Hashcode michael@0: * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) michael@0: */ michael@0: static PKIX_Error * michael@0: pkix_BuildResult_Hashcode( michael@0: PKIX_PL_Object *object, michael@0: PKIX_UInt32 *pHashcode, michael@0: void *plContext) michael@0: { michael@0: PKIX_BuildResult *buildResult = NULL; michael@0: PKIX_UInt32 hash = 0; michael@0: PKIX_UInt32 valResultHash = 0; michael@0: PKIX_UInt32 certChainHash = 0; michael@0: michael@0: PKIX_ENTER(BUILDRESULT, "pkix_BuildResult_Hashcode"); michael@0: PKIX_NULLCHECK_TWO(object, pHashcode); michael@0: michael@0: PKIX_CHECK(pkix_CheckType(object, PKIX_BUILDRESULT_TYPE, plContext), michael@0: PKIX_OBJECTNOTBUILDRESULT); michael@0: michael@0: buildResult = (PKIX_BuildResult*)object; michael@0: michael@0: PKIX_CHECK(PKIX_PL_Object_Hashcode michael@0: ((PKIX_PL_Object *)buildResult->valResult, michael@0: &valResultHash, michael@0: plContext), michael@0: PKIX_OBJECTHASHCODEFAILED); michael@0: michael@0: PKIX_CHECK(PKIX_PL_Object_Hashcode michael@0: ((PKIX_PL_Object *)buildResult->certChain, michael@0: &certChainHash, michael@0: plContext), michael@0: PKIX_OBJECTHASHCODEFAILED); michael@0: michael@0: hash = 31*(31 * valResultHash + certChainHash); michael@0: michael@0: *pHashcode = hash; michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_RETURN(BUILDRESULT); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: pkix_BuildResult_ToString michael@0: * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) michael@0: */ michael@0: static PKIX_Error * michael@0: pkix_BuildResult_ToString( michael@0: PKIX_PL_Object *object, michael@0: PKIX_PL_String **pString, michael@0: void *plContext) michael@0: { michael@0: PKIX_BuildResult *buildResult = NULL; michael@0: PKIX_PL_String *formatString = NULL; michael@0: PKIX_PL_String *buildResultString = NULL; michael@0: michael@0: PKIX_ValidateResult *valResult = NULL; michael@0: PKIX_List *certChain = NULL; michael@0: michael@0: PKIX_PL_String *valResultString = NULL; michael@0: PKIX_PL_String *certChainString = NULL; michael@0: michael@0: char *asciiFormat = michael@0: "[\n" michael@0: "\tValidateResult: \t\t%s" michael@0: "\tCertChain: \t\t%s\n" michael@0: "]\n"; michael@0: michael@0: PKIX_ENTER(BUILDRESULT, "pkix_BuildResult_ToString"); michael@0: PKIX_NULLCHECK_TWO(object, pString); michael@0: michael@0: PKIX_CHECK(pkix_CheckType(object, PKIX_BUILDRESULT_TYPE, plContext), michael@0: PKIX_OBJECTNOTBUILDRESULT); michael@0: michael@0: buildResult = (PKIX_BuildResult*)object; michael@0: michael@0: valResult = buildResult->valResult; michael@0: michael@0: PKIX_CHECK(PKIX_PL_String_Create michael@0: (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext), michael@0: PKIX_STRINGCREATEFAILED); michael@0: michael@0: PKIX_CHECK(PKIX_PL_Object_ToString michael@0: ((PKIX_PL_Object *)valResult, &valResultString, plContext), michael@0: PKIX_OBJECTTOSTRINGFAILED); michael@0: michael@0: certChain = buildResult->certChain; michael@0: michael@0: PKIX_CHECK(PKIX_PL_Object_ToString michael@0: ((PKIX_PL_Object *)certChain, &certChainString, plContext), michael@0: PKIX_OBJECTTOSTRINGFAILED); michael@0: michael@0: PKIX_CHECK(PKIX_PL_Sprintf michael@0: (&buildResultString, michael@0: plContext, michael@0: formatString, michael@0: valResultString, michael@0: certChainString), michael@0: PKIX_SPRINTFFAILED); michael@0: michael@0: *pString = buildResultString; michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_DECREF(formatString); michael@0: PKIX_DECREF(valResultString); michael@0: PKIX_DECREF(certChainString); michael@0: michael@0: PKIX_RETURN(BUILDRESULT); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: pkix_BuildResult_RegisterSelf michael@0: * DESCRIPTION: michael@0: * Registers PKIX_BUILDRESULT_TYPE and its related functions with michael@0: * systemClasses[] michael@0: * THREAD SAFETY: michael@0: * Not Thread Safe - for performance and complexity reasons michael@0: * michael@0: * Since this function is only called by PKIX_PL_Initialize, which should michael@0: * only be called once, it is acceptable that this function is not michael@0: * thread-safe. michael@0: */ michael@0: PKIX_Error * michael@0: pkix_BuildResult_RegisterSelf(void *plContext) michael@0: { michael@0: michael@0: extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; michael@0: pkix_ClassTable_Entry entry; michael@0: michael@0: PKIX_ENTER(BUILDRESULT, "pkix_BuildResult_RegisterSelf"); michael@0: michael@0: entry.description = "BuildResult"; michael@0: entry.objCounter = 0; michael@0: entry.typeObjectSize = sizeof(PKIX_BuildResult); michael@0: entry.destructor = pkix_BuildResult_Destroy; michael@0: entry.equalsFunction = pkix_BuildResult_Equals; michael@0: entry.hashcodeFunction = pkix_BuildResult_Hashcode; michael@0: entry.toStringFunction = pkix_BuildResult_ToString; michael@0: entry.comparator = NULL; michael@0: entry.duplicateFunction = pkix_duplicateImmutable; michael@0: michael@0: systemClasses[PKIX_BUILDRESULT_TYPE] = entry; michael@0: michael@0: PKIX_RETURN(BUILDRESULT); michael@0: } michael@0: michael@0: /* michael@0: * FUNCTION: pkix_BuildResult_Create michael@0: * DESCRIPTION: michael@0: * michael@0: * Creates a new BuildResult Object using the ValidateResult pointed to by michael@0: * "valResult" and the List pointed to by "certChain", and stores it at michael@0: * "pResult". michael@0: * michael@0: * PARAMETERS michael@0: * "valResult" michael@0: * Address of ValidateResult component. Must be non-NULL. michael@0: * "certChain michael@0: * Address of List component. Must be non-NULL. michael@0: * "pResult" michael@0: * Address where object pointer will be stored. Must be non-NULL. michael@0: * "plContext" michael@0: * Platform-specific context pointer. michael@0: * THREAD SAFETY: michael@0: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) michael@0: * RETURNS: michael@0: * Returns NULL if the function succeeds. michael@0: * Returns a Fatal Error if the function fails in an unrecoverable way. michael@0: */ michael@0: PKIX_Error * michael@0: pkix_BuildResult_Create( michael@0: PKIX_ValidateResult *valResult, michael@0: PKIX_List *certChain, michael@0: PKIX_BuildResult **pResult, michael@0: void *plContext) michael@0: { michael@0: PKIX_BuildResult *result = NULL; michael@0: michael@0: PKIX_ENTER(BUILDRESULT, "pkix_BuildResult_Create"); michael@0: PKIX_NULLCHECK_THREE(valResult, certChain, pResult); michael@0: michael@0: PKIX_CHECK(PKIX_PL_Object_Alloc michael@0: (PKIX_BUILDRESULT_TYPE, michael@0: sizeof (PKIX_BuildResult), michael@0: (PKIX_PL_Object **)&result, michael@0: plContext), michael@0: PKIX_COULDNOTCREATEBUILDRESULTOBJECT); michael@0: michael@0: /* initialize fields */ michael@0: michael@0: PKIX_INCREF(valResult); michael@0: result->valResult = valResult; michael@0: michael@0: PKIX_INCREF(certChain); michael@0: result->certChain = certChain; michael@0: michael@0: PKIX_CHECK(PKIX_List_SetImmutable(result->certChain, plContext), michael@0: PKIX_LISTSETIMMUTABLEFAILED); michael@0: michael@0: *pResult = result; michael@0: result = NULL; michael@0: michael@0: cleanup: michael@0: michael@0: PKIX_DECREF(result); michael@0: michael@0: PKIX_RETURN(BUILDRESULT); michael@0: michael@0: } michael@0: michael@0: /* --Public-Functions--------------------------------------------- */ michael@0: michael@0: michael@0: /* michael@0: * FUNCTION: PKIX_BuildResult_GetValidateResult michael@0: * (see comments in pkix_result.h) michael@0: */ michael@0: PKIX_Error * michael@0: PKIX_BuildResult_GetValidateResult( michael@0: PKIX_BuildResult *result, michael@0: PKIX_ValidateResult **pResult, michael@0: void *plContext) michael@0: { michael@0: PKIX_ENTER(BUILDRESULT, "PKIX_BuildResult_GetValidateResult"); michael@0: PKIX_NULLCHECK_TWO(result, pResult); michael@0: michael@0: PKIX_INCREF(result->valResult); michael@0: *pResult = result->valResult; michael@0: michael@0: cleanup: michael@0: PKIX_RETURN(BUILDRESULT); michael@0: } michael@0: michael@0: michael@0: michael@0: /* michael@0: * FUNCTION: PKIX_BuildResult_GetCertChain michael@0: * (see comments in pkix_result.h) michael@0: */ michael@0: PKIX_Error * michael@0: PKIX_BuildResult_GetCertChain( michael@0: PKIX_BuildResult *result, michael@0: PKIX_List **pChain, michael@0: void *plContext) michael@0: { michael@0: PKIX_ENTER(BUILDRESULT, "PKIX_BuildResult_GetCertChain"); michael@0: PKIX_NULLCHECK_TWO(result, pChain); michael@0: michael@0: PKIX_INCREF(result->certChain); michael@0: *pChain = result->certChain; michael@0: michael@0: cleanup: michael@0: PKIX_RETURN(BUILDRESULT); michael@0: }