VirtualBox

Changeset 86549 in vbox for trunk/src


Ignore:
Timestamp:
Oct 12, 2020 11:59:53 PM (4 years ago)
Author:
vboxsync
Message:

SUPHardNt,IPRT: If there are nested signatures (i.e. more than one signature), don't get grumpy if there are time or cert path issues with some of them, as long as one or more checks out perfectly. (Mind, all the signature data must check out, it's just the cert path or signing time we're relaxing here.) ticketref:19743 bugref:3103

Location:
trunk/src/VBox
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp

    r85172 r86549  
    13531353 * @callback_method_impl{FNRTLDRVALIDATESIGNEDDATA}
    13541354 */
    1355 static DECLCALLBACK(int) supdrvDarwinLdrOpenVerifyCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
    1356                                                            void const *pvSignature, size_t cbSignature,
    1357                                                            void const *pvExternalData, size_t cbExternalData,
     1355static DECLCALLBACK(int) supdrvDarwinLdrOpenVerifyCallback(RTLDRMOD hLdrMod, PCRTLDRSIGNATUREINFO pInfo,
    13581356                                                           PRTERRINFO pErrInfo, void *pvUser)
    13591357{
    13601358    PSUPDRVDEVEXT pDevExt = (PSUPDRVDEVEXT)pvUser;
    1361     RT_NOREF_PV(hLdrMod); RT_NOREF_PV(cbSignature);
    1362 
    1363     switch (enmSignature)
     1359    RT_NOREF_PV(hLdrMod);
     1360
     1361    switch (pInfo->enmType)
    13641362    {
    13651363        case RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA:
    1366             if (pvExternalData)
     1364            if (pInfo->pvExternalData)
    13671365            {
    1368                 PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pvSignature;
     1366                PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pInfo->pvSignature;
    13691367                RTTIMESPEC             ValidationTime;
    13701368                RTTimeNow(&ValidationTime);
     
    13761374                                                                 pDevExt->hAdditionalStore, pDevExt->hRootStore, &ValidationTime,
    13771375                                                                 supdrvDarwinLdrOpenVerifyCertificatCallback, pDevExt,
    1378                                                                  pvExternalData, cbExternalData, pErrInfo);
     1376                                                                 pInfo->pvExternalData, pInfo->cbExternalData, pErrInfo);
    13791377            }
    13801378            return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Expected external data with signature!");
    13811379
    13821380        default:
    1383             return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", enmSignature);
     1381            return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", pInfo->enmType);
    13841382    }
    13851383}
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h

    r85127 r86549  
    9898    /** The file handle. */
    9999    HANDLE      hFile;
    100     /** Handle to event sempahore in case we're force to deal with asynchronous
    101      * I/O. */
     100    /** Handle to event sempahore in case we're force to deal with asynchronous I/O. */
    102101    HANDLE      hEvent;
    103102    /** Current file offset. */
     
    107106    /** Flags for the verification callback, SUPHNTVI_F_XXX. */
    108107    uint32_t    fFlags;
    109     /** The executable timstamp in second since unix epoch. */
    110     uint64_t    uTimestamp;
     108    /** Number of signatures that verified okay. */
     109    uint16_t    cOkaySignatures;
     110    /** Number of signatures that couldn't be successfully verified (time stamp
     111     * issues, no certificate path, etc) but weren't fatal. */
     112    uint16_t    cNokSignatures;
     113    /** Total number of signatures. */
     114    uint16_t    cTotalSignatures;
     115    /** The last non-fatal signature failure. */
     116    int         rcLastSignatureFailure;
    111117    /** Log name. */
    112118    char        szFilename[1];
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp

    r85127 r86549  
    10591059
    10601060
    1061 static DECLCALLBACK(int) supHardNtViCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
    1062                                              void const *pvSignature, size_t cbSignature,
    1063                                              void const *pvExternalData, size_t cbExternalData,
    1064                                              PRTERRINFO pErrInfo, void *pvUser)
    1065 {
    1066     RT_NOREF(hLdrMod, enmSignature, pvExternalData, cbExternalData);
     1061/**
     1062 * RTTimeNow equivaltent that handles ring-3 where we cannot use it.
     1063 *
     1064 * @returns pNow
     1065 * @param   pNow                Where to return the current time.
     1066 */
     1067static PRTTIMESPEC supHardNtTimeNow(PRTTIMESPEC pNow)
     1068{
     1069#ifdef IN_RING3
     1070    /*
     1071     * Just read system time.
     1072     */
     1073    KUSER_SHARED_DATA volatile *pUserSharedData = (KUSER_SHARED_DATA volatile *)MM_SHARED_USER_DATA_VA;
     1074# ifdef RT_ARCH_AMD64
     1075    uint64_t uRet = *(uint64_t volatile *)&pUserSharedData->SystemTime; /* This is what KeQuerySystemTime does (missaligned). */
     1076    return RTTimeSpecSetNtTime(pNow, uRet);
     1077# else
     1078
     1079    LARGE_INTEGER NtTime;
     1080    do
     1081    {
     1082        NtTime.HighPart = pUserSharedData->SystemTime.High1Time;
     1083        NtTime.LowPart  = pUserSharedData->SystemTime.LowPart;
     1084    } while (pUserSharedData->SystemTime.High2Time != NtTime.HighPart);
     1085    return RTTimeSpecSetNtTime(pNow, NtTime.QuadPart);
     1086# endif
     1087#else  /* IN_RING0 */
     1088    return RTTimeNow(pNow);
     1089#endif /* IN_RING0 */
     1090}
     1091
     1092
     1093/**
     1094 * @callback_method_impl{FNRTLDRVALIDATESIGNEDDATA}
     1095 */
     1096static DECLCALLBACK(int) supHardNtViCallback(RTLDRMOD hLdrMod, PCRTLDRSIGNATUREINFO pInfo, PRTERRINFO pErrInfo, void *pvUser)
     1097{
     1098    RT_NOREF(hLdrMod);
    10671099
    10681100    /*
     
    10711103    PSUPHNTVIRDR pNtViRdr = (PSUPHNTVIRDR)pvUser;
    10721104    Assert(pNtViRdr->Core.uMagic == RTLDRREADER_MAGIC);
    1073 
    1074     AssertReturn(cbSignature == sizeof(RTCRPKCS7CONTENTINFO), VERR_INTERNAL_ERROR_5);
    1075     PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pvSignature;
     1105    pNtViRdr->cTotalSignatures = pInfo->cSignatures;
     1106
     1107    AssertReturn(pInfo->enmType == RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA, VERR_INTERNAL_ERROR_5);
     1108    AssertReturn(!pInfo->pvExternalData, VERR_INTERNAL_ERROR_5);
     1109    AssertReturn(pInfo->cbSignature == sizeof(RTCRPKCS7CONTENTINFO), VERR_INTERNAL_ERROR_5);
     1110    PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pInfo->pvSignature;
    10761111    AssertReturn(RTCrPkcs7ContentInfo_IsSignedData(pContentInfo), VERR_INTERNAL_ERROR_5);
    10771112    AssertReturn(pContentInfo->u.pSignedData->SignerInfos.cItems == 1, VERR_INTERNAL_ERROR_5);
    10781113    PCRTCRPKCS7SIGNERINFO pSignerInfo = pContentInfo->u.pSignedData->SignerInfos.papItems[0];
    10791114
    1080     AssertReturn(!pvExternalData, VERR_INTERNAL_ERROR_5);
    10811115
    10821116    /*
    10831117     * If special certificate requirements, check them out before validating
    1084      * the signature.
    1085      */
    1086     if (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_BUILD_CERT)
     1118     * the signature.  These only apply to the first signature (for now).
     1119     */
     1120    if (   (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_BUILD_CERT)
     1121        && pInfo->iSignature == 0)
    10871122    {
    10881123        if (!RTCrX509Certificate_MatchIssuerAndSerialNumber(&g_BuildX509Cert,
     
    10981133
    10991134    /*
    1100      * Verify the signature.  We instruct the verifier to use the signing time
    1101      * counter signature present when present, falling back on the timestamp
    1102      * planted by the linker when absent.  In ring-0 we don't have all the
    1103      * necessary timestamp server root certificate info, so we have to allow
    1104      * using counter signatures unverified there.  Ditto for the early period
    1105      * of ring-3 hardened stub execution.
    1106      */
    1107     RTTIMESPEC ValidationTime;
    1108     RTTimeSpecSetSeconds(&ValidationTime, pNtViRdr->uTimestamp);
    1109 
     1135     * We instruction the verifier to use the signing time counter signature
     1136     * when present, but provides the linker time then the current time as
     1137     * fallbacks should the timestamp be missing or unusable.
     1138     *
     1139     * Update: Save the first timestamp we validate with build cert and
     1140     *         use this as a minimum timestamp for further build cert
     1141     *         validations.  This works around issues with old DLLs that
     1142     *         we sign against with our certificate (crt, sdl, qt).
     1143     *
     1144     * Update: If the validation fails, retry with the current timestamp. This
     1145     *         is a workaround for NTDLL.DLL in build 14971 having a weird
     1146     *         timestamp: 0xDF1E957E (Sat Aug 14 14:05:18 2088).
     1147     */
    11101148    uint32_t fFlags = RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
    11111149                    | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT
    11121150                    | RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY;
     1151
     1152    /* In ring-0 we don't have all the necessary timestamp server root certificate
     1153     * info, so we have to allow using counter signatures unverified there.
     1154     * Ditto for the early period of ring-3 hardened stub execution. */
    11131155#ifndef IN_RING0
    11141156    if (!g_fHaveOtherRoots)
    11151157#endif
    11161158        fFlags |= RTCRPKCS7VERIFY_SD_F_USE_SIGNING_TIME_UNVERIFIED | RTCRPKCS7VERIFY_SD_F_USE_MS_TIMESTAMP_UNVERIFIED;
    1117     return RTCrPkcs7VerifySignedData(pContentInfo, fFlags, g_hSpcAndNtKernelSuppStore, g_hSpcAndNtKernelRootStore,
    1118                                      &ValidationTime, supHardNtViCertVerifyCallback, pNtViRdr, pErrInfo);
    1119 }
    1120 
    1121 
    1122 /**
    1123  * RTTimeNow equivaltent that handles ring-3 where we cannot use it.
    1124  *
    1125  * @returns pNow
    1126  * @param   pNow                Where to return the current time.
    1127  */
    1128 static PRTTIMESPEC supHardNtTimeNow(PRTTIMESPEC pNow)
    1129 {
    1130 #ifdef IN_RING3
    1131     /*
    1132      * Just read system time.
    1133      */
    1134     KUSER_SHARED_DATA volatile *pUserSharedData = (KUSER_SHARED_DATA volatile *)MM_SHARED_USER_DATA_VA;
    1135 # ifdef RT_ARCH_AMD64
    1136     uint64_t uRet = *(uint64_t volatile *)&pUserSharedData->SystemTime; /* This is what KeQuerySystemTime does (missaligned). */
    1137     return RTTimeSpecSetNtTime(pNow, uRet);
    1138 # else
    1139 
    1140     LARGE_INTEGER NtTime;
    1141     do
    1142     {
    1143         NtTime.HighPart = pUserSharedData->SystemTime.High1Time;
    1144         NtTime.LowPart  = pUserSharedData->SystemTime.LowPart;
    1145     } while (pUserSharedData->SystemTime.High2Time != NtTime.HighPart);
    1146     return RTTimeSpecSetNtTime(pNow, NtTime.QuadPart);
    1147 # endif
    1148 #else  /* IN_RING0 */
    1149     return RTTimeNow(pNow);
    1150 #endif /* IN_RING0 */
     1159
     1160    /* Fallback timestamps to try: */
     1161    struct { RTTIMESPEC TimeSpec; const char *pszDesc; } aTimes[2];
     1162    unsigned cTimes = 0;
     1163
     1164    /* 1. The linking timestamp: */
     1165    uint64_t uTimestamp = 0;
     1166    int rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &uTimestamp, sizeof(uTimestamp));
     1167    if (RT_SUCCESS(rc))
     1168    {
     1169#ifdef IN_RING3 /* Hack alert! (see above) */
     1170        if (   (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING)
     1171            && (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT)
     1172            && uTimestamp < g_uBuildTimestampHack)
     1173            uTimestamp = g_uBuildTimestampHack;
     1174#endif
     1175        RTTimeSpecSetSeconds(&aTimes[0].TimeSpec, uTimestamp);
     1176        aTimes[0].pszDesc = "link";
     1177        cTimes++;
     1178    }
     1179    else
     1180        SUP_DPRINTF(("RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on %s: %Rrc", pNtViRdr->szFilename, rc));
     1181
     1182    /* 2. Current time. */
     1183    supHardNtTimeNow(&aTimes[cTimes].TimeSpec);
     1184    aTimes[cTimes].pszDesc = "now";
     1185    cTimes++;
     1186
     1187    /* Make the verfication attempts. */
     1188    for (unsigned i = 0; ; i++)
     1189    {
     1190        Assert(i < cTimes);
     1191        rc = RTCrPkcs7VerifySignedData(pContentInfo, fFlags, g_hSpcAndNtKernelSuppStore, g_hSpcAndNtKernelRootStore,
     1192                                       &aTimes[i].TimeSpec, supHardNtViCertVerifyCallback, pNtViRdr, pErrInfo);
     1193        if (RT_SUCCESS(rc))
     1194        {
     1195            if (rc != VINF_SUCCESS)
     1196            {
     1197                SUP_DPRINTF(("%s: Signature #%u/%u: info status: %d\n", pNtViRdr->szFilename, pInfo->iSignature, pInfo->cbSignature, rc));
     1198                if (pNtViRdr->rcLastSignatureFailure == VINF_SUCCESS)
     1199                    pNtViRdr->rcLastSignatureFailure = rc;
     1200            }
     1201            pNtViRdr->cOkaySignatures++;
     1202
     1203#ifdef IN_RING3 /* Hack alert! (see above) */
     1204            if ((pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_BUILD_CERT) && g_uBuildTimestampHack == 0 && cTimes > 1)
     1205                g_uBuildTimestampHack = uTimestamp;
     1206#endif
     1207            return VINF_SUCCESS;
     1208        }
     1209
     1210        if (rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME && i + 1 < cTimes)
     1211            SUP_DPRINTF(("%s: Signature #%u/%u: VERR_CR_X509_CPV_NOT_VALID_AT_TIME for %#RX64; retrying against current time: %#RX64.\n",
     1212                         pNtViRdr->szFilename, pInfo->iSignature, pInfo->cbSignature,
     1213                         RTTimeSpecGetSeconds(&aTimes[0].TimeSpec), RTTimeSpecGetSeconds(&aTimes[1].TimeSpec)));
     1214        else
     1215        {
     1216            /* There are a couple of failures we can tollerate if there are more than
     1217               one signature and one of them works out fine.  The RTLdrVerifySignature
     1218               caller will have to check the failure counts though to make sure
     1219               something succeeded. */
     1220            pNtViRdr->rcLastSignatureFailure = rc;
     1221            if (   rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME
     1222                || rc == VERR_CR_X509_CPV_NO_TRUSTED_PATHS)
     1223            {
     1224                SUP_DPRINTF(("%s: Signature #%u/%u: %s (%d) w/ timestamp=%#RX64/%s.\n", pNtViRdr->szFilename, pInfo->iSignature, pInfo->cbSignature,
     1225                             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,
     1226                             RTTimeSpecGetSeconds(&aTimes[i].TimeSpec), aTimes[i].pszDesc));
     1227
     1228                /* This leniency is not applicable to build certificate requirements (signature #1 only). */
     1229                if (  !(pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_BUILD_CERT)
     1230                    || pInfo->iSignature != 0)
     1231                {
     1232                    pNtViRdr->cNokSignatures++;
     1233                    rc = VINF_SUCCESS;
     1234                }
     1235            }
     1236            else
     1237                SUP_DPRINTF(("%s: Signature #%u/%u: %Rrc w/ timestamp=%#RX64/%s.\n", pNtViRdr->szFilename, pInfo->iSignature, pInfo->cbSignature,
     1238                             rc, RTTimeSpecGetSeconds(&aTimes[i].TimeSpec), aTimes[i].pszDesc));
     1239            return rc;
     1240        }
     1241    }
    11511242}
    11521243
     
    12221313     * The PKCS #7 SignedData signature is checked in the callback. Any
    12231314     * signing certificate restrictions are also enforced there.
    1224      *
    1225      * For the time being, we use the executable timestamp as the
    1226      * certificate validation date.  We must query that first to avoid
    1227      * potential issues re-entering the loader code from the callback.
    1228      *
    1229      * Update: Save the first timestamp we validate with build cert and
    1230      *         use this as a minimum timestamp for further build cert
    1231      *         validations.  This works around issues with old DLLs that
    1232      *         we sign against with our certificate (crt, sdl, qt).
    1233      *
    1234      * Update: If the validation fails, retry with the current timestamp. This
    1235      *         is a workaround for NTDLL.DLL in build 14971 having a weird
    1236      *         timestamp: 0xDF1E957E (Sat Aug 14 14:05:18 2088).
    1237      */
    1238     int rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &pNtViRdr->uTimestamp, sizeof(pNtViRdr->uTimestamp));
     1315     */
     1316    pNtViRdr->cOkaySignatures        = 0;
     1317    pNtViRdr->cNokSignatures         = 0;
     1318    pNtViRdr->cTotalSignatures       = 0;
     1319    pNtViRdr->rcLastSignatureFailure = VINF_SUCCESS;
     1320    int rc = RTLdrVerifySignature(hLdrMod, supHardNtViCallback, pNtViRdr, pErrInfo);
    12391321    if (RT_SUCCESS(rc))
    12401322    {
    1241 #ifdef IN_RING3 /* Hack alert! (see above) */
    1242         if (   (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING)
    1243             && (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT)
    1244             && pNtViRdr->uTimestamp < g_uBuildTimestampHack)
    1245             pNtViRdr->uTimestamp = g_uBuildTimestampHack;
    1246 #endif
    1247 
    1248         rc = RTLdrVerifySignature(hLdrMod, supHardNtViCallback, pNtViRdr, pErrInfo);
    1249 
    1250 #ifdef IN_RING3 /* Hack alert! (see above) */
    1251         if ((pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_BUILD_CERT) && g_uBuildTimestampHack == 0 && RT_SUCCESS(rc))
    1252             g_uBuildTimestampHack = pNtViRdr->uTimestamp;
    1253 #endif
    1254 
    1255         if (rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME)
     1323        Assert(pNtViRdr->cOkaySignatures + pNtViRdr->cNokSignatures == pNtViRdr->cTotalSignatures);
     1324        if (   !pNtViRdr->cOkaySignatures
     1325            || pNtViRdr->cOkaySignatures + pNtViRdr->cNokSignatures < pNtViRdr->cTotalSignatures /* paranoia */)
    12561326        {
    1257             RTTIMESPEC Now;
    1258             uint64_t uOld = pNtViRdr->uTimestamp;
    1259             pNtViRdr->uTimestamp = RTTimeSpecGetSeconds(supHardNtTimeNow(&Now));
    1260             SUP_DPRINTF(("%ls: VERR_CR_X509_CPV_NOT_VALID_AT_TIME for %#RX64; retrying against current time: %#RX64.\n",
    1261                          pwszName, uOld, pNtViRdr->uTimestamp)); NOREF(uOld);
    1262             rc = RTLdrVerifySignature(hLdrMod, supHardNtViCallback, pNtViRdr, pErrInfo);
     1327            rc = pNtViRdr->rcLastSignatureFailure;
     1328            AssertStmt(RT_FAILURE_NP(rc), rc = VERR_INTERNAL_ERROR_3);
    12631329        }
    1264 
    1265         /*
    1266          * Microsoft doesn't sign a whole bunch of DLLs, so we have to
    1267          * ASSUME that a bunch of system DLLs are fine.
    1268          */
    1269         if (rc == VERR_LDRVI_NOT_SIGNED)
    1270             rc = supHardNtViCheckIfNotSignedOk(hLdrMod, pwszName, pNtViRdr->fFlags, pNtViRdr->hFile, rc);
    1271         if (RT_FAILURE(rc))
    1272             RTErrInfoAddF(pErrInfo, rc, ": %ls", pwszName);
    1273 
    1274         /*
    1275          * Check for the signature checking enforcement, if requested to do so.
    1276          */
    1277         if (RT_SUCCESS(rc) && (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT))
    1278         {
    1279             bool fEnforced = false;
    1280             int rc2 = RTLdrQueryProp(hLdrMod, RTLDRPROP_SIGNATURE_CHECKS_ENFORCED, &fEnforced, sizeof(fEnforced));
    1281             if (RT_FAILURE(rc2))
    1282                 rc = RTErrInfoSetF(pErrInfo, rc2, "Querying RTLDRPROP_SIGNATURE_CHECKS_ENFORCED failed on %ls: %Rrc.",
    1283                                    pwszName, rc2);
    1284             else if (!fEnforced)
    1285                 rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_SIGNATURE_CHECKS_NOT_ENFORCED,
    1286                                    "The image '%ls' was not linked with /IntegrityCheck.", pwszName);
    1287         }
    1288     }
    1289     else
    1290         RTErrInfoSetF(pErrInfo, rc, "RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on %ls: %Rrc", pwszName, rc);
     1330        else if (rc == VINF_SUCCESS && RT_SUCCESS(pNtViRdr->rcLastSignatureFailure))
     1331            rc = pNtViRdr->rcLastSignatureFailure;
     1332    }
     1333
     1334    /*
     1335     * Microsoft doesn't sign a whole bunch of DLLs, so we have to
     1336     * ASSUME that a bunch of system DLLs are fine.
     1337     */
     1338    if (rc == VERR_LDRVI_NOT_SIGNED)
     1339        rc = supHardNtViCheckIfNotSignedOk(hLdrMod, pwszName, pNtViRdr->fFlags, pNtViRdr->hFile, rc);
     1340    if (RT_FAILURE(rc))
     1341        RTErrInfoAddF(pErrInfo, rc, ": %ls", pwszName);
     1342
     1343    /*
     1344     * Check for the signature checking enforcement, if requested to do so.
     1345     */
     1346    if (RT_SUCCESS(rc) && (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT))
     1347    {
     1348        bool fEnforced = false;
     1349        int rc2 = RTLdrQueryProp(hLdrMod, RTLDRPROP_SIGNATURE_CHECKS_ENFORCED, &fEnforced, sizeof(fEnforced));
     1350        if (RT_FAILURE(rc2))
     1351            rc = RTErrInfoSetF(pErrInfo, rc2, "Querying RTLDRPROP_SIGNATURE_CHECKS_ENFORCED failed on %ls: %Rrc.",
     1352                               pwszName, rc2);
     1353        else if (!fEnforced)
     1354            rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_SIGNATURE_CHECKS_NOT_ENFORCED,
     1355                               "The image '%ls' was not linked with /IntegrityCheck.", pwszName);
     1356    }
    12911357
    12921358#ifdef IN_RING3
  • trunk/src/VBox/Runtime/common/ldr/ldrMachO.cpp

    r85678 r86549  
    55375537                     * Finally, let the caller verify the certificate chain for the PKCS#7 bit.
    55385538                     */
    5539                     rc = pfnCallback(&pThis->Core, RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA,
    5540                                      &pSignature->ContentInfo, sizeof(pSignature->ContentInfo),
    5541                                      pSignature->aCodeDirs[0].pCodeDir, pSignature->aCodeDirs[0].cb,
    5542                                      pErrInfo, pvUser);
     5539                    RTLDRSIGNATUREINFO Info;
     5540                    Info.iSignature     = 0;
     5541                    Info.cSignatures    = 1;
     5542                    Info.enmType        = RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA;
     5543                    Info.pvSignature    = &pSignature->ContentInfo;
     5544                    Info.cbSignature    = sizeof(pSignature->ContentInfo);
     5545                    Info.pvExternalData = pSignature->aCodeDirs[0].pCodeDir;
     5546                    Info.cbExternalData = pSignature->aCodeDirs[0].cb;
     5547                    rc = pfnCallback(&pThis->Core, &Info, pErrInfo, pvUser);
    55435548                }
    55445549            }
  • trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp

    r85121 r86549  
    216216#ifndef IPRT_WITHOUT_LDR_VERIFY
    217217/**
    218  * Parsed signature data.
    219  */
    220 typedef struct RTLDRPESIGNATURE
     218 * Parsed data for one signature.
     219 */
     220typedef struct RTLDRPESIGNATUREONE
    221221{
    222222    /** The outer content info wrapper. */
    223     RTCRPKCS7CONTENTINFO        ContentInfo;
     223    PRTCRPKCS7CONTENTINFO       pContentInfo;
    224224    /** Pointer to the decoded SignedData inside the ContentInfo member. */
    225225    PRTCRPKCS7SIGNEDDATA        pSignedData;
     
    228228    /** The digest type employed by the signature. */
    229229    RTDIGESTTYPE                enmDigest;
    230 
     230    /** Set if we've already validate the image hash. */
     231    bool                        fValidatedImageHash;
     232    /** The signature number. */
     233    uint16_t                    iSignature;
     234    /** Hash result. */
     235    RTLDRPEHASHRESUNION         HashRes;
     236} RTLDRPESIGNATUREONE;
     237/** Pointer to the parsed data of one signature. */
     238typedef RTLDRPESIGNATUREONE *PRTLDRPESIGNATUREONE;
     239
     240/**
     241 * Parsed signature data.
     242 */
     243typedef struct RTLDRPESIGNATURE
     244{
    231245    /** Pointer to the raw signatures.  This is allocated in the continuation of
    232246     * this structure to keep things simple.  The size is given by  the security
    233247     * export directory. */
    234248    WIN_CERTIFICATE const      *pRawData;
    235 
     249    /** The outer content info wrapper (primary signature). */
     250    RTCRPKCS7CONTENTINFO        PrimaryContentInfo;
     251    /** The info for the primary signature. */
     252    RTLDRPESIGNATUREONE         Primary;
     253    /** Number of nested signatures (zero if none). */
     254    uint16_t                    cNested;
     255    /** Pointer to an array of nested signatures (NULL if none). */
     256    PRTLDRPESIGNATUREONE        paNested;
    236257    /** Hash scratch data. */
    237258    RTLDRPEHASHCTXUNION         HashCtx;
    238     /** Hash result. */
    239     RTLDRPEHASHRESUNION         HashRes;
    240259} RTLDRPESIGNATURE;
    241260/** Pointed to SigneData parsing stat and output. */
     
    25232542{
    25242543    RT_NOREF_PV(pModPe);
    2525     RTCrPkcs7ContentInfo_Delete(&pSignature->ContentInfo);
     2544    RTCrPkcs7ContentInfo_Delete(&pSignature->PrimaryContentInfo);
     2545    if (pSignature->paNested > 0)
     2546    {
     2547        RTMemTmpFree(pSignature->paNested);
     2548        pSignature->paNested = NULL;
     2549    }
    25262550    RTMemTmpFree(pSignature);
     2551}
     2552
     2553
     2554/**
     2555 * Handles nested signatures.
     2556 *
     2557 * @returns IPRT status code.
     2558 * @param   pSignature          The signature status structure.  Returns with
     2559 *                              cNested = 0 and paNested = NULL if no nested
     2560 *                              signatures.
     2561 * @param   pErrInfo            Where to return extended error info (optional).
     2562 */
     2563static int rtldrPE_VerifySignatureDecodeNested(PRTLDRPESIGNATURE pSignature, PRTERRINFO pErrInfo)
     2564{
     2565    Assert(pSignature->cNested == 0);
     2566    Assert(pSignature->paNested == NULL);
     2567
     2568    /*
     2569     * Count nested signatures.
     2570     */
     2571    uint32_t cNested = 0;
     2572    for (uint32_t iSignerInfo = 0; iSignerInfo < pSignature->Primary.pSignedData->SignerInfos.cItems; iSignerInfo++)
     2573    {
     2574        PCRTCRPKCS7SIGNERINFO pSignerInfo = pSignature->Primary.pSignedData->SignerInfos.papItems[iSignerInfo];
     2575        for (uint32_t iAttrib = 0; iAttrib < pSignerInfo->UnauthenticatedAttributes.cItems; iAttrib++)
     2576        {
     2577            PCRTCRPKCS7ATTRIBUTE pAttrib = pSignerInfo->UnauthenticatedAttributes.papItems[iAttrib];
     2578            if (pAttrib->enmType == RTCRPKCS7ATTRIBUTETYPE_MS_NESTED_SIGNATURE)
     2579            {
     2580                Assert(pAttrib->uValues.pContentInfos);
     2581                cNested += pAttrib->uValues.pContentInfos->cItems;
     2582            }
     2583        }
     2584    }
     2585    if (!cNested)
     2586        return VINF_SUCCESS;
     2587
     2588    /*
     2589     * Allocate and populate the info structures.
     2590     */
     2591    pSignature->paNested = (PRTLDRPESIGNATUREONE)RTMemTmpAllocZ(sizeof(pSignature->paNested[0]) * cNested);
     2592    if (!pSignature->paNested)
     2593        return RTErrInfoSetF(pErrInfo, VERR_NO_TMP_MEMORY, "Failed to allocate space for %u nested signatures", cNested);
     2594    pSignature->cNested = cNested;
     2595
     2596    cNested = 0;
     2597    for (uint32_t iSignerInfo = 0; iSignerInfo < pSignature->Primary.pSignedData->SignerInfos.cItems; iSignerInfo++)
     2598    {
     2599        PCRTCRPKCS7SIGNERINFO pSignerInfo = pSignature->Primary.pSignedData->SignerInfos.papItems[iSignerInfo];
     2600        for (uint32_t iAttrib = 0; iAttrib < pSignerInfo->UnauthenticatedAttributes.cItems; iAttrib++)
     2601        {
     2602            PCRTCRPKCS7ATTRIBUTE pAttrib = pSignerInfo->UnauthenticatedAttributes.papItems[iAttrib];
     2603            if (pAttrib->enmType == RTCRPKCS7ATTRIBUTETYPE_MS_NESTED_SIGNATURE)
     2604            {
     2605                for (uint32_t iItem = 0; iItem < pAttrib->uValues.pContentInfos->cItems; iItem++, cNested++)
     2606                {
     2607                    PRTLDRPESIGNATUREONE  pInfo        = &pSignature->paNested[cNested];
     2608                    PRTCRPKCS7CONTENTINFO pContentInfo = pAttrib->uValues.pContentInfos->papItems[iItem];
     2609                    pInfo->pContentInfo = pContentInfo;
     2610                    pInfo->iSignature   = cNested;
     2611
     2612                    if (RTCrPkcs7ContentInfo_IsSignedData(pInfo->pContentInfo))
     2613                    { /* likely */ }
     2614                    else
     2615                        return RTErrInfoSetF(pErrInfo, VERR_LDRVI_EXPECTED_INDIRECT_DATA_CONTENT_OID, /** @todo error code*/
     2616                                             "Nested#%u: PKCS#7 is not 'signedData': %s", cNested, pInfo->pContentInfo->ContentType.szObjId);
     2617                    PRTCRPKCS7SIGNEDDATA pSignedData = pContentInfo->u.pSignedData;
     2618                    pInfo->pSignedData = pSignedData;
     2619
     2620                    /*
     2621                     * Check the authenticode bits.
     2622                     */
     2623                    if (!strcmp(pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID))
     2624                    { /* likely */ }
     2625                    else
     2626                        return RTErrInfoSetF(pErrInfo, VERR_LDRVI_EXPECTED_INDIRECT_DATA_CONTENT_OID,
     2627                                             "Nested#%u: Unknown pSignedData.ContentInfo.ContentType.szObjId value: %s (expected %s)",
     2628                                             cNested, pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID);
     2629                    pInfo->pIndData = pSignedData->ContentInfo.u.pIndirectDataContent;
     2630                    Assert(pInfo->pIndData);
     2631
     2632                    /*
     2633                     * Check that things add up.
     2634                     */
     2635                    int rc = RTCrPkcs7SignedData_CheckSanity(pSignedData,
     2636                                                             RTCRPKCS7SIGNEDDATA_SANITY_F_AUTHENTICODE
     2637                                                             | RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH
     2638                                                             | RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT,
     2639                                                             pErrInfo, "SD");
     2640                    if (RT_SUCCESS(rc))
     2641                        rc = RTCrSpcIndirectDataContent_CheckSanityEx(pInfo->pIndData,
     2642                                                                      pSignedData,
     2643                                                                      RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH,
     2644                                                                      pErrInfo);
     2645                    if (RT_SUCCESS(rc))
     2646                    {
     2647                        PCRTCRX509ALGORITHMIDENTIFIER pDigestAlgorithm = &pInfo->pIndData->DigestInfo.DigestAlgorithm;
     2648                        pInfo->enmDigest = RTCrX509AlgorithmIdentifier_QueryDigestType(pDigestAlgorithm);
     2649                        AssertReturn(pInfo->enmDigest != RTDIGESTTYPE_INVALID, VERR_INTERNAL_ERROR_4); /* Checked above! */
     2650                    }
     2651                    else
     2652                        return rc;
     2653                }
     2654            }
     2655        }
     2656    }
     2657
     2658    return VINF_SUCCESS;
    25272659}
    25282660
     
    25522684                            "WinCert");
    25532685
    2554     int rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &pSignature->ContentInfo, "CI");
     2686    PRTLDRPESIGNATUREONE pInfo = &pSignature->Primary;
     2687    pInfo->pContentInfo = &pSignature->PrimaryContentInfo;
     2688    int rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, pInfo->pContentInfo, "CI");
    25552689    if (RT_SUCCESS(rc))
    25562690    {
    2557         if (RTCrPkcs7ContentInfo_IsSignedData(&pSignature->ContentInfo))
    2558         {
    2559             pSignature->pSignedData = pSignature->ContentInfo.u.pSignedData;
     2691        if (RTCrPkcs7ContentInfo_IsSignedData(pInfo->pContentInfo))
     2692        {
     2693            pInfo->pSignedData = pInfo->pContentInfo->u.pSignedData;
    25602694
    25612695            /*
    25622696             * Decode the authenticode bits.
    25632697             */
    2564             if (!strcmp(pSignature->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID))
    2565             {
    2566                 pSignature->pIndData = pSignature->pSignedData->ContentInfo.u.pIndirectDataContent;
    2567                 Assert(pSignature->pIndData);
     2698            if (!strcmp(pInfo->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID))
     2699            {
     2700                pInfo->pIndData = pInfo->pSignedData->ContentInfo.u.pIndirectDataContent;
     2701                Assert(pInfo->pIndData);
    25682702
    25692703                /*
    25702704                 * Check that things add up.
    25712705                 */
     2706                rc = RTCrPkcs7SignedData_CheckSanity(pInfo->pSignedData,
     2707                                                     RTCRPKCS7SIGNEDDATA_SANITY_F_AUTHENTICODE
     2708                                                     | RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH
     2709                                                     | RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT,
     2710                                                     pErrInfo, "SD");
    25722711                if (RT_SUCCESS(rc))
    2573                     rc = RTCrPkcs7SignedData_CheckSanity(pSignature->pSignedData,
    2574                                                          RTCRPKCS7SIGNEDDATA_SANITY_F_AUTHENTICODE
    2575                                                          | RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH
    2576                                                          | RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT,
    2577                                                          pErrInfo, "SD");
    2578                 if (RT_SUCCESS(rc))
    2579                     rc = RTCrSpcIndirectDataContent_CheckSanityEx(pSignature->pIndData,
    2580                                                                   pSignature->pSignedData,
     2712                    rc = RTCrSpcIndirectDataContent_CheckSanityEx(pInfo->pIndData,
     2713                                                                  pInfo->pSignedData,
    25812714                                                                  RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH,
    25822715                                                                  pErrInfo);
    25832716                if (RT_SUCCESS(rc))
    25842717                {
    2585                     PCRTCRX509ALGORITHMIDENTIFIER pDigestAlgorithm = &pSignature->pIndData->DigestInfo.DigestAlgorithm;
    2586                     pSignature->enmDigest = RTCrX509AlgorithmIdentifier_QueryDigestType(pDigestAlgorithm);
    2587                     AssertReturn(pSignature->enmDigest != RTDIGESTTYPE_INVALID, VERR_INTERNAL_ERROR_4); /* Checked above! */
     2718                    PCRTCRX509ALGORITHMIDENTIFIER pDigestAlgorithm = &pInfo->pIndData->DigestInfo.DigestAlgorithm;
     2719                    pInfo->enmDigest = RTCrX509AlgorithmIdentifier_QueryDigestType(pDigestAlgorithm);
     2720                    AssertReturn(pInfo->enmDigest != RTDIGESTTYPE_INVALID, VERR_INTERNAL_ERROR_4); /* Checked above! */
     2721
     2722                    /*
     2723                     * Deal with nested signatures.
     2724                     */
     2725                    rc = rtldrPE_VerifySignatureDecodeNested(pSignature, pErrInfo);
    25882726                }
    25892727            }
     
    25912729                rc = RTErrInfoSetF(pErrInfo, VERR_LDRVI_EXPECTED_INDIRECT_DATA_CONTENT_OID,
    25922730                                   "Unknown pSignedData.ContentInfo.ContentType.szObjId value: %s (expected %s)",
    2593                                    pSignature->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID);
     2731                                   pInfo->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID);
    25942732        }
    25952733        else
    25962734            rc = RTErrInfoSetF(pErrInfo, VERR_LDRVI_EXPECTED_INDIRECT_DATA_CONTENT_OID, /** @todo error code*/
    2597                                "PKCS#7 is not 'signedData': %s", pSignature->ContentInfo.ContentType.szObjId);
     2735                               "PKCS#7 is not 'signedData': %s", pInfo->pContentInfo->ContentType.szObjId);
    25982736    }
    25992737    return rc;
     
    26012739
    26022740
     2741
    26032742static int rtldrPE_VerifyAllPageHashes(PRTLDRMODPE pModPe, PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttrib, RTDIGESTTYPE enmDigest,
    2604                                        void *pvScratch, size_t cbScratch, PRTERRINFO pErrInfo)
     2743                                       void *pvScratch, size_t cbScratch, uint32_t iSignature, PRTERRINFO pErrInfo)
    26052744{
    26062745    AssertReturn(cbScratch >= _4K, VERR_INTERNAL_ERROR_3);
     
    26182757    if (cPages * (cbHash + 4) != pAttrib->u.pPageHashes->RawData.Asn1Core.cb)
    26192758        return RTErrInfoSetF(pErrInfo, VERR_LDRVI_PAGE_HASH_TAB_SIZE_OVERFLOW,
    2620                              "Page hashes size issue: cb=%#x cbHash=%#x",
    2621                              pAttrib->u.pPageHashes->RawData.Asn1Core.cb, cbHash);
     2759                             "Signature #%u - Page hashes size issue in: cb=%#x cbHash=%#x",
     2760                             iSignature, pAttrib->u.pPageHashes->RawData.Asn1Core.cb, cbHash);
    26222761
    26232762    /*
     
    26402779        if (RT_UNLIKELY(offPageInFile >= SpecialPlaces.cbToHash))
    26412780            return RTErrInfoSetF(pErrInfo, VERR_LDRVI_PAGE_HASH_TAB_TOO_LONG,
    2642                                  "Page hash entry #%u is beyond the signature table start: %#x, %#x",
    2643                                  iPage, offPageInFile, SpecialPlaces.cbToHash);
     2781                                 "Signature #%u - Page hash entry #%u is beyond the signature table start: %#x, %#x",
     2782                                 iSignature, iPage, offPageInFile, SpecialPlaces.cbToHash);
    26442783        if (RT_UNLIKELY(offPageInFile < offPrev))
    26452784            return RTErrInfoSetF(pErrInfo, VERR_LDRVI_PAGE_HASH_TAB_NOT_STRICTLY_SORTED,
    2646                                  "Page hash table is not strictly sorted: entry #%u @%#x, previous @%#x\n",
    2647                                  iPage, offPageInFile, offPrev);
     2785                                 "Signature #%u - Page hash table is not strictly sorted: entry #%u @%#x, previous @%#x\n",
     2786                                 iSignature, iPage, offPageInFile, offPrev);
    26482787
    26492788#ifdef COMPLICATED_AND_WRONG
     
    26662805                else
    26672806                    return RTErrInfoSetF(pErrInfo, VERR_PAGE_HASH_TAB_HASHES_NON_SECTION_DATA,
    2668                                          "Page hash entry #%u isn't in any section: %#x", iPage, offPageInFile);
     2807                                         "Signature #%u - Page hash entry #%u isn't in any section: %#x",
     2808                                         iSignature, iPage, offPageInFile);
    26692809            }
    26702810        }
     
    27102850            if (RT_FAILURE(rc))
    27112851                return RTErrInfoSetF(pErrInfo, VERR_LDRVI_READ_ERROR_HASH,
    2712                                      "Page hash read error at %#x: %Rrc (cbScratchRead=%#zx)",
    2713                                      offScratchRead, rc, cbScratchRead);
     2852                                     "Signature #%u - Page hash read error at %#x: %Rrc (cbScratchRead=%#zx)",
     2853                                     iSignature, offScratchRead, rc, cbScratchRead);
    27142854        }
    27152855
     
    27782918        if (memcmp(pbHashTab, &HashRes, cbHash) != 0)
    27792919            return RTErrInfoSetF(pErrInfo, VERR_LDRVI_PAGE_HASH_MISMATCH,
    2780                                  "Page hash failed for page #%u, @%#x, %#x bytes: %.*Rhxs != %.*Rhxs",
    2781                                  iPage, offPageInFile, cbPageInFile, (size_t)cbHash, pbHashTab, (size_t)cbHash, &HashRes);
     2920                                 "Signature #%u - Page hash failed for page #%u, @%#x, %#x bytes: %.*Rhxs != %.*Rhxs",
     2921                                 iSignature, iPage, offPageInFile, cbPageInFile, (size_t)cbHash, pbHashTab,
     2922                                 (size_t)cbHash, &HashRes);
    27822923        pbHashTab += cbHash;
    27832924        offPrev = offPageInFile;
     
    27892930    if (!ASMMemIsZero(pbHashTab + 4, cbHash))
    27902931        return RTErrInfoSetF(pErrInfo, VERR_LDRVI_PAGE_HASH_TAB_TOO_LONG,
    2791                              "Maltform final page hash table entry: #%u %#010x %.*Rhxs",
    2792                              cPages - 1, RT_MAKE_U32_FROM_U8(pbHashTab[0], pbHashTab[1], pbHashTab[2], pbHashTab[3]),
     2932                             "Signature #%u - Malformed final page hash table entry: #%u %#010x %.*Rhxs",
     2933                             iSignature, cPages - 1, RT_MAKE_U32_FROM_U8(pbHashTab[0], pbHashTab[1], pbHashTab[2], pbHashTab[3]),
    27932934                             (size_t)cbHash, pbHashTab + 4);
    27942935    return VINF_SUCCESS;
     2936}
     2937
     2938
     2939static int rtldrPE_VerifySignatureValidateOnePageHashes(PRTLDRMODPE pModPe, PRTLDRPESIGNATUREONE pInfo,
     2940                                                        void *pvScratch, uint32_t cbScratch, PRTERRINFO pErrInfo)
     2941{
     2942    /*
     2943     * Compare the page hashes if present.
     2944     *
     2945     * Seems the difference between V1 and V2 page hash attributes is
     2946     * that v1 uses SHA-1 while v2 uses SHA-256. The data structures
     2947     * seems to be identical otherwise.  Initially we assumed the digest
     2948     * algorithm was supposed to be RTCRSPCINDIRECTDATACONTENT::DigestInfo,
     2949     * i.e. the same as for the whole image hash.  The initial approach
     2950     * worked just fine, but this makes more sense.
     2951     *
     2952     * (See also comments in osslsigncode.c (google it).)
     2953     */
     2954    PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttrib;
     2955    /* V2 - SHA-256: */
     2956    pAttrib = RTCrSpcIndirectDataContent_GetPeImageObjAttrib(pInfo->pIndData,
     2957                                                             RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V2);
     2958    if (pAttrib)
     2959        return rtldrPE_VerifyAllPageHashes(pModPe, pAttrib, RTDIGESTTYPE_SHA256, pvScratch, cbScratch,
     2960                                           pInfo->iSignature + 1, pErrInfo);
     2961
     2962    /* V1 - SHA-1: */
     2963    pAttrib = RTCrSpcIndirectDataContent_GetPeImageObjAttrib(pInfo->pIndData,
     2964                                                             RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V1);
     2965    if (pAttrib)
     2966        return rtldrPE_VerifyAllPageHashes(pModPe, pAttrib, RTDIGESTTYPE_SHA1, pvScratch, cbScratch,
     2967                                           pInfo->iSignature + 1, pErrInfo);
     2968
     2969    /* No page hashes: */
     2970    return VINF_SUCCESS;
     2971}
     2972
     2973
     2974static int rtldrPE_VerifySignatureValidateOneImageHash(PRTLDRMODPE pModPe, PRTLDRPESIGNATURE pSignature,
     2975                                                       PRTLDRPESIGNATUREONE pInfo, void *pvScratch, uint32_t cbScratch,
     2976                                                       PRTERRINFO pErrInfo)
     2977{
     2978    /*
     2979     * Assert sanity.
     2980     */
     2981    AssertReturn(pInfo->enmDigest > RTDIGESTTYPE_INVALID && pInfo->enmDigest < RTDIGESTTYPE_END, VERR_INTERNAL_ERROR_4);
     2982    AssertPtrReturn(pInfo->pIndData, VERR_INTERNAL_ERROR_5);
     2983    AssertReturn(RTASN1CORE_IS_PRESENT(&pInfo->pIndData->DigestInfo.Digest.Asn1Core), VERR_INTERNAL_ERROR_5);
     2984    AssertPtrReturn(pInfo->pIndData->DigestInfo.Digest.Asn1Core.uData.pv, VERR_INTERNAL_ERROR_5);
     2985
     2986    /*
     2987     * Skip it if we've already verified it.
     2988     */
     2989    if (pInfo->fValidatedImageHash)
     2990        return VINF_SUCCESS;
     2991
     2992    /*
     2993     * Calculate it.
     2994     */
     2995    uint32_t const cbHash = rtLdrPE_HashGetHashSize(pInfo->enmDigest);
     2996    AssertReturn(pInfo->pIndData->DigestInfo.Digest.Asn1Core.cb == cbHash, VERR_INTERNAL_ERROR_5);
     2997
     2998    int rc = rtldrPE_HashImageCommon(pModPe, pvScratch, cbScratch, pInfo->enmDigest,
     2999                                     &pSignature->HashCtx, &pInfo->HashRes, pErrInfo);
     3000    if (RT_SUCCESS(rc))
     3001    {
     3002        pInfo->fValidatedImageHash = true;
     3003        if (memcmp(&pInfo->HashRes, pInfo->pIndData->DigestInfo.Digest.Asn1Core.uData.pv, cbHash) == 0)
     3004        {
     3005            /*
     3006             * Verify other signatures with the same digest type.
     3007             */
     3008            RTLDRPEHASHRESUNION const * const pHashRes = &pInfo->HashRes;
     3009            for (uint32_t i = 0; i < pSignature->cNested; i++)
     3010            {
     3011                pInfo = &pSignature->paNested[i]; /* Note! pInfo changes! */
     3012                if (   !pInfo->fValidatedImageHash
     3013                    && pInfo->enmDigest == pInfo->enmDigest
     3014                    /* paranoia from the top of this function: */
     3015                    && pInfo->pIndData
     3016                    && RTASN1CORE_IS_PRESENT(&pInfo->pIndData->DigestInfo.Digest.Asn1Core)
     3017                    && pInfo->pIndData->DigestInfo.Digest.Asn1Core.uData.pv
     3018                    && pInfo->pIndData->DigestInfo.Digest.Asn1Core.cb == cbHash)
     3019                {
     3020                    pInfo->fValidatedImageHash = true;
     3021                    if (memcmp(pHashRes, pInfo->pIndData->DigestInfo.Digest.Asn1Core.uData.pv, cbHash) != 0)
     3022                    {
     3023                        rc = RTErrInfoSetF(pErrInfo, VERR_LDRVI_IMAGE_HASH_MISMATCH,
     3024                                           "Full image signature #%u mismatch: %.*Rhxs, expected %.*Rhxs", pInfo->iSignature + 1,
     3025                                           cbHash, pHashRes,
     3026                                           cbHash, pInfo->pIndData->DigestInfo.Digest.Asn1Core.uData.pv);
     3027                        break;
     3028                    }
     3029                }
     3030            }
     3031        }
     3032        else
     3033            rc = RTErrInfoSetF(pErrInfo, VERR_LDRVI_IMAGE_HASH_MISMATCH,
     3034                               "Full image signature #%u mismatch: %.*Rhxs, expected %.*Rhxs", pInfo->iSignature + 1,
     3035                               cbHash, &pInfo->HashRes,
     3036                               cbHash, pInfo->pIndData->DigestInfo.Digest.Asn1Core.uData.pv);
     3037    }
     3038    return rc;
    27953039}
    27963040
     
    28063050static int rtldrPE_VerifySignatureValidateHash(PRTLDRMODPE pModPe, PRTLDRPESIGNATURE pSignature, PRTERRINFO pErrInfo)
    28073051{
    2808     AssertReturn(pSignature->enmDigest > RTDIGESTTYPE_INVALID && pSignature->enmDigest < RTDIGESTTYPE_END, VERR_INTERNAL_ERROR_4);
    2809     AssertPtrReturn(pSignature->pIndData, VERR_INTERNAL_ERROR_5);
    2810     AssertReturn(RTASN1CORE_IS_PRESENT(&pSignature->pIndData->DigestInfo.Digest.Asn1Core), VERR_INTERNAL_ERROR_5);
    2811     AssertPtrReturn(pSignature->pIndData->DigestInfo.Digest.Asn1Core.uData.pv, VERR_INTERNAL_ERROR_5);
    2812 
    2813     uint32_t const cbHash = rtLdrPE_HashGetHashSize(pSignature->enmDigest);
    2814     AssertReturn(pSignature->pIndData->DigestInfo.Digest.Asn1Core.cb == cbHash, VERR_INTERNAL_ERROR_5);
    2815 
    28163052    /*
    28173053     * Allocate a temporary memory buffer.
     
    28203056     *       heap fragmentation.
    28213057     */
    2822 #ifdef IN_RING0
     3058# ifdef IN_RING0
    28233059    uint32_t    cbScratch = _256K - _4K;
    2824 #else
     3060# else
    28253061    uint32_t    cbScratch = _1M;
    2826 #endif
     3062# endif
    28273063    void       *pvScratch = RTMemTmpAlloc(cbScratch);
    28283064    if (!pvScratch)
     
    28353071
    28363072    /*
    2837      * Calculate and compare the full image hash.
    2838      */
    2839     int rc = rtldrPE_HashImageCommon(pModPe, pvScratch, cbScratch, pSignature->enmDigest,
    2840                                      &pSignature->HashCtx, &pSignature->HashRes, pErrInfo);
     3073     * Verify signatures.
     3074     */
     3075    /* Image hashes: */
     3076    int rc = rtldrPE_VerifySignatureValidateOneImageHash(pModPe, pSignature, &pSignature->Primary,
     3077                                                         pvScratch, cbScratch, pErrInfo);
     3078    for (unsigned i = 0; i < pSignature->cNested && RT_SUCCESS(rc); i++)
     3079        rc = rtldrPE_VerifySignatureValidateOneImageHash(pModPe, pSignature, &pSignature->paNested[i],
     3080                                                         pvScratch, cbScratch, pErrInfo);
     3081
     3082    /* Page hashes: */
    28413083    if (RT_SUCCESS(rc))
    28423084    {
    2843         if (!memcmp(&pSignature->HashRes, pSignature->pIndData->DigestInfo.Digest.Asn1Core.uData.pv, cbHash))
    2844         {
    2845             /*
    2846              * Compare the page hashes if present.
    2847              *
    2848              * Seems the difference between V1 and V2 page hash attributes is
    2849              * that v1 uses SHA-1 while v2 uses SHA-256. The data structures
    2850              * seems to be identical otherwise.  Initially we assumed the digest
    2851              * algorithm was supposed to be RTCRSPCINDIRECTDATACONTENT::DigestInfo,
    2852              * i.e. the same as for the whole image hash.  The initial approach
    2853              * worked just fine, but this makes more sense.
    2854              *
    2855              * (See also comments in osslsigncode.c (google it).)
    2856              */
    2857             PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttrib;
    2858             pAttrib = RTCrSpcIndirectDataContent_GetPeImageObjAttrib(pSignature->pIndData,
    2859                                                                      RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V2);
    2860             if (pAttrib)
    2861                 rc = rtldrPE_VerifyAllPageHashes(pModPe, pAttrib, RTDIGESTTYPE_SHA256, pvScratch, cbScratch, pErrInfo);
    2862             else
    2863             {
    2864                 pAttrib = RTCrSpcIndirectDataContent_GetPeImageObjAttrib(pSignature->pIndData,
    2865                                                                          RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V1);
    2866                 if (pAttrib)
    2867                     rc = rtldrPE_VerifyAllPageHashes(pModPe, pAttrib, RTDIGESTTYPE_SHA1, pvScratch, cbScratch, pErrInfo);
    2868             }
    2869         }
    2870         else
    2871             rc = RTErrInfoSetF(pErrInfo, VERR_LDRVI_IMAGE_HASH_MISMATCH,
    2872                                "Full image signature mismatch: %.*Rhxs, expected %.*Rhxs",
    2873                                cbHash, &pSignature->HashRes,
    2874                                cbHash, pSignature->pIndData->DigestInfo.Digest.Asn1Core.uData.pv);
    2875     }
    2876 
     3085        rc = rtldrPE_VerifySignatureValidateOnePageHashes(pModPe, &pSignature->Primary, pvScratch, cbScratch, pErrInfo);
     3086        for (unsigned i = 0; i < pSignature->cNested && RT_SUCCESS(rc); i++)
     3087            rc = rtldrPE_VerifySignatureValidateOnePageHashes(pModPe, &pSignature->paNested[i], pvScratch, cbScratch, pErrInfo);
     3088    }
     3089
     3090    /*
     3091     * Ditch the scratch buffer.
     3092     */
    28773093    RTMemTmpFree(pvScratch);
    28783094    return rc;
     
    29013117            if (RT_SUCCESS(rc))
    29023118            {
    2903                 rc = pfnCallback(&pModPe->Core, RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA,
    2904                                  &pSignature->ContentInfo, sizeof(pSignature->ContentInfo),
    2905                                  NULL /*pvExternalData*/, 0 /*cbExternalData*/,
    2906                                  pErrInfo, pvUser);
     3119                /*
     3120                 * Work the callback.
     3121                 */
     3122                /* The primary signature: */
     3123                RTLDRSIGNATUREINFO Info;
     3124                Info.iSignature     = 0;
     3125                Info.cSignatures    = (uint16_t)(1 + pSignature->cNested);
     3126                Info.enmType        = RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA;
     3127                Info.pvSignature    = pSignature->Primary.pContentInfo;
     3128                Info.cbSignature    = sizeof(*pSignature->Primary.pContentInfo);
     3129                Info.pvExternalData = NULL;
     3130                Info.cbExternalData = 0;
     3131                rc = pfnCallback(&pModPe->Core, &Info, pErrInfo, pvUser);
     3132
     3133                /* The nested signatures: */
     3134                for (uint32_t iNested = 0; iNested < pSignature->cNested && rc == VINF_SUCCESS; iNested++)
     3135                {
     3136                    Info.iSignature     = (uint16_t)(1 + iNested);
     3137                    Info.cSignatures    = (uint16_t)(1 + pSignature->cNested);
     3138                    Info.enmType        = RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA;
     3139                    Info.pvSignature    = pSignature->paNested[iNested].pContentInfo;
     3140                    Info.cbSignature    = sizeof(*pSignature->paNested[iNested].pContentInfo);
     3141                    Info.pvExternalData = NULL;
     3142                    Info.cbExternalData = 0;
     3143                    rc = pfnCallback(&pModPe->Core, &Info, pErrInfo, pvUser);
     3144                }
    29073145            }
    29083146            rtldrPE_VerifySignatureDestroy(pModPe, pSignature);
  • trunk/src/VBox/Runtime/testcase/tstRTLdrVerifyPeImage.cpp

    r82968 r86549  
    4444static int g_iDummy = 0;
    4545
    46 static DECLCALLBACK(int) TestCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
    47                                       void const *pvSignature, size_t cbSignature,
    48                                       void const *pvExternalData, size_t cbExternalData,
    49                                       PRTERRINFO pErrInfo, void *pvUser)
     46
     47static DECLCALLBACK(int) TestCallback(RTLDRMOD hLdrMod, PCRTLDRSIGNATUREINFO pInfo, PRTERRINFO pErrInfo, void *pvUser)
    5048{
    51     RT_NOREF_PV(hLdrMod); RT_NOREF_PV(enmSignature); RT_NOREF_PV(pvSignature); RT_NOREF_PV(cbSignature);
    52     RT_NOREF_PV(pErrInfo); RT_NOREF_PV(pvUser); RT_NOREF_PV(pvExternalData); RT_NOREF_PV(cbExternalData);
     49    RT_NOREF(hLdrMod, pInfo, pErrInfo, pvUser);
    5350    return VINF_SUCCESS;
    5451}
    55 
    5652
    5753
  • trunk/src/VBox/Runtime/tools/RTSignTool.cpp

    r84380 r86549  
    12521252    int         cVerbose;
    12531253    enum { kSignType_Windows, kSignType_OSX } enmSignType;
    1254     uint64_t    uTimestamp;
    12551254    RTLDRARCH   enmLdrArch;
     1255    uint32_t    cBad;
     1256    uint32_t    cOkay;
     1257    const char *pszFilename;
    12561258} VERIFYEXESTATE;
    12571259
     
    14021404}
    14031405
    1404 
    14051406/** @callback_method_impl{FNRTLDRVALIDATESIGNEDDATA}  */
    1406 static DECLCALLBACK(int) VerifyExeCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
    1407                                            void const *pvSignature, size_t cbSignature,
    1408                                            void const *pvExternalData, size_t cbExternalData,
    1409                                            PRTERRINFO pErrInfo, void *pvUser)
     1407static DECLCALLBACK(int) VerifyExeCallback(RTLDRMOD hLdrMod, PCRTLDRSIGNATUREINFO pInfo, PRTERRINFO pErrInfo, void *pvUser)
    14101408{
    14111409    VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser;
    1412     RT_NOREF_PV(hLdrMod); RT_NOREF_PV(cbSignature);
    1413 
    1414     switch (enmSignature)
     1410    RT_NOREF_PV(hLdrMod);
     1411
     1412    switch (pInfo->enmType)
    14151413    {
    14161414        case RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA:
    14171415        {
    1418             PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pvSignature;
    1419 
    1420             RTTIMESPEC ValidationTime;
    1421             RTTimeSpecSetSeconds(&ValidationTime, pState->uTimestamp);
     1416            PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pInfo->pvSignature;
    14221417
    14231418            /*
    1424              * Dump the signed data if so requested.
     1419             * Dump the signed data if so requested and it's the first one, assuming that
     1420             * additional signatures in contained wihtin the same ContentInfo structure.
    14251421             */
    1426             if (pState->cVerbose)
     1422            if (pState->cVerbose && pInfo->iSignature == 0)
    14271423                RTAsn1Dump(&pContentInfo->SeqCore.Asn1Core, 0, 0, RTStrmDumpPrintfV, g_pStdOut);
    14281424
    1429 
    14301425            /*
    1431              * Do the actual verification.  Will have to modify this so it takes
    1432              * the authenticode policies into account.
     1426             * We'll try different alternative timestamps here.
    14331427             */
    1434             if (pvExternalData)
    1435                 return RTCrPkcs7VerifySignedDataWithExternalData(pContentInfo,
    1436                                                                  RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY
    1437                                                                  | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
    1438                                                                  | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT
    1439                                                                  | RTCRPKCS7VERIFY_SD_F_CHECK_TRUST_ANCHORS,
    1440                                                                  pState->hAdditionalStore, pState->hRootStore, &ValidationTime,
    1441                                                                  VerifyExecCertVerifyCallback, pState,
    1442                                                                  pvExternalData, cbExternalData, pErrInfo);
    1443             return RTCrPkcs7VerifySignedData(pContentInfo,
    1444                                              RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY
    1445                                              | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
    1446                                              | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT
    1447                                              | RTCRPKCS7VERIFY_SD_F_CHECK_TRUST_ANCHORS,
    1448                                              pState->hAdditionalStore, pState->hRootStore, &ValidationTime,
    1449                                              VerifyExecCertVerifyCallback, pState, pErrInfo);
     1428            struct { RTTIMESPEC TimeSpec; const char *pszDesc; } aTimes[2];
     1429            unsigned cTimes = 0;
     1430
     1431            /* Linking timestamp: */
     1432            uint64_t uLinkingTime = 0;
     1433            int rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &uLinkingTime, sizeof(uLinkingTime));
     1434            if (RT_SUCCESS(rc))
     1435            {
     1436                RTTimeSpecSetSeconds(&aTimes[0].TimeSpec, uLinkingTime);
     1437                aTimes[0].pszDesc = "at link time";
     1438                cTimes++;
     1439            }
     1440            else if (rc != VERR_NOT_FOUND)
     1441                RTMsgError("RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on '%s': %Rrc\n", pState->pszFilename, rc);
     1442
     1443            /* Now: */
     1444            RTTimeNow(&aTimes[cTimes].TimeSpec);
     1445            aTimes[cTimes].pszDesc = "now";
     1446            cTimes++;
     1447
     1448            /*
     1449             * Do the actual verification.
     1450             */
     1451            for (unsigned iTime = 0; iTime < cTimes; iTime++)
     1452            {
     1453                if (pInfo->pvExternalData)
     1454                    rc = RTCrPkcs7VerifySignedDataWithExternalData(pContentInfo,
     1455                                                                   RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY
     1456                                                                   | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
     1457                                                                   | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT
     1458                                                                   | RTCRPKCS7VERIFY_SD_F_CHECK_TRUST_ANCHORS,
     1459                                                                   pState->hAdditionalStore, pState->hRootStore,
     1460                                                                   &aTimes[iTime].TimeSpec,
     1461                                                                   VerifyExecCertVerifyCallback, pState,
     1462                                                                   pInfo->pvExternalData, pInfo->cbExternalData, pErrInfo);
     1463                else
     1464                    rc = RTCrPkcs7VerifySignedData(pContentInfo,
     1465                                                   RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY
     1466                                                   | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
     1467                                                   | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT
     1468                                                   | RTCRPKCS7VERIFY_SD_F_CHECK_TRUST_ANCHORS,
     1469                                                   pState->hAdditionalStore, pState->hRootStore,
     1470                                                   &aTimes[iTime].TimeSpec,
     1471                                                   VerifyExecCertVerifyCallback, pState, pErrInfo);
     1472                if (RT_SUCCESS(rc))
     1473                {
     1474                    Assert(rc == VINF_SUCCESS);
     1475                    if (pInfo->cSignatures == 1)
     1476                        RTMsgInfo("'%s' is valid %s.\n", pState->pszFilename, aTimes[iTime].pszDesc);
     1477                    else
     1478                        RTMsgInfo("'%s' signature #%u is valid %s.\n",
     1479                                  pState->pszFilename, pInfo->iSignature + 1, aTimes[iTime].pszDesc);
     1480                    pState->cOkay++;
     1481                    return VINF_SUCCESS;
     1482                }
     1483                if (rc != VERR_CR_X509_CPV_NOT_VALID_AT_TIME)
     1484                {
     1485                    if (pInfo->cSignatures == 1)
     1486                        RTMsgError("%s: Failed to verify signature: %Rrc%#RTeim\n", pState->pszFilename, rc, pErrInfo);
     1487                    else
     1488                        RTMsgError("%s: Failed to verify signature #%u: %Rrc%#RTeim\n",
     1489                                   pState->pszFilename, pInfo->iSignature + 1, rc, pErrInfo);
     1490                    pState->cBad++;
     1491                    return VINF_SUCCESS;
     1492                }
     1493            }
     1494
     1495            if (pInfo->cSignatures == 1)
     1496                RTMsgError("%s: Signature is not valid at present or link time.\n", pState->pszFilename);
     1497            else
     1498                RTMsgError("%s: Signature #%u is not valid at present or link time.\n",
     1499                           pState->pszFilename, pInfo->iSignature + 1);
     1500            pState->cBad++;
     1501            return VINF_SUCCESS;
    14501502        }
    14511503
    14521504        default:
    1453             return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", enmSignature);
     1505            return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", pInfo->enmType);
    14541506    }
    14551507}
     
    14681520        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszFilename, rc);
    14691521
    1470 
    1471     RTTIMESPEC Now;
    1472     bool       fTriedNow = false;
    1473     rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &pState->uTimestamp, sizeof(pState->uTimestamp));
    1474     if (rc == VERR_NOT_FOUND)
    1475     {
    1476         fTriedNow = true;
    1477         pState->uTimestamp = RTTimeSpecGetSeconds(RTTimeNow(&Now));
    1478         rc = VINF_SUCCESS;
    1479     }
    1480     if (RT_SUCCESS(rc))
    1481     {
    1482         rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
    1483         if (RT_SUCCESS(rc))
    1484             RTMsgInfo("'%s' is valid.\n", pszFilename);
    1485         else if (rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME && !fTriedNow)
    1486         {
    1487             pState->uTimestamp = RTTimeSpecGetSeconds(RTTimeNow(&Now));
    1488             rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
    1489             if (RT_SUCCESS(rc))
    1490                 RTMsgInfo("'%s' is valid now, but not at link time.\n", pszFilename);
    1491         }
    1492         if (RT_FAILURE(rc))
    1493             RTMsgError("RTLdrVerifySignature failed on '%s': %Rrc - %s\n", pszFilename, rc, pStaticErrInfo->szMsg);
    1494     }
    1495     else
    1496         RTMsgError("RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on '%s': %Rrc\n", pszFilename, rc);
     1522    /* Reset the state. */
     1523    pState->cBad        = 0;
     1524    pState->cOkay       = 0;
     1525    pState->pszFilename = pszFilename;
     1526
     1527    rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
     1528    if (RT_FAILURE(rc))
     1529        RTMsgError("RTLdrVerifySignature failed on '%s': %Rrc - %s\n", pszFilename, rc, pStaticErrInfo->szMsg);
    14971530
    14981531    int rc2 = RTLdrClose(hLdrMod);
     
    15021535        return rc != VERR_LDRVI_NOT_SIGNED ? RTEXITCODE_FAILURE : RTEXITCODE_SKIPPED;
    15031536
    1504     return RTEXITCODE_SUCCESS;
     1537    return pState->cOkay > 0 ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
    15051538}
    15061539
     
    15311564    VERIFYEXESTATE State =
    15321565    {
    1533         NIL_RTCRSTORE, NIL_RTCRSTORE, NIL_RTCRSTORE, false, false,
    1534         VERIFYEXESTATE::kSignType_Windows, 0, RTLDRARCH_WHATEVER
     1566        NIL_RTCRSTORE, NIL_RTCRSTORE, NIL_RTCRSTORE, false, 0,
     1567        VERIFYEXESTATE::kSignType_Windows, RTLDRARCH_WHATEVER,
     1568        0, 0, NULL
    15351569    };
    15361570    int rc = RTCrStoreCreateInMem(&State.hRootStore, 0);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette