VirtualBox

Changeset 86610 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Oct 16, 2020 2:34:15 PM (4 years ago)
Author:
vboxsync
Message:

SUPHArdNt,IPRT: Recognize WHQL/attestation signatures from MS. Corrected RTCRX509TBSCERTIFICATE::T3::fExtKeyUsage type (32 -> 64 bit) as it has been to small for a while now. bugref:3103

Location:
trunk/src/VBox/HostDrivers/Support
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/testcase/tstSupVerify.cpp

    r82968 r86610  
    4040
    4141
     42//#define DYNAMIC
     43#ifdef DYNAMIC
     44# include <iprt/win/windows.h>
     45
     46# define DYNAMIC_IMPORTS() \
     47    ONE_IMPORT(RTR3InitExe); \
     48    ONE_IMPORT(RTMsgInitFailure); \
     49    ONE_IMPORT(RTGetOpt); \
     50    ONE_IMPORT(RTGetOptInit); \
     51    ONE_IMPORT(RTGetOptPrintError); \
     52    ONE_IMPORT(RTMsgError); \
     53    ONE_IMPORT(RTMsgErrorExit); \
     54    ONE_IMPORT(RTMsgInfo); \
     55    ONE_IMPORT(RTPrintf); \
     56    ONE_IMPORT(SUPR3HardenedVerifyInit); \
     57    ONE_IMPORT(SUPR3HardenedVerifyPlugIn)
     58
     59# define ONE_IMPORT(a_fnName) static decltype(a_fnName) *g_pfn##a_fnName
     60DYNAMIC_IMPORTS();
     61# undef ONE_IMPORT
     62
     63static void resolve(void)
     64{
     65    HMODULE hmod = LoadLibrary("VBoxRT.dll");
     66    DWORD cbWritten = 0;
     67
     68# define ONE_IMPORT(a_fnName) do { \
     69            g_pfn##a_fnName = (decltype(a_fnName) *)GetProcAddress(hmod, #a_fnName); \
     70            if (!g_pfn##a_fnName) \
     71                WriteFile(GetStdHandle(STD_ERROR_HANDLE), RT_STR_TUPLE("Failed to resolve: " #a_fnName "\r\n"), &cbWritten, NULL); \
     72        } while (0)
     73    DYNAMIC_IMPORTS();
     74# undef ONE_IMPORT
     75}
     76
     77#define RTR3InitExe                  g_pfnRTR3InitExe
     78#define RTMsgInitFailure             g_pfnRTMsgInitFailure
     79#define RTGetOpt                     g_pfnRTGetOpt
     80#define RTGetOptInit                 g_pfnRTGetOptInit
     81#define RTGetOptPrintError           g_pfnRTGetOptPrintError
     82#define RTMsgError                   g_pfnRTMsgError
     83#define RTMsgErrorExit               g_pfnRTMsgErrorExit
     84#define RTMsgInfo                    g_pfnRTMsgInfo
     85#define RTPrintf                     g_pfnRTPrintf
     86#define SUPR3HardenedVerifyInit      g_pfnSUPR3HardenedVerifyInit
     87#define SUPR3HardenedVerifyPlugIn    g_pfnSUPR3HardenedVerifyPlugIn
     88
     89#endif /* DYNAMIC */
     90
    4291int main(int argc, char **argv)
    4392{
     
    4594     * Init.
    4695     */
     96#ifdef DYNAMIC
     97    resolve();
     98#endif
    4799    int rc = RTR3InitExe(argc, &argv, 0);
    48100    if (RT_FAILURE(rc))
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h

    r86549 r86610  
    113113    /** Total number of signatures. */
    114114    uint16_t    cTotalSignatures;
     115    /** The current signature (for passing to supHardNtViCertVerifyCallback). */
     116    uint16_t    iCurSignature;
    115117    /** The last non-fatal signature failure. */
    116118    int         rcLastSignatureFailure;
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp

    r86549 r86610  
    959959
    960960/**
     961 * Attempts to locate a root certificate in the specified store.
     962 *
     963 * @returns IPRT status code.
     964 * @retval  VINF_SUCCESS if found.
     965 * @retval  VWRN_NOT_FOUND if not found.
     966 *
     967 * @param   hRootStore      The root certificate store to search.
     968 * @param   pSubject        The root certificate subject.
     969 * @param   pPublicKeyInfo  The public key of the root certificate to find.
     970 */
     971static int supHardNtViCertVerifyFindRootCert(RTCRSTORE hRootStore, PCRTCRX509NAME pSubject,
     972                                             PCRTCRX509SUBJECTPUBLICKEYINFO pPublicKeyInfo)
     973{
     974    RTCRSTORECERTSEARCH Search;
     975    int rc = RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280(hRootStore, pSubject, &Search);
     976    AssertRCReturn(rc, rc);
     977
     978    rc = VWRN_NOT_FOUND;
     979    PCRTCRCERTCTX pCertCtx;
     980    while ((pCertCtx = RTCrStoreCertSearchNext(hRootStore, &Search)) != NULL)
     981    {
     982        PCRTCRX509SUBJECTPUBLICKEYINFO pCertPubKeyInfo = NULL;
     983        if (pCertCtx->pCert)
     984            pCertPubKeyInfo = &pCertCtx->pCert->TbsCertificate.SubjectPublicKeyInfo;
     985        else if (pCertCtx->pTaInfo)
     986            pCertPubKeyInfo = &pCertCtx->pTaInfo->PubKey;
     987        else
     988            pCertPubKeyInfo = NULL;
     989        if (   pCertPubKeyInfo
     990            && RTCrX509SubjectPublicKeyInfo_Compare(pCertPubKeyInfo, pPublicKeyInfo) == 0)
     991        {
     992            RTCrCertCtxRelease(pCertCtx);
     993            rc = VINF_SUCCESS;
     994            break;
     995        }
     996        RTCrCertCtxRelease(pCertCtx);
     997    }
     998
     999    int rc2 = RTCrStoreCertSearchDestroy(hRootStore, &Search);
     1000    AssertRC(rc2);
     1001    return rc;
     1002}
     1003
     1004
     1005/**
    9611006 * @callback_method_impl{FNRTCRPKCS7VERIFYCERTCALLBACK,
    9621007 * Standard code signing.  Use this for Microsoft SPC.}
     
    9941039    {
    9951040        /*
    996          * If kernel signing, a valid certificate path must be anchored by the
    997          * microsoft kernel signing root certificate.
     1041         * For kernel code signing there are two options for a valid certificate path:
     1042         *  1. Anchored by the microsoft kernel signing root certificate (g_hNtKernelRootStore).
     1043         *  2. Anchored by an SPC root and signing entity including a 1.3.6.1.4.1.311.10.3.5 (WHQL)
     1044         *     or 1.3.6.1.4.1.311.10.3.5.1 (WHQL attestation) extended usage key.
    9981045         */
    9991046        if (pNtViRdr->fFlags & SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING)
     
    10181065
    10191066                    /*
    1020                      * Search the kernel signing root store for a matching anchor.
     1067                     * 1. Search the kernel signing root store for a matching anchor.
    10211068                     */
    1022                     RTCRSTORECERTSEARCH Search;
    1023                     rc = RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280(g_hNtKernelRootStore, pSubject, &Search);
     1069                    rc = supHardNtViCertVerifyFindRootCert(g_hNtKernelRootStore, pSubject, pPublicKeyInfo);
     1070                    if (rc == VINF_SUCCESS)
     1071                        cFound++;
     1072                    /*
     1073                     * 2. Check for WHQL EKU and make sure it has a SPC root.
     1074                     */
     1075                    else if (   rc == VWRN_NOT_FOUND
     1076                             && (  pCert->TbsCertificate.T3.fExtKeyUsage
     1077                                 & (RTCRX509CERT_EKU_F_MS_ATTEST_WHQL_CRYPTO | RTCRX509CERT_EKU_F_MS_WHQL_CRYPTO)))
     1078                    {
     1079                        rc = supHardNtViCertVerifyFindRootCert(g_hSpcRootStore, pSubject, pPublicKeyInfo);
     1080                        if (rc == VINF_SUCCESS)
     1081                            cFound++;
     1082                    }
    10241083                    AssertRCBreak(rc);
    1025 
    1026                     PCRTCRCERTCTX pCertCtx;
    1027                     while ((pCertCtx = RTCrStoreCertSearchNext(g_hNtKernelRootStore, &Search)) != NULL)
    1028                     {
    1029                         PCRTCRX509SUBJECTPUBLICKEYINFO pCertPubKeyInfo = NULL;
    1030                         if (pCertCtx->pCert)
    1031                             pCertPubKeyInfo = &pCertCtx->pCert->TbsCertificate.SubjectPublicKeyInfo;
    1032                         else if (pCertCtx->pTaInfo)
    1033                             pCertPubKeyInfo = &pCertCtx->pTaInfo->PubKey;
    1034                         else
    1035                             pCertPubKeyInfo = NULL;
    1036                         if (   pCertPubKeyInfo
    1037                             && RTCrX509SubjectPublicKeyInfo_Compare(pCertPubKeyInfo, pPublicKeyInfo) == 0)
    1038                             cFound++;
    1039                         RTCrCertCtxRelease(pCertCtx);
    1040                     }
    1041 
    1042                     int rc2 = RTCrStoreCertSearchDestroy(g_hNtKernelRootStore, &Search); AssertRC(rc2);
    10431084                }
    10441085            }
    10451086            if (RT_SUCCESS(rc) && cFound == 0)
    1046                 rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_NOT_VALID_KERNEL_CODE_SIGNATURE, "Not valid kernel code signature.");
     1087                rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_NOT_VALID_KERNEL_CODE_SIGNATURE,
     1088                                   "Signature #%u/%u: Not valid kernel code signature.",
     1089                                   pNtViRdr->iCurSignature + 1, pNtViRdr->cTotalSignatures);
     1090
     1091
    10471092            if (RT_SUCCESS(rc) && cValid < 2 && g_fHaveOtherRoots)
    10481093                rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_UNEXPECTED_VALID_PATH_COUNT,
    1049                                    "Expected at least %u valid paths, not %u.", 2, cValid);
     1094                                   "Signature #%u/%u: Expected at least %u valid paths, not %u.",
     1095                                   pNtViRdr->iCurSignature + 1, pNtViRdr->cTotalSignatures, 2, cValid);
     1096            if (rc == VWRN_NOT_FOUND)
     1097                rc = VINF_SUCCESS;
    10501098        }
    10511099    }
     
    11041152    Assert(pNtViRdr->Core.uMagic == RTLDRREADER_MAGIC);
    11051153    pNtViRdr->cTotalSignatures = pInfo->cSignatures;
     1154    pNtViRdr->iCurSignature    = pInfo->iSignature;
    11061155
    11071156    AssertReturn(pInfo->enmType == RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA, VERR_INTERNAL_ERROR_5);
     
    11251174                                                            &pSignerInfo->IssuerAndSerialNumber.SerialNumber))
    11261175            return RTErrInfoSetF(pErrInfo, VERR_SUP_VP_NOT_SIGNED_WITH_BUILD_CERT,
    1127                                  "Not signed with the build certificate (serial %.*Rhxs, expected %.*Rhxs)",
     1176                                 "Signature #%u/%u: Not signed with the build certificate (serial %.*Rhxs, expected %.*Rhxs)",
     1177                                 pInfo->iSignature + 1, pInfo->cSignatures,
    11281178                                 pSignerInfo->IssuerAndSerialNumber.SerialNumber.Asn1Core.cb,
    11291179                                 pSignerInfo->IssuerAndSerialNumber.SerialNumber.Asn1Core.uData.pv,
     
    11951245            if (rc != VINF_SUCCESS)
    11961246            {
    1197                 SUP_DPRINTF(("%s: Signature #%u/%u: info status: %d\n", pNtViRdr->szFilename, pInfo->iSignature, pInfo->cbSignature, rc));
     1247                SUP_DPRINTF(("%s: Signature #%u/%u: info status: %d\n", pNtViRdr->szFilename, pInfo->iSignature + 1, pInfo->cSignatures, rc));
    11981248                if (pNtViRdr->rcLastSignatureFailure == VINF_SUCCESS)
    11991249                    pNtViRdr->rcLastSignatureFailure = rc;
     
    12101260        if (rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME && i + 1 < cTimes)
    12111261            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,
     1262                         pNtViRdr->szFilename, pInfo->iSignature + 1, pInfo->cSignatures,
    12131263                         RTTimeSpecGetSeconds(&aTimes[0].TimeSpec), RTTimeSpecGetSeconds(&aTimes[1].TimeSpec)));
    12141264        else
     
    12221272                || rc == VERR_CR_X509_CPV_NO_TRUSTED_PATHS)
    12231273            {
    1224                 SUP_DPRINTF(("%s: Signature #%u/%u: %s (%d) w/ timestamp=%#RX64/%s.\n", pNtViRdr->szFilename, pInfo->iSignature, pInfo->cbSignature,
     1274                SUP_DPRINTF(("%s: Signature #%u/%u: %s (%d) w/ timestamp=%#RX64/%s.\n", pNtViRdr->szFilename, pInfo->iSignature + 1, pInfo->cSignatures,
    12251275                             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,
    12261276                             RTTimeSpecGetSeconds(&aTimes[i].TimeSpec), aTimes[i].pszDesc));
     
    12351285            }
    12361286            else
    1237                 SUP_DPRINTF(("%s: Signature #%u/%u: %Rrc w/ timestamp=%#RX64/%s.\n", pNtViRdr->szFilename, pInfo->iSignature, pInfo->cbSignature,
     1287                SUP_DPRINTF(("%s: Signature #%u/%u: %Rrc w/ timestamp=%#RX64/%s.\n", pNtViRdr->szFilename, pInfo->iSignature + 1, pInfo->cSignatures,
    12381288                             rc, RTTimeSpecGetSeconds(&aTimes[i].TimeSpec), aTimes[i].pszDesc));
    12391289            return rc;
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