ADUC_Result RootKeyWorkflow_UpdateRootKeys()

in src/rootkey_workflow/src/rootkey_workflow.c [38:209]


ADUC_Result RootKeyWorkflow_UpdateRootKeys(const char* workflowId, const char* workFolder, const char* rootKeyPkgUrl)
{
    ADUC_Result result = { .ResultCode = ADUC_GeneralResult_Failure, .ExtendedResultCode = 0 };
    ADUC_Result tmpResult = { .ResultCode = ADUC_GeneralResult_Failure, .ExtendedResultCode = 0 };

    STRING_HANDLE downloadedFilePath = NULL;
    STRING_HANDLE fileDest = NULL;
    JSON_Value* rootKeyPackageJsonValue = NULL;
    char* rootKeyPackageJsonString = NULL;
    ADUC_RootKeyPackage rootKeyPackage;

    memset(&rootKeyPackage, 0, sizeof(ADUC_RootKeyPackage));

    ADUC_RootKeyPkgDownloaderInfo rootkey_downloader_info = {
#if ROOTKEY_PKG_DOWNLOAD_USE_CURL == 1
        .name = "Curl",
        .downloadFn = DownloadRootKeyPkg_Curl,
#else
        .name = "DO",
        .downloadFn = DownloadRootKeyPkg_DO,
#endif
        .downloadBaseDir = workFolder,
    };

    if (workflowId == NULL)
    {
        Log_Error("NULL workflowId");
        result.ExtendedResultCode = ADUC_ERC_INVALIDARG;
        goto done;
    }

    RootKeyUtility_ClearReportingErc();

    tmpResult = ADUC_RootKeyPackageUtils_DownloadPackage(
        rootKeyPkgUrl, workflowId, &rootkey_downloader_info, &downloadedFilePath);

    if (IsAducResultCodeFailure(tmpResult.ResultCode))
    {
        Log_Error("Failed download of rootkey package, ERC: 0x%08x", tmpResult.ExtendedResultCode);
        result = tmpResult;
        goto done;
    }

    rootKeyPackageJsonValue = json_parse_file(STRING_c_str(downloadedFilePath));

    if (rootKeyPackageJsonValue == NULL)
    {
        Log_Error("Failed to parse JSON at '%s'", downloadedFilePath);
        result.ExtendedResultCode = ADUC_ERC_ROOTKEY_PKG_FAIL_JSON_PARSE;
        goto done;
    }

    rootKeyPackageJsonString = json_serialize_to_string(rootKeyPackageJsonValue);

    if (rootKeyPackageJsonString == NULL)
    {
        Log_Error("Failed serialization of '%s'", rootKeyPackageJsonValue);
        result.ExtendedResultCode = ADUC_ERC_ROOTKEY_PKG_FAIL_JSON_SERIALIZE;
        goto done;
    }

    tmpResult = ADUC_RootKeyPackageUtils_Parse(rootKeyPackageJsonString, &rootKeyPackage);

    if (IsAducResultCodeFailure(tmpResult.ResultCode))
    {
        Log_Error("Failed rootkeypkg parse of '%s'", rootKeyPackageJsonString);
        result = tmpResult;
        goto done;
    }

    tmpResult = RootKeyUtility_ValidateRootKeyPackageWithHardcodedKeys(&rootKeyPackage);

    if (IsAducResultCodeFailure(tmpResult.ResultCode))
    {
        Log_Error("Failed validation of root key pkg with hardcoded keys");
        result = tmpResult;
        goto done;
    }

#ifndef ADUC_ENABLE_SRVC_E2E_TESTING

#    ifdef ADUC_E2E_TESTING_ENABLED
    if (!rootKeyPackage.protectedProperties.isTest)
    {
        result.ExtendedResultCode = ADUC_ERC_ROOTKEY_PROD_PKG_ON_TEST_AGENT;
        goto done;
    }
#    else
    if (rootKeyPackage.protectedProperties.isTest)
    {
        result.ExtendedResultCode = ADUC_ERC_ROOTKEY_TEST_PKG_ON_PROD_AGENT;
        goto done;
    }
#    endif

#endif
    if (!ADUC_SystemUtils_Exists(ADUC_ROOTKEY_STORE_PATH))
    {
        if (ADUC_SystemUtils_MkDirRecursiveDefault(ADUC_ROOTKEY_STORE_PATH) != 0)
        {
            Log_Error("Failed creation of rootkey store path: '%s'", ADUC_ROOTKEY_STORE_PATH);
            result.ExtendedResultCode = ADUC_ERC_ROOTKEY_STORE_PATH_CREATE;
            goto done;
        }
    }

    fileDest = STRING_construct(ADUC_ROOTKEY_STORE_PACKAGE_PATH);

    if (fileDest == NULL)
    {
        result.ExtendedResultCode = ADUC_ERC_NOMEM;
        goto done;
    }

    if (!ADUC_RootKeyUtility_IsUpdateStoreNeeded(fileDest, &rootKeyPackage))
    {
        // This is a success, but skips writing to local store and includes informational ERC.
        Log_Debug("RootKey pkg unchanged, continuing...");
        result.ResultCode = ADUC_Result_RootKey_Continue;
        result.ExtendedResultCode = ADUC_ERC_ROOTKEY_PKG_UNCHANGED;
        goto done;
    }

    tmpResult = RootKeyUtility_WriteRootKeyPackageToFileAtomically(&rootKeyPackage, fileDest);

    if (IsAducResultCodeFailure(tmpResult.ResultCode))
    {
        Log_Error("Failed persist of rootkey pkg to '%s'", STRING_c_str(fileDest));
        result = tmpResult;
        goto done;
    }

    tmpResult = RootKeyUtility_ReloadPackageFromDisk(STRING_c_str(fileDest), true /* validateSignatures */);

    if (IsAducResultCodeFailure(tmpResult.ResultCode))
    {
        Log_Error("Failed reload of pkg from '%s'", STRING_c_str(fileDest));
        result = tmpResult;
        goto done;
    }

    result.ResultCode = ADUC_GeneralResult_Success;
    result.ExtendedResultCode = ADUC_ERC_ROOTKEY_PACKAGE_CHANGED;

done:

    if (IsAducResultCodeFailure(result.ResultCode) || result.ResultCode == ADUC_Result_RootKey_Continue)
    {
        if (IsAducResultCodeFailure(result.ResultCode))
        {
            Log_Error("Fail update root keys, ERC 0x%08x", result.ExtendedResultCode);
        }
        else
        {
            Log_Debug("No root key change.");
        }
    }
    else
    {
        Log_Info("Update RootKey, ResultCode %d, ERC 0x%08x", result.ResultCode, result.ExtendedResultCode);
    }

    RootKeyUtility_SetReportingErc(result.ExtendedResultCode);

    STRING_delete(downloadedFilePath);
    STRING_delete(fileDest);
    json_value_free(rootKeyPackageJsonValue);
    free(rootKeyPackageJsonString);

    ADUC_RootKeyPackageUtils_Destroy(&rootKeyPackage);
    return result;
}