summaryrefslogtreecommitdiff
path: root/src/VBox/Runtime/tools/RTSignTool.cpp
diff options
context:
space:
mode:
authorvboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2022-07-14 02:12:29 +0000
committervboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2022-07-14 02:12:29 +0000
commit96da0130d558e742b3cb8fbe240fc77984c00337 (patch)
tree26ee54a06bf98724ef64896c8b4bc41fc8bb5cf2 /src/VBox/Runtime/tools/RTSignTool.cpp
parent699f63cc84eab0c6dc2fe630a7de2790b1a344bd (diff)
downloadVirtualBox-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.cpp107
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;
}