VirtualBox

Ignore:
Timestamp:
May 14, 2020 5:40:35 PM (5 years ago)
Author:
vboxsync
Message:

IPRT/crypto: Adding RTAsn1EncodeQueryRawBits to deal with getting encoded bytes cheaply if possible and always safely. Fixed another place using RTASN1CORE_GET_RAW_ASN1_PTR and assuming input was decoded and had valid data pointers. Added RTCrStoreCertAddPkcs7 and RTCrStoreCertAddX509 for more conveniently adding decoded certs to stores. Added RTCRPKCS7VERIFY_SD_F_TRUST_ALL_CERTS to the PKCS7 verification code. Added RTCrPkcs7_ReadFromBuffer. bugref:9699

Location:
trunk/src/VBox/Runtime/common/crypto
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/crypto/iprt-openssl.cpp

    r84248 r84310  
    7070{
    7171    const unsigned char *pabEncoded;
    72 
    73     /*
    74      * ASSUME that if the certificate has data pointers, it's been parsed out
    75      * of a binary blob and we can safely access that here.
    76      */
    77     if (pCert->SeqCore.Asn1Core.uData.pv)
     72    uint32_t             cbEncoded;
     73    void                *pvFree;
     74    int rc = RTAsn1EncodeQueryRawBits(RTCrX509Certificate_GetAsn1Core(pCert),
     75                                      (const uint8_t **)&pabEncoded, &cbEncoded, &pvFree, pErrInfo);
     76    if (RT_SUCCESS(rc))
    7877    {
    79         pabEncoded = (const unsigned char *)RTASN1CORE_GET_RAW_ASN1_PTR(&pCert->SeqCore.Asn1Core);
    80         uint32_t cbEncoded  = RTASN1CORE_GET_RAW_ASN1_SIZE(&pCert->SeqCore.Asn1Core);
    81         X509    *pOsslCert  = NULL;
    82         if (d2i_X509(&pOsslCert, &pabEncoded, cbEncoded) == pOsslCert)
     78        X509 *pOsslCert = NULL;
     79        X509 *pOsslCertRet = d2i_X509(&pOsslCert, &pabEncoded, cbEncoded);
     80        RTMemTmpFree(pvFree);
     81        if (pOsslCertRet == pOsslCert)
    8382        {
    8483            *ppvOsslCert = pOsslCert;
    8584            return VINF_SUCCESS;
    8685        }
     86        rc = RTErrInfoSet(pErrInfo, VERR_CR_X509_OSSL_D2I_FAILED, "d2i_X509");
     87
    8788    }
    88     /*
    89      * Otherwise, we'll have to encode it into a temporary buffer that openssl
    90      * can decode into its structures.
    91      */
    92     else
    93     {
    94         PRTASN1CORE pNonConstCore = (PRTASN1CORE)&pCert->SeqCore.Asn1Core;
    95         uint32_t    cbEncoded     = 0;
    96         int rc = RTAsn1EncodePrepare(pNonConstCore, RTASN1ENCODE_F_DER, &cbEncoded, pErrInfo);
    97         AssertRCReturn(rc, rc);
    98 
    99         void * const pvEncoded = RTMemTmpAllocZ(cbEncoded);
    100         AssertReturn(pvEncoded, VERR_NO_TMP_MEMORY);
    101 
    102         rc = RTAsn1EncodeToBuffer(pNonConstCore, RTASN1ENCODE_F_DER, pvEncoded, cbEncoded, pErrInfo);
    103         if (RT_SUCCESS(rc))
    104         {
    105             pabEncoded = (const unsigned char *)pvEncoded;
    106             X509 *pOsslCert = NULL;
    107             if (d2i_X509(&pOsslCert, &pabEncoded, cbEncoded) == pOsslCert)
    108             {
    109                 *ppvOsslCert = pOsslCert;
    110                 RTMemTmpFree(pvEncoded);
    111                 return VINF_SUCCESS;
    112             }
    113         }
    114         else
    115         {
    116             RTMemTmpFree(pvEncoded);
    117             return rc;
    118         }
    119     }
    120 
    12189    *ppvOsslCert = NULL;
    122     return RTErrInfoSet(pErrInfo, VERR_CR_X509_OSSL_D2I_FAILED, "d2i_X509");
     90    return rc;
    12391}
    12492
  • trunk/src/VBox/Runtime/common/crypto/pkcs7-verify.cpp

    r84230 r84310  
    3333
    3434#include <iprt/err.h>
     35#include <iprt/mem.h>
    3536#include <iprt/string.h>
    3637#include <iprt/crypto/digest.h>
     
    5960     * Verify using OpenSSL.          ERR_PUT_error
    6061     */
    61     int rcOssl;
    62     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);
    65     PKCS7 *pOsslPkcs7 = NULL;
    66     if (d2i_PKCS7(&pOsslPkcs7, &pbRawContent, cbRawContent) != NULL)
     62    unsigned char const *pbRawContent;
     63    uint32_t             cbRawContent;
     64    void                *pvFree;
     65    int rcOssl = RTAsn1EncodeQueryRawBits(RTCrPkcs7ContentInfo_GetAsn1Core(pContentInfo),
     66                                          (const uint8_t **)&pbRawContent, &cbRawContent, &pvFree, pErrInfo);
     67    AssertRCReturn(rcOssl, rcOssl);
     68
     69    PKCS7 *pOsslPkcs7   = NULL;
     70    PKCS7 *pOsslPkcs7Ret = d2i_PKCS7(&pOsslPkcs7, &pbRawContent, cbRawContent);
     71
     72    RTMemTmpFree(pvFree);
     73
     74    if (pOsslPkcs7Ret != NULL)
    6775    {
    6876        STACK_OF(X509) *pAddCerts = NULL;
     
    317325
    318326        /* ASSUMES that the attributes are encoded according to DER. */
    319         uint8_t const  *pbData = (uint8_t const *)RTASN1CORE_GET_RAW_ASN1_PTR(&pSignerInfo->AuthenticatedAttributes.SetCore.Asn1Core);
    320         uint32_t        cbData = RTASN1CORE_GET_RAW_ASN1_SIZE(&pSignerInfo->AuthenticatedAttributes.SetCore.Asn1Core);
    321         uint8_t         bSetOfTag = ASN1_TAG_SET | ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED;
    322         rc = RTCrDigestUpdate(hDigest, &bSetOfTag, sizeof(bSetOfTag)); /* Replace the implict tag with a SET-OF tag. */
     327        uint8_t const  *pbData;
     328        uint32_t        cbData;
     329        void           *pvFree = NULL;
     330        rc = RTAsn1EncodeQueryRawBits(RTCrPkcs7Attributes_GetAsn1Core(&pSignerInfo->AuthenticatedAttributes),
     331                                      &pbData, &cbData, &pvFree, pErrInfo);
    323332        if (RT_SUCCESS(rc))
    324             rc = RTCrDigestUpdate(hDigest, pbData + sizeof(bSetOfTag), cbData - sizeof(bSetOfTag)); /* Skip the implicit tag. */
    325         if (RT_SUCCESS(rc))
    326             rc = RTCrDigestFinal(hDigest, NULL, 0);
     333        {
     334            uint8_t bSetOfTag = ASN1_TAG_SET | ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED;
     335            rc = RTCrDigestUpdate(hDigest, &bSetOfTag, sizeof(bSetOfTag)); /* Replace the implict tag with a SET-OF tag. */
     336            if (RT_SUCCESS(rc))
     337                rc = RTCrDigestUpdate(hDigest, pbData + sizeof(bSetOfTag), cbData - sizeof(bSetOfTag)); /* Skip the implicit tag. */
     338            if (RT_SUCCESS(rc))
     339                rc = RTCrDigestFinal(hDigest, NULL, 0);
     340            RTMemTmpFree(pvFree);
     341        }
    327342    }
    328343    return rc;
     
    425440     */
    426441    int rc = VINF_SUCCESS;
    427     if (   hSignerCertSrc == NIL_RTCRSTORE
    428         || hSignerCertSrc != hTrustedCerts)
     442    if (   (   hSignerCertSrc == NIL_RTCRSTORE
     443            || hSignerCertSrc != hTrustedCerts)
     444        && !(fFlags & RTCRPKCS7VERIFY_SD_F_TRUST_ALL_CERTS) )
    429445    {
    430446        RTCRX509CERTPATHS hCertPaths;
  • trunk/src/VBox/Runtime/common/crypto/store.cpp

    r84253 r84310  
    3737#include <iprt/string.h>
    3838
     39#include <iprt/crypto/pkcs7.h>
    3940#include <iprt/crypto/x509.h>
    4041
     
    188189}
    189190
     191
     192RTDECL(int) RTCrStoreCertAddX509(RTCRSTORE hStore, uint32_t fFlags, PRTCRX509CERTIFICATE pCertificate, PRTERRINFO pErrInfo)
     193{
     194    /*
     195     * Validate.
     196     */
     197    PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
     198    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     199    AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, VERR_INVALID_HANDLE);
     200
     201    AssertPtrReturn(pCertificate, VERR_INVALID_POINTER);
     202    AssertReturn(RTCrX509Certificate_IsPresent(pCertificate), VERR_INVALID_PARAMETER);
     203    int rc = RTCrX509Certificate_CheckSanity(pCertificate, 0, pErrInfo, "Cert");
     204    AssertRCReturn(rc, rc);
     205
     206    AssertReturn(!(fFlags & ~(RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ENC_MASK)), VERR_INVALID_FLAGS);
     207    AssertCompile(RTCRCERTCTX_F_ENC_X509_DER == 0);
     208    AssertMsgReturn((fFlags & RTCRCERTCTX_F_ENC_MASK) == RTCRCERTCTX_F_ENC_X509_DER,
     209                    ("Invalid encoding: %#x\n", fFlags), VERR_INVALID_FLAGS);
     210
     211    /*
     212     * Encode and add it using pfnCertAddEncoded.
     213     */
     214    if (pThis->pProvider->pfnCertAddEncoded)
     215    {
     216        PRTASN1CORE pCore     = RTCrX509Certificate_GetAsn1Core(pCertificate);
     217        uint32_t    cbEncoded = 0;
     218        rc = RTAsn1EncodePrepare(pCore, RTASN1ENCODE_F_DER, &cbEncoded, pErrInfo);
     219        if (RT_SUCCESS(rc))
     220        {
     221            uint8_t * const pbEncoded = (uint8_t *)RTMemTmpAllocZ(cbEncoded);
     222            if (pbEncoded)
     223            {
     224                rc = RTAsn1EncodeToBuffer(pCore, RTASN1ENCODE_F_DER, pbEncoded, cbEncoded, pErrInfo);
     225                if (RT_SUCCESS(rc))
     226                    rc = pThis->pProvider->pfnCertAddEncoded(pThis->pvProvider, fFlags, pbEncoded, cbEncoded, pErrInfo);
     227                RTMemTmpFree(pbEncoded);
     228            }
     229            else
     230                rc = VERR_NO_TMP_MEMORY;
     231        }
     232    }
     233    else
     234        rc = VERR_WRITE_PROTECT;
     235
     236    return rc;
     237}
     238
     239
     240RTDECL(int) RTCrStoreCertAddPkcs7(RTCRSTORE hStore, uint32_t fFlags, PRTCRPKCS7CERT pCertificate, PRTERRINFO pErrInfo)
     241{
     242    AssertPtrReturn(pCertificate, VERR_INVALID_POINTER);
     243    AssertReturn(RTCrPkcs7Cert_IsPresent(pCertificate), VERR_INVALID_PARAMETER);
     244    switch (pCertificate->enmChoice)
     245    {
     246        case RTCRPKCS7CERTCHOICE_X509:
     247            return RTCrStoreCertAddX509(hStore, fFlags, pCertificate->u.pX509Cert, pErrInfo);
     248
     249        case RTCRPKCS7CERTCHOICE_EXTENDED_PKCS6:
     250            return RTErrInfoSetF(pErrInfo, VERR_NOT_IMPLEMENTED, "RTCrStoreCertAddPkcs7 does not implement EXTENDED_PKCS6");
     251        case RTCRPKCS7CERTCHOICE_AC_V1:
     252            return RTErrInfoSetF(pErrInfo, VERR_NOT_IMPLEMENTED, "RTCrStoreCertAddPkcs7 does not implement AC_V1");
     253        case RTCRPKCS7CERTCHOICE_AC_V2:
     254            return RTErrInfoSetF(pErrInfo, VERR_NOT_IMPLEMENTED, "RTCrStoreCertAddPkcs7 does not implement AC_V2");
     255        case RTCRPKCS7CERTCHOICE_OTHER:
     256            return RTErrInfoSetF(pErrInfo, VERR_NOT_IMPLEMENTED, "RTCrStoreCertAddPkcs7 does not implement OTHER");
     257        case RTCRPKCS7CERTCHOICE_END:
     258        case RTCRPKCS7CERTCHOICE_INVALID:
     259        case RTCRPKCS7CERTCHOICE_32BIT_HACK:
     260            break;
     261        /* no default */
     262    }
     263    return RTErrInfoSetF(pErrInfo, VERR_INVALID_PARAMETER, "Invalid RTCRPKCS7CERT enmChoice value: %d", pCertificate->enmChoice);
     264}
    190265
    191266
  • trunk/src/VBox/Runtime/common/crypto/x509-verify.cpp

    r82968 r84310  
    8989     * encoded bits are missing.
    9090     */
    91     if (   pThis->TbsCertificate.SeqCore.Asn1Core.uData.pu8
    92         && pThis->TbsCertificate.SeqCore.Asn1Core.cb > 0)
     91    const uint8_t  *pbRaw;
     92    uint32_t        cbRaw;
     93    void           *pvFree = NULL;
     94    rc = RTAsn1EncodeQueryRawBits(RTCrX509TbsCertificate_GetAsn1Core(&pThis->TbsCertificate), &pbRaw, &cbRaw, &pvFree, pErrInfo);
     95    if (RT_SUCCESS(rc))
     96    {
    9397        rc = RTCrPkixPubKeyVerifySignature(&pThis->SignatureAlgorithm.Algorithm, hPubKey, pParameters, &pThis->SignatureValue,
    94                                            RTASN1CORE_GET_RAW_ASN1_PTR(&pThis->TbsCertificate.SeqCore.Asn1Core),
    95                                            RTASN1CORE_GET_RAW_ASN1_SIZE(&pThis->TbsCertificate.SeqCore.Asn1Core),
    96                                            pErrInfo);
    97     else
    98     {
    99         uint32_t cbEncoded;
    100         rc = RTAsn1EncodePrepare((PRTASN1CORE)&pThis->TbsCertificate.SeqCore.Asn1Core, RTASN1ENCODE_F_DER, &cbEncoded, pErrInfo);
    101         if (RT_SUCCESS(rc))
    102         {
    103             void *pvTbsBits = RTMemTmpAlloc(cbEncoded);
    104             if (pvTbsBits)
    105             {
    106                 rc = RTAsn1EncodeToBuffer(&pThis->TbsCertificate.SeqCore.Asn1Core, RTASN1ENCODE_F_DER,
    107                                           pvTbsBits, cbEncoded, pErrInfo);
    108                 if (RT_SUCCESS(rc))
    109                     rc = RTCrPkixPubKeyVerifySignature(&pThis->SignatureAlgorithm.Algorithm, hPubKey, pParameters,
    110                                                        &pThis->SignatureValue, pvTbsBits, cbEncoded, pErrInfo);
    111                 else
    112                     AssertRC(rc);
    113                 RTMemTmpFree(pvTbsBits);
    114             }
    115             else
    116                 rc = VERR_NO_TMP_MEMORY;
    117         }
     98                                           pbRaw, cbRaw, pErrInfo);
     99        RTMemTmpFree(pvFree);
    118100    }
    119101
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