diff options
author | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2022-07-14 02:12:29 +0000 |
---|---|---|
committer | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2022-07-14 02:12:29 +0000 |
commit | 96da0130d558e742b3cb8fbe240fc77984c00337 (patch) | |
tree | 26ee54a06bf98724ef64896c8b4bc41fc8bb5cf2 /src/VBox/Runtime/tools/RTSignTool.cpp | |
parent | 699f63cc84eab0c6dc2fe630a7de2790b1a344bd (diff) | |
download | VirtualBox-svn-96da0130d558e742b3cb8fbe240fc77984c00337.tar.gz |
RTSignTool: Initial implementation of page hashes. bugref:8691
git-svn-id: https://www.virtualbox.org/svn/vbox/trunk@95637 cfe28804-0f27-0410-a406-dd0f0b0b656f
Diffstat (limited to 'src/VBox/Runtime/tools/RTSignTool.cpp')
-rw-r--r-- | src/VBox/Runtime/tools/RTSignTool.cpp | 107 |
1 files changed, 106 insertions, 1 deletions
diff --git a/src/VBox/Runtime/tools/RTSignTool.cpp b/src/VBox/Runtime/tools/RTSignTool.cpp index 59143416edf..0d05f9d1f72 100644 --- a/src/VBox/Runtime/tools/RTSignTool.cpp +++ b/src/VBox/Runtime/tools/RTSignTool.cpp @@ -1565,7 +1565,112 @@ static RTEXITCODE SignToolPkcs7_SpcCompleteWithoutPageHashes(RTCRSPCINDIRECTDATA static RTEXITCODE SignToolPkcs7_SpcAddImagePageHashes(SIGNTOOLPKCS7EXE *pThis, RTCRSPCINDIRECTDATACONTENT *pSpcIndData, RTDIGESTTYPE enmSigType) { - RT_NOREF(pThis, pSpcIndData, enmSigType); + PCRTASN1ALLOCATORVTABLE const pAllocator = &g_RTAsn1DefaultAllocator; + PRTCRSPCPEIMAGEDATA const pPeImage = pSpcIndData->Data.uValue.pPeImage; + Assert(pPeImage); + + /* + * The hashes are stored in the 'Moniker' attribute. + */ + /* Create a temporary SpcLink with a default moniker. */ + RTCRSPCLINK SpcLink; + int rc = RTCrSpcLink_Init(&SpcLink, pAllocator); + if (RT_FAILURE(rc)) + return RTMsgErrorExitFailure("RTCrSpcLink_Init failed: %Rrc", rc); + rc = RTCrSpcLink_SetMoniker(&SpcLink, NULL, pAllocator); + if (RT_SUCCESS(rc)) + { + /* Use the setter to copy SpcLink to the PeImage structure. */ + rc = RTCrSpcPeImageData_SetFile(pPeImage, &SpcLink, pAllocator); + if (RT_FAILURE(rc)) + RTMsgError("RTCrSpcLink_SetFile failed: %Rrc", rc); + } + else + RTMsgError("RTCrSpcLink_SetMoniker failed: %Rrc", rc); + RTCrSpcLink_Delete(&SpcLink); + if (RT_FAILURE(rc)) + return RTEXITCODE_FAILURE; + + /* + * Now go to work on the moniker. It doesn't have any autogenerated + * setters, so we must do stuff manually. + */ + PRTCRSPCSERIALIZEDOBJECT pMoniker = pPeImage->T0.File.u.pMoniker; + RTUUID Uuid; + rc = RTUuidFromStr(&Uuid, RTCRSPCSERIALIZEDOBJECT_UUID_STR); + if (RT_FAILURE(rc)) + return RTMsgErrorExitFailure("RTUuidFromStr failed: %Rrc", rc); + + rc = RTAsn1OctetString_AllocContent(&pMoniker->Uuid, &Uuid, sizeof(Uuid), pAllocator); + if (RT_FAILURE(rc)) + return RTMsgErrorExitFailure("RTAsn1String_InitWithValue/UUID failed: %Rrc", rc); + + /* Create a new set of attributes and associate this with the SerializedData member. */ + PRTCRSPCSERIALIZEDOBJECTATTRIBUTES pSpcAttribs; + rc = RTAsn1MemAllocZ(&pMoniker->SerializedData.EncapsulatedAllocation, + (void **)&pSpcAttribs, sizeof(*pSpcAttribs)); + if (RT_FAILURE(rc)) + return RTMsgErrorExitFailure("RTAsn1MemAllocZ/pSpcAttribs failed: %Rrc", rc); + pMoniker->SerializedData.pEncapsulated = RTCrSpcSerializedObjectAttributes_GetAsn1Core(pSpcAttribs); + pMoniker->enmType = RTCRSPCSERIALIZEDOBJECTTYPE_ATTRIBUTES; + pMoniker->u.pData = pSpcAttribs; + + rc = RTCrSpcSerializedObjectAttributes_Init(pSpcAttribs, pAllocator); + if (RT_FAILURE(rc)) + return RTMsgErrorExitFailure("RTCrSpcSerializedObjectAttributes_Init failed: %Rrc", rc); + + /* + * Add a single attribute to the set that we'll use for page hashes. + */ + int32_t iPos = RTCrSpcSerializedObjectAttributes_Append(pSpcAttribs); + if (iPos < 0) + return RTMsgErrorExitFailure("RTCrSpcSerializedObjectAttributes_Append failed: %Rrc", iPos); + PRTCRSPCSERIALIZEDOBJECTATTRIBUTE pSpcObjAttr = pSpcAttribs->papItems[iPos]; + + if (enmSigType == RTDIGESTTYPE_SHA1) + rc = RTCrSpcSerializedObjectAttribute_SetV1Hashes(pSpcObjAttr, NULL, pAllocator); + else if (enmSigType == RTDIGESTTYPE_SHA256) + rc = RTCrSpcSerializedObjectAttribute_SetV2Hashes(pSpcObjAttr, NULL, pAllocator); + else + rc = VERR_CR_DIGEST_NOT_SUPPORTED; + if (RT_FAILURE(rc)) + return RTMsgErrorExitFailure("RTCrSpcSerializedObjectAttribute_SetV1Hashes/SetV2Hashes failed: %Rrc", rc); + PRTCRSPCSERIALIZEDPAGEHASHES pSpcPageHashes = pSpcObjAttr->u.pPageHashes; + Assert(pSpcPageHashes); + + /* + * Now ask the loader for the number of pages in the page hash table + * and calculate its size. + */ + uint32_t cPages = 0; + rc = RTLdrQueryPropEx(pThis->hLdrMod, RTLDRPROP_HASHABLE_PAGES, NULL, &cPages, sizeof(cPages), NULL); + if (RT_FAILURE(rc)) + return RTMsgErrorExitFailure("RTLdrQueryPropEx/RTLDRPROP_HASHABLE_PAGES failed: %Rrc", rc); + + uint32_t const cbHash = RTCrDigestTypeToHashSize(enmSigType); + AssertReturn(cbHash > 0, RTMsgErrorExitFailure("Invalid value: enmSigType=%d", enmSigType)); + uint32_t const cbTable = (sizeof(uint32_t) + cbHash) * cPages; + + /* + * Allocate memory in the octect string. + */ + rc = RTAsn1ContentAllocZ(&pSpcPageHashes->RawData.Asn1Core, cbTable, pAllocator); + if (RT_FAILURE(rc)) + return RTMsgErrorExitFailure("RTAsn1ContentAllocZ failed to allocate %#x bytes for page hashes: %Rrc", cbTable, rc); + pSpcPageHashes->pData = (PCRTCRSPCPEIMAGEPAGEHASHES)pSpcPageHashes->RawData.Asn1Core.uData.pu8; + + RTLDRPROP enmLdrProp; + switch (enmSigType) + { + case RTDIGESTTYPE_SHA1: enmLdrProp = RTLDRPROP_SHA1_PAGE_HASHES; break; + case RTDIGESTTYPE_SHA256: enmLdrProp = RTLDRPROP_SHA256_PAGE_HASHES; break; + default: AssertFailedReturn(RTMsgErrorExitFailure("Invalid value: enmSigType=%d", enmSigType)); + + } + rc = RTLdrQueryPropEx(pThis->hLdrMod, enmLdrProp, NULL, (void *)pSpcPageHashes->RawData.Asn1Core.uData.pv, cbTable, NULL); + if (RT_FAILURE(rc)) + return RTMsgErrorExitFailure("RTLdrQueryPropEx/RTLDRPROP_SHA?_PAGE_HASHES/%#x failed: %Rrc", cbTable, rc); + return RTEXITCODE_SUCCESS; } |