VirtualBox

Changeset 64883 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Dec 15, 2016 3:26:20 PM (8 years ago)
Author:
vboxsync
Message:

IPRT/ASN.1: Refactored array handling (SET OF, SEQUENCE OF) to use a pointer array instead of an object instance array. The old approach would move objects around in memory after they'd be initialized/decoded, making certain core optimziations involving pointers to object members impossible, as well as causing potentially causing trouble when modifying structures that takes down pointers after decoding. Fixed validation bug in rtCrX509Name_CheckSanityExtra where it didn't check that the RDNs had subitems but instead checked the parent twice (slight risk).

Location:
trunk/src/VBox/Runtime
Files:
14 edited

Legend:

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

    r62564 r64883  
    7575
    7676
    77 
    78 RTDECL(int) RTAsn1MemGrowArray(PRTASN1ALLOCATION pAllocation, void **ppvArray, size_t cbEntry,
    79                                uint32_t cCurrent, uint32_t cNew)
     77RTDECL(int) RTAsn1MemResizeArray(PRTASN1ARRAYALLOCATION pAllocation, void ***ppapvArray, uint32_t cCurrent, uint32_t cNew)
    8078{
    8179    AssertReturn(pAllocation->pAllocator != NULL, VERR_WRONG_ORDER);
    82     AssertReturn(cbEntry > 0, VERR_INVALID_PARAMETER);
    83     AssertReturn(cNew > cCurrent, VERR_INVALID_PARAMETER);
     80    AssertReturn(pAllocation->cbEntry > 0, VERR_WRONG_ORDER);
     81    AssertReturn(cCurrent <= pAllocation->cEntriesAllocated, VERR_INVALID_PARAMETER);
     82    AssertReturn(cCurrent <= pAllocation->cPointersAllocated, VERR_INVALID_PARAMETER);
    8483    AssertReturn(cNew < _1M, VERR_OUT_OF_RANGE);
    85 
    86     pAllocation->cReallocs++;
    87 
    88     void *pvOld = *ppvArray;
    89 
    90     /* Initial allocation? */
    91     if (cCurrent == 0)
    92     {
    93         AssertReturn(pvOld == NULL, VERR_INVALID_PARAMETER);
    94         AssertReturn(cNew != 0, VERR_INVALID_PARAMETER);
    95         return pAllocation->pAllocator->pfnAlloc(pAllocation->pAllocator, pAllocation, ppvArray, cNew * cbEntry);
    96     }
    97 
    98     /* Do we need to grow the allocation or did we already allocate sufficient memory in a previous call? */
    99     size_t cbNew = cNew * cbEntry;
    100     if (pAllocation->cbAllocated < cbNew)
    101     {
    102         /* Need to grow.  Adjust the new size according to how many times we've been called. */
    103         if (pAllocation->cReallocs > 2)
    104         {
    105             if (pAllocation->cReallocs > 8)
    106                 cNew += 8;
    107             else if (pAllocation->cReallocs < 4)
    108                 cNew += 2;
    109             else
    110                 cNew += 4;
    111             cbNew += cNew * cbEntry;
    112         }
    113 
    114         int rc = pAllocation->pAllocator->pfnRealloc(pAllocation->pAllocator, pAllocation, pvOld, ppvArray, cbNew);
    115         if (RT_FAILURE(rc))
    116             return rc;
    117         Assert(pAllocation->cbAllocated >= cbNew);
    118 
    119         /* Clear the memory. */
    120         size_t cbOld = cCurrent * cbEntry;
    121         RT_BZERO((uint8_t *)*ppvArray + cbOld, pAllocation->cbAllocated - cbOld);
    122     }
    123 
    124     return VINF_SUCCESS;
     84    Assert(pAllocation->cEntriesAllocated <= pAllocation->cPointersAllocated);
     85
     86    /*
     87     * Is there sufficent space allocated already?
     88     *
     89     * We keep unused entires ZEROed, therefore we must always call the allocator
     90     * when shrinking (this also helps with the electric fence allocator).
     91     */
     92    if (cNew <= pAllocation->cEntriesAllocated)
     93    {
     94        if (cCurrent <= cNew)
     95            return VINF_SUCCESS;
     96        pAllocation->pAllocator->pfnShrinkArray(pAllocation->pAllocator, pAllocation, ppapvArray, cCurrent, cNew);
     97        return VINF_SUCCESS;
     98    }
     99
     100    /*
     101     * Must grow (or do initial alloc).
     102     */
     103    pAllocation->cResizeCalls++;
     104    return pAllocation->pAllocator->pfnGrowArray(pAllocation->pAllocator, pAllocation, ppapvArray, cNew);
     105}
     106
     107
     108RTDECL(void) RTAsn1MemFreeArray(PRTASN1ARRAYALLOCATION pAllocation, void **papvArray)
     109{
     110    Assert(pAllocation->pAllocator != NULL);
     111    if (papvArray)
     112    {
     113        pAllocation->pAllocator->pfnFreeArray(pAllocation->pAllocator, pAllocation, papvArray);
     114        Assert(pAllocation->cPointersAllocated == 0);
     115        Assert(pAllocation->cEntriesAllocated == 0);
     116    }
    125117}
    126118
     
    171163    pAllocation->uReserved0  = 0;
    172164    pAllocation->pAllocator  = pAllocator;
     165    return pAllocation;
     166}
     167
     168
     169RTDECL(PRTASN1ARRAYALLOCATION) RTAsn1MemInitArrayAllocation(PRTASN1ARRAYALLOCATION pAllocation,
     170                                                            PCRTASN1ALLOCATORVTABLE pAllocator, size_t cbEntry)
     171{
     172    Assert(cbEntry >= sizeof(RTASN1CORE));
     173    Assert(cbEntry < _1M);
     174    Assert(RT_ALIGN_Z(cbEntry, sizeof(void *)) == cbEntry);
     175    pAllocation->cbEntry            = (uint32_t)cbEntry;
     176    pAllocation->cPointersAllocated = 0;
     177    pAllocation->cEntriesAllocated  = 0;
     178    pAllocation->cResizeCalls       = 0;
     179    pAllocation->uReserved0         = 0;
     180    pAllocation->pAllocator         = pAllocator;
    173181    return pAllocation;
    174182}
  • trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp

    r63451 r64883  
    202202    pAllocation->uReserved0  = 0;
    203203    pAllocation->pAllocator  = pCursor->pPrimary->pAllocator;
     204    return pAllocation;
     205}
     206
     207
     208RTDECL(PRTASN1ARRAYALLOCATION) RTAsn1CursorInitArrayAllocation(PRTASN1CURSOR pCursor, PRTASN1ARRAYALLOCATION pAllocation,
     209                                                               size_t cbEntry)
     210{
     211    Assert(cbEntry >= sizeof(RTASN1CORE));
     212    Assert(cbEntry < _1M);
     213    Assert(RT_ALIGN_Z(cbEntry, sizeof(void *)) == cbEntry);
     214    pAllocation->cbEntry            = (uint32_t)cbEntry;
     215    pAllocation->cPointersAllocated = 0;
     216    pAllocation->cEntriesAllocated  = 0;
     217    pAllocation->cResizeCalls       = 0;
     218    pAllocation->uReserved0         = 0;
     219    pAllocation->pAllocator         = pCursor->pPrimary->pAllocator;
    204220    return pAllocation;
    205221}
  • trunk/src/VBox/Runtime/common/asn1/asn1-default-allocator.cpp

    r62564 r64883  
    100100
    101101
     102/** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnFreeArray} */
     103static DECLCALLBACK(void) rtAsn1DefaultAllocator_FreeArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation,
     104                                                           void **papvArray)
     105{
     106    RT_NOREF_PV(pThis);
     107    Assert(papvArray);
     108    Assert(pAllocation->cbEntry);
     109
     110    uint32_t i = pAllocation->cEntriesAllocated;
     111    while (i-- > 0)
     112        RTMemFree(papvArray[i]);
     113    RTMemFree(papvArray);
     114
     115    pAllocation->cEntriesAllocated  = 0;
     116    pAllocation->cPointersAllocated = 0;
     117}
     118
     119
     120/** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnGrowArray} */
     121static DECLCALLBACK(int) rtAsn1DefaultAllocator_GrowArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation,
     122                                                          void ***ppapvArray, uint32_t cMinEntries)
     123{
     124    RT_NOREF_PV(pThis);
     125
     126    /*
     127     * Resize the pointer array.  We do chunks of 64 bytes for now.
     128     */
     129    void **papvArray = *ppapvArray;
     130    uint32_t cPointers = RT_ALIGN_32(cMinEntries, 64 / sizeof(void *));
     131    if (cPointers > pAllocation->cPointersAllocated)
     132    {
     133        void *pvPointers = RTMemRealloc(papvArray, cPointers * sizeof(void *));
     134        if (pvPointers)
     135        { /* likely */ }
     136        else if (cMinEntries > pAllocation->cPointersAllocated)
     137        {
     138            cPointers  = cMinEntries;
     139            pvPointers = RTMemRealloc(*ppapvArray, cPointers * sizeof(void *));
     140            if (!pvPointers)
     141                return VERR_NO_MEMORY;
     142        }
     143        else
     144        {
     145            cPointers  = pAllocation->cPointersAllocated;
     146            pvPointers = papvArray;
     147        }
     148
     149        *ppapvArray = papvArray = (void **)pvPointers;
     150        RT_BZERO(&papvArray[pAllocation->cPointersAllocated], (cPointers - pAllocation->cPointersAllocated) * sizeof(void *));
     151        pAllocation->cPointersAllocated = cPointers;
     152    }
     153
     154    /*
     155     * Add more entries.  Do multiple as the array grows.
     156     *
     157     * Note! We could possibly optimize this by allocating slabs of entries and
     158     *       slice them up.  However, keep things as simple as possible for now.
     159     */
     160    uint32_t cEntries = cMinEntries;
     161    if (cEntries > 2)
     162    {
     163        if (cEntries > 8)
     164            cEntries = RT_ALIGN_32(cEntries, 4);
     165        else
     166            cEntries = RT_ALIGN_32(cEntries, 2);
     167        cEntries = RT_MIN(cEntries, cPointers);
     168        Assert(cEntries >= cMinEntries);
     169    }
     170    Assert(cEntries <= pAllocation->cPointersAllocated);
     171
     172    while (pAllocation->cEntriesAllocated < cEntries)
     173    {
     174        void *pv;
     175        papvArray[pAllocation->cEntriesAllocated] = pv = RTMemAllocZ(pAllocation->cbEntry);
     176        if (pv)
     177            pAllocation->cEntriesAllocated++;
     178        else if (pAllocation->cEntriesAllocated >= cMinEntries)
     179            break;
     180        else
     181            return VERR_NO_MEMORY;
     182    }
     183
     184    return VINF_SUCCESS;
     185}
     186
     187
     188/** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnShrinkArray} */
     189static DECLCALLBACK(void) rtAsn1DefaultAllocator_ShrinkArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation,
     190                                                             void ***ppapvArray, uint32_t cNew, uint32_t cCurrent)
     191{
     192    RT_NOREF_PV(pThis);
     193
     194    /*
     195     * For now we only zero the entries being removed.
     196     */
     197    void **papvArray = *ppapvArray;
     198    while (cNew < cCurrent)
     199    {
     200        RT_BZERO(papvArray[cNew], pAllocation->cbEntry);
     201        cNew++;
     202    }
     203}
     204
     205
     206
    102207/** The default ASN.1 allocator. */
     208#if 1 || !defined(IN_RING3) || defined(DOXYGEN_RUNNING)
    103209RT_DECL_DATA_CONST(RTASN1ALLOCATORVTABLE const) g_RTAsn1DefaultAllocator =
     210#else
     211RT_DECL_DATA_CONST(RTASN1ALLOCATORVTABLE const) g_RTAsn1DefaultAllocatorDisabled =
     212#endif
    104213{
    105214    rtAsn1DefaultAllocator_Free,
    106215    rtAsn1DefaultAllocator_Alloc,
    107     rtAsn1DefaultAllocator_Realloc
     216    rtAsn1DefaultAllocator_Realloc,
     217    rtAsn1DefaultAllocator_FreeArray,
     218    rtAsn1DefaultAllocator_GrowArray,
     219    rtAsn1DefaultAllocator_ShrinkArray
    108220};
    109221
  • trunk/src/VBox/Runtime/common/asn1/asn1-efence-allocator.cpp

    r62564 r64883  
    8080
    8181
     82/** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnFreeArray} */
     83static DECLCALLBACK(void) rtAsn1EFenceAllocator_FreeArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation,
     84                                                          void **papvArray)
     85{
     86    RT_NOREF_PV(pThis);
     87    Assert(papvArray);
     88    Assert(pAllocation->cbEntry);
     89    Assert(pAllocation->cEntriesAllocated <= pAllocation->cPointersAllocated);
     90
     91    uint32_t i = pAllocation->cEntriesAllocated;
     92    while (i-- > 0)
     93    {
     94        RTMemEfFreeNP(papvArray[i]);
     95        papvArray[i] = NULL;
     96    }
     97    RTMemEfFreeNP(papvArray);
     98
     99    pAllocation->cEntriesAllocated  = 0;
     100    pAllocation->cPointersAllocated = 0;
     101}
     102
     103
     104/** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnGrowArray} */
     105static DECLCALLBACK(int) rtAsn1EFenceAllocator_GrowArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation,
     106                                                         void ***ppapvArray, uint32_t cMinEntries)
     107{
     108    RT_NOREF_PV(pThis);
     109    Assert(pAllocation->cbEntry);
     110    Assert(pAllocation->cEntriesAllocated <= pAllocation->cPointersAllocated);
     111
     112    /*
     113     * Resize the pointer array.
     114     */
     115    void **papvArray = *ppapvArray;
     116    void *pvPointers = RTMemEfReallocNP(papvArray, cMinEntries * sizeof(void *), RTMEM_TAG);
     117    if (pvPointers)
     118    {
     119        *ppapvArray = papvArray = (void **)pvPointers;
     120        if (cMinEntries > pAllocation->cPointersAllocated) /* possible on multiple shrink failures */
     121            RT_BZERO(&papvArray[pAllocation->cPointersAllocated],
     122                     (cMinEntries - pAllocation->cPointersAllocated) * sizeof(void *));
     123        else
     124            AssertFailed();
     125        pAllocation->cPointersAllocated = cMinEntries;
     126    }
     127    else if (cMinEntries > pAllocation->cPointersAllocated)
     128        return VERR_NO_MEMORY;
     129    /* else: possible but unlikely */
     130
     131    /*
     132     * Add more entries.
     133     */
     134    while (pAllocation->cEntriesAllocated < cMinEntries)
     135    {
     136        void *pv;
     137        papvArray[pAllocation->cEntriesAllocated] = pv = RTMemEfAllocZNP(pAllocation->cbEntry, RTMEM_TAG);
     138        if (pv)
     139            pAllocation->cEntriesAllocated++;
     140        else
     141            return VERR_NO_MEMORY;
     142    }
     143
     144    return VINF_SUCCESS;
     145}
     146
     147
     148/** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnShrinkArray} */
     149static DECLCALLBACK(void) rtAsn1EFenceAllocator_ShrinkArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation,
     150                                                            void ***ppapvArray, uint32_t cNew, uint32_t cCurrent)
     151{
     152    RT_NOREF_PV(pThis);
     153    Assert(pAllocation->cbEntry);
     154    Assert(pAllocation->cEntriesAllocated <= pAllocation->cPointersAllocated);
     155
     156    /*
     157     * We always free and resize.
     158     */
     159    Assert(pAllocation->cEntriesAllocated == cCurrent);
     160    Assert(cNew < cCurrent);
     161
     162    /* Free entries. */
     163    void **papvArray = *ppapvArray;
     164    while (cCurrent-- > cNew)
     165    {
     166        RTMemEfFreeNP(papvArray[cCurrent]);
     167        papvArray[cCurrent] = NULL;
     168    }
     169    pAllocation->cEntriesAllocated = cNew;
     170
     171    /* Try resize pointer array.  Failure here is a genuine possibility since the
     172       efence code will try allocate a new block.  This causes extra fun in the
     173       grow method above. */
     174    void *pvPointers = RTMemEfReallocNP(papvArray, cNew * sizeof(void *), RTMEM_TAG);
     175    if (pvPointers)
     176    {
     177        *ppapvArray = (void **)pvPointers;
     178        pAllocation->cPointersAllocated = cNew;
     179    }
     180}
     181
     182
    82183/** The Electric Fence ASN.1 allocator. */
    83184RT_DECL_DATA_CONST(RTASN1ALLOCATORVTABLE const) g_RTAsn1EFenceAllocator =
     
    85186    rtAsn1EFenceAllocator_Free,
    86187    rtAsn1EFenceAllocator_Alloc,
    87     rtAsn1EFenceAllocator_Realloc
     188    rtAsn1EFenceAllocator_Realloc,
     189    rtAsn1EFenceAllocator_FreeArray,
     190    rtAsn1EFenceAllocator_GrowArray,
     191    rtAsn1EFenceAllocator_ShrinkArray
    88192};
    89193
     194#if 0 && defined(IN_RING3) /* for efence testing */
     195RT_DECL_DATA_CONST(RTASN1ALLOCATORVTABLE const) g_RTAsn1DefaultAllocator =
     196{
     197    rtAsn1EFenceAllocator_Free,
     198    rtAsn1EFenceAllocator_Alloc,
     199    rtAsn1EFenceAllocator_Realloc,
     200    rtAsn1EFenceAllocator_FreeArray,
     201    rtAsn1EFenceAllocator_GrowArray,
     202    rtAsn1EFenceAllocator_ShrinkArray
     203};
     204#endif
     205
  • trunk/src/VBox/Runtime/common/crypto/pkcs7-core.cpp

    r62477 r64883  
    4949     * Note! We ASSUME a single signing time attribute, which simplifies the interface.
    5050     */
    51     uint32_t                cAttrsLeft;
    52     PCRTCRPKCS7ATTRIBUTE    pAttr;
     51    uint32_t                    cAttrsLeft;
     52    PRTCRPKCS7ATTRIBUTE const  *ppAttr;
    5353    if (!ppSignerInfo || *ppSignerInfo == NULL)
    5454    {
    5555        cAttrsLeft = pThis->AuthenticatedAttributes.cItems;
    56         pAttr      = pThis->AuthenticatedAttributes.paItems;
     56        ppAttr     = pThis->AuthenticatedAttributes.papItems;
    5757        while (cAttrsLeft-- > 0)
    5858        {
     59            PCRTCRPKCS7ATTRIBUTE pAttr = *ppAttr;
    5960            if (   pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_SIGNING_TIME
    6061                && pAttr->uValues.pSigningTime->cItems > 0)
     
    6263                if (ppSignerInfo)
    6364                    *ppSignerInfo = pThis;
    64                 return &pAttr->uValues.pSigningTime->paItems[0];
     65                return pAttr->uValues.pSigningTime->papItems[0];
    6566            }
    66             pAttr++;
     67            ppAttr++;
    6768        }
    6869    }
     
    7475     */
    7576    cAttrsLeft = pThis->UnauthenticatedAttributes.cItems;
    76     pAttr      = pThis->UnauthenticatedAttributes.paItems;
     77    ppAttr     = pThis->UnauthenticatedAttributes.papItems;
    7778    while (cAttrsLeft-- > 0)
    7879    {
     80        PCRTCRPKCS7ATTRIBUTE pAttr = *ppAttr;
    7981        if (pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_COUNTER_SIGNATURES)
    8082        {
    81             uint32_t              cSignatures = pAttr->uValues.pCounterSignatures->cItems;
    82             PCRTCRPKCS7SIGNERINFO pSignature  = pAttr->uValues.pCounterSignatures->paItems;
     83            uint32_t               cSignatures = pAttr->uValues.pCounterSignatures->cItems;
     84            PRTCRPKCS7SIGNERINFO  *ppSignature = pAttr->uValues.pCounterSignatures->papItems;
    8385
    8486            /* Skip past the previous counter signature. */
     
    8789                {
    8890                    cSignatures--;
    89                     if (pSignature == *ppSignerInfo)
     91                    if (*ppSignature == *ppSignerInfo)
    9092                    {
    9193                        *ppSignerInfo = NULL;
    92                         pSignature++;
     94                        ppSignature++;
    9395                        break;
    9496                    }
    95                     pSignature++;
     97                    ppSignature++;
    9698                }
    9799
     
    99101            while (cSignatures-- > 0)
    100102            {
    101                 uint32_t                cCounterAttrsLeft = pSignature->AuthenticatedAttributes.cItems;
    102                 PCRTCRPKCS7ATTRIBUTE    pCounterAttr      = pSignature->AuthenticatedAttributes.paItems;
     103                PCRTCRPKCS7SIGNERINFO       pSignature        = *ppSignature;
     104                uint32_t                    cCounterAttrsLeft = pSignature->AuthenticatedAttributes.cItems;
     105                PRTCRPKCS7ATTRIBUTE const  *ppCounterAttr     = pSignature->AuthenticatedAttributes.papItems;
    103106                while (cCounterAttrsLeft-- > 0)
    104107                {
     108                    PCRTCRPKCS7ATTRIBUTE pCounterAttr = *ppCounterAttr;
    105109                    if (   pCounterAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_SIGNING_TIME
    106110                        && pCounterAttr->uValues.pSigningTime->cItems > 0)
     
    108112                        if (ppSignerInfo)
    109113                            *ppSignerInfo = pSignature;
    110                         return &pCounterAttr->uValues.pSigningTime->paItems[0];
     114                        return pCounterAttr->uValues.pSigningTime->papItems[0];
    111115                    }
    112                     pCounterAttr++;
     116                    ppCounterAttr++;
    113117                }
    114                 pSignature++;
     118                ppSignature++;
    115119            }
    116120        }
    117         pAttr++;
     121        ppAttr++;
    118122    }
    119123
     
    128132
    129133
    130 RTDECL(PCRTASN1TIME) RTCrPkcs7SignerInfo_GetMsTimestamp(PCRTCRPKCS7SIGNERINFO pThis, PCRTCRPKCS7CONTENTINFO *ppContentInfo)
     134RTDECL(PCRTASN1TIME) RTCrPkcs7SignerInfo_GetMsTimestamp(PCRTCRPKCS7SIGNERINFO pThis, PCRTCRPKCS7CONTENTINFO *ppContentInfoRet)
    131135{
    132136    /*
    133137     * Assume there is only one, so no need to enumerate anything here.
    134138     */
    135     uint32_t             cAttrsLeft = pThis->UnauthenticatedAttributes.cItems;
    136     PCRTCRPKCS7ATTRIBUTE pAttr      = pThis->UnauthenticatedAttributes.paItems;
     139    uint32_t                    cAttrsLeft = pThis->UnauthenticatedAttributes.cItems;
     140    PRTCRPKCS7ATTRIBUTE const  *ppAttr      = pThis->UnauthenticatedAttributes.papItems;
    137141    while (cAttrsLeft-- > 0)
    138142    {
     143        PCRTCRPKCS7ATTRIBUTE pAttr = *ppAttr;
    139144        if (pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_MS_TIMESTAMP)
    140145        {
    141             uint32_t                cLeft        = pAttr->uValues.pContentInfos->cItems;
    142             PCRTCRPKCS7CONTENTINFO  pContentInfo = &pAttr->uValues.pContentInfos->paItems[0];
     146            uint32_t                     cLeft         = pAttr->uValues.pContentInfos->cItems;
     147            PRTCRPKCS7CONTENTINFO const *ppContentInfo = pAttr->uValues.pContentInfos->papItems;
    143148            while (cLeft-- > 0)
    144149            {
     150                PCRTCRPKCS7CONTENTINFO pContentInfo = *ppContentInfo;
    145151                if (RTAsn1ObjId_CompareWithString(&pContentInfo->ContentType, RTCRPKCS7SIGNEDDATA_OID) == 0)
    146152                {
     
    148154                                                      RTCRTSPTSTINFO_OID) == 0)
    149155                    {
    150                         if (ppContentInfo)
    151                             *ppContentInfo = pContentInfo;
     156                        if (ppContentInfoRet)
     157                            *ppContentInfoRet = pContentInfo;
    152158                        return &pContentInfo->u.pSignedData->ContentInfo.u.pTstInfo->GenTime;
    153159                    }
     
    157163            }
    158164        }
    159         pAttr++;
     165        ppAttr++;
    160166    }
    161167
     
    163169     * No signature was found.
    164170     */
    165     if (ppContentInfo)
    166         *ppContentInfo = NULL;
     171    if (ppContentInfoRet)
     172        *ppContentInfoRet = NULL;
    167173
    168174    return NULL;
     
    189195{
    190196    for (uint32_t i = 0; i < pCertificates->cItems; i++)
    191         if (   pCertificates->paItems[i].enmChoice == RTCRPKCS7CERTCHOICE_X509
    192             && RTCrX509Certificate_MatchIssuerAndSerialNumber(pCertificates->paItems[i].u.pX509Cert, pIssuer, pSerialNumber))
    193             return pCertificates->paItems[i].u.pX509Cert;
     197    {
     198        PCRTCRPKCS7CERT pCert = pCertificates->papItems[i];
     199        if (   pCert->enmChoice == RTCRPKCS7CERTCHOICE_X509
     200            && RTCrX509Certificate_MatchIssuerAndSerialNumber(pCert->u.pX509Cert, pIssuer, pSerialNumber))
     201            return pCert->u.pX509Cert;
     202    }
    194203    return NULL;
    195204}
  • trunk/src/VBox/Runtime/common/crypto/pkcs7-sanity.cpp

    r62564 r64883  
    6868        for (uint32_t i = 0; i < pSignedData->DigestAlgorithms.cItems; i++)
    6969        {
    70             if (RTCrX509AlgorithmIdentifier_QueryDigestType(&pSignedData->DigestAlgorithms.paItems[i]) == RTDIGESTTYPE_INVALID)
     70            if (RTCrX509AlgorithmIdentifier_QueryDigestType(pSignedData->DigestAlgorithms.papItems[i]) == RTDIGESTTYPE_INVALID)
    7171                return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_UNKNOWN_DIGEST_ALGORITHM,
    7272                                     "%s: SignedData.DigestAlgorithms[%i] is not known: %s",
    73                                      pszErrorTag, i, pSignedData->DigestAlgorithms.paItems[i].Algorithm.szObjId);
    74             if (pSignedData->DigestAlgorithms.paItems[i].Parameters.enmType != RTASN1TYPE_NULL)
     73                                     pszErrorTag, i, pSignedData->DigestAlgorithms.papItems[i]->Algorithm.szObjId);
     74            if (pSignedData->DigestAlgorithms.papItems[i]->Parameters.enmType != RTASN1TYPE_NULL)
    7575                return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_DIGEST_PARAMS_NOT_IMPL,
    7676                                     "%s: SignedData.DigestAlgorithms[%i] has parameters: tag=%u",
    77                                      pszErrorTag, i, pSignedData->DigestAlgorithms.paItems[i].Parameters.u.Core.uTag);
     77                                     pszErrorTag, i, pSignedData->DigestAlgorithms.papItems[i]->Parameters.u.Core.uTag);
    7878        }
    7979
     
    106106    for (uint32_t i = 0; i < pSignedData->SignerInfos.cItems; i++)
    107107    {
    108         PCRTCRPKCS7SIGNERINFO pSignerInfo = &pSignedData->SignerInfos.paItems[i];
     108        PCRTCRPKCS7SIGNERINFO pSignerInfo = pSignedData->SignerInfos.papItems[i];
    109109
    110110        if (RTAsn1Integer_UnsignedCompareWithU32(&pSignerInfo->Version, RTCRPKCS7SIGNERINFO_V1) != 0)
     
    136136        uint32_t j = 0;
    137137        while (   j < pSignedData->DigestAlgorithms.cItems
    138                && RTCrX509AlgorithmIdentifier_Compare(&pSignedData->DigestAlgorithms.paItems[j],
     138               && RTCrX509AlgorithmIdentifier_Compare(pSignedData->DigestAlgorithms.papItems[j],
    139139                                                      &pSignerInfo->DigestAlgorithm) != 0)
    140140            j++;
     
    162162            for (j = 0; j < pSignerInfo->AuthenticatedAttributes.cItems; j++)
    163163            {
    164                 PCRTCRPKCS7ATTRIBUTE pAttrib = &pSignerInfo->AuthenticatedAttributes.paItems[j];
     164                PCRTCRPKCS7ATTRIBUTE pAttrib = pSignerInfo->AuthenticatedAttributes.papItems[j];
    165165                if (RTAsn1ObjId_CompareWithString(&pAttrib->Type, RTCR_PKCS9_ID_CONTENT_TYPE_OID) == 0)
    166166                {
  • trunk/src/VBox/Runtime/common/crypto/pkcs7-verify.cpp

    r64531 r64883  
    7575            PCRTCRPKCS7SETOFCERTS pCerts = &pContentInfo->u.pSignedData->Certificates;
    7676            for (uint32_t i = 0; i < pCerts->cItems; i++)
    77                 if (pCerts->paItems[i].enmChoice == RTCRPKCS7CERTCHOICE_X509)
    78                     rtCrOpenSslAddX509CertToStack(pAddCerts, pCerts->paItems[i].u.pX509Cert);
     77                if (pCerts->papItems[i]->enmChoice == RTCRPKCS7CERTCHOICE_X509)
     78                    rtCrOpenSslAddX509CertToStack(pAddCerts, pCerts->papItems[i]->u.pX509Cert);
    7979
    8080
     
    238238    while (i-- > 0)
    239239    {
    240         PCRTCRPKCS7ATTRIBUTE pAttrib = &pSignerInfo->AuthenticatedAttributes.paItems[i];
     240        PCRTCRPKCS7ATTRIBUTE pAttrib = pSignerInfo->AuthenticatedAttributes.papItems[i];
    241241
    242242        if (RTAsn1ObjId_CompareWithString(&pAttrib->Type, RTCR_PKCS9_ID_CONTENT_TYPE_OID) == 0)
     
    247247
    248248            if (   !(fFlags & RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE) /* See note about microsoft below. */
    249                 && RTAsn1ObjId_Compare(&pAttrib->uValues.pObjIds->paItems[0], &pSignedData->ContentInfo.ContentType) != 0)
     249                && RTAsn1ObjId_Compare(pAttrib->uValues.pObjIds->papItems[0], &pSignedData->ContentInfo.ContentType) != 0)
    250250                   return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_CONTENT_TYPE_ATTRIB_MISMATCH,
    251                                         "Expected content-type %s, found %s",
    252                                         &pAttrib->uValues.pObjIds->paItems[0], pSignedData->ContentInfo.ContentType.szObjId);
     251                                        "Expected content-type %s, found %s", pAttrib->uValues.pObjIds->papItems[0]->szObjId,
     252                                        pSignedData->ContentInfo.ContentType.szObjId);
    253253            cContentTypes++;
    254254        }
     
    260260
    261261            if (!RTCrDigestMatch(*phDigest,
    262                                  pAttrib->uValues.pOctetStrings->paItems[0].Asn1Core.uData.pv,
    263                                  pAttrib->uValues.pOctetStrings->paItems[0].Asn1Core.cb))
     262                                 pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.uData.pv,
     263                                 pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.cb))
    264264            {
    265265                size_t cbHash = RTCrDigestGetHashSize(*phDigest);
    266                 if (cbHash != pAttrib->uValues.pOctetStrings->paItems[0].Asn1Core.cb)
     266                if (cbHash != pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.cb)
    267267                    return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_MESSAGE_DIGEST_ATTRIB_MISMATCH,
    268268                                         "Authenticated message-digest attribute mismatch: cbHash=%#zx cbValue=%#x",
    269                                          cbHash, pAttrib->uValues.pOctetStrings->paItems[0].Asn1Core.cb);
     269                                         cbHash, pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.cb);
    270270                return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_MESSAGE_DIGEST_ATTRIB_MISMATCH,
    271271                                     "Authenticated message-digest attribute mismatch (cbHash=%#zx):\n"
     
    273273                                     "our:    %.*Rhxs\n",
    274274                                     cbHash,
    275                                      cbHash, pAttrib->uValues.pOctetStrings->paItems[0].Asn1Core.uData.pv,
     275                                     cbHash, pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.uData.pv,
    276276                                     cbHash, RTCrDigestGetHash(*phDigest));
    277277            }
     
    342342    uint32_t iDigest = pSignedData->DigestAlgorithms.cItems;
    343343    while (iDigest-- > 0)
    344         if (RTCrX509AlgorithmIdentifier_Compare(&pSignedData->DigestAlgorithms.paItems[iDigest],
     344        if (RTCrX509AlgorithmIdentifier_Compare(pSignedData->DigestAlgorithms.papItems[iDigest],
    345345                                                &pSignerInfo->DigestAlgorithm) == 0)
    346346        {
     
    620620    for (i = 0; i < cDigests; i++)
    621621    {
    622         rc = RTCrDigestCreateByObjId(&ahDigests[i], &pSignedData->DigestAlgorithms.paItems[i].Algorithm);
     622        rc = RTCrDigestCreateByObjId(&ahDigests[i], &pSignedData->DigestAlgorithms.papItems[i]->Algorithm);
    623623        if (RT_FAILURE(rc))
    624624        {
    625625            rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_DIGEST_CREATE_ERROR, "Error creating digest for '%s': %Rrc",
    626                                pSignedData->DigestAlgorithms.paItems[i].Algorithm.szObjId, rc);
     626                               pSignedData->DigestAlgorithms.papItems[i]->Algorithm.szObjId, rc);
    627627            break;
    628628        }
     
    647647            for (i = 0; i < pSignedData->SignerInfos.cItems; i++)
    648648            {
    649                 PCRTCRPKCS7SIGNERINFO   pSignerInfo = &pSignedData->SignerInfos.paItems[i];
     649                PCRTCRPKCS7SIGNERINFO   pSignerInfo = pSignedData->SignerInfos.papItems[i];
    650650                RTCRDIGEST              hThisDigest = NIL_RTCRDIGEST; /* (gcc maybe incredible stupid.) */
    651651                rc = rtCrPkcs7VerifyFindDigest(&hThisDigest, pSignedData, pSignerInfo, ahDigests, pErrInfo);
  • trunk/src/VBox/Runtime/common/crypto/spc-core.cpp

    r62477 r64883  
    6969                if (pData)
    7070                    for (uint32_t i = 0; i < pData->cItems; i++)
    71                         if (pData->paItems[i].enmType == enmType)
    72                             return &pData->paItems[i];
     71                        if (pData->papItems[i]->enmType == enmType)
     72                            return pData->papItems[i];
    7373            }
    7474        }
  • trunk/src/VBox/Runtime/common/crypto/spc-sanity.cpp

    r62477 r64883  
    5757
    5858    if (RTCrX509AlgorithmIdentifier_Compare(&pIndData->DigestInfo.DigestAlgorithm, /** @todo not entirely sure about this check... */
    59                                             &pSignedData->SignerInfos.paItems[0].DigestAlgorithm) != 0)
     59                                            &pSignedData->SignerInfos.papItems[0]->DigestAlgorithm) != 0)
    6060        return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_SIGNED_IND_DATA_DIGEST_ALGO_MISMATCH,
    6161                             "SpcIndirectDataContent DigestInfo and SignerInfos algorithms mismatch: %s vs %s",
    6262                             pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId,
    63                              pSignedData->SignerInfos.paItems[0].DigestAlgorithm.Algorithm.szObjId);
     63                             pSignedData->SignerInfos.papItems[0]->DigestAlgorithm.Algorithm.szObjId);
    6464
    6565    if (RTCrX509AlgorithmIdentifier_Compare(&pIndData->DigestInfo.DigestAlgorithm,
    66                                             &pSignedData->DigestAlgorithms.paItems[0]) != 0)
     66                                            pSignedData->DigestAlgorithms.papItems[0]) != 0)
    6767        return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_IND_DATA_DIGEST_ALGO_NOT_IN_DIGEST_ALGOS,
    6868                             "SpcIndirectDataContent DigestInfo and SignedData.DigestAlgorithms[0] mismatch: %s vs %s",
    6969                             pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId,
    70                              pSignedData->DigestAlgorithms.paItems[0].Algorithm.szObjId);
     70                             pSignedData->DigestAlgorithms.papItems[0]->Algorithm.szObjId);
    7171
    7272    if (fFlags & RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH)
     
    126126            for (uint32_t i = 0; i < pObj->u.pData->cItems; i++)
    127127            {
    128                 PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttr = &pObj->u.pData->paItems[i];
     128                PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttr = pObj->u.pData->papItems[i];
    129129                if (   RTAsn1ObjId_CompareWithString(&pAttr->Type, RTCRSPC_PE_IMAGE_HASHES_V1_OID) == 0
    130130                    || RTAsn1ObjId_CompareWithString(&pAttr->Type, RTCRSPC_PE_IMAGE_HASHES_V2_OID) == 0 )
  • trunk/src/VBox/Runtime/common/crypto/x509-certpaths.cpp

    r64531 r64883  
    723723    if (pThis->pUntrustedCertsSet)
    724724    {
    725         uint32_t const  cCerts  = pThis->pUntrustedCertsSet->cItems;
    726         PCRTCRPKCS7CERT paCerts = pThis->pUntrustedCertsSet->paItems;
     725        uint32_t const        cCerts   = pThis->pUntrustedCertsSet->cItems;
     726        PRTCRPKCS7CERT const *papCerts = pThis->pUntrustedCertsSet->papItems;
    727727        for (uint32_t i = 0; i < cCerts; i++)
    728             if (   paCerts[i].enmChoice == RTCRPKCS7CERTCHOICE_X509
    729                 && RTCrX509Certificate_MatchSubjectOrAltSubjectByRfc5280(paCerts[i].u.pX509Cert, pIssuer))
    730                 rtCrX509CertPathsAddIssuer(pThis, pNode, paCerts[i].u.pX509Cert, NULL, RTCRX509CERTPATHNODE_SRC_UNTRUSTED_SET);
     728        {
     729            PCRTCRPKCS7CERT pCert = papCerts[i];
     730            if (   pCert->enmChoice == RTCRPKCS7CERTCHOICE_X509
     731                && RTCrX509Certificate_MatchSubjectOrAltSubjectByRfc5280(pCert->u.pX509Cert, pIssuer))
     732                rtCrX509CertPathsAddIssuer(pThis, pNode, pCert->u.pX509Cert, NULL, RTCRX509CERTPATHNODE_SRC_UNTRUSTED_SET);
     733        }
    731734    }
    732735}
     
    10571060{
    10581061    for (uint32_t i = 0; i < pName->cItems; i++)
    1059         for (uint32_t j = 0; j < pName->paItems[i].cItems; j++)
    1060         {
    1061             PRTCRX509ATTRIBUTETYPEANDVALUE pAttrib = &pName->paItems[i].paItems[j];
     1062    {
     1063        PCRTCRX509RELATIVEDISTINGUISHEDNAME const pRdn = pName->papItems[i];
     1064        for (uint32_t j = 0; j < pRdn->cItems; j++)
     1065        {
     1066            PRTCRX509ATTRIBUTETYPEANDVALUE pAttrib = pRdn->papItems[j];
    10621067
    10631068            const char *pszType = pAttrib->Type.szObjId;
     
    11181123                rtDumpPrintf(pfnPrintfV, pvUser, "<not-string: uTag=%#x>", pAttrib->Value.u.Core.uTag);
    11191124        }
     1125    }
    11201126}
    11211127
     
    13501356 * @param   pThis               The validator instance.
    13511357 * @param   cSubtrees           The number of sub-trees to add.
    1352  * @param   paSubtrees          Array of sub-trees to add.
    1353  */
    1354 static bool rtCrX509CpvAddPermittedSubtrees(PRTCRX509CERTPATHSINT pThis, uint32_t cSubtrees, PCRTCRX509GENERALSUBTREE paSubtrees)
     1358 * @param   papSubtrees         Array of sub-trees to add.
     1359 */
     1360static bool rtCrX509CpvAddPermittedSubtrees(PRTCRX509CERTPATHSINT pThis, uint32_t cSubtrees,
     1361                                            PRTCRX509GENERALSUBTREE const *papSubtrees)
    13551362{
    13561363    /*
     
    13751382    for (uint32_t iSrc = 0; iSrc < cSubtrees; iSrc++)
    13761383    {
    1377         if (!rtCrX509CpvCheckSubtreeValidity(pThis, &paSubtrees[iSrc]))
     1384        if (!rtCrX509CpvCheckSubtreeValidity(pThis, papSubtrees[iSrc]))
    13781385            return false;
    1379         pThis->v.papPermittedSubtrees[iDst] = &paSubtrees[iSrc];
     1386        pThis->v.papPermittedSubtrees[iDst] = papSubtrees[iSrc];
    13801387        iDst++;
    13811388    }
     
    13831390
    13841391    return true;
     1392}
     1393
     1394
     1395/**
     1396 * Adds a one permitted sub-tree.
     1397 *
     1398 * We store reference to each individual sub-tree because we must support
     1399 * intersection calculation.
     1400 *
     1401 * @returns success indiciator.
     1402 * @param   pThis               The validator instance.
     1403 * @param   pSubtree            Array of sub-trees to add.
     1404 */
     1405static bool rtCrX509CpvAddPermittedSubtree(PRTCRX509CERTPATHSINT pThis, PCRTCRX509GENERALSUBTREE pSubtree)
     1406{
     1407    return rtCrX509CpvAddPermittedSubtrees(pThis, 1, (PRTCRX509GENERALSUBTREE const *)&pSubtree);
    13851408}
    13861409
     
    14051428    }
    14061429
    1407     uint32_t                    cRight  = pSubtrees->cItems;
    1408     PCRTCRX509GENERALSUBTREE    paRight = pSubtrees->paItems;
     1430    uint32_t                       cRight   = pSubtrees->cItems;
     1431    PRTCRX509GENERALSUBTREE const *papRight = pSubtrees->papItems;
    14091432    if (cRight == 0)
    14101433    {
     
    14171440    PCRTCRX509GENERALSUBTREE   *papLeft = pThis->v.papPermittedSubtrees;
    14181441    if (!cLeft) /* first name constraint, no initial constraint */
    1419         return rtCrX509CpvAddPermittedSubtrees(pThis, cRight, paRight);
     1442        return rtCrX509CpvAddPermittedSubtrees(pThis, cRight, papRight);
    14201443
    14211444    /*
     
    14311454    for (uint32_t iRight = 0; iRight < cRight; iRight++)
    14321455    {
    1433         if (!rtCrX509CpvCheckSubtreeValidity(pThis, &paRight[iRight]))
     1456        if (!rtCrX509CpvCheckSubtreeValidity(pThis, papRight[iRight]))
    14341457            return false;
    14351458
    1436         RTCRX509GENERALNAMECHOICE const enmRightChoice = paRight[iRight].Base.enmChoice;
     1459        RTCRX509GENERALNAMECHOICE const enmRightChoice = papRight[iRight]->Base.enmChoice;
    14371460        afRightTags[enmRightChoice] = true;
    14381461
     
    14411464            if (papLeft[iLeft]->Base.enmChoice == enmRightChoice)
    14421465            {
    1443                 if (RTCrX509GeneralSubtree_Compare(papLeft[iLeft], &paRight[iRight]) == 0)
     1466                if (RTCrX509GeneralSubtree_Compare(papLeft[iLeft], papRight[iRight]) == 0)
    14441467                {
    14451468                    if (!fHaveRight)
    14461469                    {
    14471470                        fHaveRight = true;
    1448                         rtCrX509CpvAddPermittedSubtrees(pThis, 1, papLeft[iLeft]);
     1471                        rtCrX509CpvAddPermittedSubtree(pThis, papLeft[iLeft]);
    14491472                    }
    14501473                }
    1451                 else if (RTCrX509GeneralSubtree_ConstraintMatch(papLeft[iLeft], &paRight[iRight]))
     1474                else if (RTCrX509GeneralSubtree_ConstraintMatch(papLeft[iLeft], papRight[iRight]))
    14521475                {
    14531476                    if (!fHaveRight)
    14541477                    {
    14551478                        fHaveRight = true;
    1456                         rtCrX509CpvAddPermittedSubtrees(pThis, 1, &paRight[iRight]);
     1479                        rtCrX509CpvAddPermittedSubtree(pThis, papRight[iRight]);
    14571480                    }
    14581481                }
    1459                 else if (RTCrX509GeneralSubtree_ConstraintMatch(&paRight[iRight], papLeft[iLeft]))
    1460                     rtCrX509CpvAddPermittedSubtrees(pThis, 1, papLeft[iLeft]);
     1482                else if (RTCrX509GeneralSubtree_ConstraintMatch(papRight[iRight], papLeft[iLeft]))
     1483                    rtCrX509CpvAddPermittedSubtree(pThis, papLeft[iLeft]);
    14611484            }
    14621485    }
     
    14671490    for (uint32_t iLeft = 0; iLeft < cLeft; iLeft++)
    14681491        if (!afRightTags[papLeft[iLeft]->Base.enmChoice])
    1469             rtCrX509CpvAddPermittedSubtrees(pThis, 1, papLeft[iLeft]);
     1492            rtCrX509CpvAddPermittedSubtree(pThis, papLeft[iLeft]);
    14701493
    14711494    /*
     
    15411564        uint32_t j = pSubTrees->cItems;
    15421565        while (j-- > 0)
    1543             if (   RTCRX509GENERALNAME_IS_DIRECTORY_NAME(&pSubTrees->paItems[j].Base)
    1544                 && RTCrX509Name_ConstraintMatch(&pSubTrees->paItems[j].Base.u.pT4->DirectoryName, pName))
     1566        {
     1567            PCRTCRX509GENERALSUBTREE const pSubTree = pSubTrees->papItems[j];
     1568            if (   RTCRX509GENERALNAME_IS_DIRECTORY_NAME(&pSubTree->Base)
     1569                && RTCrX509Name_ConstraintMatch(&pSubTree->Base.u.pT4->DirectoryName, pName))
    15451570                return true;
     1571        }
    15461572    }
    15471573    return false;
     
    15661592        uint32_t j = pSubTrees->cItems;
    15671593        while (j-- > 0)
    1568             if (RTCrX509GeneralName_ConstraintMatch(&pSubTrees->paItems[j].Base, pGeneralName))
     1594            if (RTCrX509GeneralName_ConstraintMatch(&pSubTrees->papItems[j]->Base, pGeneralName))
    15691595                return true;
    15701596    }
     
    19511977    if (pThis->pInitialPermittedSubtrees)
    19521978        rtCrX509CpvAddPermittedSubtrees(pThis, pThis->pInitialPermittedSubtrees->cItems,
    1953                                         pThis->pInitialPermittedSubtrees->paItems);
     1979                                        pThis->pInitialPermittedSubtrees->papItems);
    19541980    if (pThis->pInitialExcludedSubtrees)
    19551981        rtCrX509CpvAddExcludedSubtrees(pThis, pThis->pInitialExcludedSubtrees);
     
    20532079        uint32_t i = pAltSubjectName->cItems;
    20542080        while (i-- > 0)
    2055             if (   !rtCrX509CpvIsGeneralNamePermitted(pThis, &pAltSubjectName->paItems[i])
    2056                 || rtCrX509CpvIsGeneralNameExcluded(pThis, &pAltSubjectName->paItems[i]))
     2081            if (   !rtCrX509CpvIsGeneralNamePermitted(pThis, pAltSubjectName->papItems[i])
     2082                || rtCrX509CpvIsGeneralNameExcluded(pThis, pAltSubjectName->papItems[i]))
    20572083                return rtCrX509CpvFailed(pThis, VERR_CR_X509_CPV_ALT_NAME_NOT_PERMITTED,
    20582084                                         "Alternative name #%u is is not permitted by current name constraints", i);
     
    20812107        while (i-- > 0)
    20822108        {
    2083             PCRTCRX509POLICYQUALIFIERINFOS const    pQualifiers = &pPolicies->paItems[i].PolicyQualifiers;
    2084             PCRTASN1OBJID const                     pIdP        = &pPolicies->paItems[i].PolicyIdentifier;
     2109            PCRTCRX509POLICYQUALIFIERINFOS const    pQualifiers = &pPolicies->papItems[i]->PolicyQualifiers;
     2110            PCRTASN1OBJID const                     pIdP        = &pPolicies->papItems[i]->PolicyIdentifier;
    20852111            if (RTAsn1ObjId_CompareWithString(pIdP, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0)
    20862112            {
     
    21322158                || (pNode->pParent && fSelfIssued) ) )
    21332159        {
    2134             PCRTCRX509POLICYQUALIFIERINFOS pApQ = &pPolicies->paItems[iAnyPolicy].PolicyQualifiers;
     2160            PCRTCRX509POLICYQUALIFIERINFOS pApQ = &pPolicies->papItems[iAnyPolicy]->PolicyQualifiers;
    21352161            RTListForEach(pListAbove, pCur, RTCRX509CERTPATHSPOLICYNODE, DepthEntry)
    21362162            {
     
    21832209    while (i-- > 0)
    21842210    {
    2185         if (RTAsn1ObjId_CompareWithString(&pPolicyMappings->paItems[i].IssuerDomainPolicy, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0)
     2211        PCRTCRX509POLICYMAPPING const pOne = pPolicyMappings->papItems[i];
     2212        if (RTAsn1ObjId_CompareWithString(&pOne->IssuerDomainPolicy, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0)
    21862213            return rtCrX509CpvFailed(pThis, VERR_CR_X509_CPV_INVALID_POLICY_MAPPING,
    21872214                                     "Invalid policy mapping %#u: IssuerDomainPolicy is anyPolicy.", i);
    21882215
    2189         if (RTAsn1ObjId_CompareWithString(&pPolicyMappings->paItems[i].SubjectDomainPolicy, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0)
     2216        if (RTAsn1ObjId_CompareWithString(&pOne->SubjectDomainPolicy, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0)
    21902217            return rtCrX509CpvFailed(pThis, VERR_CR_X509_CPV_INVALID_POLICY_MAPPING,
    21912218                                     "Invalid policy mapping %#u: SubjectDomainPolicy is anyPolicy.", i);
     
    22012228        while (i-- > 0)
    22022229        {
     2230            PCRTCRX509POLICYMAPPING const pOne = pPolicyMappings->papItems[i];
     2231
    22032232            uint32_t cFound = 0;
    22042233            RTListForEach(&pThis->v.paValidPolicyDepthLists[iDepth], pCur, RTCRX509CERTPATHSPOLICYNODE, DepthEntry)
    22052234            {
    2206                 if (RTAsn1ObjId_Compare(pCur->pValidPolicy, &pPolicyMappings->paItems[i].IssuerDomainPolicy))
     2235                if (RTAsn1ObjId_Compare(pCur->pValidPolicy, &pOne->IssuerDomainPolicy))
    22072236                {
    22082237                    if (!pCur->fAlreadyMapped)
    22092238                    {
    22102239                        pCur->fAlreadyMapped = true;
    2211                         pCur->pExpectedPolicyFirst = &pPolicyMappings->paItems[i].SubjectDomainPolicy;
     2240                        pCur->pExpectedPolicyFirst = &pOne->SubjectDomainPolicy;
    22122241                    }
    22132242                    else
     
    22212250                                                     pCur->cMoreExpectedPolicySet, iDepth);
    22222251                        pCur->papMoreExpectedPolicySet = (PCRTASN1OBJID *)pvNew;
    2223                         pCur->papMoreExpectedPolicySet[iExpected] = &pPolicyMappings->paItems[i].SubjectDomainPolicy;
     2252                        pCur->papMoreExpectedPolicySet[iExpected] = &pOne->SubjectDomainPolicy;
    22242253                        pCur->cMoreExpectedPolicySet = iExpected  + 1;
    22252254                    }
     
    22382267                    {
    22392268                        if (!rtCrX509CpvPolicyTreeInsertNew(pThis, pCur->pParent, iDepth,
    2240                                                             &pPolicyMappings->paItems[i].IssuerDomainPolicy,
     2269                                                            &pOne->IssuerDomainPolicy,
    22412270                                                            pCur->pPolicyQualifiers,
    2242                                                             &pPolicyMappings->paItems[i].SubjectDomainPolicy))
     2271                                                            &pOne->SubjectDomainPolicy))
    22432272                            return false;
    22442273                        break;
     
    22582287        while (i-- > 0)
    22592288        {
     2289            PCRTCRX509POLICYMAPPING const pOne = pPolicyMappings->papItems[i];
    22602290            RTListForEachSafe(&pThis->v.paValidPolicyDepthLists[iDepth], pCur, pNext, RTCRX509CERTPATHSPOLICYNODE, DepthEntry)
    22612291            {
    2262                 if (RTAsn1ObjId_Compare(pCur->pValidPolicy, &pPolicyMappings->paItems[i].IssuerDomainPolicy))
     2292                if (RTAsn1ObjId_Compare(pCur->pValidPolicy, &pOne->IssuerDomainPolicy))
    22632293                {
    22642294                    rtCrX509CpvPolicyTreeDestroyNode(pThis, pCur);
     
    24102440static bool rtCrX509CpvCheckCriticalExtensions(PRTCRX509CERTPATHSINT pThis, PRTCRX509CERTPATHNODE pNode)
    24112441{
    2412     uint32_t                cLeft = pNode->pCert->TbsCertificate.T3.Extensions.cItems;
    2413     PCRTCRX509EXTENSION     pCur  = pNode->pCert->TbsCertificate.T3.Extensions.paItems;
     2442    uint32_t                  cLeft = pNode->pCert->TbsCertificate.T3.Extensions.cItems;
     2443    PRTCRX509EXTENSION const *ppCur = pNode->pCert->TbsCertificate.T3.Extensions.papItems;
    24142444    while (cLeft-- > 0)
    24152445    {
     2446        PCRTCRX509EXTENSION const pCur = *ppCur;
    24162447        if (pCur->Critical.fValue)
    24172448        {
     
    24312462        }
    24322463
    2433         pCur++;
     2464        ppCur++;
    24342465    }
    24352466
  • trunk/src/VBox/Runtime/common/crypto/x509-core.cpp

    r62477 r64883  
    608608        for (uint32_t iLeft = 0; iLeft < cItems; iLeft++)
    609609        {
    610             PCRTCRX509ATTRIBUTETYPEANDVALUE pLeftAttr = &pLeft->paItems[iLeft];
     610            PCRTCRX509ATTRIBUTETYPEANDVALUE pLeftAttr = pLeft->papItems[iLeft];
    611611            bool fFound = false;
    612612            for (uint32_t iRight = 0; iRight < cItems; iRight++)
    613                 if (RTCrX509AttributeTypeAndValue_MatchAsRdnByRfc5280(pLeftAttr, &pRight->paItems[iRight]))
     613                if (RTCrX509AttributeTypeAndValue_MatchAsRdnByRfc5280(pLeftAttr, pRight->papItems[iRight]))
    614614                {
    615615                    fFound = true;
     
    637637        /* Require exact order. */
    638638        for (uint32_t iRdn = 0; iRdn < cItems; iRdn++)
    639             if (!RTCrX509RelativeDistinguishedName_MatchByRfc5280(&pLeft->paItems[iRdn], &pRight->paItems[iRdn]))
     639            if (!RTCrX509RelativeDistinguishedName_MatchByRfc5280(pLeft->papItems[iRdn], pRight->papItems[iRdn]))
    640640                return false;
    641641        return true;
     
    658658        for (uint32_t i = 0; pConstraint->cItems; i++)
    659659        {
    660             PCRTCRX509RELATIVEDISTINGUISHEDNAME pConstrRdns = &pConstraint->paItems[i];
    661             PCRTCRX509RELATIVEDISTINGUISHEDNAME pNameRdns   = &pName->paItems[i];
     660            PCRTCRX509RELATIVEDISTINGUISHEDNAME pConstrRdns = pConstraint->papItems[i];
     661            PCRTCRX509RELATIVEDISTINGUISHEDNAME pNameRdns   = pName->papItems[i];
    662662
    663663            /*
     
    666666            for (uint32_t iConstrAttrib = 0; iConstrAttrib < pConstrRdns->cItems; iConstrAttrib++)
    667667            {
    668                 PCRTCRX509ATTRIBUTETYPEANDVALUE pConstrAttrib = &pConstrRdns->paItems[iConstrAttrib];
     668                PCRTCRX509ATTRIBUTETYPEANDVALUE pConstrAttrib = pConstrRdns->papItems[iConstrAttrib];
    669669
    670670                /*
     
    673673                bool fFound = false;
    674674                for (uint32_t iNameAttrib = 0; iNameAttrib < pNameRdns->cItems; iNameAttrib++)
    675                     if (RTCrX509AttributeTypeAndValue_MatchAsRdnByRfc5280(pConstrAttrib, &pNameRdns->paItems[iNameAttrib]))
     675                    if (RTCrX509AttributeTypeAndValue_MatchAsRdnByRfc5280(pConstrAttrib, pNameRdns->papItems[iNameAttrib]))
    676676                    {
    677677                        fFound = true;
     
    737737    for (uint32_t i = 0; i < pThis->cItems; i++)
    738738    {
    739         PCRTCRX509RELATIVEDISTINGUISHEDNAME pRdn = &pThis->paItems[i];
     739        PCRTCRX509RELATIVEDISTINGUISHEDNAME pRdn = pThis->papItems[i];
    740740        for (uint32_t j = 0; j < pRdn->cItems; j++)
    741741        {
    742             PCRTCRX509ATTRIBUTETYPEANDVALUE pComponent = &pRdn->paItems[j];
     742            PCRTCRX509ATTRIBUTETYPEANDVALUE pComponent = pRdn->papItems[j];
    743743
    744744            /*
     
    816816    for (uint32_t i = 0; i < pThis->cItems; i++)
    817817    {
    818         PCRTCRX509RELATIVEDISTINGUISHEDNAME pRdn = &pThis->paItems[i];
     818        PCRTCRX509RELATIVEDISTINGUISHEDNAME pRdn = pThis->papItems[i];
    819819        for (uint32_t j = 0; j < pRdn->cItems; j++)
    820820        {
    821             PCRTCRX509ATTRIBUTETYPEANDVALUE pComponent = &pRdn->paItems[j];
     821            PCRTCRX509ATTRIBUTETYPEANDVALUE pComponent = pRdn->papItems[j];
    822822
    823823            /*
     
    13321332    {
    13331333
    1334         if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_ANY_EXTENDED_KEY_USAGE_OID) == 0)
     1334        if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_ANY_EXTENDED_KEY_USAGE_OID) == 0)
    13351335            pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_ANY;
    1336         else if (RTAsn1ObjId_StartsWith(&pObjIds->paItems[i], RTCRX509_ID_KP_OID))
    1337         {
    1338             if (RTAsn1ObjIdCountComponents(&pObjIds->paItems[i]) == 9)
    1339                 switch (RTAsn1ObjIdGetLastComponentsAsUInt32(&pObjIds->paItems[i]))
     1336        else if (RTAsn1ObjId_StartsWith(pObjIds->papItems[i], RTCRX509_ID_KP_OID))
     1337        {
     1338            if (RTAsn1ObjIdCountComponents(pObjIds->papItems[i]) == 9)
     1339                switch (RTAsn1ObjIdGetLastComponentsAsUInt32(pObjIds->papItems[i]))
    13401340                {
    13411341                    case  1: pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_SERVER_AUTH; break;
     
    13571357                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_OTHER;
    13581358        }
    1359         else if (RTAsn1ObjId_StartsWith(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_APPLE_EXTENDED_KEY_USAGE_OID))
    1360         {
    1361             if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_OID) == 0)
     1359        else if (RTAsn1ObjId_StartsWith(pObjIds->papItems[i], RTCRX509_APPLE_EKU_APPLE_EXTENDED_KEY_USAGE_OID))
     1360        {
     1361            if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_OID) == 0)
    13621362                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_CODE_SIGNING;
    1363             else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_DEVELOPMENT_OID) == 0)
     1363            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_DEVELOPMENT_OID) == 0)
    13641364                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_CODE_SIGNING_DEVELOPMENT;
    1365             else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_SOFTWARE_UPDATE_SIGNING_OID) == 0)
     1365            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_SOFTWARE_UPDATE_SIGNING_OID) == 0)
    13661366                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_SOFTWARE_UPDATE_SIGNING;
    1367             else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_THRID_PARTY_OID) == 0)
     1367            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_THRID_PARTY_OID) == 0)
    13681368                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_CODE_SIGNING_THIRD_PARTY;
    1369             else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_RESOURCE_SIGNING_OID) == 0)
     1369            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_RESOURCE_SIGNING_OID) == 0)
    13701370                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_RESOURCE_SIGNING;
    1371             else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_SYSTEM_IDENTITY_OID) == 0)
     1371            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_SYSTEM_IDENTITY_OID) == 0)
    13721372                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_SYSTEM_IDENTITY;
    13731373            else
    13741374                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_OTHER;
    13751375        }
    1376         else if (RTAsn1ObjId_StartsWith(&pObjIds->paItems[i], "1.3.6.1.4.1.311"))
    1377         {
    1378             if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_TIMESTAMP_SIGNING_OID) == 0)
     1376        else if (RTAsn1ObjId_StartsWith(pObjIds->papItems[i], "1.3.6.1.4.1.311"))
     1377        {
     1378            if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_TIMESTAMP_SIGNING_OID) == 0)
    13791379                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_TIMESTAMP_SIGNING;
    1380             else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_NT5_CRYPTO_OID) == 0)
     1380            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_NT5_CRYPTO_OID) == 0)
    13811381                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_NT5_CRYPTO;
    1382             else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_OEM_WHQL_CRYPTO_OID) == 0)
     1382            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_OEM_WHQL_CRYPTO_OID) == 0)
    13831383                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_OEM_WHQL_CRYPTO;
    1384             else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_EMBEDDED_NT_CRYPTO_OID) == 0)
     1384            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_EMBEDDED_NT_CRYPTO_OID) == 0)
    13851385                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_EMBEDDED_NT_CRYPTO;
    1386             else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_KERNEL_MODE_CODE_SIGNING_OID) == 0)
     1386            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_KERNEL_MODE_CODE_SIGNING_OID) == 0)
    13871387                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_KERNEL_MODE_CODE_SIGNING;
    1388             else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_LIFETIME_SIGNING_OID) == 0)
     1388            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_LIFETIME_SIGNING_OID) == 0)
    13891389                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_LIFETIME_SIGNING;
    1390             else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_DRM_OID) == 0)
     1390            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_DRM_OID) == 0)
    13911391                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_DRM;
    1392             else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_DRM_INDIVIDUALIZATION_OID) == 0)
     1392            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_DRM_INDIVIDUALIZATION_OID) == 0)
    13931393                pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_DRM_INDIVIDUALIZATION;
    13941394            else
     
    14431443    for (uint32_t i = 0; i < pThis->T3.Extensions.cItems; i++)
    14441444    {
    1445         PCRTASN1OBJID       pExtnId   = &pThis->T3.Extensions.paItems[i].ExtnId;
    1446         PCRTASN1OCTETSTRING pExtValue = &pThis->T3.Extensions.paItems[i].ExtnValue;
     1445        PCRTASN1OBJID       pExtnId   = &pThis->T3.Extensions.papItems[i]->ExtnId;
     1446        PCRTASN1OCTETSTRING pExtValue = &pThis->T3.Extensions.papItems[i]->ExtnValue;
    14471447        if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_KEY_USAGE_OID) == 0)
    14481448        {
    14491449            CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_KEY_USAGE);
    1450             rtCrx509TbsCertificate_AddKeyUsageFlags(pThis, &pThis->T3.Extensions.paItems[i]);
    1451             Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_BIT_STRING);
     1450            rtCrx509TbsCertificate_AddKeyUsageFlags(pThis, pThis->T3.Extensions.papItems[i]);
     1451            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_BIT_STRING);
    14521452        }
    14531453        else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_EXT_KEY_USAGE_OID) == 0)
    14541454        {
    14551455            CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_EXT_KEY_USAGE);
    1456             rtCrx509TbsCertificate_AddExtKeyUsageFlags(pThis, &pThis->T3.Extensions.paItems[i]);
    1457             Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_SEQ_OF_OBJ_IDS);
     1456            rtCrx509TbsCertificate_AddExtKeyUsageFlags(pThis, pThis->T3.Extensions.papItems[i]);
     1457            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_SEQ_OF_OBJ_IDS);
    14581458        }
    14591459        else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_AUTHORITY_KEY_IDENTIFIER_OID) == 0)
     
    14611461            CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_AUTHORITY_KEY_IDENTIFIER);
    14621462            pThis->T3.pAuthorityKeyIdentifier = (PCRTCRX509AUTHORITYKEYIDENTIFIER)pExtValue->pEncapsulated;
    1463             Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_AUTHORITY_KEY_IDENTIFIER);
     1463            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_AUTHORITY_KEY_IDENTIFIER);
    14641464        }
    14651465        else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_OLD_AUTHORITY_KEY_IDENTIFIER_OID) == 0)
     
    14671467            CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_OLD_AUTHORITY_KEY_IDENTIFIER);
    14681468            pThis->T3.pOldAuthorityKeyIdentifier = (PCRTCRX509OLDAUTHORITYKEYIDENTIFIER)pExtValue->pEncapsulated;
    1469             Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_OLD_AUTHORITY_KEY_IDENTIFIER);
     1469            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_OLD_AUTHORITY_KEY_IDENTIFIER);
    14701470        }
    14711471        else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_SUBJECT_KEY_IDENTIFIER_OID) == 0)
     
    14731473            CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_SUBJECT_KEY_IDENTIFIER);
    14741474            pThis->T3.pSubjectKeyIdentifier = (PCRTASN1OCTETSTRING)pExtValue->pEncapsulated;
    1475             Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_OCTET_STRING);
     1475            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_OCTET_STRING);
    14761476        }
    14771477        else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_SUBJECT_ALT_NAME_OID) == 0)
     
    14791479            CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_SUBJECT_ALT_NAME);
    14801480            pThis->T3.pAltSubjectName = (PCRTCRX509GENERALNAMES)pExtValue->pEncapsulated;
    1481             Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES);
     1481            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES);
    14821482        }
    14831483        else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_ISSUER_ALT_NAME_OID) == 0)
     
    14851485            CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_ISSUER_ALT_NAME);
    14861486            pThis->T3.pAltIssuerName = (PCRTCRX509GENERALNAMES)pExtValue->pEncapsulated;
    1487             Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES);
     1487            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES);
    14881488        }
    14891489        else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_CERTIFICATE_POLICIES_OID) == 0)
     
    14911491            CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_CERTIFICATE_POLICIES);
    14921492            pThis->T3.pCertificatePolicies = (PCRTCRX509CERTIFICATEPOLICIES)pExtValue->pEncapsulated;
    1493             Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_CERTIFICATE_POLICIES);
     1493            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_CERTIFICATE_POLICIES);
    14941494        }
    14951495        else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_POLICY_MAPPINGS_OID) == 0)
     
    14971497            CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_POLICY_MAPPINGS);
    14981498            pThis->T3.pPolicyMappings = (PCRTCRX509POLICYMAPPINGS)pExtValue->pEncapsulated;
    1499             Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_POLICY_MAPPINGS);
     1499            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_POLICY_MAPPINGS);
    15001500        }
    15011501        else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_BASIC_CONSTRAINTS_OID) == 0)
     
    15031503            CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_BASIC_CONSTRAINTS);
    15041504            pThis->T3.pBasicConstraints = (PCRTCRX509BASICCONSTRAINTS)pExtValue->pEncapsulated;
    1505             Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_BASIC_CONSTRAINTS);
     1505            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_BASIC_CONSTRAINTS);
    15061506        }
    15071507        else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_NAME_CONSTRAINTS_OID) == 0)
     
    15091509            CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_NAME_CONSTRAINTS);
    15101510            pThis->T3.pNameConstraints = (PCRTCRX509NAMECONSTRAINTS)pExtValue->pEncapsulated;
    1511             Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_NAME_CONSTRAINTS);
     1511            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_NAME_CONSTRAINTS);
    15121512        }
    15131513        else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_POLICY_CONSTRAINTS_OID) == 0)
     
    15151515            CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_POLICY_CONSTRAINTS);
    15161516            pThis->T3.pPolicyConstraints = (PCRTCRX509POLICYCONSTRAINTS)pExtValue->pEncapsulated;
    1517             Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_POLICY_CONSTRAINTS);
     1517            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_POLICY_CONSTRAINTS);
    15181518        }
    15191519        else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_INHIBIT_ANY_POLICY_OID) == 0)
     
    15211521            CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_INHIBIT_ANY_POLICY);
    15221522            pThis->T3.pInhibitAnyPolicy = (PCRTASN1INTEGER)pExtValue->pEncapsulated;
    1523             Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_INTEGER);
     1523            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_INTEGER);
    15241524        }
    15251525        else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_ACCEPTABLE_CERT_POLICIES_OID) == 0)
     
    15601560        for (uint32_t i = 0; i < pThis->TbsCertificate.T3.Extensions.cItems; i++)
    15611561        {
    1562             PCRTCRX509EXTENSION pExt = &pThis->TbsCertificate.T3.Extensions.paItems[i];
     1562            PCRTCRX509EXTENSION pExt = pThis->TbsCertificate.T3.Extensions.papItems[i];
    15631563            if (   pExt->enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES
    15641564                && RTAsn1ObjId_CompareWithString(&pExt->ExtnId, RTCRX509_ID_CE_SUBJECT_ALT_NAME_OID))
     
    15661566                PCRTCRX509GENERALNAMES pGeneralNames = (PCRTCRX509GENERALNAMES)pExt->ExtnValue.pEncapsulated;
    15671567                for (uint32_t j = 0; j < pGeneralNames->cItems; j++)
    1568                     if (   RTCRX509GENERALNAME_IS_DIRECTORY_NAME(&pGeneralNames->paItems[j])
    1569                         && RTCrX509Name_MatchByRfc5280(&pGeneralNames->paItems[j].u.pT4->DirectoryName, pName))
     1568                    if (   RTCRX509GENERALNAME_IS_DIRECTORY_NAME(pGeneralNames->papItems[j])
     1569                        && RTCrX509Name_MatchByRfc5280(&pGeneralNames->papItems[j]->u.pT4->DirectoryName, pName))
    15701570                        return true;
    15711571            }
     
    15951595{
    15961596    for (uint32_t i = 0; i < pCertificates->cItems; i++)
    1597         if (RTCrX509Certificate_MatchIssuerAndSerialNumber(&pCertificates->paItems[i], pIssuer, pSerialNumber))
    1598             return &pCertificates->paItems[i];
     1597        if (RTCrX509Certificate_MatchIssuerAndSerialNumber(pCertificates->papItems[i], pIssuer, pSerialNumber))
     1598            return pCertificates->papItems[i];
    15991599    return NULL;
    16001600}
  • trunk/src/VBox/Runtime/common/crypto/x509-init.cpp

    r62477 r64883  
    4949{
    5050    uint32_t                            cRdns = pThis->cItems;
    51     PRTCRX509RELATIVEDISTINGUISHEDNAME  pRdn   = &pThis->paItems[0];
     51    PRTCRX509RELATIVEDISTINGUISHEDNAME *ppRdn = pThis->papItems;
    5252    while (cRdns-- > 0)
    5353    {
    54         uint32_t                        cAttribs = pRdn->cItems;
    55         PRTCRX509ATTRIBUTETYPEANDVALUE  pAttrib  = &pRdn->paItems[0];
     54        PRTCRX509RELATIVEDISTINGUISHEDNAME const pRdn     = *ppRdn;
     55        uint32_t                                 cAttribs = pRdn->cItems;
     56        PRTCRX509ATTRIBUTETYPEANDVALUE          *ppAttrib = pRdn->papItems;
    5657        while (cAttribs-- > 0)
    5758        {
     59            PRTCRX509ATTRIBUTETYPEANDVALUE const pAttrib = *ppAttrib;
    5860            if (pAttrib->Value.enmType == RTASN1TYPE_STRING)
    5961            {
     
    6264                    return rc;
    6365            }
    64             pAttrib++;
     66            ppAttrib++;
    6567        }
    66         pRdn++;
     68        ppRdn++;
    6769    }
    6870    return VINF_SUCCESS;
  • trunk/src/VBox/Runtime/common/crypto/x509-sanity.cpp

    r62564 r64883  
    5959    for (uint32_t i = 0; i < pThis->cItems; i++)
    6060    {
    61         if (pThis->cItems == 0)
     61        PCRTCRX509RELATIVEDISTINGUISHEDNAME const pRdn = pThis->papItems[i];
     62        if (pRdn->cItems == 0)
    6263            return RTErrInfoSetF(pErrInfo, VERR_CR_X509_NAME_EMPTY_SUB_SET,
    6364                                 "%s: Items[%u] has no sub components.", pszErrorTag, i);
    6465
    65         for (uint32_t j = 0; j < pThis->paItems[i].cItems; j++)
     66        for (uint32_t j = 0; j < pRdn->cItems; j++)
    6667        {
    67             if (pThis->paItems[i].paItems[j].Value.enmType != RTASN1TYPE_STRING)
     68            PCRTCRX509ATTRIBUTETYPEANDVALUE const pAttr = pRdn->papItems[j];
     69
     70            if (pAttr->Value.enmType != RTASN1TYPE_STRING)
    6871                return RTErrInfoSetF(pErrInfo, VERR_CR_X509_NAME_NOT_STRING,
    6972                                     "%s: Items[%u].paItems[%u].enmType is %d instead of string (%d).",
    70                                      pszErrorTag, i, j, pThis->paItems[i].paItems[j].Value.enmType, RTASN1TYPE_STRING);
    71             if (pThis->paItems[i].paItems[j].Value.u.String.Asn1Core.cb == 0)
     73                                     pszErrorTag, i, j, pAttr->Value.enmType, RTASN1TYPE_STRING);
     74            if (pAttr->Value.u.String.Asn1Core.cb == 0)
    7275                return RTErrInfoSetF(pErrInfo, VERR_CR_X509_NAME_EMPTY_STRING,
    7376                                     "%s: Items[%u].paItems[%u] is an empty string", pszErrorTag, i, j);
    74             switch (pThis->paItems[i].paItems[j].Value.u.String.Asn1Core.uTag)
     77            switch (pAttr->Value.u.String.Asn1Core.uTag)
    7578            {
    7679                case ASN1_TAG_PRINTABLE_STRING:
     
    8689                    return RTErrInfoSetF(pErrInfo, VERR_CR_X509_INVALID_NAME_STRING_TAG,
    8790                                         "%s: Items[%u].paItems[%u] invalid string type: %u",  pszErrorTag, i, j,
    88                                          pThis->paItems[i].paItems[j].Value.u.String.Asn1Core.uTag);
     91                                         pAttr->Value.u.String.Asn1Core.uTag);
    8992            }
    9093        }
  • trunk/src/VBox/Runtime/tools/RTSignTool.cpp

    r64877 r64883  
    6363
    6464
    65 typedef struct SHOWEXEPKCS7
    66 {
    67     uint8_t const              *pbBuf;
     65/**
     66 * PKCS\#7 signature data.
     67 */
     68typedef struct SIGNTOOLPKCS7
     69{
     70    /** The raw signature. */
     71    uint8_t                    *pbBuf;
     72    /** Size of the raw signature. */
    6873    size_t                      cbBuf;
     74    /** The filename.   */
    6975    const char                 *pszFilename;
    70     unsigned                    cVerbosity;
    71     RTLDRMOD                    hLdrMod;
    7276    /** The outer content info wrapper. */
    7377    RTCRPKCS7CONTENTINFO        ContentInfo;
     
    7680    /** Pointer to the indirect data content. */
    7781    PRTCRSPCINDIRECTDATACONTENT pIndData;
    78 
     82} SIGNTOOLPKCS7;
     83typedef SIGNTOOLPKCS7 *PSIGNTOOLPKCS7;
     84
     85
     86/**
     87 * PKCS\#7 signature data for executable.
     88 */
     89typedef struct SIGNTOOLPKCS7EXE : public SIGNTOOLPKCS7
     90{
     91    /** The module handle. */
     92    RTLDRMOD                    hLdrMod;
     93} SIGNTOOLPKCS7EXE;
     94typedef SIGNTOOLPKCS7EXE *PSIGNTOOLPKCS7EXE;
     95
     96
     97/**
     98 * Data for the show exe (signature) command.
     99 */
     100typedef struct SHOWEXEPKCS7 : public SIGNTOOLPKCS7EXE
     101{
     102    /** The verbosity. */
     103    unsigned                    cVerbosity;
     104    /** The prefix buffer. */
    79105    char                        szPrefix[256];
     106    /** Temporary buffer. */
    80107    char                        szTmp[4096];
    81108} SHOWEXEPKCS7;
     
    94121
    95122
    96 
    97 
    98 /*
    99  * The 'extract-exe-signer-cert' command.
    100  */
    101 static RTEXITCODE HelpExtractExeSignerCert(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
    102 {
    103     RT_NOREF_PV(enmLevel);
    104     RTStrmPrintf(pStrm, "extract-exe-signer-cert [--ber|--cer|--der] [--exe|-e] <exe> [--output|-o] <outfile.cer>\n");
    105     return RTEXITCODE_SUCCESS;
    106 }
    107 
    108 static RTEXITCODE HandleExtractExeSignerCert(int cArgs, char **papszArgs)
    109 {
    110     /*
    111      * Parse arguments.
    112      */
    113     static const RTGETOPTDEF s_aOptions[] =
    114     {
    115         { "--ber",    'b', RTGETOPT_REQ_NOTHING },
    116         { "--cer",    'c', RTGETOPT_REQ_NOTHING },
    117         { "--der",    'd', RTGETOPT_REQ_NOTHING },
    118         { "--exe",    'e', RTGETOPT_REQ_STRING },
    119         { "--output", 'o', RTGETOPT_REQ_STRING },
    120     };
    121 
    122     const char *pszExe = NULL;
    123     const char *pszOut = NULL;
    124     RTLDRARCH   enmLdrArch   = RTLDRARCH_WHATEVER;
    125     uint32_t    fCursorFlags = RTASN1CURSOR_FLAGS_DER;
    126 
    127     RTGETOPTSTATE GetState;
    128     int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
    129     AssertRCReturn(rc, RTEXITCODE_FAILURE);
    130     RTGETOPTUNION ValueUnion;
    131     int ch;
    132     while ((ch = RTGetOpt(&GetState, &ValueUnion)))
    133     {
    134         switch (ch)
    135         {
    136             case 'e':   pszExe = ValueUnion.psz; break;
    137             case 'o':   pszOut = ValueUnion.psz; break;
    138             case 'b':   fCursorFlags = 0; break;
    139             case 'c':   fCursorFlags = RTASN1CURSOR_FLAGS_CER; break;
    140             case 'd':   fCursorFlags = RTASN1CURSOR_FLAGS_DER; break;
    141             case 'V':   return HandleVersion(cArgs, papszArgs);
    142             case 'h':   return HelpExtractExeSignerCert(g_pStdOut, RTSIGNTOOLHELP_FULL);
    143 
    144             case VINF_GETOPT_NOT_OPTION:
    145                 if (!pszExe)
    146                     pszExe = ValueUnion.psz;
    147                 else if (!pszOut)
    148                     pszOut = ValueUnion.psz;
    149                 else
    150                     return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many file arguments: %s", ValueUnion.psz);
    151                 break;
    152 
    153             default:
    154                 return RTGetOptPrintError(ch, &ValueUnion);
    155         }
    156     }
    157     if (!pszExe)
    158         return RTMsgErrorExit(RTEXITCODE_FAILURE, "No executable given.");
    159     if (!pszOut)
    160         return RTMsgErrorExit(RTEXITCODE_FAILURE, "No output file given.");
    161     if (RTPathExists(pszOut))
    162         return RTMsgErrorExit(RTEXITCODE_FAILURE, "The output file '%s' exists.", pszOut);
    163 
    164     /*
    165      * Do it.
    166      */
    167 
    168     /* Open the executable image and query the PKCS7 info. */
    169     RTLDRMOD hLdrMod;
    170     rc = RTLdrOpen(pszExe, RTLDR_O_FOR_VALIDATION, enmLdrArch, &hLdrMod);
    171     if (RT_FAILURE(rc))
    172         return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszExe, rc);
    173 
    174     RTEXITCODE rcExit = RTEXITCODE_FAILURE;
    175 #ifdef DEBUG
    176     size_t     cbBuf = 64;
    177 #else
    178     size_t     cbBuf = _512K;
    179 #endif
    180     void      *pvBuf = RTMemAlloc(cbBuf);
    181     size_t     cbRet = 0;
    182     rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbRet);
    183     if (rc == VERR_BUFFER_OVERFLOW && cbRet < _4M && cbRet > 0)
    184     {
    185         RTMemFree(pvBuf);
    186         cbBuf = cbRet;
    187         pvBuf = RTMemAlloc(cbBuf);
    188         rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbRet);
    189     }
    190     if (RT_SUCCESS(rc))
    191     {
    192         static RTERRINFOSTATIC s_StaticErrInfo;
    193         RTErrInfoInitStatic(&s_StaticErrInfo);
    194 
    195         /*
    196          * Decode the output.
    197          */
    198         RTASN1CURSORPRIMARY PrimaryCursor;
    199         RTAsn1CursorInitPrimary(&PrimaryCursor, pvBuf, (uint32_t)cbRet, &s_StaticErrInfo.Core,
    200                                 &g_RTAsn1DefaultAllocator, fCursorFlags, "exe");
    201         RTCRPKCS7CONTENTINFO Pkcs7Ci;
    202         rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &Pkcs7Ci, "pkcs7");
    203         if (RT_SUCCESS(rc))
    204         {
    205             if (RTCrPkcs7ContentInfo_IsSignedData(&Pkcs7Ci))
    206             {
    207                 PCRTCRPKCS7SIGNEDDATA pSd = Pkcs7Ci.u.pSignedData;
    208                 if (pSd->SignerInfos.cItems == 1)
    209                 {
    210                     PCRTCRPKCS7ISSUERANDSERIALNUMBER pISN = &pSd->SignerInfos.paItems[0].IssuerAndSerialNumber;
    211                     PCRTCRX509CERTIFICATE pCert;
    212                     pCert = RTCrPkcs7SetOfCerts_FindX509ByIssuerAndSerialNumber(&pSd->Certificates,
    213                                                                                 &pISN->Name, &pISN->SerialNumber);
    214                     if (pCert)
    215                     {
    216                         /*
    217                          * Write it out.
    218                          */
    219                         RTFILE hFile;
    220                         rc = RTFileOpen(&hFile, pszOut, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE);
    221                         if (RT_SUCCESS(rc))
    222                         {
    223                             uint32_t cbCert = pCert->SeqCore.Asn1Core.cbHdr + pCert->SeqCore.Asn1Core.cb;
    224                             rc = RTFileWrite(hFile, pCert->SeqCore.Asn1Core.uData.pu8 - pCert->SeqCore.Asn1Core.cbHdr,
    225                                              cbCert, NULL);
    226                             if (RT_SUCCESS(rc))
    227                             {
    228                                 rc = RTFileClose(hFile);
    229                                 if (RT_SUCCESS(rc))
    230                                 {
    231                                     hFile  = NIL_RTFILE;
    232                                     rcExit = RTEXITCODE_SUCCESS;
    233                                     RTMsgInfo("Successfully wrote %u bytes to '%s'", cbCert, pszOut);
    234                                 }
    235                                 else
    236                                     RTMsgError("RTFileClose failed: %Rrc", rc);
    237                             }
    238                             else
    239                                 RTMsgError("RTFileWrite failed: %Rrc", rc);
    240                             RTFileClose(hFile);
    241                         }
    242                         else
    243                             RTMsgError("Error opening '%s': %Rrc", pszOut, rc);
    244                     }
    245                     else
    246                         RTMsgError("Certificate not found.");
    247                 }
    248                 else
    249                     RTMsgError("SignerInfo count: %u", pSd->SignerInfos.cItems);
    250             }
    251             else
    252                 RTMsgError("No PKCS7 content: ContentType=%s", Pkcs7Ci.ContentType.szObjId);
    253             RTAsn1VtDelete(&Pkcs7Ci.SeqCore.Asn1Core);
    254         }
    255         else
    256             RTMsgError("RTPkcs7ContentInfoDecodeAsn1 failed: %Rrc - %s", rc, s_StaticErrInfo.szMsg);
    257     }
    258     else
    259         RTMsgError("RTLDRPROP_PKCS7_SIGNED_DATA failed on '%s': %Rrc", pszExe, rc);
    260     RTMemFree(pvBuf);
    261     rc = RTLdrClose(hLdrMod);
    262     if (RT_FAILURE(rc))
    263         rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTLdrClose failed: %Rrc\n", rc);
    264     return rcExit;
    265 }
    266 
    267 #ifndef IPRT_IN_BUILD_TOOL
    268 
    269 /*
    270  * The 'verify-exe' command.
    271  */
    272 static RTEXITCODE HelpVerifyExe(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
    273 {
    274     RT_NOREF_PV(enmLevel);
    275     RTStrmPrintf(pStrm,
    276                  "verify-exe [--verbose|--quiet] [--kernel] [--root <root-cert.der>] [--additional <supp-cert.der>]\n"
    277                  "        [--type <win|osx>] <exe1> [exe2 [..]]\n");
    278     return RTEXITCODE_SUCCESS;
    279 }
    280 
    281 typedef struct VERIFYEXESTATE
    282 {
    283     RTCRSTORE   hRootStore;
    284     RTCRSTORE   hKernelRootStore;
    285     RTCRSTORE   hAdditionalStore;
    286     bool        fKernel;
    287     int         cVerbose;
    288     enum { kSignType_Windows, kSignType_OSX } enmSignType;
    289     uint64_t    uTimestamp;
    290     RTLDRARCH   enmLdrArch;
    291 } VERIFYEXESTATE;
    292 
    293 # ifdef VBOX
    294 /** Certificate store load set.
    295  * Declared outside HandleVerifyExe because of braindead gcc visibility crap. */
    296 struct STSTORESET
    297 {
    298     RTCRSTORE       hStore;
    299     PCSUPTAENTRY    paTAs;
    300     unsigned        cTAs;
    301 };
    302 # endif
    303 
    304123/**
    305  * @callback_method_impl{FNRTCRPKCS7VERIFYCERTCALLBACK,
    306  * Standard code signing.  Use this for Microsoft SPC.}
    307  */
    308 static DECLCALLBACK(int) VerifyExecCertVerifyCallback(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags,
    309                                                       void *pvUser, PRTERRINFO pErrInfo)
    310 {
    311     VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser;
    312     uint32_t        cPaths = hCertPaths != NIL_RTCRX509CERTPATHS ? RTCrX509CertPathsGetPathCount(hCertPaths) : 0;
    313 
    314     /*
    315      * Dump all the paths.
    316      */
    317     if (pState->cVerbose > 0)
    318     {
    319         for (uint32_t iPath = 0; iPath < cPaths; iPath++)
    320         {
    321             RTPrintf("---\n");
    322             RTCrX509CertPathsDumpOne(hCertPaths, iPath, pState->cVerbose, RTStrmDumpPrintfV, g_pStdOut);
    323             *pErrInfo->pszMsg = '\0';
    324         }
    325         RTPrintf("---\n");
    326     }
    327 
    328     /*
    329      * Test signing certificates normally doesn't have all the necessary
    330      * features required below.  So, treat them as special cases.
    331      */
    332     if (   hCertPaths == NIL_RTCRX509CERTPATHS
    333         && RTCrX509Name_Compare(&pCert->TbsCertificate.Issuer, &pCert->TbsCertificate.Subject) == 0)
    334     {
    335         RTMsgInfo("Test signed.\n");
    336         return VINF_SUCCESS;
    337     }
    338 
    339     if (hCertPaths == NIL_RTCRX509CERTPATHS)
    340         RTMsgInfo("Signed by trusted certificate.\n");
    341 
    342     /*
    343      * Standard code signing capabilites required.
    344      */
    345     int rc = RTCrPkcs7VerifyCertCallbackCodeSigning(pCert, hCertPaths, fFlags, NULL, pErrInfo);
    346     if (   RT_SUCCESS(rc)
    347         && (fFlags & RTCRPKCS7VCC_F_SIGNED_DATA))
    348     {
    349         /*
    350          * If kernel signing, a valid certificate path must be anchored by the
    351          * microsoft kernel signing root certificate.  The only alternative is
    352          * test signing.
    353          */
    354         if (pState->fKernel && hCertPaths != NIL_RTCRX509CERTPATHS)
    355         {
    356             uint32_t cFound = 0;
    357             uint32_t cValid = 0;
    358             for (uint32_t iPath = 0; iPath < cPaths; iPath++)
    359             {
    360                 bool                            fTrusted;
    361                 PCRTCRX509NAME                  pSubject;
    362                 PCRTCRX509SUBJECTPUBLICKEYINFO  pPublicKeyInfo;
    363                 int                             rcVerify;
    364                 rc = RTCrX509CertPathsQueryPathInfo(hCertPaths, iPath, &fTrusted, NULL /*pcNodes*/, &pSubject, &pPublicKeyInfo,
    365                                                     NULL, NULL /*pCertCtx*/, &rcVerify);
    366                 AssertRCBreak(rc);
    367 
    368                 if (RT_SUCCESS(rcVerify))
    369                 {
    370                     Assert(fTrusted);
    371                     cValid++;
    372 
    373                     /* Search the kernel signing root store for a matching anchor. */
    374                     RTCRSTORECERTSEARCH Search;
    375                     rc = RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280(pState->hKernelRootStore, pSubject, &Search);
    376                     AssertRCBreak(rc);
    377                     PCRTCRCERTCTX pCertCtx;
    378                     while ((pCertCtx = RTCrStoreCertSearchNext(pState->hKernelRootStore, &Search)) != NULL)
    379                     {
    380                         PCRTCRX509SUBJECTPUBLICKEYINFO pPubKeyInfo;
    381                         if (pCertCtx->pCert)
    382                             pPubKeyInfo = &pCertCtx->pCert->TbsCertificate.SubjectPublicKeyInfo;
    383                         else if (pCertCtx->pTaInfo)
    384                             pPubKeyInfo = &pCertCtx->pTaInfo->PubKey;
    385                         else
    386                             pPubKeyInfo = NULL;
    387                         if (RTCrX509SubjectPublicKeyInfo_Compare(pPubKeyInfo, pPublicKeyInfo) == 0)
    388                             cFound++;
    389                         RTCrCertCtxRelease(pCertCtx);
    390                     }
    391 
    392                     int rc2 = RTCrStoreCertSearchDestroy(pState->hKernelRootStore, &Search); AssertRC(rc2);
    393                 }
    394             }
    395             if (RT_SUCCESS(rc) && cFound == 0)
    396                 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "Not valid kernel code signature.");
    397             if (RT_SUCCESS(rc) && cValid != 2)
    398                 RTMsgWarning("%u valid paths, expected 2", cValid);
    399         }
    400     }
    401 
    402     return rc;
    403 }
    404 
    405 
    406 /** @callback_method_impl{FNRTLDRVALIDATESIGNEDDATA}  */
    407 static DECLCALLBACK(int) VerifyExeCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
    408                                            void const *pvSignature, size_t cbSignature,
    409                                            PRTERRINFO pErrInfo, void *pvUser)
    410 {
    411     VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser;
    412     RT_NOREF_PV(hLdrMod); RT_NOREF_PV(cbSignature);
    413 
    414     switch (enmSignature)
    415     {
    416         case RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA:
    417         {
    418             PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pvSignature;
    419 
    420             RTTIMESPEC ValidationTime;
    421             RTTimeSpecSetSeconds(&ValidationTime, pState->uTimestamp);
    422 
    423             /*
    424              * Dump the signed data if so requested.
    425              */
    426             if (pState->cVerbose)
    427                 RTAsn1Dump(&pContentInfo->SeqCore.Asn1Core, 0, 0, RTStrmDumpPrintfV, g_pStdOut);
    428 
    429 
    430             /*
    431              * Do the actual verification.  Will have to modify this so it takes
    432              * the authenticode policies into account.
    433              */
    434             return RTCrPkcs7VerifySignedData(pContentInfo,
    435                                              RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY
    436                                              | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
    437                                              | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT,
    438                                              pState->hAdditionalStore, pState->hRootStore, &ValidationTime,
    439                                              VerifyExecCertVerifyCallback, pState, pErrInfo);
    440         }
    441 
    442         default:
    443             return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", enmSignature);
    444     }
    445 }
    446 
    447 /** Worker for HandleVerifyExe. */
    448 static RTEXITCODE HandleVerifyExeWorker(VERIFYEXESTATE *pState, const char *pszFilename, PRTERRINFOSTATIC pStaticErrInfo)
    449 {
    450     /*
    451      * Open the executable image and verify it.
    452      */
    453     RTLDRMOD hLdrMod;
    454     int rc = RTLdrOpen(pszFilename, RTLDR_O_FOR_VALIDATION, pState->enmLdrArch, &hLdrMod);
    455     if (RT_FAILURE(rc))
    456         return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszFilename, rc);
    457 
    458 
    459     rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &pState->uTimestamp, sizeof(pState->uTimestamp));
    460     if (RT_SUCCESS(rc))
    461     {
    462         rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
    463         if (RT_SUCCESS(rc))
    464             RTMsgInfo("'%s' is valid.\n", pszFilename);
    465         else if (rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME)
    466         {
    467             RTTIMESPEC Now;
    468             pState->uTimestamp = RTTimeSpecGetSeconds(RTTimeNow(&Now));
    469             rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
    470             if (RT_SUCCESS(rc))
    471                 RTMsgInfo("'%s' is valid now, but not at link time.\n", pszFilename);
    472         }
    473         if (RT_FAILURE(rc))
    474             RTMsgError("RTLdrVerifySignature failed on '%s': %Rrc - %s\n", pszFilename, rc, pStaticErrInfo->szMsg);
    475     }
    476     else
    477         RTMsgError("RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on '%s': %Rrc\n", pszFilename, rc);
    478 
    479     int rc2 = RTLdrClose(hLdrMod);
    480     if (RT_FAILURE(rc2))
    481         return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTLdrClose failed: %Rrc\n", rc2);
    482     if (RT_FAILURE(rc))
    483         return rc != VERR_LDRVI_NOT_SIGNED ? RTEXITCODE_FAILURE : RTEXITCODE_SKIPPED;
    484 
    485     return RTEXITCODE_SUCCESS;
    486 }
    487 
    488 
    489 static RTEXITCODE HandleVerifyExe(int cArgs, char **papszArgs)
    490 {
    491     RTERRINFOSTATIC StaticErrInfo;
    492 
    493     /* Note! This code does not try to clean up the crypto stores on failure.
    494              This is intentional as the code is only expected to be used in a
    495              one-command-per-process environment where we do exit() upon
    496              returning from this function. */
    497 
    498     /*
    499      * Parse arguments.
    500      */
    501     static const RTGETOPTDEF s_aOptions[] =
    502     {
    503         { "--kernel",       'k', RTGETOPT_REQ_NOTHING },
    504         { "--root",         'r', RTGETOPT_REQ_STRING },
    505         { "--additional",   'a', RTGETOPT_REQ_STRING },
    506         { "--add",          'a', RTGETOPT_REQ_STRING },
    507         { "--type",         't', RTGETOPT_REQ_STRING },
    508         { "--verbose",      'v', RTGETOPT_REQ_NOTHING },
    509         { "--quiet",        'q', RTGETOPT_REQ_NOTHING },
    510     };
    511 
    512     VERIFYEXESTATE State =
    513     {
    514         NIL_RTCRSTORE, NIL_RTCRSTORE, NIL_RTCRSTORE, false, false,
    515         VERIFYEXESTATE::kSignType_Windows, 0, RTLDRARCH_WHATEVER
    516     };
    517     int rc = RTCrStoreCreateInMem(&State.hRootStore, 0);
    518     if (RT_SUCCESS(rc))
    519         rc = RTCrStoreCreateInMem(&State.hKernelRootStore, 0);
    520     if (RT_SUCCESS(rc))
    521         rc = RTCrStoreCreateInMem(&State.hAdditionalStore, 0);
    522     if (RT_FAILURE(rc))
    523         return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error creating in-memory certificate store: %Rrc", rc);
    524 
    525     RTGETOPTSTATE GetState;
    526     rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
    527     AssertRCReturn(rc, RTEXITCODE_FAILURE);
    528     RTGETOPTUNION ValueUnion;
    529     int ch;
    530     while ((ch = RTGetOpt(&GetState, &ValueUnion)) && ch != VINF_GETOPT_NOT_OPTION)
    531     {
    532         switch (ch)
    533         {
    534             case 'r': case 'a':
    535                 rc = RTCrStoreCertAddFromFile(ch == 'r' ? State.hRootStore : State.hAdditionalStore,
    536                                               RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR,
    537                                               ValueUnion.psz, RTErrInfoInitStatic(&StaticErrInfo));
    538                 if (RT_FAILURE(rc))
    539                     return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error loading certificate '%s': %Rrc - %s",
    540                                           ValueUnion.psz, rc, StaticErrInfo.szMsg);
    541                 if (RTErrInfoIsSet(&StaticErrInfo.Core))
    542                     RTMsgWarning("Warnings loading certificate '%s': %s", ValueUnion.psz, StaticErrInfo.szMsg);
    543                 break;
    544 
    545             case 't':
    546                 if (!strcmp(ValueUnion.psz, "win") || !strcmp(ValueUnion.psz, "windows"))
    547                     State.enmSignType = VERIFYEXESTATE::kSignType_Windows;
    548                 else if (!strcmp(ValueUnion.psz, "osx") || !strcmp(ValueUnion.psz, "apple"))
    549                     State.enmSignType = VERIFYEXESTATE::kSignType_OSX;
    550                 else
    551                     return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown signing type: '%s'", ValueUnion.psz);
    552                 break;
    553 
    554             case 'k': State.fKernel = true; break;
    555             case 'v': State.cVerbose++; break;
    556             case 'q': State.cVerbose = 0; break;
    557             case 'V': return HandleVersion(cArgs, papszArgs);
    558             case 'h': return HelpVerifyExe(g_pStdOut, RTSIGNTOOLHELP_FULL);
    559             default:  return RTGetOptPrintError(ch, &ValueUnion);
    560         }
    561     }
    562     if (ch != VINF_GETOPT_NOT_OPTION)
    563         return RTMsgErrorExit(RTEXITCODE_FAILURE, "No executable given.");
    564 
    565     /*
    566      * Populate the certificate stores according to the signing type.
    567      */
    568 #ifdef VBOX
    569     unsigned          cSets = 0;
    570     struct STSTORESET aSets[6];
    571 #endif
    572 
    573     switch (State.enmSignType)
    574     {
    575         case VERIFYEXESTATE::kSignType_Windows:
    576 #ifdef VBOX
    577             aSets[cSets].hStore  = State.hRootStore;
    578             aSets[cSets].paTAs   = g_aSUPTimestampTAs;
    579             aSets[cSets].cTAs    = g_cSUPTimestampTAs;
    580             cSets++;
    581             aSets[cSets].hStore  = State.hRootStore;
    582             aSets[cSets].paTAs   = g_aSUPSpcRootTAs;
    583             aSets[cSets].cTAs    = g_cSUPSpcRootTAs;
    584             cSets++;
    585             aSets[cSets].hStore  = State.hRootStore;
    586             aSets[cSets].paTAs   = g_aSUPNtKernelRootTAs;
    587             aSets[cSets].cTAs    = g_cSUPNtKernelRootTAs;
    588             cSets++;
    589             aSets[cSets].hStore  = State.hKernelRootStore;
    590             aSets[cSets].paTAs   = g_aSUPNtKernelRootTAs;
    591             aSets[cSets].cTAs    = g_cSUPNtKernelRootTAs;
    592             cSets++;
    593 #endif
    594             break;
    595 
    596         case VERIFYEXESTATE::kSignType_OSX:
    597             return RTMsgErrorExit(RTEXITCODE_FAILURE, "Mac OS X executable signing is not implemented.");
    598     }
    599 
    600 #ifdef VBOX
    601     for (unsigned i = 0; i < cSets; i++)
    602         for (unsigned j = 0; j < aSets[i].cTAs; j++)
    603         {
    604             rc = RTCrStoreCertAddEncoded(aSets[i].hStore, RTCRCERTCTX_F_ENC_TAF_DER, aSets[i].paTAs[j].pch,
    605                                          aSets[i].paTAs[j].cb, RTErrInfoInitStatic(&StaticErrInfo));
    606             if (RT_FAILURE(rc))
    607                 return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTCrStoreCertAddEncoded failed (%u/%u): %s",
    608                                       i, j, StaticErrInfo.szMsg);
    609         }
    610 #endif
    611 
    612     /*
    613      * Do it.
    614      */
    615     RTEXITCODE rcExit;
    616     for (;;)
    617     {
    618         rcExit = HandleVerifyExeWorker(&State, ValueUnion.psz, &StaticErrInfo);
    619         if (rcExit != RTEXITCODE_SUCCESS)
    620             break;
    621 
    622         /*
    623          * Next file
    624          */
    625         ch = RTGetOpt(&GetState, &ValueUnion);
    626         if (ch == 0)
    627             break;
    628         if (ch != VINF_GETOPT_NOT_OPTION)
    629         {
    630             rcExit = RTGetOptPrintError(ch, &ValueUnion);
    631             break;
    632         }
    633     }
    634 
    635     /*
    636      * Clean up.
    637      */
    638     uint32_t cRefs;
    639     cRefs = RTCrStoreRelease(State.hRootStore);       Assert(cRefs == 0);
    640     cRefs = RTCrStoreRelease(State.hKernelRootStore); Assert(cRefs == 0);
    641     cRefs = RTCrStoreRelease(State.hAdditionalStore); Assert(cRefs == 0);
    642 
    643     return rcExit;
    644 }
    645 
    646 #endif /* !IPRT_IN_BUILD_TOOL */
    647 ////
    648 #ifndef IPRT_IN_BUILD_TOOL
    649 
    650 /*
    651  * The 'show-exe' command.
    652  */
    653 static RTEXITCODE HelpShowExe(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
    654 {
    655     RT_NOREF_PV(enmLevel);
    656     RTStrmPrintf(pStrm,
    657                  "show-exe [--verbose|-v] [--quiet|-q] <exe1> [exe2 [..]]\n");
    658     return RTEXITCODE_SUCCESS;
     124 * Deletes the structure.
     125 *
     126 * @param   pThis               The structure to initialize.
     127 */
     128static void SignToolPkcs7_Delete(PSIGNTOOLPKCS7 pThis)
     129{
     130    RTCrPkcs7ContentInfo_Delete(&pThis->ContentInfo);
     131    pThis->pIndData    = NULL;
     132    pThis->pSignedData = NULL;
     133    pThis->pIndData    = NULL;
     134    RTMemFree(pThis->pbBuf);
     135    pThis->pbBuf       = NULL;
     136    pThis->cbBuf       = 0;
     137}
     138
     139
     140/**
     141 * Deletes the structure.
     142 *
     143 * @param   pThis               The structure to initialize.
     144 */
     145static void SignToolPkcs7Exe_Delete(PSIGNTOOLPKCS7EXE pThis)
     146{
     147    if (pThis->hLdrMod != NIL_RTLDRMOD)
     148    {
     149        int rc2 = RTLdrClose(pThis->hLdrMod);
     150        if (RT_FAILURE(rc2))
     151            RTMsgError("RTLdrClose failed: %Rrc\n", rc2);
     152        pThis->hLdrMod = NIL_RTLDRMOD;
     153    }
     154    SignToolPkcs7_Delete(pThis);
    659155}
    660156
     
    663159 * Decodes the PKCS #7 blob pointed to by pThis->pbBuf.
    664160 *
    665  * @returns IPRT status code.
    666  * @param   pThis               The show exe instance data.
    667  */
    668 static int HandleShowExeWorkerPkcs7Decode(PSHOWEXEPKCS7 pThis)
     161 * @returns IPRT status code (error message already shown on failure).
     162 * @param   pThis               The PKCS\#7 signature to decode.
     163 */
     164static int SignToolPkcs7_Decode(PSIGNTOOLPKCS7 pThis)
    669165{
    670166    RTERRINFOSTATIC     ErrInfo;
     
    724220
    725221/**
     222 * Reads and decodes PKCS\#7 signature from the given executable.
     223 *
     224 * @returns RTEXITCODE_SUCCESS on success, RTEXITCODE_FAILURE with error message
     225 *          on failure.
     226 * @param   pThis               The structure to initialize.
     227 * @param   pszFilename         The executable filename.
     228 * @param   cVerbosity          The verbosity.
     229 * @param   enmLdrArch          For FAT binaries.
     230 */
     231static RTEXITCODE SignToolPkcs7Exe_InitFromFile(PSIGNTOOLPKCS7EXE pThis, const char *pszFilename,
     232                                                unsigned cVerbosity, RTLDRARCH enmLdrArch = RTLDRARCH_WHATEVER)
     233{
     234    /*
     235     * Init the return structure.
     236     */
     237    RT_ZERO(*pThis);
     238    pThis->hLdrMod = NIL_RTLDRMOD;
     239    pThis->pszFilename = pszFilename;
     240
     241    /*
     242     * Open the image and check if it's signed.
     243     */
     244    int rc = RTLdrOpen(pszFilename, RTLDR_O_FOR_VALIDATION, enmLdrArch, &pThis->hLdrMod);
     245    if (RT_SUCCESS(rc))
     246    {
     247        bool fIsSigned = false;
     248        rc = RTLdrQueryProp(pThis->hLdrMod, RTLDRPROP_IS_SIGNED, &fIsSigned, sizeof(fIsSigned));
     249        if (RT_SUCCESS(rc) && fIsSigned)
     250        {
     251            /*
     252             * Query the PKCS#7 data (assuming M$ style signing) and hand it to a worker.
     253             */
     254            size_t cbActual = 0;
     255#ifdef DEBUG
     256            size_t cbBuf    = 64;
     257#else
     258            size_t cbBuf    = _512K;
     259#endif
     260            void  *pvBuf    = RTMemAllocZ(cbBuf);
     261            if (pvBuf)
     262            {
     263                rc = RTLdrQueryPropEx(pThis->hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbActual);
     264                if (rc == VERR_BUFFER_OVERFLOW)
     265                {
     266                    RTMemFree(pvBuf);
     267                    cbBuf = cbActual;
     268                    pvBuf = RTMemAllocZ(cbActual);
     269                    if (pvBuf)
     270                        rc = RTLdrQueryPropEx(pThis->hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/,
     271                                              pvBuf, cbBuf, &cbActual);
     272                    else
     273                        rc = VERR_NO_MEMORY;
     274                }
     275            }
     276            else
     277                rc = VERR_NO_MEMORY;
     278
     279            pThis->pbBuf = (uint8_t *)pvBuf;
     280            pThis->cbBuf = cbActual;
     281            if (RT_SUCCESS(rc))
     282            {
     283                if (cVerbosity > 2)
     284                    RTPrintf("PKCS#7 signature: %u bytes\n", cbActual);
     285
     286                /*
     287                 * Decode it.
     288                 */
     289                rc = SignToolPkcs7_Decode(pThis);
     290                if (RT_SUCCESS(rc))
     291                    return RTEXITCODE_SUCCESS;
     292            }
     293            else
     294                RTMsgError("RTLdrQueryPropEx/RTLDRPROP_PKCS7_SIGNED_DATA failed on '%s': %Rrc\n", pszFilename, rc);
     295        }
     296        else if (RT_SUCCESS(rc))
     297            RTMsgInfo("'%s': not signed\n", pszFilename);
     298        else
     299            RTMsgError("RTLdrQueryProp/RTLDRPROP_IS_SIGNED failed on '%s': %Rrc\n", pszFilename, rc);
     300    }
     301    else
     302        RTMsgError("Error opening executable image '%s': %Rrc", pszFilename, rc);
     303
     304    SignToolPkcs7Exe_Delete(pThis);
     305    return RTEXITCODE_FAILURE;
     306
     307}
     308
     309
     310/*
     311 * The 'extract-exe-signer-cert' command.
     312 */
     313static RTEXITCODE HelpExtractExeSignerCert(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
     314{
     315    RT_NOREF_PV(enmLevel);
     316    RTStrmPrintf(pStrm, "extract-exe-signer-cert [--ber|--cer|--der] [--exe|-e] <exe> [--output|-o] <outfile.cer>\n");
     317    return RTEXITCODE_SUCCESS;
     318}
     319
     320static RTEXITCODE HandleExtractExeSignerCert(int cArgs, char **papszArgs)
     321{
     322    /*
     323     * Parse arguments.
     324     */
     325    static const RTGETOPTDEF s_aOptions[] =
     326    {
     327        { "--ber",    'b', RTGETOPT_REQ_NOTHING },
     328        { "--cer",    'c', RTGETOPT_REQ_NOTHING },
     329        { "--der",    'd', RTGETOPT_REQ_NOTHING },
     330        { "--exe",    'e', RTGETOPT_REQ_STRING },
     331        { "--output", 'o', RTGETOPT_REQ_STRING },
     332    };
     333
     334    const char *pszExe = NULL;
     335    const char *pszOut = NULL;
     336    RTLDRARCH   enmLdrArch   = RTLDRARCH_WHATEVER;
     337    unsigned    cVerbosity   = 0;
     338    uint32_t    fCursorFlags = RTASN1CURSOR_FLAGS_DER;
     339
     340    RTGETOPTSTATE GetState;
     341    int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
     342    AssertRCReturn(rc, RTEXITCODE_FAILURE);
     343    RTGETOPTUNION ValueUnion;
     344    int ch;
     345    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
     346    {
     347        switch (ch)
     348        {
     349            case 'e':   pszExe = ValueUnion.psz; break;
     350            case 'o':   pszOut = ValueUnion.psz; break;
     351            case 'b':   fCursorFlags = 0; break;
     352            case 'c':   fCursorFlags = RTASN1CURSOR_FLAGS_CER; break;
     353            case 'd':   fCursorFlags = RTASN1CURSOR_FLAGS_DER; break;
     354            case 'V':   return HandleVersion(cArgs, papszArgs);
     355            case 'h':   return HelpExtractExeSignerCert(g_pStdOut, RTSIGNTOOLHELP_FULL);
     356
     357            case VINF_GETOPT_NOT_OPTION:
     358                if (!pszExe)
     359                    pszExe = ValueUnion.psz;
     360                else if (!pszOut)
     361                    pszOut = ValueUnion.psz;
     362                else
     363                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many file arguments: %s", ValueUnion.psz);
     364                break;
     365
     366            default:
     367                return RTGetOptPrintError(ch, &ValueUnion);
     368        }
     369    }
     370    if (!pszExe)
     371        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No executable given.");
     372    if (!pszOut)
     373        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No output file given.");
     374    if (RTPathExists(pszOut))
     375        return RTMsgErrorExit(RTEXITCODE_FAILURE, "The output file '%s' exists.", pszOut);
     376
     377    /*
     378     * Do it.
     379     */
     380    /* Read & decode the PKCS#7 signature. */
     381    SIGNTOOLPKCS7EXE This;
     382    RTEXITCODE rcExit = SignToolPkcs7Exe_InitFromFile(&This, pszExe, cVerbosity, enmLdrArch);
     383    if (rcExit == RTEXITCODE_SUCCESS)
     384    {
     385        /* Find the signing certificate (ASSUMING there's only one signer and that
     386           the certificate used is shipped in the set of certificates). */
     387        rcExit = RTEXITCODE_FAILURE;
     388        if (This.pSignedData->SignerInfos.cItems == 1)
     389        {
     390            PCRTCRPKCS7ISSUERANDSERIALNUMBER pISN = &This.pSignedData->SignerInfos.papItems[0]->IssuerAndSerialNumber;
     391            PCRTCRX509CERTIFICATE pCert;
     392            pCert = RTCrPkcs7SetOfCerts_FindX509ByIssuerAndSerialNumber(&This.pSignedData->Certificates,
     393                                                                        &pISN->Name, &pISN->SerialNumber);
     394            if (pCert)
     395            {
     396                /*
     397                 * Write it out.
     398                 */
     399                RTFILE hFile;
     400                rc = RTFileOpen(&hFile, pszOut, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE);
     401                if (RT_SUCCESS(rc))
     402                {
     403                    uint32_t cbCert = pCert->SeqCore.Asn1Core.cbHdr + pCert->SeqCore.Asn1Core.cb;
     404                    rc = RTFileWrite(hFile, pCert->SeqCore.Asn1Core.uData.pu8 - pCert->SeqCore.Asn1Core.cbHdr,
     405                                     cbCert, NULL);
     406                    if (RT_SUCCESS(rc))
     407                    {
     408                        rc = RTFileClose(hFile);
     409                        if (RT_SUCCESS(rc))
     410                        {
     411                            hFile  = NIL_RTFILE;
     412                            rcExit = RTEXITCODE_SUCCESS;
     413                            RTMsgInfo("Successfully wrote %u bytes to '%s'", cbCert, pszOut);
     414                        }
     415                        else
     416                            RTMsgError("RTFileClose failed: %Rrc", rc);
     417                    }
     418                    else
     419                        RTMsgError("RTFileWrite failed: %Rrc", rc);
     420                    RTFileClose(hFile);
     421                }
     422                else
     423                    RTMsgError("Error opening '%s' for writing: %Rrc", pszOut, rc);
     424            }
     425            else
     426                RTMsgError("Certificate not found.");
     427        }
     428        else
     429            RTMsgError("SignerInfo count: %u", This.pSignedData->SignerInfos.cItems);
     430
     431
     432        /* Delete the signature data. */
     433        SignToolPkcs7Exe_Delete(&This);
     434    }
     435    return rcExit;
     436}
     437
     438
     439/*
     440 * The 'add-nested-exe-signature' command.
     441 */
     442static RTEXITCODE HelpAddNestedExeSignature(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
     443{
     444    RT_NOREF_PV(enmLevel);
     445    RTStrmPrintf(pStrm, "add-nested-exe-signature [-v|--verbose] <destination-exe> <source-exe>\n");
     446    return RTEXITCODE_SUCCESS;
     447}
     448
     449
     450static RTEXITCODE HandleAddNestedExeSignature(int cArgs, char **papszArgs)
     451{
     452    /*
     453     * Parse arguments.
     454     */
     455    static const RTGETOPTDEF s_aOptions[] =
     456    {
     457        { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
     458    };
     459
     460    const char *pszDst = NULL;
     461    const char *pszSrc = NULL;
     462    unsigned    cVerbosity = 0;
     463
     464    RTGETOPTSTATE GetState;
     465    int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
     466    AssertRCReturn(rc, RTEXITCODE_FAILURE);
     467    RTGETOPTUNION ValueUnion;
     468    int ch;
     469    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
     470    {
     471        switch (ch)
     472        {
     473            case 'v':   cVerbosity++; break;
     474            case 'V':   return HandleVersion(cArgs, papszArgs);
     475            case 'h':   return HelpExtractExeSignerCert(g_pStdOut, RTSIGNTOOLHELP_FULL);
     476
     477            case VINF_GETOPT_NOT_OPTION:
     478                if (!pszDst)
     479                    pszDst = ValueUnion.psz;
     480                else if (!pszSrc)
     481                    pszSrc = ValueUnion.psz;
     482                else
     483                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many file arguments: %s", ValueUnion.psz);
     484                break;
     485
     486            default:
     487                return RTGetOptPrintError(ch, &ValueUnion);
     488        }
     489    }
     490    if (!pszDst)
     491        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No destination excutable given.");
     492    if (!pszSrc)
     493        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No source executable file given.");
     494
     495    /*
     496     * Do it.
     497     */
     498    /* Read & decode the source PKCS#7 signature. */
     499    SIGNTOOLPKCS7EXE Src;
     500    RTEXITCODE rcExit = SignToolPkcs7Exe_InitFromFile(&Src, pszSrc, cVerbosity);
     501    if (rcExit == RTEXITCODE_SUCCESS)
     502    {
     503        /* Ditto for the destination PKCS#7 signature. */
     504        SIGNTOOLPKCS7EXE Dst;
     505        RTEXITCODE rcExit = SignToolPkcs7Exe_InitFromFile(&Dst, pszSrc, cVerbosity);
     506        if (rcExit == RTEXITCODE_SUCCESS)
     507        {
     508            /* Add the source to the destination as a nested signature. */
     509            //Src.pSignedData->SignerInfos.paItems
     510
     511
     512            SignToolPkcs7Exe_Delete(&Dst);
     513        }
     514        SignToolPkcs7Exe_Delete(&Src);
     515    }
     516
     517    return rcExit;
     518}
     519
     520#ifndef IPRT_IN_BUILD_TOOL
     521
     522/*
     523 * The 'verify-exe' command.
     524 */
     525static RTEXITCODE HelpVerifyExe(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
     526{
     527    RT_NOREF_PV(enmLevel);
     528    RTStrmPrintf(pStrm,
     529                 "verify-exe [--verbose|--quiet] [--kernel] [--root <root-cert.der>] [--additional <supp-cert.der>]\n"
     530                 "        [--type <win|osx>] <exe1> [exe2 [..]]\n");
     531    return RTEXITCODE_SUCCESS;
     532}
     533
     534typedef struct VERIFYEXESTATE
     535{
     536    RTCRSTORE   hRootStore;
     537    RTCRSTORE   hKernelRootStore;
     538    RTCRSTORE   hAdditionalStore;
     539    bool        fKernel;
     540    int         cVerbose;
     541    enum { kSignType_Windows, kSignType_OSX } enmSignType;
     542    uint64_t    uTimestamp;
     543    RTLDRARCH   enmLdrArch;
     544} VERIFYEXESTATE;
     545
     546# ifdef VBOX
     547/** Certificate store load set.
     548 * Declared outside HandleVerifyExe because of braindead gcc visibility crap. */
     549struct STSTORESET
     550{
     551    RTCRSTORE       hStore;
     552    PCSUPTAENTRY    paTAs;
     553    unsigned        cTAs;
     554};
     555# endif
     556
     557/**
     558 * @callback_method_impl{FNRTCRPKCS7VERIFYCERTCALLBACK,
     559 * Standard code signing.  Use this for Microsoft SPC.}
     560 */
     561static DECLCALLBACK(int) VerifyExecCertVerifyCallback(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags,
     562                                                      void *pvUser, PRTERRINFO pErrInfo)
     563{
     564    VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser;
     565    uint32_t        cPaths = hCertPaths != NIL_RTCRX509CERTPATHS ? RTCrX509CertPathsGetPathCount(hCertPaths) : 0;
     566
     567    /*
     568     * Dump all the paths.
     569     */
     570    if (pState->cVerbose > 0)
     571    {
     572        for (uint32_t iPath = 0; iPath < cPaths; iPath++)
     573        {
     574            RTPrintf("---\n");
     575            RTCrX509CertPathsDumpOne(hCertPaths, iPath, pState->cVerbose, RTStrmDumpPrintfV, g_pStdOut);
     576            *pErrInfo->pszMsg = '\0';
     577        }
     578        RTPrintf("---\n");
     579    }
     580
     581    /*
     582     * Test signing certificates normally doesn't have all the necessary
     583     * features required below.  So, treat them as special cases.
     584     */
     585    if (   hCertPaths == NIL_RTCRX509CERTPATHS
     586        && RTCrX509Name_Compare(&pCert->TbsCertificate.Issuer, &pCert->TbsCertificate.Subject) == 0)
     587    {
     588        RTMsgInfo("Test signed.\n");
     589        return VINF_SUCCESS;
     590    }
     591
     592    if (hCertPaths == NIL_RTCRX509CERTPATHS)
     593        RTMsgInfo("Signed by trusted certificate.\n");
     594
     595    /*
     596     * Standard code signing capabilites required.
     597     */
     598    int rc = RTCrPkcs7VerifyCertCallbackCodeSigning(pCert, hCertPaths, fFlags, NULL, pErrInfo);
     599    if (   RT_SUCCESS(rc)
     600        && (fFlags & RTCRPKCS7VCC_F_SIGNED_DATA))
     601    {
     602        /*
     603         * If kernel signing, a valid certificate path must be anchored by the
     604         * microsoft kernel signing root certificate.  The only alternative is
     605         * test signing.
     606         */
     607        if (pState->fKernel && hCertPaths != NIL_RTCRX509CERTPATHS)
     608        {
     609            uint32_t cFound = 0;
     610            uint32_t cValid = 0;
     611            for (uint32_t iPath = 0; iPath < cPaths; iPath++)
     612            {
     613                bool                            fTrusted;
     614                PCRTCRX509NAME                  pSubject;
     615                PCRTCRX509SUBJECTPUBLICKEYINFO  pPublicKeyInfo;
     616                int                             rcVerify;
     617                rc = RTCrX509CertPathsQueryPathInfo(hCertPaths, iPath, &fTrusted, NULL /*pcNodes*/, &pSubject, &pPublicKeyInfo,
     618                                                    NULL, NULL /*pCertCtx*/, &rcVerify);
     619                AssertRCBreak(rc);
     620
     621                if (RT_SUCCESS(rcVerify))
     622                {
     623                    Assert(fTrusted);
     624                    cValid++;
     625
     626                    /* Search the kernel signing root store for a matching anchor. */
     627                    RTCRSTORECERTSEARCH Search;
     628                    rc = RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280(pState->hKernelRootStore, pSubject, &Search);
     629                    AssertRCBreak(rc);
     630                    PCRTCRCERTCTX pCertCtx;
     631                    while ((pCertCtx = RTCrStoreCertSearchNext(pState->hKernelRootStore, &Search)) != NULL)
     632                    {
     633                        PCRTCRX509SUBJECTPUBLICKEYINFO pPubKeyInfo;
     634                        if (pCertCtx->pCert)
     635                            pPubKeyInfo = &pCertCtx->pCert->TbsCertificate.SubjectPublicKeyInfo;
     636                        else if (pCertCtx->pTaInfo)
     637                            pPubKeyInfo = &pCertCtx->pTaInfo->PubKey;
     638                        else
     639                            pPubKeyInfo = NULL;
     640                        if (RTCrX509SubjectPublicKeyInfo_Compare(pPubKeyInfo, pPublicKeyInfo) == 0)
     641                            cFound++;
     642                        RTCrCertCtxRelease(pCertCtx);
     643                    }
     644
     645                    int rc2 = RTCrStoreCertSearchDestroy(pState->hKernelRootStore, &Search); AssertRC(rc2);
     646                }
     647            }
     648            if (RT_SUCCESS(rc) && cFound == 0)
     649                rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "Not valid kernel code signature.");
     650            if (RT_SUCCESS(rc) && cValid != 2)
     651                RTMsgWarning("%u valid paths, expected 2", cValid);
     652        }
     653    }
     654
     655    return rc;
     656}
     657
     658
     659/** @callback_method_impl{FNRTLDRVALIDATESIGNEDDATA}  */
     660static DECLCALLBACK(int) VerifyExeCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
     661                                           void const *pvSignature, size_t cbSignature,
     662                                           PRTERRINFO pErrInfo, void *pvUser)
     663{
     664    VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser;
     665    RT_NOREF_PV(hLdrMod); RT_NOREF_PV(cbSignature);
     666
     667    switch (enmSignature)
     668    {
     669        case RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA:
     670        {
     671            PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pvSignature;
     672
     673            RTTIMESPEC ValidationTime;
     674            RTTimeSpecSetSeconds(&ValidationTime, pState->uTimestamp);
     675
     676            /*
     677             * Dump the signed data if so requested.
     678             */
     679            if (pState->cVerbose)
     680                RTAsn1Dump(&pContentInfo->SeqCore.Asn1Core, 0, 0, RTStrmDumpPrintfV, g_pStdOut);
     681
     682
     683            /*
     684             * Do the actual verification.  Will have to modify this so it takes
     685             * the authenticode policies into account.
     686             */
     687            return RTCrPkcs7VerifySignedData(pContentInfo,
     688                                             RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY
     689                                             | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
     690                                             | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT,
     691                                             pState->hAdditionalStore, pState->hRootStore, &ValidationTime,
     692                                             VerifyExecCertVerifyCallback, pState, pErrInfo);
     693        }
     694
     695        default:
     696            return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", enmSignature);
     697    }
     698}
     699
     700/** Worker for HandleVerifyExe. */
     701static RTEXITCODE HandleVerifyExeWorker(VERIFYEXESTATE *pState, const char *pszFilename, PRTERRINFOSTATIC pStaticErrInfo)
     702{
     703    /*
     704     * Open the executable image and verify it.
     705     */
     706    RTLDRMOD hLdrMod;
     707    int rc = RTLdrOpen(pszFilename, RTLDR_O_FOR_VALIDATION, pState->enmLdrArch, &hLdrMod);
     708    if (RT_FAILURE(rc))
     709        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszFilename, rc);
     710
     711
     712    rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &pState->uTimestamp, sizeof(pState->uTimestamp));
     713    if (RT_SUCCESS(rc))
     714    {
     715        rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
     716        if (RT_SUCCESS(rc))
     717            RTMsgInfo("'%s' is valid.\n", pszFilename);
     718        else if (rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME)
     719        {
     720            RTTIMESPEC Now;
     721            pState->uTimestamp = RTTimeSpecGetSeconds(RTTimeNow(&Now));
     722            rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
     723            if (RT_SUCCESS(rc))
     724                RTMsgInfo("'%s' is valid now, but not at link time.\n", pszFilename);
     725        }
     726        if (RT_FAILURE(rc))
     727            RTMsgError("RTLdrVerifySignature failed on '%s': %Rrc - %s\n", pszFilename, rc, pStaticErrInfo->szMsg);
     728    }
     729    else
     730        RTMsgError("RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on '%s': %Rrc\n", pszFilename, rc);
     731
     732    int rc2 = RTLdrClose(hLdrMod);
     733    if (RT_FAILURE(rc2))
     734        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTLdrClose failed: %Rrc\n", rc2);
     735    if (RT_FAILURE(rc))
     736        return rc != VERR_LDRVI_NOT_SIGNED ? RTEXITCODE_FAILURE : RTEXITCODE_SKIPPED;
     737
     738    return RTEXITCODE_SUCCESS;
     739}
     740
     741
     742static RTEXITCODE HandleVerifyExe(int cArgs, char **papszArgs)
     743{
     744    RTERRINFOSTATIC StaticErrInfo;
     745
     746    /* Note! This code does not try to clean up the crypto stores on failure.
     747             This is intentional as the code is only expected to be used in a
     748             one-command-per-process environment where we do exit() upon
     749             returning from this function. */
     750
     751    /*
     752     * Parse arguments.
     753     */
     754    static const RTGETOPTDEF s_aOptions[] =
     755    {
     756        { "--kernel",       'k', RTGETOPT_REQ_NOTHING },
     757        { "--root",         'r', RTGETOPT_REQ_STRING },
     758        { "--additional",   'a', RTGETOPT_REQ_STRING },
     759        { "--add",          'a', RTGETOPT_REQ_STRING },
     760        { "--type",         't', RTGETOPT_REQ_STRING },
     761        { "--verbose",      'v', RTGETOPT_REQ_NOTHING },
     762        { "--quiet",        'q', RTGETOPT_REQ_NOTHING },
     763    };
     764
     765    VERIFYEXESTATE State =
     766    {
     767        NIL_RTCRSTORE, NIL_RTCRSTORE, NIL_RTCRSTORE, false, false,
     768        VERIFYEXESTATE::kSignType_Windows, 0, RTLDRARCH_WHATEVER
     769    };
     770    int rc = RTCrStoreCreateInMem(&State.hRootStore, 0);
     771    if (RT_SUCCESS(rc))
     772        rc = RTCrStoreCreateInMem(&State.hKernelRootStore, 0);
     773    if (RT_SUCCESS(rc))
     774        rc = RTCrStoreCreateInMem(&State.hAdditionalStore, 0);
     775    if (RT_FAILURE(rc))
     776        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error creating in-memory certificate store: %Rrc", rc);
     777
     778    RTGETOPTSTATE GetState;
     779    rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
     780    AssertRCReturn(rc, RTEXITCODE_FAILURE);
     781    RTGETOPTUNION ValueUnion;
     782    int ch;
     783    while ((ch = RTGetOpt(&GetState, &ValueUnion)) && ch != VINF_GETOPT_NOT_OPTION)
     784    {
     785        switch (ch)
     786        {
     787            case 'r': case 'a':
     788                rc = RTCrStoreCertAddFromFile(ch == 'r' ? State.hRootStore : State.hAdditionalStore,
     789                                              RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR,
     790                                              ValueUnion.psz, RTErrInfoInitStatic(&StaticErrInfo));
     791                if (RT_FAILURE(rc))
     792                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error loading certificate '%s': %Rrc - %s",
     793                                          ValueUnion.psz, rc, StaticErrInfo.szMsg);
     794                if (RTErrInfoIsSet(&StaticErrInfo.Core))
     795                    RTMsgWarning("Warnings loading certificate '%s': %s", ValueUnion.psz, StaticErrInfo.szMsg);
     796                break;
     797
     798            case 't':
     799                if (!strcmp(ValueUnion.psz, "win") || !strcmp(ValueUnion.psz, "windows"))
     800                    State.enmSignType = VERIFYEXESTATE::kSignType_Windows;
     801                else if (!strcmp(ValueUnion.psz, "osx") || !strcmp(ValueUnion.psz, "apple"))
     802                    State.enmSignType = VERIFYEXESTATE::kSignType_OSX;
     803                else
     804                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown signing type: '%s'", ValueUnion.psz);
     805                break;
     806
     807            case 'k': State.fKernel = true; break;
     808            case 'v': State.cVerbose++; break;
     809            case 'q': State.cVerbose = 0; break;
     810            case 'V': return HandleVersion(cArgs, papszArgs);
     811            case 'h': return HelpVerifyExe(g_pStdOut, RTSIGNTOOLHELP_FULL);
     812            default:  return RTGetOptPrintError(ch, &ValueUnion);
     813        }
     814    }
     815    if (ch != VINF_GETOPT_NOT_OPTION)
     816        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No executable given.");
     817
     818    /*
     819     * Populate the certificate stores according to the signing type.
     820     */
     821#ifdef VBOX
     822    unsigned          cSets = 0;
     823    struct STSTORESET aSets[6];
     824#endif
     825
     826    switch (State.enmSignType)
     827    {
     828        case VERIFYEXESTATE::kSignType_Windows:
     829#ifdef VBOX
     830            aSets[cSets].hStore  = State.hRootStore;
     831            aSets[cSets].paTAs   = g_aSUPTimestampTAs;
     832            aSets[cSets].cTAs    = g_cSUPTimestampTAs;
     833            cSets++;
     834            aSets[cSets].hStore  = State.hRootStore;
     835            aSets[cSets].paTAs   = g_aSUPSpcRootTAs;
     836            aSets[cSets].cTAs    = g_cSUPSpcRootTAs;
     837            cSets++;
     838            aSets[cSets].hStore  = State.hRootStore;
     839            aSets[cSets].paTAs   = g_aSUPNtKernelRootTAs;
     840            aSets[cSets].cTAs    = g_cSUPNtKernelRootTAs;
     841            cSets++;
     842            aSets[cSets].hStore  = State.hKernelRootStore;
     843            aSets[cSets].paTAs   = g_aSUPNtKernelRootTAs;
     844            aSets[cSets].cTAs    = g_cSUPNtKernelRootTAs;
     845            cSets++;
     846#endif
     847            break;
     848
     849        case VERIFYEXESTATE::kSignType_OSX:
     850            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Mac OS X executable signing is not implemented.");
     851    }
     852
     853#ifdef VBOX
     854    for (unsigned i = 0; i < cSets; i++)
     855        for (unsigned j = 0; j < aSets[i].cTAs; j++)
     856        {
     857            rc = RTCrStoreCertAddEncoded(aSets[i].hStore, RTCRCERTCTX_F_ENC_TAF_DER, aSets[i].paTAs[j].pch,
     858                                         aSets[i].paTAs[j].cb, RTErrInfoInitStatic(&StaticErrInfo));
     859            if (RT_FAILURE(rc))
     860                return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTCrStoreCertAddEncoded failed (%u/%u): %s",
     861                                      i, j, StaticErrInfo.szMsg);
     862        }
     863#endif
     864
     865    /*
     866     * Do it.
     867     */
     868    RTEXITCODE rcExit;
     869    for (;;)
     870    {
     871        rcExit = HandleVerifyExeWorker(&State, ValueUnion.psz, &StaticErrInfo);
     872        if (rcExit != RTEXITCODE_SUCCESS)
     873            break;
     874
     875        /*
     876         * Next file
     877         */
     878        ch = RTGetOpt(&GetState, &ValueUnion);
     879        if (ch == 0)
     880            break;
     881        if (ch != VINF_GETOPT_NOT_OPTION)
     882        {
     883            rcExit = RTGetOptPrintError(ch, &ValueUnion);
     884            break;
     885        }
     886    }
     887
     888    /*
     889     * Clean up.
     890     */
     891    uint32_t cRefs;
     892    cRefs = RTCrStoreRelease(State.hRootStore);       Assert(cRefs == 0);
     893    cRefs = RTCrStoreRelease(State.hKernelRootStore); Assert(cRefs == 0);
     894    cRefs = RTCrStoreRelease(State.hAdditionalStore); Assert(cRefs == 0);
     895
     896    return rcExit;
     897}
     898
     899#endif /* !IPRT_IN_BUILD_TOOL */
     900#ifndef IPRT_IN_BUILD_TOOL
     901
     902/*
     903 * The 'show-exe' command.
     904 */
     905static RTEXITCODE HelpShowExe(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
     906{
     907    RT_NOREF_PV(enmLevel);
     908    RTStrmPrintf(pStrm,
     909                 "show-exe [--verbose|-v] [--quiet|-q] <exe1> [exe2 [..]]\n");
     910    return RTEXITCODE_SUCCESS;
     911}
     912
     913
     914/**
     915 * Decodes the PKCS #7 blob pointed to by pThis->pbBuf.
     916 *
     917 * @returns IPRT status code.
     918 * @param   pThis               The show exe instance data.
     919 */
     920static int HandleShowExeWorkerPkcs7Decode(PSHOWEXEPKCS7 pThis)
     921{
     922    RTERRINFOSTATIC     ErrInfo;
     923    RTASN1CURSORPRIMARY PrimaryCursor;
     924    RTAsn1CursorInitPrimary(&PrimaryCursor, pThis->pbBuf, (uint32_t)pThis->cbBuf, RTErrInfoInitStatic(&ErrInfo),
     925                            &g_RTAsn1DefaultAllocator, 0, "WinCert");
     926
     927    int rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &pThis->ContentInfo, "CI");
     928    if (RT_SUCCESS(rc))
     929    {
     930        if (RTCrPkcs7ContentInfo_IsSignedData(&pThis->ContentInfo))
     931        {
     932            pThis->pSignedData = pThis->ContentInfo.u.pSignedData;
     933
     934            /*
     935             * Decode the authenticode bits.
     936             */
     937            if (!strcmp(pThis->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID))
     938            {
     939                pThis->pIndData = pThis->pSignedData->ContentInfo.u.pIndirectDataContent;
     940                Assert(pThis->pIndData);
     941
     942                /*
     943                 * Check that things add up.
     944                 */
     945                rc = RTCrPkcs7SignedData_CheckSanity(pThis->pSignedData,
     946                                                     RTCRPKCS7SIGNEDDATA_SANITY_F_AUTHENTICODE
     947                                                     | RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH
     948                                                     | RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT,
     949                                                     RTErrInfoInitStatic(&ErrInfo), "SD");
     950                if (RT_FAILURE(rc))
     951                    RTMsgError("PKCS#7 sanity check failed for '%s': %Rrc - %s\n", pThis->pszFilename, rc, ErrInfo.szMsg);
     952                if (RT_SUCCESS(rc))
     953                {
     954                    rc = RTCrSpcIndirectDataContent_CheckSanityEx(pThis->pIndData,
     955                                                                  pThis->pSignedData,
     956                                                                  RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH,
     957                                                                  RTErrInfoInitStatic(&ErrInfo));
     958                    if (RT_FAILURE(rc))
     959                        RTMsgError("SPC indirect data content sanity check failed for '%s': %Rrc - %s\n",
     960                                   pThis->pszFilename, rc, ErrInfo.szMsg);
     961                }
     962            }
     963            else
     964                RTMsgError("Unexpected the signed content in '%s': %s (expected %s)", pThis->pszFilename,
     965                           pThis->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID);
     966        }
     967        else
     968            RTMsgError("PKCS#7 content is inside '%s' is not 'signedData': %s\n",
     969                       pThis->pszFilename, pThis->ContentInfo.ContentType.szObjId);
     970    }
     971    else
     972        RTMsgError("RTCrPkcs7ContentInfo_DecodeAsn1 failed on '%s': %Rrc - %s\n", pThis->pszFilename, rc, ErrInfo.szMsg);
     973    return rc;
     974}
     975
     976
     977/**
    726978 * Display an object ID.
    727979 *
     
    8021054                else
    8031055                    RTPrintf("%s ObjId[%u]: ", pThis->szPrefix, i);
    804                 HandleShowExeWorkerDisplayObjIdSimple(pThis, &pAttr->uValues.pObjIds->paItems[i], "\n");
     1056                HandleShowExeWorkerDisplayObjIdSimple(pThis, pAttr->uValues.pObjIds->papItems[i], "\n");
    8051057            }
    8061058            break;
     
    8121064            for (unsigned i = 0; i < pAttr->uValues.pObjIdSeqs->cItems; i++)
    8131065            {
    814                 uint32_t const cObjIds = pAttr->uValues.pObjIdSeqs->paItems[i].cItems;
     1066                uint32_t const cObjIds = pAttr->uValues.pObjIdSeqs->papItems[i]->cItems;
    8151067                for (unsigned j = 0; j < cObjIds; j++)
    8161068                {
     
    8211073                    if (cObjIds != 1)
    8221074                        RTPrintf(" ObjId[%u]: ", j);
    823                     HandleShowExeWorkerDisplayObjIdSimple(pThis, &pAttr->uValues.pObjIdSeqs->paItems[i].paItems[i], "\n");
     1075                    HandleShowExeWorkerDisplayObjIdSimple(pThis, pAttr->uValues.pObjIdSeqs->papItems[i]->papItems[i], "\n");
    8241076                }
    8251077            }
     
    8321084            for (unsigned i = 0; i < pAttr->uValues.pOctetStrings->cItems; i++)
    8331085            {
    834                 PCRTASN1OCTETSTRING pOctetString = &pAttr->uValues.pOctetStrings->paItems[i];
     1086                PCRTASN1OCTETSTRING pOctetString = pAttr->uValues.pOctetStrings->papItems[i];
    8351087                uint32_t cbContent = pOctetString->Asn1Core.cb;
    8361088                if (cbContent > 0 && (cbContent <= 128 || pThis->cVerbosity >= 2))
     
    8791131                    offPrefix2 += RTStrPrintf(&pThis->szPrefix[offPrefix], sizeof(pThis->szPrefix) - offPrefix, "  ");
    8801132                //    offPrefix2 += RTStrPrintf(&pThis->szPrefix[offPrefix], sizeof(pThis->szPrefix) - offPrefix, "NestedSig: ", i);
    881                 PCRTCRPKCS7CONTENTINFO pContentInfo = &pAttr->uValues.pContentInfos->paItems[i];
     1133                PCRTCRPKCS7CONTENTINFO pContentInfo = pAttr->uValues.pContentInfos->papItems[i];
    8821134                int rc2;
    8831135                if (RTCrPkcs7ContentInfo_IsSignedData(pContentInfo))
     
    9601212                                                "MonikerAttrib[%u]: ", i);
    9611213
    962                                     switch (pData->paItems[i].enmType)
     1214                                    switch (pData->papItems[i]->enmType)
    9631215                                    {
    9641216                                        case RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V2:
    9651217                                        case RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V1:
    9661218                                        {
    967                                             PCRTCRSPCSERIALIZEDPAGEHASHES pPgHashes = pData->paItems[i].u.pPageHashes;
    968                                             uint32_t const cbHash =    pData->paItems[i].enmType
     1219                                            PCRTCRSPCSERIALIZEDPAGEHASHES pPgHashes = pData->papItems[i]->u.pPageHashes;
     1220                                            uint32_t const cbHash =    pData->papItems[i]->enmType
    9691221                                                                    == RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V1
    9701222                                                                  ? 160/8 /*SHA-1*/ : 256/8 /*SHA-256*/;
     
    9721224
    9731225                                            RTPrintf("%sPage Hashes version %u - %u pages (%u bytes total)\n", pThis->szPrefix,
    974                                                         pData->paItems[i].enmType
     1226                                                        pData->papItems[i]->enmType
    9751227                                                     == RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V1 ? 1 : 2,
    9761228                                                     cPages, pPgHashes->RawData.Asn1Core.cb);
     
    10061258
    10071259                                        case RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_UNKNOWN:
    1008                                             HandleShowExeWorkerDisplayObjIdSimple(pThis, &pData->paItems[i].Type, "\n");
     1260                                            HandleShowExeWorkerDisplayObjIdSimple(pThis, &pData->papItems[i]->Type, "\n");
    10091261                                            break;
    10101262                                        case RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_NOT_PRESENT:
     
    10121264                                            break;
    10131265                                        default:
    1014                                             RTPrintf("%senmType=%d!\n", pThis->szPrefix, pData->paItems[i].enmType);
     1266                                            RTPrintf("%senmType=%d!\n", pThis->szPrefix, pData->papItems[i]->enmType);
    10151267                                            break;
    10161268                                    }
     
    10991351    for (unsigned i = 0; i < pSignedData->DigestAlgorithms.cItems; i++)
    11001352    {
    1101         PCRTCRX509ALGORITHMIDENTIFIER pAlgoId = &pSignedData->DigestAlgorithms.paItems[i];
     1353        PCRTCRX509ALGORITHMIDENTIFIER pAlgoId = pSignedData->DigestAlgorithms.papItems[i];
    11021354        const char *pszDigestType = RTCrDigestTypeToName(RTCrX509AlgorithmIdentifier_QueryDigestType(pAlgoId));
    11031355        if (!pszDigestType)
     
    11211373    }
    11221374    else
    1123         RTPrintf("%s     ContentType: %s\n", pThis->szPrefix, pSignedData->ContentInfo.ContentType.szObjId);
     1375        HandleShowExeWorkerDisplayObjId(pThis, &pSignedData->ContentInfo.ContentType, "     ContentType: ", " - not implemented.\n");
    11241376
    11251377    /*
    11261378     * Display certificates (Certificates).
    11271379     */
     1380    if (pSignedData->Certificates.cItems > 0)
     1381        RTPrintf("%s    Certificates: %u\n", pThis->szPrefix, pSignedData->Certificates.cItems);
     1382        /** @todo display certificates. */
     1383
     1384    if (pSignedData->Crls.cb > 0)
     1385        RTPrintf("%s            CRLs: %u bytes\n", pThis->szPrefix, pSignedData->Crls.cb);
    11281386
    11291387    /*
     
    11341392    for (unsigned i = 0; i < cSigInfos; i++)
    11351393    {
    1136         PRTCRPKCS7SIGNERINFO pSigInfo = &pSignedData->SignerInfos.paItems[i];
     1394        PRTCRPKCS7SIGNERINFO pSigInfo = pSignedData->SignerInfos.papItems[i];
    11371395        size_t offPrefix2 = offPrefix;
    11381396        if (cSigInfos != 1)
     
    11701428            for (unsigned j = 0; j < pSigInfo->AuthenticatedAttributes.cItems; j++)
    11711429            {
    1172                 PRTCRPKCS7ATTRIBUTE pAttr = &pSigInfo->AuthenticatedAttributes.paItems[j];
     1430                PRTCRPKCS7ATTRIBUTE pAttr = pSigInfo->AuthenticatedAttributes.papItems[j];
    11731431                size_t offPrefix3 = offPrefix2 + RTStrPrintf(&pThis->szPrefix[offPrefix2], sizeof(pThis->szPrefix) - offPrefix2,
    11741432                                                             "              AuthAttrib[%u]: ", j);
     
    11861444            for (unsigned j = 0; j < pSigInfo->UnauthenticatedAttributes.cItems; j++)
    11871445            {
    1188                 PRTCRPKCS7ATTRIBUTE pAttr = &pSigInfo->UnauthenticatedAttributes.paItems[j];
     1446                PRTCRPKCS7ATTRIBUTE pAttr = pSigInfo->UnauthenticatedAttributes.papItems[j];
    11891447                size_t offPrefix3 = offPrefix2 + RTStrPrintf(&pThis->szPrefix[offPrefix2], sizeof(pThis->szPrefix) - offPrefix2,
    11901448                                                             "            UnauthAttrib[%u]: ", j);
     
    12121470static RTEXITCODE HandleShowExeWorker(const char *pszFilename, unsigned cVerbosity, RTLDRARCH enmLdrArch)
    12131471{
    1214     /*
    1215      * Open the image and check if it's signed.
    1216      */
    1217     RTLDRMOD hLdrMod;
    1218     int rc = RTLdrOpen(pszFilename, RTLDR_O_FOR_VALIDATION, enmLdrArch, &hLdrMod);
    1219     if (RT_FAILURE(rc))
    1220         return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszFilename, rc);
    1221 
    1222     bool fIsSigned = false;
    1223     rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_IS_SIGNED, &fIsSigned, sizeof(fIsSigned));
    1224     if (RT_SUCCESS(rc) && fIsSigned)
    1225     {
    1226         /*
    1227          * Query the PKCS#7 data (assuming M$ style signing) and hand it to a worker.
    1228          */
    1229         size_t cbActual = 0;
    1230         size_t cbBuf = _64K;
    1231         void  *pvBuf = RTMemAllocZ(cbBuf);
    1232         if (pvBuf)
    1233         {
    1234             rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbActual);
    1235             if (rc == VERR_BUFFER_OVERFLOW)
    1236             {
    1237                 RTMemFree(pvBuf);
    1238                 cbBuf = cbActual;
    1239                 pvBuf = RTMemAllocZ(cbActual);
    1240                 if (pvBuf)
    1241                     rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbActual);
    1242                 else
    1243                     rc = VERR_NO_MEMORY;
    1244             }
    1245         }
    1246         else
    1247             rc = VERR_NO_MEMORY;
    1248         if (RT_SUCCESS(rc))
    1249         {
    1250             SHOWEXEPKCS7 This;
    1251             RT_ZERO(This);
    1252             This.pbBuf       = (uint8_t const *)pvBuf;
    1253             This.cbBuf       = cbActual;
    1254             This.cVerbosity  = cVerbosity;
    1255             This.pszFilename = pszFilename;
    1256             This.hLdrMod     = hLdrMod;
    1257             rc = HandleShowExeWorkerPkcs7Decode(&This);
    1258             if (RT_SUCCESS(rc))
    1259                 rc = HandleShowExeWorkerPkcs7Display(&This, This.pSignedData, 0);
    1260             RTCrPkcs7ContentInfo_Delete(&This.ContentInfo);
    1261         }
    1262         else
    1263             RTMsgError("RTLdrQueryPropEx/RTLDRPROP_PKCS7_SIGNED_DATA failed on '%s': %Rrc\n", pszFilename, rc);
    1264         RTMemFree(pvBuf);
    1265     }
    1266     else if (RT_SUCCESS(rc))
    1267         RTMsgInfo("'%s': not signed\n", pszFilename);
    1268     else
    1269         RTMsgError("RTLdrQueryProp/RTLDRPROP_IS_SIGNED failed on '%s': %Rrc\n", pszFilename, rc);
    1270 
    1271     int rc2 = RTLdrClose(hLdrMod);
    1272     if (RT_FAILURE(rc2))
    1273         return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTLdrClose failed: %Rrc\n", rc2);
    1274     if (RT_FAILURE(rc))
    1275         return rc != VERR_LDRVI_NOT_SIGNED ? RTEXITCODE_FAILURE : RTEXITCODE_SKIPPED;
    1276 
    1277     return RTEXITCODE_SUCCESS;
     1472    SHOWEXEPKCS7 This;
     1473    RT_ZERO(This);
     1474    This.cVerbosity = cVerbosity;
     1475
     1476    RTEXITCODE rcExit = SignToolPkcs7Exe_InitFromFile(&This, pszFilename, cVerbosity, enmLdrArch);
     1477    if (rcExit == RTEXITCODE_SUCCESS)
     1478    {
     1479        int rc = HandleShowExeWorkerPkcs7Display(&This, This.pSignedData, 0);
     1480        if (RT_FAILURE(rc))
     1481            rcExit = RTEXITCODE_FAILURE;
     1482        SignToolPkcs7Exe_Delete(&This);
     1483    }
     1484
     1485    return rcExit;
    12781486}
    12791487
     
    15991807    { "extract-exe-signer-cert",        HandleExtractExeSignerCert,         HelpExtractExeSignerCert },
    16001808#ifndef IPRT_IN_BUILD_TOOL
     1809    { "add-nested-exe-signature",       HandleAddNestedExeSignature,        HelpAddNestedExeSignature },
    16011810    { "verify-exe",                     HandleVerifyExe,                    HelpVerifyExe },
    16021811    { "show-exe",                       HandleShowExe,                      HelpShowExe },
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