VirtualBox

Changeset 74760 in vbox for trunk/src/VBox/Runtime/common


Ignore:
Timestamp:
Oct 11, 2018 11:25:24 AM (6 years ago)
Author:
vboxsync
Message:

IPRT/ldr/asn1/pkcs7: Ironed out issues in decoding indefinite ASN.1 length records and successfully verified the first Mach-O signature. bugref:9232

Location:
trunk/src/VBox/Runtime/common
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp

    r74672 r74760  
    7575    pPrimaryCursor->pErrInfo                = pErrInfo;
    7676    pPrimaryCursor->pAllocator              = pAllocator;
     77    pPrimaryCursor->pbFirst                 = (uint8_t const *)pvFirst;
    7778    return &pPrimaryCursor->Cursor;
    7879}
     
    239240static int rtAsn1CursorCheckSeqOrSetEnd(PRTASN1CURSOR pCursor, PRTASN1CORE pAsn1Core)
    240241{
    241     if (pCursor->cbLeft == 0)
    242         return VINF_SUCCESS;
    243 
    244     if (pAsn1Core->fFlags & RTASN1CORE_F_INDEFINITE_LENGTH)
    245     {
    246         if (pCursor->cbLeft >= 2)
     242    if (!(pAsn1Core->fFlags & RTASN1CORE_F_INDEFINITE_LENGTH))
     243    {
     244        if (pCursor->cbLeft == 0)
     245            return VINF_SUCCESS;
     246        return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END,
     247                                   "%u (%#x) bytes left over", pCursor->cbLeft, pCursor->cbLeft);
     248    }
     249
     250    if (pCursor->cbLeft >= 2)
     251    {
     252        if (   pCursor->pbCur[0] == 0
     253            && pCursor->pbCur[1] == 0)
    247254        {
    248             if (   pCursor->pbCur[0] == 0
    249                 && pCursor->pbCur[1] == 0)
     255            pAsn1Core->cb = (uint32_t)(pCursor->pbCur - pAsn1Core->uData.pu8);
     256            pCursor->cbLeft -= 2;
     257            pCursor->pbCur  += 2;
     258
     259            PRTASN1CURSOR pParentCursor = pCursor->pUp;
     260            if (   pParentCursor
     261                && (pParentCursor->fFlags & RTASN1CURSOR_FLAGS_INDEFINITE_LENGTH))
    250262            {
    251                 pAsn1Core->cb = (uint32_t)(pCursor->pbCur - pAsn1Core->uData.pu8);
    252                 pCursor->cbLeft -= 2;
    253                 pCursor->pbCur  += 2;
    254 
    255                 PRTASN1CURSOR pParentCursor = pCursor->pUp;
    256                 if (   pParentCursor
    257                     && (pParentCursor->fFlags & RTASN1CURSOR_FLAGS_INDEFINITE_LENGTH))
    258                 {
    259                     pParentCursor->pbCur  -= pCursor->cbLeft;
    260                     pParentCursor->cbLeft += pCursor->cbLeft;
    261                     return VINF_SUCCESS;
    262                 }
    263 
    264                 if (pCursor->cbLeft == 0)
    265                     return VINF_SUCCESS;
    266 
    267                 return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END,
    268                                            "%u (%#x) bytes left over (parent not indefinite length)", pCursor->cbLeft, pCursor->cbLeft);
     263                pParentCursor->pbCur  -= pCursor->cbLeft;
     264                pParentCursor->cbLeft += pCursor->cbLeft;
     265                return VINF_SUCCESS;
    269266            }
    270             return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END, "%u (%#x) bytes left over [indef: %.*Rhxs]",
    271                                        pCursor->cbLeft, pCursor->cbLeft, RT_MIN(pCursor->cbLeft, 16), pCursor->pbCur);
     267
     268            if (pCursor->cbLeft == 0)
     269                return VINF_SUCCESS;
     270
     271            return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END,
     272                                       "%u (%#x) bytes left over (parent not indefinite length)", pCursor->cbLeft, pCursor->cbLeft);
    272273        }
    273         return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END,
    274                                    "1 byte left over, expected two for indefinite length end-of-content sequence");
    275     }
    276 
     274        return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END, "%u (%#x) bytes left over [indef: %.*Rhxs]",
     275                                   pCursor->cbLeft, pCursor->cbLeft, RT_MIN(pCursor->cbLeft, 16), pCursor->pbCur);
     276    }
    277277    return RTAsn1CursorSetInfo(pCursor, VERR_ASN1_CURSOR_NOT_AT_END,
    278                                "%u (%#x) bytes left over", pCursor->cbLeft, pCursor->cbLeft);
    279 
     278                               "1 byte left over, expected two for indefinite length end-of-content sequence");
    280279}
    281280
     
    290289{
    291290    return rtAsn1CursorCheckSeqOrSetEnd(pCursor, &pSetCore->Asn1Core);
     291}
     292
     293
     294RTDECL(int) RTAsn1CursorCheckOctStrEnd(PRTASN1CURSOR pCursor, PRTASN1OCTETSTRING pOctetString)
     295{
     296    return rtAsn1CursorCheckSeqOrSetEnd(pCursor, &pOctetString->Asn1Core);
    292297}
    293298
     
    426431                pCursor->fFlags   |= RTASN1CURSOR_FLAGS_INDEFINITE_LENGTH;
    427432                pAsn1Core->fFlags |= RTASN1CORE_F_INDEFINITE_LENGTH;
    428                 cb = pCursor->cbLeft - 2; /* tentatively for sequences and sets, definite for others */
     433                cb = pCursor->cbLeft; /* Start out with the whole sequence, adjusted later upon reach the end. */
    429434            }
    430435        }
  • trunk/src/VBox/Runtime/common/crypto/pkcs7-asn1-decoder.cpp

    r74672 r74760  
    144144                }
    145145                if (RT_SUCCESS(rc))
    146                     rc = RTAsn1CursorCheckEnd(&ContentCursor);
     146                    rc = RTAsn1CursorCheckOctStrEnd(&ContentCursor, &pThis->Content);
    147147                if (RT_SUCCESS(rc))
    148148                    return VINF_SUCCESS;
  • trunk/src/VBox/Runtime/common/crypto/pkcs7-verify.cpp

    r73665 r74760  
    5252static int rtCrPkcs7VerifySignedDataUsingOpenSsl(PCRTCRPKCS7CONTENTINFO pContentInfo, uint32_t fFlags,
    5353                                                 RTCRSTORE hAdditionalCerts, RTCRSTORE hTrustedCerts,
    54                                                  void const *pvContent, uint32_t cbContent, PRTERRINFO pErrInfo)
     54                                                 void const *pvContent, size_t cbContent, PRTERRINFO pErrInfo)
    5555{
    5656    RT_NOREF_PV(fFlags);
    5757
    5858    /*
    59      * Verify using OpenSSL.
     59     * Verify using OpenSSL.          ERR_PUT_error
    6060     */
    6161    int rcOssl;
    6262    unsigned char const *pbRawContent = RTASN1CORE_GET_RAW_ASN1_PTR(&pContentInfo->SeqCore.Asn1Core);
     63    uint32_t             cbRawContent = RTASN1CORE_GET_RAW_ASN1_SIZE(&pContentInfo->SeqCore.Asn1Core)
     64                                      + (pContentInfo->SeqCore.Asn1Core.fFlags & RTASN1CORE_F_INDEFINITE_LENGTH ? 2 : 0);
    6365    PKCS7 *pOsslPkcs7 = NULL;
    64     if (d2i_PKCS7(&pOsslPkcs7, &pbRawContent, RTASN1CORE_GET_RAW_ASN1_SIZE(&pContentInfo->SeqCore.Asn1Core)) == pOsslPkcs7)
     66    if (d2i_PKCS7(&pOsslPkcs7, &pbRawContent, cbRawContent) != NULL)
    6567    {
    6668        STACK_OF(X509) *pAddCerts = NULL;
     
    7880                if (pCerts->papItems[i]->enmChoice == RTCRPKCS7CERTCHOICE_X509)
    7981                    rtCrOpenSslAddX509CertToStack(pAddCerts, pCerts->papItems[i]->u.pX509Cert);
    80 
    8182
    8283            X509_STORE *pTrustedCerts = NULL;
     
    8788                rtCrOpenSslInit();
    8889
    89                 BIO *pBioContent = BIO_new_mem_buf((void *)pvContent, cbContent);
     90                BIO *pBioContent = BIO_new_mem_buf((void *)pvContent, (int)cbContent);
    9091                if (pBioContent)
    9192                {
     
    115116    }
    116117    else
     118    {
    117119        rcOssl = RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_OSSL_D2I_FAILED, "d2i_PKCS7 failed");
     120        if (pErrInfo)
     121            ERR_print_errors_cb(rtCrOpenSslErrInfoCallback, pErrInfo);
     122    }
    118123
    119124    return rcOssl;
     
    575580
    576581
    577 RTDECL(int) RTCrPkcs7VerifySignedData(PCRTCRPKCS7CONTENTINFO pContentInfo, uint32_t fFlags,
    578                                       RTCRSTORE hAdditionalCerts, RTCRSTORE hTrustedCerts,
    579                                       PCRTTIMESPEC pValidationTime, PFNRTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, void *pvUser,
    580                                       PRTERRINFO pErrInfo)
    581 {
    582     /*
    583      * Check the input.
     582/**
     583 * Worker.
     584 */
     585static int rtCrPkcs7VerifySignedDataEx(PCRTCRPKCS7CONTENTINFO pContentInfo, uint32_t fFlags,
     586                                       RTCRSTORE hAdditionalCerts, RTCRSTORE hTrustedCerts,
     587                                       PCRTTIMESPEC pValidationTime,
     588                                       PFNRTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, void *pvUser,
     589                                       void const *pvContent, size_t cbContent, PRTERRINFO pErrInfo)
     590{
     591    /*
     592     * Check and adjust the input.
    584593     */
    585594    if (pfnVerifyCert)
     
    598607     * Hash the content info.
    599608     */
    600     /* Exactly what the content is, for some stupid reason unnecessarily
    601        complicated.  Figure it out here as we'll need it for the OpenSSL code
    602        path as well. */
    603     void const *pvContent = pSignedData->ContentInfo.Content.Asn1Core.uData.pv;
    604     uint32_t    cbContent = pSignedData->ContentInfo.Content.Asn1Core.cb;
    605     if (pSignedData->ContentInfo.Content.pEncapsulated)
    606     {
    607         pvContent = pSignedData->ContentInfo.Content.pEncapsulated->uData.pv;
    608         cbContent = pSignedData->ContentInfo.Content.pEncapsulated->cb;
    609     }
    610 
    611609    /* Check that there aren't too many or too few hash algorithms for our
    612610       implementation and purposes. */
     
    784782}
    785783
     784
     785RTDECL(int) RTCrPkcs7VerifySignedData(PCRTCRPKCS7CONTENTINFO pContentInfo, uint32_t fFlags,
     786                                      RTCRSTORE hAdditionalCerts, RTCRSTORE hTrustedCerts,
     787                                      PCRTTIMESPEC pValidationTime, PFNRTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, void *pvUser,
     788                                      PRTERRINFO pErrInfo)
     789{
     790    /*
     791     * Find the content and pass it on to common worker.
     792     */
     793    if (!RTCrPkcs7ContentInfo_IsSignedData(pContentInfo))
     794        return RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_NOT_SIGNED_DATA, "Not PKCS #7 SignedData.");
     795
     796    /* Exactly what the content is, is for some stupid reason unnecessarily complicated. */
     797    PCRTCRPKCS7SIGNEDDATA pSignedData = pContentInfo->u.pSignedData;
     798    void const *pvContent = pSignedData->ContentInfo.Content.Asn1Core.uData.pv;
     799    uint32_t    cbContent = pSignedData->ContentInfo.Content.Asn1Core.cb;
     800    if (pSignedData->ContentInfo.Content.pEncapsulated)
     801    {
     802        pvContent = pSignedData->ContentInfo.Content.pEncapsulated->uData.pv;
     803        cbContent = pSignedData->ContentInfo.Content.pEncapsulated->cb;
     804    }
     805
     806    return rtCrPkcs7VerifySignedDataEx(pContentInfo, fFlags, hAdditionalCerts, hTrustedCerts, pValidationTime,
     807                                       pfnVerifyCert, pvUser, pvContent, cbContent, pErrInfo);
     808}
     809
     810
     811RTDECL(int) RTCrPkcs7VerifySignedDataWithExternalData(PCRTCRPKCS7CONTENTINFO pContentInfo, uint32_t fFlags,
     812                                                      RTCRSTORE hAdditionalCerts, RTCRSTORE hTrustedCerts,
     813                                                      PCRTTIMESPEC pValidationTime,
     814                                                      PFNRTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, void *pvUser,
     815                                                      void const *pvData, size_t cbData, PRTERRINFO pErrInfo)
     816{
     817    /*
     818     * Require 'data' as inner content type.
     819     */
     820    if (!RTCrPkcs7ContentInfo_IsSignedData(pContentInfo))
     821        return RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_NOT_SIGNED_DATA, "Not PKCS #7 SignedData.");
     822    PCRTCRPKCS7SIGNEDDATA pSignedData = pContentInfo->u.pSignedData;
     823
     824    if (RTAsn1ObjId_CompareWithString(&pSignedData->ContentInfo.ContentType, RTCR_PKCS7_DATA_OID) != 0)
     825        return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_NOT_DATA,
     826                             "The signedData content type is %s, expected 'data' (%s)",
     827                             pSignedData->ContentInfo.ContentType.szObjId, RTCR_PKCS7_DATA_OID);
     828
     829    return rtCrPkcs7VerifySignedDataEx(pContentInfo, fFlags, hAdditionalCerts, hTrustedCerts, pValidationTime,
     830                                       pfnVerifyCert, pvUser, pvData, cbData, pErrInfo);
     831}
     832
     833
  • trunk/src/VBox/Runtime/common/ldr/ldrMachO.cpp

    r74750 r74760  
    48494849                    rc = pfnCallback(&pThis->Core, RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA,
    48504850                                     &pSignature->ContentInfo, sizeof(pSignature->ContentInfo),
     4851                                     pSignature->aCodeDirs[0].pCodeDir, pSignature->aCodeDirs[0].cb,
    48514852                                     pErrInfo, pvUser);
    48524853                }
  • trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp

    r74721 r74760  
    28992899                rc = pfnCallback(&pModPe->Core, RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA,
    29002900                                 &pSignature->ContentInfo, sizeof(pSignature->ContentInfo),
     2901                                 NULL /*pvExternalData*/, 0 /*cbExternalData*/,
    29012902                                 pErrInfo, pvUser);
    29022903            }
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