Index: /trunk/include/iprt/ldr.h
===================================================================
--- /trunk/include/iprt/ldr.h	(revision 86548)
+++ /trunk/include/iprt/ldr.h	(revision 86549)
@@ -1208,23 +1208,49 @@
 
 /**
+ * Signature information provided by FNRTLDRVALIDATESIGNEDDATA.
+ */
+typedef struct RTLDRSIGNATUREINFO
+{
+    /** The signature number (0-based). */
+    uint16_t            iSignature;
+    /** The total number of signatures. */
+    uint16_t            cSignatures;
+    /** Sginature format type. */
+    RTLDRSIGNATURETYPE  enmType;
+    /** The signature data (formatted according to enmType). */
+    void const         *pvSignature;
+    /** The size of the buffer pvSignature points to. */
+    size_t              cbSignature;
+    /** Pointer to the signed data, if external.
+     * NULL if the data is internal to the signature structure. */
+    void const         *pvExternalData;
+    /** Size of the signed data, if external.
+     * 0 if internal to the signature structure. */
+    size_t              cbExternalData;
+} RTLDRSIGNATUREINFO;
+/** Pointer to a signature structure. */
+typedef RTLDRSIGNATUREINFO *PRTLDRSIGNATUREINFO;
+/** Pointer to a const signature structure. */
+typedef RTLDRSIGNATUREINFO const *PCRTLDRSIGNATUREINFO;
+
+/**
  * Callback used by RTLdrVerifySignature to verify the signature and associated
  * certificates.
  *
- * @returns IPRT status code.
+ * This is called multiple times when the executable contains more than one
+ * signature (PE only at the moment).  The RTLDRSIGNATUREINFO::cSignatures gives
+ * the total number of signatures (and thereby callbacks) and
+ * RTLDRSIGNATUREINFO::iSignature indicates the current one.
+ *
+ * @returns IPRT status code.  A status code other than VINF_SUCCESS will
+ *          prevent callbacks the remaining signatures (if any).
  * @param   hLdrMod         The module handle.
  * @param   enmSignature    The signature format.
- * @param   pvSignature     The signature data. Format given by @a enmSignature.
- * @param   cbSignature     The size of the buffer @a pvSignature points to.
- * @param   pvExternalData  Pointer to the signed data, if external. NULL if the
- *                          data is internal to the signature structure.
- * @param   cbExternalData Size of the signed data, if external.  0 if
- *                          internal to the signature structure.
+ * @param   pInfo           Signature information.
  * @param   pErrInfo        Pointer to an error info buffer, optional.
  * @param   pvUser          User argument.
  *
  */
-typedef DECLCALLBACKTYPE(int, FNRTLDRVALIDATESIGNEDDATA,(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
-                                                         void const *pvSignature, size_t cbSignature,
-                                                         void const *pvExternalData, size_t cbExternalData,
+typedef DECLCALLBACKTYPE(int, FNRTLDRVALIDATESIGNEDDATA,(RTLDRMOD hLdrMod, PCRTLDRSIGNATUREINFO pInfo,
                                                          PRTERRINFO pErrInfo, void *pvUser));
 /** Pointer to a signature verification callback. */
Index: /trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp	(revision 86548)
+++ /trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp	(revision 86549)
@@ -1353,18 +1353,16 @@
  * @callback_method_impl{FNRTLDRVALIDATESIGNEDDATA}
  */
-static DECLCALLBACK(int) supdrvDarwinLdrOpenVerifyCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
-                                                           void const *pvSignature, size_t cbSignature,
-                                                           void const *pvExternalData, size_t cbExternalData,
+static DECLCALLBACK(int) supdrvDarwinLdrOpenVerifyCallback(RTLDRMOD hLdrMod, PCRTLDRSIGNATUREINFO pInfo,
                                                            PRTERRINFO pErrInfo, void *pvUser)
 {
     PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pvUser;
-    RT_NOREF_PV(hLdrMod); RT_NOREF_PV(cbSignature);
-
-    switch (enmSignature)
+    RT_NOREF_PV(hLdrMod);
+
+    switch (pInfo->enmType)
     {
         case RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA:
-            if (pvExternalData)
+            if (pInfo->pvExternalData)
             {
-                PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pvSignature;
+                PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pInfo->pvSignature;
                 RTTIMESPEC             ValidationTime;
                 RTTimeNow(&ValidationTime);
@@ -1376,10 +1374,10 @@
                                                                  pDevExt->hAdditionalStore, pDevExt->hRootStore, &ValidationTime,
                                                                  supdrvDarwinLdrOpenVerifyCertificatCallback, pDevExt,
-                                                                 pvExternalData, cbExternalData, pErrInfo);
+                                                                 pInfo->pvExternalData, pInfo->cbExternalData, pErrInfo);
             }
             return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Expected external data with signature!");
 
         default:
-            return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", enmSignature);
+            return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", pInfo->enmType);
     }
 }
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h	(revision 86548)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h	(revision 86549)
@@ -98,6 +98,5 @@
     /** The file handle. */
     HANDLE      hFile;
-    /** Handle to event sempahore in case we're force to deal with asynchronous
-     * I/O. */
+    /** Handle to event sempahore in case we're force to deal with asynchronous I/O. */
     HANDLE      hEvent;
     /** Current file offset. */
@@ -107,6 +106,13 @@
     /** Flags for the verification callback, SUPHNTVI_F_XXX. */
     uint32_t    fFlags;
-    /** The executable timstamp in second since unix epoch. */
-    uint64_t    uTimestamp;
+    /** Number of signatures that verified okay. */
+    uint16_t    cOkaySignatures;
+    /** Number of signatures that couldn't be successfully verified (time stamp
+     * issues, no certificate path, etc) but weren't fatal. */
+    uint16_t    cNokSignatures;
+    /** Total number of signatures. */
+    uint16_t    cTotalSignatures;
+    /** The last non-fatal signature failure. */
+    int         rcLastSignatureFailure;
     /** Log name. */
     char        szFilename[1];
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 86548)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 86549)
@@ -1059,10 +1059,42 @@
 
 
-static DECLCALLBACK(int) supHardNtViCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
-                                             void const *pvSignature, size_t cbSignature,
-                                             void const *pvExternalData, size_t cbExternalData,
-                                             PRTERRINFO pErrInfo, void *pvUser)
-{
-    RT_NOREF(hLdrMod, enmSignature, pvExternalData, cbExternalData);
+/**
+ * RTTimeNow equivaltent that handles ring-3 where we cannot use it.
+ *
+ * @returns pNow
+ * @param   pNow                Where to return the current time.
+ */
+static PRTTIMESPEC supHardNtTimeNow(PRTTIMESPEC pNow)
+{
+#ifdef IN_RING3
+    /*
+     * Just read system time.
+     */
+    KUSER_SHARED_DATA volatile *pUserSharedData = (KUSER_SHARED_DATA volatile *)MM_SHARED_USER_DATA_VA;
+# ifdef RT_ARCH_AMD64
+    uint64_t uRet = *(uint64_t volatile *)&pUserSharedData->SystemTime; /* This is what KeQuerySystemTime does (missaligned). */
+    return RTTimeSpecSetNtTime(pNow, uRet);
+# else
+
+    LARGE_INTEGER NtTime;
+    do
+    {
+        NtTime.HighPart = pUserSharedData->SystemTime.High1Time;
+        NtTime.LowPart  = pUserSharedData->SystemTime.LowPart;
+    } while (pUserSharedData->SystemTime.High2Time != NtTime.HighPart);
+    return RTTimeSpecSetNtTime(pNow, NtTime.QuadPart);
+# endif
+#else  /* IN_RING0 */
+    return RTTimeNow(pNow);
+#endif /* IN_RING0 */
+}
+
+
+/**
+ * @callback_method_impl{FNRTLDRVALIDATESIGNEDDATA}
+ */
+static DECLCALLBACK(int) supHardNtViCallback(RTLDRMOD hLdrMod, PCRTLDRSIGNATUREINFO pInfo, PRTERRINFO pErrInfo, void *pvUser)
+{
+    RT_NOREF(hLdrMod);
 
     /*
@@ -1071,18 +1103,21 @@
     PSUPHNTVIRDR pNtViRdr = (PSUPHNTVIRDR)pvUser;
     Assert(pNtViRdr->Core.uMagic == RTLDRREADER_MAGIC);
-
-    AssertReturn(cbSignature == sizeof(RTCRPKCS7CONTENTINFO), VERR_INTERNAL_ERROR_5);
-    PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pvSignature;
+    pNtViRdr->cTotalSignatures = pInfo->cSignatures;
+
+    AssertReturn(pInfo->enmType == RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA, VERR_INTERNAL_ERROR_5);
+    AssertReturn(!pInfo->pvExternalData, VERR_INTERNAL_ERROR_5);
+    AssertReturn(pInfo->cbSignature == sizeof(RTCRPKCS7CONTENTINFO), VERR_INTERNAL_ERROR_5);
+    PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pInfo->pvSignature;
     AssertReturn(RTCrPkcs7ContentInfo_IsSignedData(pContentInfo), VERR_INTERNAL_ERROR_5);
     AssertReturn(pContentInfo->u.pSignedData->SignerInfos.cItems == 1, VERR_INTERNAL_ERROR_5);
     PCRTCRPKCS7SIGNERINFO pSignerInfo = pContentInfo->u.pSignedData->SignerInfos.papItems[0];
 
-    AssertReturn(!pvExternalData, VERR_INTERNAL_ERROR_5);
 
     /*
      * If special certificate requirements, check them out before validating
-     * the signature.
-     */
-    if (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_BUILD_CERT)
+     * the signature.  These only apply to the first signature (for now).
+     */
+    if (   (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_BUILD_CERT)
+        && pInfo->iSignature == 0)
     {
         if (!RTCrX509Certificate_MatchIssuerAndSerialNumber(&g_BuildX509Cert,
@@ -1098,55 +1133,111 @@
 
     /*
-     * Verify the signature.  We instruct the verifier to use the signing time
-     * counter signature present when present, falling back on the timestamp
-     * planted by the linker when absent.  In ring-0 we don't have all the
-     * necessary timestamp server root certificate info, so we have to allow
-     * using counter signatures unverified there.  Ditto for the early period
-     * of ring-3 hardened stub execution.
-     */
-    RTTIMESPEC ValidationTime;
-    RTTimeSpecSetSeconds(&ValidationTime, pNtViRdr->uTimestamp);
-
+     * We instruction the verifier to use the signing time counter signature
+     * when present, but provides the linker time then the current time as
+     * fallbacks should the timestamp be missing or unusable.
+     *
+     * Update: Save the first timestamp we validate with build cert and
+     *         use this as a minimum timestamp for further build cert
+     *         validations.  This works around issues with old DLLs that
+     *         we sign against with our certificate (crt, sdl, qt).
+     *
+     * Update: If the validation fails, retry with the current timestamp. This
+     *         is a workaround for NTDLL.DLL in build 14971 having a weird
+     *         timestamp: 0xDF1E957E (Sat Aug 14 14:05:18 2088).
+     */
     uint32_t fFlags = RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
                     | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT
                     | RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY;
+
+    /* In ring-0 we don't have all the necessary timestamp server root certificate
+     * info, so we have to allow using counter signatures unverified there.
+     * Ditto for the early period of ring-3 hardened stub execution. */
 #ifndef IN_RING0
     if (!g_fHaveOtherRoots)
 #endif
         fFlags |= RTCRPKCS7VERIFY_SD_F_USE_SIGNING_TIME_UNVERIFIED | RTCRPKCS7VERIFY_SD_F_USE_MS_TIMESTAMP_UNVERIFIED;
-    return RTCrPkcs7VerifySignedData(pContentInfo, fFlags, g_hSpcAndNtKernelSuppStore, g_hSpcAndNtKernelRootStore,
-                                     &ValidationTime, supHardNtViCertVerifyCallback, pNtViRdr, pErrInfo);
-}
-
-
-/**
- * RTTimeNow equivaltent that handles ring-3 where we cannot use it.
- *
- * @returns pNow
- * @param   pNow                Where to return the current time.
- */
-static PRTTIMESPEC supHardNtTimeNow(PRTTIMESPEC pNow)
-{
-#ifdef IN_RING3
-    /*
-     * Just read system time.
-     */
-    KUSER_SHARED_DATA volatile *pUserSharedData = (KUSER_SHARED_DATA volatile *)MM_SHARED_USER_DATA_VA;
-# ifdef RT_ARCH_AMD64
-    uint64_t uRet = *(uint64_t volatile *)&pUserSharedData->SystemTime; /* This is what KeQuerySystemTime does (missaligned). */
-    return RTTimeSpecSetNtTime(pNow, uRet);
-# else
-
-    LARGE_INTEGER NtTime;
-    do
-    {
-        NtTime.HighPart = pUserSharedData->SystemTime.High1Time;
-        NtTime.LowPart  = pUserSharedData->SystemTime.LowPart;
-    } while (pUserSharedData->SystemTime.High2Time != NtTime.HighPart);
-    return RTTimeSpecSetNtTime(pNow, NtTime.QuadPart);
-# endif
-#else  /* IN_RING0 */
-    return RTTimeNow(pNow);
-#endif /* IN_RING0 */
+
+    /* Fallback timestamps to try: */
+    struct { RTTIMESPEC TimeSpec; const char *pszDesc; } aTimes[2];
+    unsigned cTimes = 0;
+
+    /* 1. The linking timestamp: */
+    uint64_t uTimestamp = 0;
+    int rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &uTimestamp, sizeof(uTimestamp));
+    if (RT_SUCCESS(rc))
+    {
+#ifdef IN_RING3 /* Hack alert! (see above) */
+        if (   (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING)
+            && (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT)
+            && uTimestamp < g_uBuildTimestampHack)
+            uTimestamp = g_uBuildTimestampHack;
+#endif
+        RTTimeSpecSetSeconds(&aTimes[0].TimeSpec, uTimestamp);
+        aTimes[0].pszDesc = "link";
+        cTimes++;
+    }
+    else
+        SUP_DPRINTF(("RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on %s: %Rrc", pNtViRdr->szFilename, rc));
+
+    /* 2. Current time. */
+    supHardNtTimeNow(&aTimes[cTimes].TimeSpec);
+    aTimes[cTimes].pszDesc = "now";
+    cTimes++;
+
+    /* Make the verfication attempts. */
+    for (unsigned i = 0; ; i++)
+    {
+        Assert(i < cTimes);
+        rc = RTCrPkcs7VerifySignedData(pContentInfo, fFlags, g_hSpcAndNtKernelSuppStore, g_hSpcAndNtKernelRootStore,
+                                       &aTimes[i].TimeSpec, supHardNtViCertVerifyCallback, pNtViRdr, pErrInfo);
+        if (RT_SUCCESS(rc))
+        {
+            if (rc != VINF_SUCCESS)
+            {
+                SUP_DPRINTF(("%s: Signature #%u/%u: info status: %d\n", pNtViRdr->szFilename, pInfo->iSignature, pInfo->cbSignature, rc));
+                if (pNtViRdr->rcLastSignatureFailure == VINF_SUCCESS)
+                    pNtViRdr->rcLastSignatureFailure = rc;
+            }
+            pNtViRdr->cOkaySignatures++;
+
+#ifdef IN_RING3 /* Hack alert! (see above) */
+            if ((pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_BUILD_CERT) && g_uBuildTimestampHack == 0 && cTimes > 1)
+                g_uBuildTimestampHack = uTimestamp;
+#endif
+            return VINF_SUCCESS;
+        }
+
+        if (rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME && i + 1 < cTimes)
+            SUP_DPRINTF(("%s: Signature #%u/%u: VERR_CR_X509_CPV_NOT_VALID_AT_TIME for %#RX64; retrying against current time: %#RX64.\n",
+                         pNtViRdr->szFilename, pInfo->iSignature, pInfo->cbSignature,
+                         RTTimeSpecGetSeconds(&aTimes[0].TimeSpec), RTTimeSpecGetSeconds(&aTimes[1].TimeSpec)));
+        else
+        {
+            /* There are a couple of failures we can tollerate if there are more than
+               one signature and one of them works out fine.  The RTLdrVerifySignature
+               caller will have to check the failure counts though to make sure
+               something succeeded. */
+            pNtViRdr->rcLastSignatureFailure = rc;
+            if (   rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME
+                || rc == VERR_CR_X509_CPV_NO_TRUSTED_PATHS)
+            {
+                SUP_DPRINTF(("%s: Signature #%u/%u: %s (%d) w/ timestamp=%#RX64/%s.\n", pNtViRdr->szFilename, pInfo->iSignature, pInfo->cbSignature,
+                             rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME ? "VERR_CR_X509_CPV_NOT_VALID_AT_TIME" : "VERR_CR_X509_CPV_NO_TRUSTED_PATHS", rc,
+                             RTTimeSpecGetSeconds(&aTimes[i].TimeSpec), aTimes[i].pszDesc));
+
+                /* This leniency is not applicable to build certificate requirements (signature #1 only). */
+                if (  !(pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_BUILD_CERT)
+                    || pInfo->iSignature != 0)
+                {
+                    pNtViRdr->cNokSignatures++;
+                    rc = VINF_SUCCESS;
+                }
+            }
+            else
+                SUP_DPRINTF(("%s: Signature #%u/%u: %Rrc w/ timestamp=%#RX64/%s.\n", pNtViRdr->szFilename, pInfo->iSignature, pInfo->cbSignature,
+                             rc, RTTimeSpecGetSeconds(&aTimes[i].TimeSpec), aTimes[i].pszDesc));
+            return rc;
+        }
+    }
 }
 
@@ -1222,71 +1313,46 @@
      * The PKCS #7 SignedData signature is checked in the callback. Any
      * signing certificate restrictions are also enforced there.
-     *
-     * For the time being, we use the executable timestamp as the
-     * certificate validation date.  We must query that first to avoid
-     * potential issues re-entering the loader code from the callback.
-     *
-     * Update: Save the first timestamp we validate with build cert and
-     *         use this as a minimum timestamp for further build cert
-     *         validations.  This works around issues with old DLLs that
-     *         we sign against with our certificate (crt, sdl, qt).
-     *
-     * Update: If the validation fails, retry with the current timestamp. This
-     *         is a workaround for NTDLL.DLL in build 14971 having a weird
-     *         timestamp: 0xDF1E957E (Sat Aug 14 14:05:18 2088).
-     */
-    int rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &pNtViRdr->uTimestamp, sizeof(pNtViRdr->uTimestamp));
+     */
+    pNtViRdr->cOkaySignatures        = 0;
+    pNtViRdr->cNokSignatures         = 0;
+    pNtViRdr->cTotalSignatures       = 0;
+    pNtViRdr->rcLastSignatureFailure = VINF_SUCCESS;
+    int rc = RTLdrVerifySignature(hLdrMod, supHardNtViCallback, pNtViRdr, pErrInfo);
     if (RT_SUCCESS(rc))
     {
-#ifdef IN_RING3 /* Hack alert! (see above) */
-        if (   (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING)
-            && (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT)
-            && pNtViRdr->uTimestamp < g_uBuildTimestampHack)
-            pNtViRdr->uTimestamp = g_uBuildTimestampHack;
-#endif
-
-        rc = RTLdrVerifySignature(hLdrMod, supHardNtViCallback, pNtViRdr, pErrInfo);
-
-#ifdef IN_RING3 /* Hack alert! (see above) */
-        if ((pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_BUILD_CERT) && g_uBuildTimestampHack == 0 && RT_SUCCESS(rc))
-            g_uBuildTimestampHack = pNtViRdr->uTimestamp;
-#endif
-
-        if (rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME)
+        Assert(pNtViRdr->cOkaySignatures + pNtViRdr->cNokSignatures == pNtViRdr->cTotalSignatures);
+        if (   !pNtViRdr->cOkaySignatures
+            || pNtViRdr->cOkaySignatures + pNtViRdr->cNokSignatures < pNtViRdr->cTotalSignatures /* paranoia */)
         {
-            RTTIMESPEC Now;
-            uint64_t uOld = pNtViRdr->uTimestamp;
-            pNtViRdr->uTimestamp = RTTimeSpecGetSeconds(supHardNtTimeNow(&Now));
-            SUP_DPRINTF(("%ls: VERR_CR_X509_CPV_NOT_VALID_AT_TIME for %#RX64; retrying against current time: %#RX64.\n",
-                         pwszName, uOld, pNtViRdr->uTimestamp)); NOREF(uOld);
-            rc = RTLdrVerifySignature(hLdrMod, supHardNtViCallback, pNtViRdr, pErrInfo);
+            rc = pNtViRdr->rcLastSignatureFailure;
+            AssertStmt(RT_FAILURE_NP(rc), rc = VERR_INTERNAL_ERROR_3);
         }
-
-        /*
-         * Microsoft doesn't sign a whole bunch of DLLs, so we have to
-         * ASSUME that a bunch of system DLLs are fine.
-         */
-        if (rc == VERR_LDRVI_NOT_SIGNED)
-            rc = supHardNtViCheckIfNotSignedOk(hLdrMod, pwszName, pNtViRdr->fFlags, pNtViRdr->hFile, rc);
-        if (RT_FAILURE(rc))
-            RTErrInfoAddF(pErrInfo, rc, ": %ls", pwszName);
-
-        /*
-         * Check for the signature checking enforcement, if requested to do so.
-         */
-        if (RT_SUCCESS(rc) && (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT))
-        {
-            bool fEnforced = false;
-            int rc2 = RTLdrQueryProp(hLdrMod, RTLDRPROP_SIGNATURE_CHECKS_ENFORCED, &fEnforced, sizeof(fEnforced));
-            if (RT_FAILURE(rc2))
-                rc = RTErrInfoSetF(pErrInfo, rc2, "Querying RTLDRPROP_SIGNATURE_CHECKS_ENFORCED failed on %ls: %Rrc.",
-                                   pwszName, rc2);
-            else if (!fEnforced)
-                rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_SIGNATURE_CHECKS_NOT_ENFORCED,
-                                   "The image '%ls' was not linked with /IntegrityCheck.", pwszName);
-        }
-    }
-    else
-        RTErrInfoSetF(pErrInfo, rc, "RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on %ls: %Rrc", pwszName, rc);
+        else if (rc == VINF_SUCCESS && RT_SUCCESS(pNtViRdr->rcLastSignatureFailure))
+            rc = pNtViRdr->rcLastSignatureFailure;
+    }
+
+    /*
+     * Microsoft doesn't sign a whole bunch of DLLs, so we have to
+     * ASSUME that a bunch of system DLLs are fine.
+     */
+    if (rc == VERR_LDRVI_NOT_SIGNED)
+        rc = supHardNtViCheckIfNotSignedOk(hLdrMod, pwszName, pNtViRdr->fFlags, pNtViRdr->hFile, rc);
+    if (RT_FAILURE(rc))
+        RTErrInfoAddF(pErrInfo, rc, ": %ls", pwszName);
+
+    /*
+     * Check for the signature checking enforcement, if requested to do so.
+     */
+    if (RT_SUCCESS(rc) && (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT))
+    {
+        bool fEnforced = false;
+        int rc2 = RTLdrQueryProp(hLdrMod, RTLDRPROP_SIGNATURE_CHECKS_ENFORCED, &fEnforced, sizeof(fEnforced));
+        if (RT_FAILURE(rc2))
+            rc = RTErrInfoSetF(pErrInfo, rc2, "Querying RTLDRPROP_SIGNATURE_CHECKS_ENFORCED failed on %ls: %Rrc.",
+                               pwszName, rc2);
+        else if (!fEnforced)
+            rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_SIGNATURE_CHECKS_NOT_ENFORCED,
+                               "The image '%ls' was not linked with /IntegrityCheck.", pwszName);
+    }
 
 #ifdef IN_RING3
Index: /trunk/src/VBox/Runtime/common/ldr/ldrMachO.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/ldr/ldrMachO.cpp	(revision 86548)
+++ /trunk/src/VBox/Runtime/common/ldr/ldrMachO.cpp	(revision 86549)
@@ -5537,8 +5537,13 @@
                      * Finally, let the caller verify the certificate chain for the PKCS#7 bit.
                      */
-                    rc = pfnCallback(&pThis->Core, RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA,
-                                     &pSignature->ContentInfo, sizeof(pSignature->ContentInfo),
-                                     pSignature->aCodeDirs[0].pCodeDir, pSignature->aCodeDirs[0].cb,
-                                     pErrInfo, pvUser);
+                    RTLDRSIGNATUREINFO Info;
+                    Info.iSignature     = 0;
+                    Info.cSignatures    = 1;
+                    Info.enmType        = RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA;
+                    Info.pvSignature    = &pSignature->ContentInfo;
+                    Info.cbSignature    = sizeof(pSignature->ContentInfo);
+                    Info.pvExternalData = pSignature->aCodeDirs[0].pCodeDir;
+                    Info.cbExternalData = pSignature->aCodeDirs[0].cb;
+                    rc = pfnCallback(&pThis->Core, &Info, pErrInfo, pvUser);
                 }
             }
Index: /trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp	(revision 86548)
+++ /trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp	(revision 86549)
@@ -216,10 +216,10 @@
 #ifndef IPRT_WITHOUT_LDR_VERIFY
 /**
- * Parsed signature data.
- */
-typedef struct RTLDRPESIGNATURE
+ * Parsed data for one signature.
+ */
+typedef struct RTLDRPESIGNATUREONE
 {
     /** The outer content info wrapper. */
-    RTCRPKCS7CONTENTINFO        ContentInfo;
+    PRTCRPKCS7CONTENTINFO       pContentInfo;
     /** Pointer to the decoded SignedData inside the ContentInfo member. */
     PRTCRPKCS7SIGNEDDATA        pSignedData;
@@ -228,14 +228,33 @@
     /** The digest type employed by the signature. */
     RTDIGESTTYPE                enmDigest;
-
+    /** Set if we've already validate the image hash. */
+    bool                        fValidatedImageHash;
+    /** The signature number. */
+    uint16_t                    iSignature;
+    /** Hash result. */
+    RTLDRPEHASHRESUNION         HashRes;
+} RTLDRPESIGNATUREONE;
+/** Pointer to the parsed data of one signature. */
+typedef RTLDRPESIGNATUREONE *PRTLDRPESIGNATUREONE;
+
+/**
+ * Parsed signature data.
+ */
+typedef struct RTLDRPESIGNATURE
+{
     /** Pointer to the raw signatures.  This is allocated in the continuation of
      * this structure to keep things simple.  The size is given by  the security
      * export directory. */
     WIN_CERTIFICATE const      *pRawData;
-
+    /** The outer content info wrapper (primary signature). */
+    RTCRPKCS7CONTENTINFO        PrimaryContentInfo;
+    /** The info for the primary signature. */
+    RTLDRPESIGNATUREONE         Primary;
+    /** Number of nested signatures (zero if none). */
+    uint16_t                    cNested;
+    /** Pointer to an array of nested signatures (NULL if none). */
+    PRTLDRPESIGNATUREONE        paNested;
     /** Hash scratch data. */
     RTLDRPEHASHCTXUNION         HashCtx;
-    /** Hash result. */
-    RTLDRPEHASHRESUNION         HashRes;
 } RTLDRPESIGNATURE;
 /** Pointed to SigneData parsing stat and output. */
@@ -2523,6 +2542,119 @@
 {
     RT_NOREF_PV(pModPe);
-    RTCrPkcs7ContentInfo_Delete(&pSignature->ContentInfo);
+    RTCrPkcs7ContentInfo_Delete(&pSignature->PrimaryContentInfo);
+    if (pSignature->paNested > 0)
+    {
+        RTMemTmpFree(pSignature->paNested);
+        pSignature->paNested = NULL;
+    }
     RTMemTmpFree(pSignature);
+}
+
+
+/**
+ * Handles nested signatures.
+ *
+ * @returns IPRT status code.
+ * @param   pSignature          The signature status structure.  Returns with
+ *                              cNested = 0 and paNested = NULL if no nested
+ *                              signatures.
+ * @param   pErrInfo            Where to return extended error info (optional).
+ */
+static int rtldrPE_VerifySignatureDecodeNested(PRTLDRPESIGNATURE pSignature, PRTERRINFO pErrInfo)
+{
+    Assert(pSignature->cNested == 0);
+    Assert(pSignature->paNested == NULL);
+
+    /*
+     * Count nested signatures.
+     */
+    uint32_t cNested = 0;
+    for (uint32_t iSignerInfo = 0; iSignerInfo < pSignature->Primary.pSignedData->SignerInfos.cItems; iSignerInfo++)
+    {
+        PCRTCRPKCS7SIGNERINFO pSignerInfo = pSignature->Primary.pSignedData->SignerInfos.papItems[iSignerInfo];
+        for (uint32_t iAttrib = 0; iAttrib < pSignerInfo->UnauthenticatedAttributes.cItems; iAttrib++)
+        {
+            PCRTCRPKCS7ATTRIBUTE pAttrib = pSignerInfo->UnauthenticatedAttributes.papItems[iAttrib];
+            if (pAttrib->enmType == RTCRPKCS7ATTRIBUTETYPE_MS_NESTED_SIGNATURE)
+            {
+                Assert(pAttrib->uValues.pContentInfos);
+                cNested += pAttrib->uValues.pContentInfos->cItems;
+            }
+        }
+    }
+    if (!cNested)
+        return VINF_SUCCESS;
+
+    /*
+     * Allocate and populate the info structures.
+     */
+    pSignature->paNested = (PRTLDRPESIGNATUREONE)RTMemTmpAllocZ(sizeof(pSignature->paNested[0]) * cNested);
+    if (!pSignature->paNested)
+        return RTErrInfoSetF(pErrInfo, VERR_NO_TMP_MEMORY, "Failed to allocate space for %u nested signatures", cNested);
+    pSignature->cNested = cNested;
+
+    cNested = 0;
+    for (uint32_t iSignerInfo = 0; iSignerInfo < pSignature->Primary.pSignedData->SignerInfos.cItems; iSignerInfo++)
+    {
+        PCRTCRPKCS7SIGNERINFO pSignerInfo = pSignature->Primary.pSignedData->SignerInfos.papItems[iSignerInfo];
+        for (uint32_t iAttrib = 0; iAttrib < pSignerInfo->UnauthenticatedAttributes.cItems; iAttrib++)
+        {
+            PCRTCRPKCS7ATTRIBUTE pAttrib = pSignerInfo->UnauthenticatedAttributes.papItems[iAttrib];
+            if (pAttrib->enmType == RTCRPKCS7ATTRIBUTETYPE_MS_NESTED_SIGNATURE)
+            {
+                for (uint32_t iItem = 0; iItem < pAttrib->uValues.pContentInfos->cItems; iItem++, cNested++)
+                {
+                    PRTLDRPESIGNATUREONE  pInfo        = &pSignature->paNested[cNested];
+                    PRTCRPKCS7CONTENTINFO pContentInfo = pAttrib->uValues.pContentInfos->papItems[iItem];
+                    pInfo->pContentInfo = pContentInfo;
+                    pInfo->iSignature   = cNested;
+
+                    if (RTCrPkcs7ContentInfo_IsSignedData(pInfo->pContentInfo))
+                    { /* likely */ }
+                    else
+                        return RTErrInfoSetF(pErrInfo, VERR_LDRVI_EXPECTED_INDIRECT_DATA_CONTENT_OID, /** @todo error code*/
+                                             "Nested#%u: PKCS#7 is not 'signedData': %s", cNested, pInfo->pContentInfo->ContentType.szObjId);
+                    PRTCRPKCS7SIGNEDDATA pSignedData = pContentInfo->u.pSignedData;
+                    pInfo->pSignedData = pSignedData;
+
+                    /*
+                     * Check the authenticode bits.
+                     */
+                    if (!strcmp(pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID))
+                    { /* likely */ }
+                    else
+                        return RTErrInfoSetF(pErrInfo, VERR_LDRVI_EXPECTED_INDIRECT_DATA_CONTENT_OID,
+                                             "Nested#%u: Unknown pSignedData.ContentInfo.ContentType.szObjId value: %s (expected %s)",
+                                             cNested, pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID);
+                    pInfo->pIndData = pSignedData->ContentInfo.u.pIndirectDataContent;
+                    Assert(pInfo->pIndData);
+
+                    /*
+                     * Check that things add up.
+                     */
+                    int rc = RTCrPkcs7SignedData_CheckSanity(pSignedData,
+                                                             RTCRPKCS7SIGNEDDATA_SANITY_F_AUTHENTICODE
+                                                             | RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH
+                                                             | RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT,
+                                                             pErrInfo, "SD");
+                    if (RT_SUCCESS(rc))
+                        rc = RTCrSpcIndirectDataContent_CheckSanityEx(pInfo->pIndData,
+                                                                      pSignedData,
+                                                                      RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH,
+                                                                      pErrInfo);
+                    if (RT_SUCCESS(rc))
+                    {
+                        PCRTCRX509ALGORITHMIDENTIFIER pDigestAlgorithm = &pInfo->pIndData->DigestInfo.DigestAlgorithm;
+                        pInfo->enmDigest = RTCrX509AlgorithmIdentifier_QueryDigestType(pDigestAlgorithm);
+                        AssertReturn(pInfo->enmDigest != RTDIGESTTYPE_INVALID, VERR_INTERNAL_ERROR_4); /* Checked above! */
+                    }
+                    else
+                        return rc;
+                }
+            }
+        }
+    }
+
+    return VINF_SUCCESS;
 }
 
@@ -2552,38 +2684,44 @@
                             "WinCert");
 
-    int rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &pSignature->ContentInfo, "CI");
+    PRTLDRPESIGNATUREONE pInfo = &pSignature->Primary;
+    pInfo->pContentInfo = &pSignature->PrimaryContentInfo;
+    int rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, pInfo->pContentInfo, "CI");
     if (RT_SUCCESS(rc))
     {
-        if (RTCrPkcs7ContentInfo_IsSignedData(&pSignature->ContentInfo))
-        {
-            pSignature->pSignedData = pSignature->ContentInfo.u.pSignedData;
+        if (RTCrPkcs7ContentInfo_IsSignedData(pInfo->pContentInfo))
+        {
+            pInfo->pSignedData = pInfo->pContentInfo->u.pSignedData;
 
             /*
              * Decode the authenticode bits.
              */
-            if (!strcmp(pSignature->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID))
-            {
-                pSignature->pIndData = pSignature->pSignedData->ContentInfo.u.pIndirectDataContent;
-                Assert(pSignature->pIndData);
+            if (!strcmp(pInfo->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID))
+            {
+                pInfo->pIndData = pInfo->pSignedData->ContentInfo.u.pIndirectDataContent;
+                Assert(pInfo->pIndData);
 
                 /*
                  * Check that things add up.
                  */
+                rc = RTCrPkcs7SignedData_CheckSanity(pInfo->pSignedData,
+                                                     RTCRPKCS7SIGNEDDATA_SANITY_F_AUTHENTICODE
+                                                     | RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH
+                                                     | RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT,
+                                                     pErrInfo, "SD");
                 if (RT_SUCCESS(rc))
-                    rc = RTCrPkcs7SignedData_CheckSanity(pSignature->pSignedData,
-                                                         RTCRPKCS7SIGNEDDATA_SANITY_F_AUTHENTICODE
-                                                         | RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH
-                                                         | RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT,
-                                                         pErrInfo, "SD");
-                if (RT_SUCCESS(rc))
-                    rc = RTCrSpcIndirectDataContent_CheckSanityEx(pSignature->pIndData,
-                                                                  pSignature->pSignedData,
+                    rc = RTCrSpcIndirectDataContent_CheckSanityEx(pInfo->pIndData,
+                                                                  pInfo->pSignedData,
                                                                   RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH,
                                                                   pErrInfo);
                 if (RT_SUCCESS(rc))
                 {
-                    PCRTCRX509ALGORITHMIDENTIFIER pDigestAlgorithm = &pSignature->pIndData->DigestInfo.DigestAlgorithm;
-                    pSignature->enmDigest = RTCrX509AlgorithmIdentifier_QueryDigestType(pDigestAlgorithm);
-                    AssertReturn(pSignature->enmDigest != RTDIGESTTYPE_INVALID, VERR_INTERNAL_ERROR_4); /* Checked above! */
+                    PCRTCRX509ALGORITHMIDENTIFIER pDigestAlgorithm = &pInfo->pIndData->DigestInfo.DigestAlgorithm;
+                    pInfo->enmDigest = RTCrX509AlgorithmIdentifier_QueryDigestType(pDigestAlgorithm);
+                    AssertReturn(pInfo->enmDigest != RTDIGESTTYPE_INVALID, VERR_INTERNAL_ERROR_4); /* Checked above! */
+
+                    /*
+                     * Deal with nested signatures.
+                     */
+                    rc = rtldrPE_VerifySignatureDecodeNested(pSignature, pErrInfo);
                 }
             }
@@ -2591,9 +2729,9 @@
                 rc = RTErrInfoSetF(pErrInfo, VERR_LDRVI_EXPECTED_INDIRECT_DATA_CONTENT_OID,
                                    "Unknown pSignedData.ContentInfo.ContentType.szObjId value: %s (expected %s)",
-                                   pSignature->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID);
+                                   pInfo->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID);
         }
         else
             rc = RTErrInfoSetF(pErrInfo, VERR_LDRVI_EXPECTED_INDIRECT_DATA_CONTENT_OID, /** @todo error code*/
-                               "PKCS#7 is not 'signedData': %s", pSignature->ContentInfo.ContentType.szObjId);
+                               "PKCS#7 is not 'signedData': %s", pInfo->pContentInfo->ContentType.szObjId);
     }
     return rc;
@@ -2601,6 +2739,7 @@
 
 
+
 static int rtldrPE_VerifyAllPageHashes(PRTLDRMODPE pModPe, PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttrib, RTDIGESTTYPE enmDigest,
-                                       void *pvScratch, size_t cbScratch, PRTERRINFO pErrInfo)
+                                       void *pvScratch, size_t cbScratch, uint32_t iSignature, PRTERRINFO pErrInfo)
 {
     AssertReturn(cbScratch >= _4K, VERR_INTERNAL_ERROR_3);
@@ -2618,6 +2757,6 @@
     if (cPages * (cbHash + 4) != pAttrib->u.pPageHashes->RawData.Asn1Core.cb)
         return RTErrInfoSetF(pErrInfo, VERR_LDRVI_PAGE_HASH_TAB_SIZE_OVERFLOW,
-                             "Page hashes size issue: cb=%#x cbHash=%#x",
-                             pAttrib->u.pPageHashes->RawData.Asn1Core.cb, cbHash);
+                             "Signature #%u - Page hashes size issue in: cb=%#x cbHash=%#x",
+                             iSignature, pAttrib->u.pPageHashes->RawData.Asn1Core.cb, cbHash);
 
     /*
@@ -2640,10 +2779,10 @@
         if (RT_UNLIKELY(offPageInFile >= SpecialPlaces.cbToHash))
             return RTErrInfoSetF(pErrInfo, VERR_LDRVI_PAGE_HASH_TAB_TOO_LONG,
-                                 "Page hash entry #%u is beyond the signature table start: %#x, %#x",
-                                 iPage, offPageInFile, SpecialPlaces.cbToHash);
+                                 "Signature #%u - Page hash entry #%u is beyond the signature table start: %#x, %#x",
+                                 iSignature, iPage, offPageInFile, SpecialPlaces.cbToHash);
         if (RT_UNLIKELY(offPageInFile < offPrev))
             return RTErrInfoSetF(pErrInfo, VERR_LDRVI_PAGE_HASH_TAB_NOT_STRICTLY_SORTED,
-                                 "Page hash table is not strictly sorted: entry #%u @%#x, previous @%#x\n",
-                                 iPage, offPageInFile, offPrev);
+                                 "Signature #%u - Page hash table is not strictly sorted: entry #%u @%#x, previous @%#x\n",
+                                 iSignature, iPage, offPageInFile, offPrev);
 
 #ifdef COMPLICATED_AND_WRONG
@@ -2666,5 +2805,6 @@
                 else
                     return RTErrInfoSetF(pErrInfo, VERR_PAGE_HASH_TAB_HASHES_NON_SECTION_DATA,
-                                         "Page hash entry #%u isn't in any section: %#x", iPage, offPageInFile);
+                                         "Signature #%u - Page hash entry #%u isn't in any section: %#x",
+                                         iSignature, iPage, offPageInFile);
             }
         }
@@ -2710,6 +2850,6 @@
             if (RT_FAILURE(rc))
                 return RTErrInfoSetF(pErrInfo, VERR_LDRVI_READ_ERROR_HASH,
-                                     "Page hash read error at %#x: %Rrc (cbScratchRead=%#zx)",
-                                     offScratchRead, rc, cbScratchRead);
+                                     "Signature #%u - Page hash read error at %#x: %Rrc (cbScratchRead=%#zx)",
+                                     iSignature, offScratchRead, rc, cbScratchRead);
         }
 
@@ -2778,6 +2918,7 @@
         if (memcmp(pbHashTab, &HashRes, cbHash) != 0)
             return RTErrInfoSetF(pErrInfo, VERR_LDRVI_PAGE_HASH_MISMATCH,
-                                 "Page hash failed for page #%u, @%#x, %#x bytes: %.*Rhxs != %.*Rhxs",
-                                 iPage, offPageInFile, cbPageInFile, (size_t)cbHash, pbHashTab, (size_t)cbHash, &HashRes);
+                                 "Signature #%u - Page hash failed for page #%u, @%#x, %#x bytes: %.*Rhxs != %.*Rhxs",
+                                 iSignature, iPage, offPageInFile, cbPageInFile, (size_t)cbHash, pbHashTab,
+                                 (size_t)cbHash, &HashRes);
         pbHashTab += cbHash;
         offPrev = offPageInFile;
@@ -2789,8 +2930,111 @@
     if (!ASMMemIsZero(pbHashTab + 4, cbHash))
         return RTErrInfoSetF(pErrInfo, VERR_LDRVI_PAGE_HASH_TAB_TOO_LONG,
-                             "Maltform final page hash table entry: #%u %#010x %.*Rhxs",
-                             cPages - 1, RT_MAKE_U32_FROM_U8(pbHashTab[0], pbHashTab[1], pbHashTab[2], pbHashTab[3]),
+                             "Signature #%u - Malformed final page hash table entry: #%u %#010x %.*Rhxs",
+                             iSignature, cPages - 1, RT_MAKE_U32_FROM_U8(pbHashTab[0], pbHashTab[1], pbHashTab[2], pbHashTab[3]),
                              (size_t)cbHash, pbHashTab + 4);
     return VINF_SUCCESS;
+}
+
+
+static int rtldrPE_VerifySignatureValidateOnePageHashes(PRTLDRMODPE pModPe, PRTLDRPESIGNATUREONE pInfo,
+                                                        void *pvScratch, uint32_t cbScratch, PRTERRINFO pErrInfo)
+{
+    /*
+     * Compare the page hashes if present.
+     *
+     * Seems the difference between V1 and V2 page hash attributes is
+     * that v1 uses SHA-1 while v2 uses SHA-256. The data structures
+     * seems to be identical otherwise.  Initially we assumed the digest
+     * algorithm was supposed to be RTCRSPCINDIRECTDATACONTENT::DigestInfo,
+     * i.e. the same as for the whole image hash.  The initial approach
+     * worked just fine, but this makes more sense.
+     *
+     * (See also comments in osslsigncode.c (google it).)
+     */
+    PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttrib;
+    /* V2 - SHA-256: */
+    pAttrib = RTCrSpcIndirectDataContent_GetPeImageObjAttrib(pInfo->pIndData,
+                                                             RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V2);
+    if (pAttrib)
+        return rtldrPE_VerifyAllPageHashes(pModPe, pAttrib, RTDIGESTTYPE_SHA256, pvScratch, cbScratch,
+                                           pInfo->iSignature + 1, pErrInfo);
+
+    /* V1 - SHA-1: */
+    pAttrib = RTCrSpcIndirectDataContent_GetPeImageObjAttrib(pInfo->pIndData,
+                                                             RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V1);
+    if (pAttrib)
+        return rtldrPE_VerifyAllPageHashes(pModPe, pAttrib, RTDIGESTTYPE_SHA1, pvScratch, cbScratch,
+                                           pInfo->iSignature + 1, pErrInfo);
+
+    /* No page hashes: */
+    return VINF_SUCCESS;
+}
+
+
+static int rtldrPE_VerifySignatureValidateOneImageHash(PRTLDRMODPE pModPe, PRTLDRPESIGNATURE pSignature,
+                                                       PRTLDRPESIGNATUREONE pInfo, void *pvScratch, uint32_t cbScratch,
+                                                       PRTERRINFO pErrInfo)
+{
+    /*
+     * Assert sanity.
+     */
+    AssertReturn(pInfo->enmDigest > RTDIGESTTYPE_INVALID && pInfo->enmDigest < RTDIGESTTYPE_END, VERR_INTERNAL_ERROR_4);
+    AssertPtrReturn(pInfo->pIndData, VERR_INTERNAL_ERROR_5);
+    AssertReturn(RTASN1CORE_IS_PRESENT(&pInfo->pIndData->DigestInfo.Digest.Asn1Core), VERR_INTERNAL_ERROR_5);
+    AssertPtrReturn(pInfo->pIndData->DigestInfo.Digest.Asn1Core.uData.pv, VERR_INTERNAL_ERROR_5);
+
+    /*
+     * Skip it if we've already verified it.
+     */
+    if (pInfo->fValidatedImageHash)
+        return VINF_SUCCESS;
+
+    /*
+     * Calculate it.
+     */
+    uint32_t const cbHash = rtLdrPE_HashGetHashSize(pInfo->enmDigest);
+    AssertReturn(pInfo->pIndData->DigestInfo.Digest.Asn1Core.cb == cbHash, VERR_INTERNAL_ERROR_5);
+
+    int rc = rtldrPE_HashImageCommon(pModPe, pvScratch, cbScratch, pInfo->enmDigest,
+                                     &pSignature->HashCtx, &pInfo->HashRes, pErrInfo);
+    if (RT_SUCCESS(rc))
+    {
+        pInfo->fValidatedImageHash = true;
+        if (memcmp(&pInfo->HashRes, pInfo->pIndData->DigestInfo.Digest.Asn1Core.uData.pv, cbHash) == 0)
+        {
+            /*
+             * Verify other signatures with the same digest type.
+             */
+            RTLDRPEHASHRESUNION const * const pHashRes = &pInfo->HashRes;
+            for (uint32_t i = 0; i < pSignature->cNested; i++)
+            {
+                pInfo = &pSignature->paNested[i]; /* Note! pInfo changes! */
+                if (   !pInfo->fValidatedImageHash
+                    && pInfo->enmDigest == pInfo->enmDigest
+                    /* paranoia from the top of this function: */
+                    && pInfo->pIndData
+                    && RTASN1CORE_IS_PRESENT(&pInfo->pIndData->DigestInfo.Digest.Asn1Core)
+                    && pInfo->pIndData->DigestInfo.Digest.Asn1Core.uData.pv
+                    && pInfo->pIndData->DigestInfo.Digest.Asn1Core.cb == cbHash)
+                {
+                    pInfo->fValidatedImageHash = true;
+                    if (memcmp(pHashRes, pInfo->pIndData->DigestInfo.Digest.Asn1Core.uData.pv, cbHash) != 0)
+                    {
+                        rc = RTErrInfoSetF(pErrInfo, VERR_LDRVI_IMAGE_HASH_MISMATCH,
+                                           "Full image signature #%u mismatch: %.*Rhxs, expected %.*Rhxs", pInfo->iSignature + 1,
+                                           cbHash, pHashRes,
+                                           cbHash, pInfo->pIndData->DigestInfo.Digest.Asn1Core.uData.pv);
+                        break;
+                    }
+                }
+            }
+        }
+        else
+            rc = RTErrInfoSetF(pErrInfo, VERR_LDRVI_IMAGE_HASH_MISMATCH,
+                               "Full image signature #%u mismatch: %.*Rhxs, expected %.*Rhxs", pInfo->iSignature + 1,
+                               cbHash, &pInfo->HashRes,
+                               cbHash, pInfo->pIndData->DigestInfo.Digest.Asn1Core.uData.pv);
+    }
+    return rc;
 }
 
@@ -2806,12 +3050,4 @@
 static int rtldrPE_VerifySignatureValidateHash(PRTLDRMODPE pModPe, PRTLDRPESIGNATURE pSignature, PRTERRINFO pErrInfo)
 {
-    AssertReturn(pSignature->enmDigest > RTDIGESTTYPE_INVALID && pSignature->enmDigest < RTDIGESTTYPE_END, VERR_INTERNAL_ERROR_4);
-    AssertPtrReturn(pSignature->pIndData, VERR_INTERNAL_ERROR_5);
-    AssertReturn(RTASN1CORE_IS_PRESENT(&pSignature->pIndData->DigestInfo.Digest.Asn1Core), VERR_INTERNAL_ERROR_5);
-    AssertPtrReturn(pSignature->pIndData->DigestInfo.Digest.Asn1Core.uData.pv, VERR_INTERNAL_ERROR_5);
-
-    uint32_t const cbHash = rtLdrPE_HashGetHashSize(pSignature->enmDigest);
-    AssertReturn(pSignature->pIndData->DigestInfo.Digest.Asn1Core.cb == cbHash, VERR_INTERNAL_ERROR_5);
-
     /*
      * Allocate a temporary memory buffer.
@@ -2820,9 +3056,9 @@
      *       heap fragmentation.
      */
-#ifdef IN_RING0
+# ifdef IN_RING0
     uint32_t    cbScratch = _256K - _4K;
-#else
+# else
     uint32_t    cbScratch = _1M;
-#endif
+# endif
     void       *pvScratch = RTMemTmpAlloc(cbScratch);
     if (!pvScratch)
@@ -2835,44 +3071,24 @@
 
     /*
-     * Calculate and compare the full image hash.
-     */
-    int rc = rtldrPE_HashImageCommon(pModPe, pvScratch, cbScratch, pSignature->enmDigest,
-                                     &pSignature->HashCtx, &pSignature->HashRes, pErrInfo);
+     * Verify signatures.
+     */
+    /* Image hashes: */
+    int rc = rtldrPE_VerifySignatureValidateOneImageHash(pModPe, pSignature, &pSignature->Primary,
+                                                         pvScratch, cbScratch, pErrInfo);
+    for (unsigned i = 0; i < pSignature->cNested && RT_SUCCESS(rc); i++)
+        rc = rtldrPE_VerifySignatureValidateOneImageHash(pModPe, pSignature, &pSignature->paNested[i],
+                                                         pvScratch, cbScratch, pErrInfo);
+
+    /* Page hashes: */
     if (RT_SUCCESS(rc))
     {
-        if (!memcmp(&pSignature->HashRes, pSignature->pIndData->DigestInfo.Digest.Asn1Core.uData.pv, cbHash))
-        {
-            /*
-             * Compare the page hashes if present.
-             *
-             * Seems the difference between V1 and V2 page hash attributes is
-             * that v1 uses SHA-1 while v2 uses SHA-256. The data structures
-             * seems to be identical otherwise.  Initially we assumed the digest
-             * algorithm was supposed to be RTCRSPCINDIRECTDATACONTENT::DigestInfo,
-             * i.e. the same as for the whole image hash.  The initial approach
-             * worked just fine, but this makes more sense.
-             *
-             * (See also comments in osslsigncode.c (google it).)
-             */
-            PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttrib;
-            pAttrib = RTCrSpcIndirectDataContent_GetPeImageObjAttrib(pSignature->pIndData,
-                                                                     RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V2);
-            if (pAttrib)
-                rc = rtldrPE_VerifyAllPageHashes(pModPe, pAttrib, RTDIGESTTYPE_SHA256, pvScratch, cbScratch, pErrInfo);
-            else
-            {
-                pAttrib = RTCrSpcIndirectDataContent_GetPeImageObjAttrib(pSignature->pIndData,
-                                                                         RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V1);
-                if (pAttrib)
-                    rc = rtldrPE_VerifyAllPageHashes(pModPe, pAttrib, RTDIGESTTYPE_SHA1, pvScratch, cbScratch, pErrInfo);
-            }
-        }
-        else
-            rc = RTErrInfoSetF(pErrInfo, VERR_LDRVI_IMAGE_HASH_MISMATCH,
-                               "Full image signature mismatch: %.*Rhxs, expected %.*Rhxs",
-                               cbHash, &pSignature->HashRes,
-                               cbHash, pSignature->pIndData->DigestInfo.Digest.Asn1Core.uData.pv);
-    }
-
+        rc = rtldrPE_VerifySignatureValidateOnePageHashes(pModPe, &pSignature->Primary, pvScratch, cbScratch, pErrInfo);
+        for (unsigned i = 0; i < pSignature->cNested && RT_SUCCESS(rc); i++)
+            rc = rtldrPE_VerifySignatureValidateOnePageHashes(pModPe, &pSignature->paNested[i], pvScratch, cbScratch, pErrInfo);
+    }
+
+    /*
+     * Ditch the scratch buffer.
+     */
     RTMemTmpFree(pvScratch);
     return rc;
@@ -2901,8 +3117,30 @@
             if (RT_SUCCESS(rc))
             {
-                rc = pfnCallback(&pModPe->Core, RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA,
-                                 &pSignature->ContentInfo, sizeof(pSignature->ContentInfo),
-                                 NULL /*pvExternalData*/, 0 /*cbExternalData*/,
-                                 pErrInfo, pvUser);
+                /*
+                 * Work the callback.
+                 */
+                /* The primary signature: */
+                RTLDRSIGNATUREINFO Info;
+                Info.iSignature     = 0;
+                Info.cSignatures    = (uint16_t)(1 + pSignature->cNested);
+                Info.enmType        = RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA;
+                Info.pvSignature    = pSignature->Primary.pContentInfo;
+                Info.cbSignature    = sizeof(*pSignature->Primary.pContentInfo);
+                Info.pvExternalData = NULL;
+                Info.cbExternalData = 0;
+                rc = pfnCallback(&pModPe->Core, &Info, pErrInfo, pvUser);
+
+                /* The nested signatures: */
+                for (uint32_t iNested = 0; iNested < pSignature->cNested && rc == VINF_SUCCESS; iNested++)
+                {
+                    Info.iSignature     = (uint16_t)(1 + iNested);
+                    Info.cSignatures    = (uint16_t)(1 + pSignature->cNested);
+                    Info.enmType        = RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA;
+                    Info.pvSignature    = pSignature->paNested[iNested].pContentInfo;
+                    Info.cbSignature    = sizeof(*pSignature->paNested[iNested].pContentInfo);
+                    Info.pvExternalData = NULL;
+                    Info.cbExternalData = 0;
+                    rc = pfnCallback(&pModPe->Core, &Info, pErrInfo, pvUser);
+                }
             }
             rtldrPE_VerifySignatureDestroy(pModPe, pSignature);
Index: /trunk/src/VBox/Runtime/testcase/tstRTLdrVerifyPeImage.cpp
===================================================================
--- /trunk/src/VBox/Runtime/testcase/tstRTLdrVerifyPeImage.cpp	(revision 86548)
+++ /trunk/src/VBox/Runtime/testcase/tstRTLdrVerifyPeImage.cpp	(revision 86549)
@@ -44,14 +44,10 @@
 static int g_iDummy = 0;
 
-static DECLCALLBACK(int) TestCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
-                                      void const *pvSignature, size_t cbSignature,
-                                      void const *pvExternalData, size_t cbExternalData,
-                                      PRTERRINFO pErrInfo, void *pvUser)
+
+static DECLCALLBACK(int) TestCallback(RTLDRMOD hLdrMod, PCRTLDRSIGNATUREINFO pInfo, PRTERRINFO pErrInfo, void *pvUser)
 {
-    RT_NOREF_PV(hLdrMod); RT_NOREF_PV(enmSignature); RT_NOREF_PV(pvSignature); RT_NOREF_PV(cbSignature);
-    RT_NOREF_PV(pErrInfo); RT_NOREF_PV(pvUser); RT_NOREF_PV(pvExternalData); RT_NOREF_PV(cbExternalData);
+    RT_NOREF(hLdrMod, pInfo, pErrInfo, pvUser);
     return VINF_SUCCESS;
 }
-
 
 
Index: /trunk/src/VBox/Runtime/tools/RTSignTool.cpp
===================================================================
--- /trunk/src/VBox/Runtime/tools/RTSignTool.cpp	(revision 86548)
+++ /trunk/src/VBox/Runtime/tools/RTSignTool.cpp	(revision 86549)
@@ -1252,6 +1252,8 @@
     int         cVerbose;
     enum { kSignType_Windows, kSignType_OSX } enmSignType;
-    uint64_t    uTimestamp;
     RTLDRARCH   enmLdrArch;
+    uint32_t    cBad;
+    uint32_t    cOkay;
+    const char *pszFilename;
 } VERIFYEXESTATE;
 
@@ -1402,54 +1404,104 @@
 }
 
-
 /** @callback_method_impl{FNRTLDRVALIDATESIGNEDDATA}  */
-static DECLCALLBACK(int) VerifyExeCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
-                                           void const *pvSignature, size_t cbSignature,
-                                           void const *pvExternalData, size_t cbExternalData,
-                                           PRTERRINFO pErrInfo, void *pvUser)
+static DECLCALLBACK(int) VerifyExeCallback(RTLDRMOD hLdrMod, PCRTLDRSIGNATUREINFO pInfo, PRTERRINFO pErrInfo, void *pvUser)
 {
     VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser;
-    RT_NOREF_PV(hLdrMod); RT_NOREF_PV(cbSignature);
-
-    switch (enmSignature)
+    RT_NOREF_PV(hLdrMod);
+
+    switch (pInfo->enmType)
     {
         case RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA:
         {
-            PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pvSignature;
-
-            RTTIMESPEC ValidationTime;
-            RTTimeSpecSetSeconds(&ValidationTime, pState->uTimestamp);
+            PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pInfo->pvSignature;
 
             /*
-             * Dump the signed data if so requested.
+             * Dump the signed data if so requested and it's the first one, assuming that
+             * additional signatures in contained wihtin the same ContentInfo structure.
              */
-            if (pState->cVerbose)
+            if (pState->cVerbose && pInfo->iSignature == 0)
                 RTAsn1Dump(&pContentInfo->SeqCore.Asn1Core, 0, 0, RTStrmDumpPrintfV, g_pStdOut);
 
-
             /*
-             * Do the actual verification.  Will have to modify this so it takes
-             * the authenticode policies into account.
+             * We'll try different alternative timestamps here.
              */
-            if (pvExternalData)
-                return RTCrPkcs7VerifySignedDataWithExternalData(pContentInfo,
-                                                                 RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY
-                                                                 | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
-                                                                 | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT
-                                                                 | RTCRPKCS7VERIFY_SD_F_CHECK_TRUST_ANCHORS,
-                                                                 pState->hAdditionalStore, pState->hRootStore, &ValidationTime,
-                                                                 VerifyExecCertVerifyCallback, pState,
-                                                                 pvExternalData, cbExternalData, pErrInfo);
-            return RTCrPkcs7VerifySignedData(pContentInfo,
-                                             RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY
-                                             | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
-                                             | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT
-                                             | RTCRPKCS7VERIFY_SD_F_CHECK_TRUST_ANCHORS,
-                                             pState->hAdditionalStore, pState->hRootStore, &ValidationTime,
-                                             VerifyExecCertVerifyCallback, pState, pErrInfo);
+            struct { RTTIMESPEC TimeSpec; const char *pszDesc; } aTimes[2];
+            unsigned cTimes = 0;
+
+            /* Linking timestamp: */
+            uint64_t uLinkingTime = 0;
+            int rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &uLinkingTime, sizeof(uLinkingTime));
+            if (RT_SUCCESS(rc))
+            {
+                RTTimeSpecSetSeconds(&aTimes[0].TimeSpec, uLinkingTime);
+                aTimes[0].pszDesc = "at link time";
+                cTimes++;
+            }
+            else if (rc != VERR_NOT_FOUND)
+                RTMsgError("RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on '%s': %Rrc\n", pState->pszFilename, rc);
+
+            /* Now: */
+            RTTimeNow(&aTimes[cTimes].TimeSpec);
+            aTimes[cTimes].pszDesc = "now";
+            cTimes++;
+
+            /*
+             * Do the actual verification.
+             */
+            for (unsigned iTime = 0; iTime < cTimes; iTime++)
+            {
+                if (pInfo->pvExternalData)
+                    rc = RTCrPkcs7VerifySignedDataWithExternalData(pContentInfo,
+                                                                   RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY
+                                                                   | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
+                                                                   | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT
+                                                                   | RTCRPKCS7VERIFY_SD_F_CHECK_TRUST_ANCHORS,
+                                                                   pState->hAdditionalStore, pState->hRootStore,
+                                                                   &aTimes[iTime].TimeSpec,
+                                                                   VerifyExecCertVerifyCallback, pState,
+                                                                   pInfo->pvExternalData, pInfo->cbExternalData, pErrInfo);
+                else
+                    rc = RTCrPkcs7VerifySignedData(pContentInfo,
+                                                   RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY
+                                                   | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
+                                                   | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT
+                                                   | RTCRPKCS7VERIFY_SD_F_CHECK_TRUST_ANCHORS,
+                                                   pState->hAdditionalStore, pState->hRootStore,
+                                                   &aTimes[iTime].TimeSpec,
+                                                   VerifyExecCertVerifyCallback, pState, pErrInfo);
+                if (RT_SUCCESS(rc))
+                {
+                    Assert(rc == VINF_SUCCESS);
+                    if (pInfo->cSignatures == 1)
+                        RTMsgInfo("'%s' is valid %s.\n", pState->pszFilename, aTimes[iTime].pszDesc);
+                    else
+                        RTMsgInfo("'%s' signature #%u is valid %s.\n",
+                                  pState->pszFilename, pInfo->iSignature + 1, aTimes[iTime].pszDesc);
+                    pState->cOkay++;
+                    return VINF_SUCCESS;
+                }
+                if (rc != VERR_CR_X509_CPV_NOT_VALID_AT_TIME)
+                {
+                    if (pInfo->cSignatures == 1)
+                        RTMsgError("%s: Failed to verify signature: %Rrc%#RTeim\n", pState->pszFilename, rc, pErrInfo);
+                    else
+                        RTMsgError("%s: Failed to verify signature #%u: %Rrc%#RTeim\n",
+                                   pState->pszFilename, pInfo->iSignature + 1, rc, pErrInfo);
+                    pState->cBad++;
+                    return VINF_SUCCESS;
+                }
+            }
+
+            if (pInfo->cSignatures == 1)
+                RTMsgError("%s: Signature is not valid at present or link time.\n", pState->pszFilename);
+            else
+                RTMsgError("%s: Signature #%u is not valid at present or link time.\n",
+                           pState->pszFilename, pInfo->iSignature + 1);
+            pState->cBad++;
+            return VINF_SUCCESS;
         }
 
         default:
-            return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", enmSignature);
+            return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", pInfo->enmType);
     }
 }
@@ -1468,31 +1520,12 @@
         return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszFilename, rc);
 
-
-    RTTIMESPEC Now;
-    bool       fTriedNow = false;
-    rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &pState->uTimestamp, sizeof(pState->uTimestamp));
-    if (rc == VERR_NOT_FOUND)
-    {
-        fTriedNow = true;
-        pState->uTimestamp = RTTimeSpecGetSeconds(RTTimeNow(&Now));
-        rc = VINF_SUCCESS;
-    }
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
-        if (RT_SUCCESS(rc))
-            RTMsgInfo("'%s' is valid.\n", pszFilename);
-        else if (rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME && !fTriedNow)
-        {
-            pState->uTimestamp = RTTimeSpecGetSeconds(RTTimeNow(&Now));
-            rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
-            if (RT_SUCCESS(rc))
-                RTMsgInfo("'%s' is valid now, but not at link time.\n", pszFilename);
-        }
-        if (RT_FAILURE(rc))
-            RTMsgError("RTLdrVerifySignature failed on '%s': %Rrc - %s\n", pszFilename, rc, pStaticErrInfo->szMsg);
-    }
-    else
-        RTMsgError("RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on '%s': %Rrc\n", pszFilename, rc);
+    /* Reset the state. */
+    pState->cBad        = 0;
+    pState->cOkay       = 0;
+    pState->pszFilename = pszFilename;
+
+    rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
+    if (RT_FAILURE(rc))
+        RTMsgError("RTLdrVerifySignature failed on '%s': %Rrc - %s\n", pszFilename, rc, pStaticErrInfo->szMsg);
 
     int rc2 = RTLdrClose(hLdrMod);
@@ -1502,5 +1535,5 @@
         return rc != VERR_LDRVI_NOT_SIGNED ? RTEXITCODE_FAILURE : RTEXITCODE_SKIPPED;
 
-    return RTEXITCODE_SUCCESS;
+    return pState->cOkay > 0 ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
 }
 
@@ -1531,6 +1564,7 @@
     VERIFYEXESTATE State =
     {
-        NIL_RTCRSTORE, NIL_RTCRSTORE, NIL_RTCRSTORE, false, false,
-        VERIFYEXESTATE::kSignType_Windows, 0, RTLDRARCH_WHATEVER
+        NIL_RTCRSTORE, NIL_RTCRSTORE, NIL_RTCRSTORE, false, 0,
+        VERIFYEXESTATE::kSignType_Windows, RTLDRARCH_WHATEVER,
+        0, 0, NULL
     };
     int rc = RTCrStoreCreateInMem(&State.hRootStore, 0);
