Index: /trunk/include/iprt/asn1-generator-pass.h
===================================================================
--- /trunk/include/iprt/asn1-generator-pass.h	(revision 64882)
+++ /trunk/include/iprt/asn1-generator-pass.h	(revision 64883)
@@ -372,5 +372,5 @@
 # define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, a_OfApi, a_OfMember) \
     RTASN1TMPL_BEGIN_COMMON(); \
-    RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
+    RTAsn1MemInitArrayAllocation(&pThis->Allocation, pAllocator, sizeof(a_ItemType)); \
     int rc = RT_CONCAT(a_OfApi,_Init)(&pThis->a_OfMember, &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable)); \
     if (RT_FAILURE(rc)) \
@@ -555,5 +555,5 @@
         pCursor = &ThisCursor; \
         pThis->a_OfMember.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable); \
-        RTAsn1CursorInitAllocation(pCursor, &pThis->Allocation); \
+        RTAsn1CursorInitArrayAllocation(pCursor, &pThis->Allocation, sizeof(a_ItemType)); \
         \
         uint32_t i = 0; \
@@ -561,12 +561,8 @@
                && RT_SUCCESS(rc)) \
         { \
-            rc = RTAsn1MemGrowArray(&pThis->Allocation, \
-                                    (void **)&pThis->paItems, \
-                                    sizeof(pThis->paItems[0]), \
-                                    i, \
-                                    i + 1); \
+            rc = RTAsn1MemResizeArray(&pThis->Allocation, (void ***)&pThis->papItems, i, i + 1); \
             if (RT_SUCCESS(rc)) \
             { \
-                rc = RT_CONCAT(a_ItemApi,_DecodeAsn1)(pCursor, 0, &pThis->paItems[i], "paItems[#]"); \
+                rc = RT_CONCAT(a_ItemApi,_DecodeAsn1)(pCursor, 0, pThis->papItems[i], "papItems[#]"); \
                 if (RT_SUCCESS(rc)) \
                 { \
@@ -663,5 +659,5 @@
     RTASN1TMPL_BEGIN_COMMON(); \
     for (uint32_t i = 0; i < pThis->cItems && rc == VINF_SUCCESS; i++) \
-        rc = pfnCallback(RT_CONCAT(a_ItemApi,_GetAsn1Core)(&pThis->paItems[i]), "paItems[#]", uDepth, pvUser); \
+        rc = pfnCallback(RT_CONCAT(a_ItemApi,_GetAsn1Core)(pThis->papItems[i]), "papItems[#]", uDepth, pvUser); \
     RTASN1TMPL_END_COMMON()
 # define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
@@ -773,9 +769,9 @@
     if (RT_SUCCESS(rc)) \
     { \
-        RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
+        RTAsn1MemInitArrayAllocation(&pThis->Allocation, pAllocator, sizeof(a_ItemType)); \
         uint32_t const cItems = pSrc->cItems; \
         if (cItems > 0) \
         { \
-            rc = RTAsn1MemGrowArray(&pThis->Allocation, (void **)&pThis->paItems, sizeof(pThis->paItems[0]), 0, cItems); \
+            rc = RTAsn1MemResizeArray(&pThis->Allocation, (void ***)&pThis->papItems, 0, cItems); \
             if (RT_SUCCESS(rc)) \
             { \
@@ -783,5 +779,5 @@
                 while (i < cItems) \
                 { \
-                    rc = RT_CONCAT(a_ItemApi,_Clone)(&pThis->paItems[i], &pSrc->paItems[i], pAllocator); \
+                    rc = RT_CONCAT(a_ItemApi,_Clone)(pThis->papItems[i], pSrc->papItems[i], pAllocator); \
                     if (RT_SUCCESS(rc)) \
                         pThis->cItems = ++i; \
@@ -990,5 +986,5 @@
     if (cItems == pRight->cItems) \
         for (uint32_t i = 0; iDiff == 0 && i < cItems; i++) \
-            iDiff = RT_CONCAT(a_ItemApi,_Compare)(&pLeft->paItems[i], &pRight->paItems[i]); \
+            iDiff = RT_CONCAT(a_ItemApi,_Compare)(pLeft->papItems[i], pRight->papItems[i]); \
     else \
         iDiff = cItems < pRight->cItems ? -1 : 1; \
@@ -1135,6 +1131,6 @@
     RTASN1TMPL_BEGIN_COMMON(); \
     for (uint32_t i = 0; RT_SUCCESS(rc) && i < pThis->cItems; i++) \
-        rc = RT_CONCAT(a_ItemApi,_CheckSanity)(&pThis->paItems[i], fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
-                                               pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::paItems[#]"); \
+        rc = RT_CONCAT(a_ItemApi,_CheckSanity)(pThis->papItems[i], fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
+                                               pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::papItems[#]"); \
     if (RT_SUCCESS(rc)) { RTASN1TMPL_SET_SEQ_EXEC_CHECK_SANITY(); } \
     RTASN1TMPL_END_COMMON()
@@ -1269,7 +1265,8 @@
     uint32_t i = pThis->cItems; \
     while (i-- > 0) \
-        RT_CONCAT(a_ItemApi,_Delete)(&pThis->paItems[i]); \
-    RTAsn1MemFree(&pThis->Allocation, pThis->paItems); \
-    pThis->paItems = NULL; \
+        RT_CONCAT(a_ItemApi,_Delete)(pThis->papItems[i]); \
+    RTAsn1MemFreeArray(&pThis->Allocation, (void **)pThis->papItems); \
+    pThis->papItems = NULL; \
+    pThis->cItems   = 0; \
     RTASN1TMPL_END_COMMON()
 # define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
Index: /trunk/include/iprt/asn1.h
===================================================================
--- /trunk/include/iprt/asn1.h	(revision 64882)
+++ /trunk/include/iprt/asn1.h	(revision 64883)
@@ -43,4 +43,6 @@
 /** Pointer to ASN.1 allocation information. */
 typedef struct RTASN1ALLOCATION *PRTASN1ALLOCATION;
+/** Pointer to ASN.1 array allocation information. */
+typedef struct RTASN1ARRAYALLOCATION *PRTASN1ARRAYALLOCATION;
 /** Pointer to a ASN.1 byte decoder cursor. */
 typedef struct RTASN1CURSOR *PRTASN1CURSOR;
@@ -101,4 +103,47 @@
     DECLCALLBACKMEMBER(int, pfnRealloc)(struct RTASN1ALLOCATORVTABLE const *pThis, PRTASN1ALLOCATION pAllocation,
                                         void *pvOld, void **ppvNew, size_t cbNew);
+
+    /**
+     * Frees an array allocation (the array an all instances in it).
+     *
+     * @returns IPRT status code.
+     * @param   pThis           Pointer to the vtable structure.
+     * @param   pAllocation     Pointer to the allocation info structure.
+     * @param   papvArray       Pointer to the pointer array to be freed.  Not NULL.
+     */
+    DECLCALLBACKMEMBER(void, pfnFreeArray)(struct RTASN1ALLOCATORVTABLE const *pThis, PRTASN1ARRAYALLOCATION pAllocation,
+                                           void **papvArray);
+    /**
+     * Grows the array to at least @a cMinEntries.
+     *
+     * The entries are initalized with ZEROs.
+     *
+     * @returns IPRT status code.
+     * @param   pThis           Pointer to the vtable structure.
+     * @param   pAllocation     Pointer to the allocation info structure.
+     * @param   ppapvArray      Pointer to the pointer to the array to be grown (or
+     *                          allocated).
+     * @param   cMinEntries     The minimum number of entries (array size and
+     *                          instantiated entries) that must be available
+     *                          on successful return.
+     */
+    DECLCALLBACKMEMBER(int, pfnGrowArray)(struct RTASN1ALLOCATORVTABLE const *pThis, PRTASN1ARRAYALLOCATION pAllocation,
+                                          void ***ppapvArray, uint32_t cMinEntries);
+    /**
+     * Shrinks the array (depends on allocator policy).
+     *
+     * If memory isn't freed, the implementation must fill the entries being
+     * shredded with ZEROs so the growth optimizations in RTAsn1MemResizeArray
+     * returns ZEROed entries.
+     *
+     * @returns IPRT status code.
+     * @param   pThis           Pointer to the vtable structure.
+     * @param   pAllocation     Pointer to the allocation info structure.
+     * @param   ppapvArray      Pointer to the pointer to the array to shrunk.
+     * @param   cNew            The new entry count.
+     * @param   cCurrent        The new entry count.
+     */
+    DECLCALLBACKMEMBER(void, pfnShrinkArray)(struct RTASN1ALLOCATORVTABLE const *pThis, PRTASN1ARRAYALLOCATION pAllocation,
+                                             void ***ppapvArray, uint32_t cNew, uint32_t cCurrent);
 } RTASN1ALLOCATORVTABLE;
 /** Pointer to an ASN.1 allocator vtable. */
@@ -131,18 +176,27 @@
 
 /**
- * Grow an array by zero initialized memory.
- *
- * @returns IPRT status code.
- * @param   pAllocation The allocation record (initialized by
- *                      RTAsn1CursorInitAllocation or similar).
- * @param   ppvArray    Pointer to the variable pointing to the array.  This is
- *                      both input and output. Remains valid on failure.
- * @param   cbEntry     The size of an array entry.
- * @param   cCurrent    The current entry count.  (Relevant for zero
- *                      initialization of the new entries.)
- * @param   cNew        The new entry count.
- */
-RTDECL(int) RTAsn1MemGrowArray(PRTASN1ALLOCATION pAllocation, void **ppvArray, size_t cbEntry,
-                               uint32_t cCurrent, uint32_t cNew);
+ * Pointer array allocation information.
+ *
+ * Used by SET OF and SEQUENCE OF structures (typically automatically
+ * generated).
+ */
+typedef struct RTASN1ARRAYALLOCATION
+{
+    /** The size of the array entry. */
+    uint32_t                    cbEntry;
+    /** The size of the pointer array allocation. */
+    uint32_t                    cPointersAllocated;
+    /** Number of entry instances allocated.  This can be greater than the
+     * official array size. */
+    uint32_t                    cEntriesAllocated;
+    /** Number of array resizing calls (for increasing growth rate).
+     * Maintained by RTAsn1MemResizeArray().  */
+    uint16_t                    cResizeCalls;
+    /** Reserved / padding. */
+    uint16_t                    uReserved0;
+    /** Allocator vtable, NULL for the default allocator. */
+    PCRTASN1ALLOCATORVTABLE     pAllocator;
+} RTASN1ARRAYALLOCATION;
+
 
 /**
@@ -181,4 +235,5 @@
  * Initalize an allocation.
  *
+ * @returns pAllocation
  * @param   pAllocation The allocation record (initialized by
  *                      RTAsn1CursorInitAllocation or similar).
@@ -186,4 +241,40 @@
  */
 RTDECL(PRTASN1ALLOCATION) RTAsn1MemInitAllocation(PRTASN1ALLOCATION pAllocation, PCRTASN1ALLOCATORVTABLE pAllocator);
+
+/**
+ * Initalize an array allocation.
+ *
+ * @returns pAllocation
+ * @param   pAllocation The allocation record (initialized by
+ *                      RTAsn1CursorInitAllocation or similar).
+ * @param   pAllocator  The allocator
+ * @param   cbEntry     The entry size.
+ */
+RTDECL(PRTASN1ARRAYALLOCATION) RTAsn1MemInitArrayAllocation(PRTASN1ARRAYALLOCATION pAllocation,
+                                                            PCRTASN1ALLOCATORVTABLE pAllocator, size_t cbEntry);
+
+/**
+ * Resize an array with zero initialized memory.
+ *
+ * @returns IPRT status code.
+ * @param   pAllocation The allocation record (initialized by
+ *                      RTAsn1CursorInitAllocation or similar).
+ * @param   ppapvArray  Pointer to the variable pointing to the array.  This is
+ *                      both input and output.  Remains valid on failure.
+ * @param   cCurrent    The current entry count.  (Relevant for zero
+ *                      initialization of the new entries.)
+ * @param   cNew        The new entry count.
+ */
+RTDECL(int) RTAsn1MemResizeArray(PRTASN1ARRAYALLOCATION pAllocation, void ***ppapvArray, uint32_t cCurrent, uint32_t cNew);
+
+/**
+ * Frees an array and all its entries.
+ *
+ * @param   pAllocation The array allocation record (initialized by
+ *                      RTAsn1CursorInitArrayAllocation or similar).
+ * @param   pv          The memory block to free.  NULL will be ignored.
+ */
+RTDECL(void) RTAsn1MemFreeArray(PRTASN1ARRAYALLOCATION pAllocation, void **papvArray);
+
 
 /** Pointer to a core ASN.1 encoding info structure. */
@@ -654,9 +745,9 @@
         RTASN1SEQUENCECORE          SeqCore; \
         /** The array allocation tracker. */ \
-        RTASN1ALLOCATION            Allocation; \
+        RTASN1ARRAYALLOCATION       Allocation; \
         /** Items in the array. */ \
         uint32_t                    cItems; \
-        /** Array.  */ \
-        RT_CONCAT(P,a_ItemType)     paItems; \
+        /** Array. */ \
+        RT_CONCAT(P,a_ItemType)    *papItems; \
     } a_SeqOfType; \
     typedef a_SeqOfType *RT_CONCAT(P,a_SeqOfType); \
@@ -710,9 +801,9 @@
         RTASN1SETCORE               SetCore; \
         /** The array allocation tracker. */ \
-        RTASN1ALLOCATION            Allocation; \
+        RTASN1ARRAYALLOCATION       Allocation; \
         /** Items in the array. */ \
         uint32_t                    cItems; \
-        /** Array.  */ \
-        RT_CONCAT(P,a_ItemType)     paItems; \
+        /** Array. */ \
+        RT_CONCAT(P,a_ItemType)    *papItems; \
     } a_SetOfType; \
     typedef a_SetOfType *RT_CONCAT(P,a_SetOfType); \
@@ -1613,5 +1704,5 @@
  * construction of ASN.1 objects, each allocation has an allocation structure
  * associated with it.  This stores the allocator and keep statistics for
- * optimizing array allocations.
+ * optimizing resizable allocations.
  *
  * @returns Pointer to the allocator info (for call in alloc parameter).
@@ -1621,4 +1712,17 @@
 RTDECL(PRTASN1ALLOCATION) RTAsn1CursorInitAllocation(PRTASN1CURSOR pCursor, PRTASN1ALLOCATION pAllocation);
 
+/**
+ * Initalizes the an array allocation structure prior to making an allocation.
+ *
+ * This is a special case of RTAsn1CursorInitAllocation.  We store a little bit
+ * more detail here in order to optimize growing and shrinking of arrays.
+ *
+ * @returns Pointer to the allocator info (for call in alloc parameter).
+ * @param   pCursor             The cursor.
+ * @param   pAllocation         The allocation structure to initialize.
+ * @param   cbEntry             The array entry size.
+ */
+RTDECL(PRTASN1ARRAYALLOCATION) RTAsn1CursorInitArrayAllocation(PRTASN1CURSOR pCursor, PRTASN1ARRAYALLOCATION pAllocation,
+                                                               size_t cbEntry);
 
 /**
Index: /trunk/include/iprt/crypto/pkcs7.h
===================================================================
--- /trunk/include/iprt/crypto/pkcs7.h	(revision 64882)
+++ /trunk/include/iprt/crypto/pkcs7.h	(revision 64883)
@@ -225,9 +225,9 @@
  * @returns Pointer to the signing time if found, NULL if not.
  * @param   pThis               The SignerInfo to search.
- * @param   ppContentInfo       Where to return the pointer to the counter
+ * @param   ppContentInfoRet    Where to return the pointer to the counter
  *                              signature, optional.
  */
 RTDECL(PCRTASN1TIME) RTCrPkcs7SignerInfo_GetMsTimestamp(PCRTCRPKCS7SIGNERINFO pThis,
-                                                        struct RTCRPKCS7CONTENTINFO const **ppContentInfo);
+                                                        struct RTCRPKCS7CONTENTINFO const **ppContentInfoRet);
 
 
Index: /trunk/include/iprt/mangling.h
===================================================================
--- /trunk/include/iprt/mangling.h	(revision 64882)
+++ /trunk/include/iprt/mangling.h	(revision 64883)
@@ -2399,6 +2399,8 @@
 # define RTAsn1MemDup                                   RT_MANGLER(RTAsn1MemDup)
 # define RTAsn1MemFree                                  RT_MANGLER(RTAsn1MemFree)
-# define RTAsn1MemGrowArray                             RT_MANGLER(RTAsn1MemGrowArray)
+# define RTAsn1MemFreeArray                             RT_MANGLER(RTAsn1MemFreeArray)
+# define RTAsn1MemResizeArray                           RT_MANGLER(RTAsn1MemResizeArray)
 # define RTAsn1MemInitAllocation                        RT_MANGLER(RTAsn1MemInitAllocation)
+# define RTAsn1MemInitArrayAllocation                   RT_MANGLER(RTAsn1MemInitArrayAllocation)
 # define RTAsn1SeqOfCore_Clone                          RT_MANGLER(RTAsn1SeqOfCore_Clone)
 # define RTAsn1SeqOfCore_Init                           RT_MANGLER(RTAsn1SeqOfCore_Init)
@@ -2433,4 +2435,5 @@
 # define RTAsn1CursorGetUtf8String                      RT_MANGLER(RTAsn1CursorGetUtf8String)
 # define RTAsn1CursorInitAllocation                     RT_MANGLER(RTAsn1CursorInitAllocation)
+# define RTAsn1CursorInitArrayAllocation                RT_MANGLER(RTAsn1CursorInitArrayAllocation)
 # define RTAsn1CursorInitPrimary                        RT_MANGLER(RTAsn1CursorInitPrimary)
 # define RTAsn1CursorInitSubFromCore                    RT_MANGLER(RTAsn1CursorInitSubFromCore)
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 64882)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 64883)
@@ -1057,5 +1057,5 @@
     AssertReturn(RTCrPkcs7ContentInfo_IsSignedData(pContentInfo), VERR_INTERNAL_ERROR_5);
     AssertReturn(pContentInfo->u.pSignedData->SignerInfos.cItems == 1, VERR_INTERNAL_ERROR_5);
-    PCRTCRPKCS7SIGNERINFO pSignerInfo = &pContentInfo->u.pSignedData->SignerInfos.paItems[0];
+    PCRTCRPKCS7SIGNERINFO pSignerInfo = pContentInfo->u.pSignedData->SignerInfos.papItems[0];
 
     /*
Index: /trunk/src/VBox/Runtime/common/asn1/asn1-basics.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/asn1/asn1-basics.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/common/asn1/asn1-basics.cpp	(revision 64883)
@@ -75,52 +75,44 @@
 
 
-
-RTDECL(int) RTAsn1MemGrowArray(PRTASN1ALLOCATION pAllocation, void **ppvArray, size_t cbEntry,
-                               uint32_t cCurrent, uint32_t cNew)
+RTDECL(int) RTAsn1MemResizeArray(PRTASN1ARRAYALLOCATION pAllocation, void ***ppapvArray, uint32_t cCurrent, uint32_t cNew)
 {
     AssertReturn(pAllocation->pAllocator != NULL, VERR_WRONG_ORDER);
-    AssertReturn(cbEntry > 0, VERR_INVALID_PARAMETER);
-    AssertReturn(cNew > cCurrent, VERR_INVALID_PARAMETER);
+    AssertReturn(pAllocation->cbEntry > 0, VERR_WRONG_ORDER);
+    AssertReturn(cCurrent <= pAllocation->cEntriesAllocated, VERR_INVALID_PARAMETER);
+    AssertReturn(cCurrent <= pAllocation->cPointersAllocated, VERR_INVALID_PARAMETER);
     AssertReturn(cNew < _1M, VERR_OUT_OF_RANGE);
-
-    pAllocation->cReallocs++;
-
-    void *pvOld = *ppvArray;
-
-    /* Initial allocation? */
-    if (cCurrent == 0)
-    {
-        AssertReturn(pvOld == NULL, VERR_INVALID_PARAMETER);
-        AssertReturn(cNew != 0, VERR_INVALID_PARAMETER);
-        return pAllocation->pAllocator->pfnAlloc(pAllocation->pAllocator, pAllocation, ppvArray, cNew * cbEntry);
-    }
-
-    /* Do we need to grow the allocation or did we already allocate sufficient memory in a previous call? */
-    size_t cbNew = cNew * cbEntry;
-    if (pAllocation->cbAllocated < cbNew)
-    {
-        /* Need to grow.  Adjust the new size according to how many times we've been called. */
-        if (pAllocation->cReallocs > 2)
-        {
-            if (pAllocation->cReallocs > 8)
-                cNew += 8;
-            else if (pAllocation->cReallocs < 4)
-                cNew += 2;
-            else
-                cNew += 4;
-            cbNew += cNew * cbEntry;
-        }
-
-        int rc = pAllocation->pAllocator->pfnRealloc(pAllocation->pAllocator, pAllocation, pvOld, ppvArray, cbNew);
-        if (RT_FAILURE(rc))
-            return rc;
-        Assert(pAllocation->cbAllocated >= cbNew);
-
-        /* Clear the memory. */
-        size_t cbOld = cCurrent * cbEntry;
-        RT_BZERO((uint8_t *)*ppvArray + cbOld, pAllocation->cbAllocated - cbOld);
-    }
-
-    return VINF_SUCCESS;
+    Assert(pAllocation->cEntriesAllocated <= pAllocation->cPointersAllocated);
+
+    /*
+     * Is there sufficent space allocated already?
+     *
+     * We keep unused entires ZEROed, therefore we must always call the allocator
+     * when shrinking (this also helps with the electric fence allocator).
+     */
+    if (cNew <= pAllocation->cEntriesAllocated)
+    {
+        if (cCurrent <= cNew)
+            return VINF_SUCCESS;
+        pAllocation->pAllocator->pfnShrinkArray(pAllocation->pAllocator, pAllocation, ppapvArray, cCurrent, cNew);
+        return VINF_SUCCESS;
+    }
+
+    /*
+     * Must grow (or do initial alloc).
+     */
+    pAllocation->cResizeCalls++;
+    return pAllocation->pAllocator->pfnGrowArray(pAllocation->pAllocator, pAllocation, ppapvArray, cNew);
+}
+
+
+RTDECL(void) RTAsn1MemFreeArray(PRTASN1ARRAYALLOCATION pAllocation, void **papvArray)
+{
+    Assert(pAllocation->pAllocator != NULL);
+    if (papvArray)
+    {
+        pAllocation->pAllocator->pfnFreeArray(pAllocation->pAllocator, pAllocation, papvArray);
+        Assert(pAllocation->cPointersAllocated == 0);
+        Assert(pAllocation->cEntriesAllocated == 0);
+    }
 }
 
@@ -171,4 +163,20 @@
     pAllocation->uReserved0  = 0;
     pAllocation->pAllocator  = pAllocator;
+    return pAllocation;
+}
+
+
+RTDECL(PRTASN1ARRAYALLOCATION) RTAsn1MemInitArrayAllocation(PRTASN1ARRAYALLOCATION pAllocation,
+                                                            PCRTASN1ALLOCATORVTABLE pAllocator, size_t cbEntry)
+{
+    Assert(cbEntry >= sizeof(RTASN1CORE));
+    Assert(cbEntry < _1M);
+    Assert(RT_ALIGN_Z(cbEntry, sizeof(void *)) == cbEntry);
+    pAllocation->cbEntry            = (uint32_t)cbEntry;
+    pAllocation->cPointersAllocated = 0;
+    pAllocation->cEntriesAllocated  = 0;
+    pAllocation->cResizeCalls       = 0;
+    pAllocation->uReserved0         = 0;
+    pAllocation->pAllocator         = pAllocator;
     return pAllocation;
 }
Index: /trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/common/asn1/asn1-cursor.cpp	(revision 64883)
@@ -202,4 +202,20 @@
     pAllocation->uReserved0  = 0;
     pAllocation->pAllocator  = pCursor->pPrimary->pAllocator;
+    return pAllocation;
+}
+
+
+RTDECL(PRTASN1ARRAYALLOCATION) RTAsn1CursorInitArrayAllocation(PRTASN1CURSOR pCursor, PRTASN1ARRAYALLOCATION pAllocation,
+                                                               size_t cbEntry)
+{
+    Assert(cbEntry >= sizeof(RTASN1CORE));
+    Assert(cbEntry < _1M);
+    Assert(RT_ALIGN_Z(cbEntry, sizeof(void *)) == cbEntry);
+    pAllocation->cbEntry            = (uint32_t)cbEntry;
+    pAllocation->cPointersAllocated = 0;
+    pAllocation->cEntriesAllocated  = 0;
+    pAllocation->cResizeCalls       = 0;
+    pAllocation->uReserved0         = 0;
+    pAllocation->pAllocator         = pCursor->pPrimary->pAllocator;
     return pAllocation;
 }
Index: /trunk/src/VBox/Runtime/common/asn1/asn1-default-allocator.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/asn1/asn1-default-allocator.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/common/asn1/asn1-default-allocator.cpp	(revision 64883)
@@ -100,10 +100,122 @@
 
 
+/** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnFreeArray} */
+static DECLCALLBACK(void) rtAsn1DefaultAllocator_FreeArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation,
+                                                           void **papvArray)
+{
+    RT_NOREF_PV(pThis);
+    Assert(papvArray);
+    Assert(pAllocation->cbEntry);
+
+    uint32_t i = pAllocation->cEntriesAllocated;
+    while (i-- > 0)
+        RTMemFree(papvArray[i]);
+    RTMemFree(papvArray);
+
+    pAllocation->cEntriesAllocated  = 0;
+    pAllocation->cPointersAllocated = 0;
+}
+
+
+/** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnGrowArray} */
+static DECLCALLBACK(int) rtAsn1DefaultAllocator_GrowArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation,
+                                                          void ***ppapvArray, uint32_t cMinEntries)
+{
+    RT_NOREF_PV(pThis);
+
+    /*
+     * Resize the pointer array.  We do chunks of 64 bytes for now.
+     */
+    void **papvArray = *ppapvArray;
+    uint32_t cPointers = RT_ALIGN_32(cMinEntries, 64 / sizeof(void *));
+    if (cPointers > pAllocation->cPointersAllocated)
+    {
+        void *pvPointers = RTMemRealloc(papvArray, cPointers * sizeof(void *));
+        if (pvPointers)
+        { /* likely */ }
+        else if (cMinEntries > pAllocation->cPointersAllocated)
+        {
+            cPointers  = cMinEntries;
+            pvPointers = RTMemRealloc(*ppapvArray, cPointers * sizeof(void *));
+            if (!pvPointers)
+                return VERR_NO_MEMORY;
+        }
+        else
+        {
+            cPointers  = pAllocation->cPointersAllocated;
+            pvPointers = papvArray;
+        }
+
+        *ppapvArray = papvArray = (void **)pvPointers;
+        RT_BZERO(&papvArray[pAllocation->cPointersAllocated], (cPointers - pAllocation->cPointersAllocated) * sizeof(void *));
+        pAllocation->cPointersAllocated = cPointers;
+    }
+
+    /*
+     * Add more entries.  Do multiple as the array grows.
+     *
+     * Note! We could possibly optimize this by allocating slabs of entries and
+     *       slice them up.  However, keep things as simple as possible for now.
+     */
+    uint32_t cEntries = cMinEntries;
+    if (cEntries > 2)
+    {
+        if (cEntries > 8)
+            cEntries = RT_ALIGN_32(cEntries, 4);
+        else
+            cEntries = RT_ALIGN_32(cEntries, 2);
+        cEntries = RT_MIN(cEntries, cPointers);
+        Assert(cEntries >= cMinEntries);
+    }
+    Assert(cEntries <= pAllocation->cPointersAllocated);
+
+    while (pAllocation->cEntriesAllocated < cEntries)
+    {
+        void *pv;
+        papvArray[pAllocation->cEntriesAllocated] = pv = RTMemAllocZ(pAllocation->cbEntry);
+        if (pv)
+            pAllocation->cEntriesAllocated++;
+        else if (pAllocation->cEntriesAllocated >= cMinEntries)
+            break;
+        else
+            return VERR_NO_MEMORY;
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+/** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnShrinkArray} */
+static DECLCALLBACK(void) rtAsn1DefaultAllocator_ShrinkArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation,
+                                                             void ***ppapvArray, uint32_t cNew, uint32_t cCurrent)
+{
+    RT_NOREF_PV(pThis);
+
+    /*
+     * For now we only zero the entries being removed.
+     */
+    void **papvArray = *ppapvArray;
+    while (cNew < cCurrent)
+    {
+        RT_BZERO(papvArray[cNew], pAllocation->cbEntry);
+        cNew++;
+    }
+}
+
+
+
 /** The default ASN.1 allocator. */
+#if 1 || !defined(IN_RING3) || defined(DOXYGEN_RUNNING)
 RT_DECL_DATA_CONST(RTASN1ALLOCATORVTABLE const) g_RTAsn1DefaultAllocator =
+#else
+RT_DECL_DATA_CONST(RTASN1ALLOCATORVTABLE const) g_RTAsn1DefaultAllocatorDisabled =
+#endif
 {
     rtAsn1DefaultAllocator_Free,
     rtAsn1DefaultAllocator_Alloc,
-    rtAsn1DefaultAllocator_Realloc
+    rtAsn1DefaultAllocator_Realloc,
+    rtAsn1DefaultAllocator_FreeArray,
+    rtAsn1DefaultAllocator_GrowArray,
+    rtAsn1DefaultAllocator_ShrinkArray
 };
 
Index: /trunk/src/VBox/Runtime/common/asn1/asn1-efence-allocator.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/asn1/asn1-efence-allocator.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/common/asn1/asn1-efence-allocator.cpp	(revision 64883)
@@ -80,4 +80,105 @@
 
 
+/** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnFreeArray} */
+static DECLCALLBACK(void) rtAsn1EFenceAllocator_FreeArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation,
+                                                          void **papvArray)
+{
+    RT_NOREF_PV(pThis);
+    Assert(papvArray);
+    Assert(pAllocation->cbEntry);
+    Assert(pAllocation->cEntriesAllocated <= pAllocation->cPointersAllocated);
+
+    uint32_t i = pAllocation->cEntriesAllocated;
+    while (i-- > 0)
+    {
+        RTMemEfFreeNP(papvArray[i]);
+        papvArray[i] = NULL;
+    }
+    RTMemEfFreeNP(papvArray);
+
+    pAllocation->cEntriesAllocated  = 0;
+    pAllocation->cPointersAllocated = 0;
+}
+
+
+/** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnGrowArray} */
+static DECLCALLBACK(int) rtAsn1EFenceAllocator_GrowArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation,
+                                                         void ***ppapvArray, uint32_t cMinEntries)
+{
+    RT_NOREF_PV(pThis);
+    Assert(pAllocation->cbEntry);
+    Assert(pAllocation->cEntriesAllocated <= pAllocation->cPointersAllocated);
+
+    /*
+     * Resize the pointer array.
+     */
+    void **papvArray = *ppapvArray;
+    void *pvPointers = RTMemEfReallocNP(papvArray, cMinEntries * sizeof(void *), RTMEM_TAG);
+    if (pvPointers)
+    {
+        *ppapvArray = papvArray = (void **)pvPointers;
+        if (cMinEntries > pAllocation->cPointersAllocated) /* possible on multiple shrink failures */
+            RT_BZERO(&papvArray[pAllocation->cPointersAllocated],
+                     (cMinEntries - pAllocation->cPointersAllocated) * sizeof(void *));
+        else
+            AssertFailed();
+        pAllocation->cPointersAllocated = cMinEntries;
+    }
+    else if (cMinEntries > pAllocation->cPointersAllocated)
+        return VERR_NO_MEMORY;
+    /* else: possible but unlikely */
+
+    /*
+     * Add more entries.
+     */
+    while (pAllocation->cEntriesAllocated < cMinEntries)
+    {
+        void *pv;
+        papvArray[pAllocation->cEntriesAllocated] = pv = RTMemEfAllocZNP(pAllocation->cbEntry, RTMEM_TAG);
+        if (pv)
+            pAllocation->cEntriesAllocated++;
+        else
+            return VERR_NO_MEMORY;
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+/** @interface_method_impl{RTASN1ALLOCATORVTABLE, pfnShrinkArray} */
+static DECLCALLBACK(void) rtAsn1EFenceAllocator_ShrinkArray(PCRTASN1ALLOCATORVTABLE pThis, PRTASN1ARRAYALLOCATION pAllocation,
+                                                            void ***ppapvArray, uint32_t cNew, uint32_t cCurrent)
+{
+    RT_NOREF_PV(pThis);
+    Assert(pAllocation->cbEntry);
+    Assert(pAllocation->cEntriesAllocated <= pAllocation->cPointersAllocated);
+
+    /*
+     * We always free and resize.
+     */
+    Assert(pAllocation->cEntriesAllocated == cCurrent);
+    Assert(cNew < cCurrent);
+
+    /* Free entries. */
+    void **papvArray = *ppapvArray;
+    while (cCurrent-- > cNew)
+    {
+        RTMemEfFreeNP(papvArray[cCurrent]);
+        papvArray[cCurrent] = NULL;
+    }
+    pAllocation->cEntriesAllocated = cNew;
+
+    /* Try resize pointer array.  Failure here is a genuine possibility since the
+       efence code will try allocate a new block.  This causes extra fun in the
+       grow method above. */
+    void *pvPointers = RTMemEfReallocNP(papvArray, cNew * sizeof(void *), RTMEM_TAG);
+    if (pvPointers)
+    {
+        *ppapvArray = (void **)pvPointers;
+        pAllocation->cPointersAllocated = cNew;
+    }
+}
+
+
 /** The Electric Fence ASN.1 allocator. */
 RT_DECL_DATA_CONST(RTASN1ALLOCATORVTABLE const) g_RTAsn1EFenceAllocator =
@@ -85,5 +186,20 @@
     rtAsn1EFenceAllocator_Free,
     rtAsn1EFenceAllocator_Alloc,
-    rtAsn1EFenceAllocator_Realloc
+    rtAsn1EFenceAllocator_Realloc,
+    rtAsn1EFenceAllocator_FreeArray,
+    rtAsn1EFenceAllocator_GrowArray,
+    rtAsn1EFenceAllocator_ShrinkArray
 };
 
+#if 0 && defined(IN_RING3) /* for efence testing */
+RT_DECL_DATA_CONST(RTASN1ALLOCATORVTABLE const) g_RTAsn1DefaultAllocator =
+{
+    rtAsn1EFenceAllocator_Free,
+    rtAsn1EFenceAllocator_Alloc,
+    rtAsn1EFenceAllocator_Realloc,
+    rtAsn1EFenceAllocator_FreeArray,
+    rtAsn1EFenceAllocator_GrowArray,
+    rtAsn1EFenceAllocator_ShrinkArray
+};
+#endif
+
Index: /trunk/src/VBox/Runtime/common/crypto/pkcs7-core.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/pkcs7-core.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/common/crypto/pkcs7-core.cpp	(revision 64883)
@@ -49,12 +49,13 @@
      * Note! We ASSUME a single signing time attribute, which simplifies the interface.
      */
-    uint32_t                cAttrsLeft;
-    PCRTCRPKCS7ATTRIBUTE    pAttr;
+    uint32_t                    cAttrsLeft;
+    PRTCRPKCS7ATTRIBUTE const  *ppAttr;
     if (!ppSignerInfo || *ppSignerInfo == NULL)
     {
         cAttrsLeft = pThis->AuthenticatedAttributes.cItems;
-        pAttr      = pThis->AuthenticatedAttributes.paItems;
+        ppAttr     = pThis->AuthenticatedAttributes.papItems;
         while (cAttrsLeft-- > 0)
         {
+            PCRTCRPKCS7ATTRIBUTE pAttr = *ppAttr;
             if (   pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_SIGNING_TIME
                 && pAttr->uValues.pSigningTime->cItems > 0)
@@ -62,7 +63,7 @@
                 if (ppSignerInfo)
                     *ppSignerInfo = pThis;
-                return &pAttr->uValues.pSigningTime->paItems[0];
+                return pAttr->uValues.pSigningTime->papItems[0];
             }
-            pAttr++;
+            ppAttr++;
         }
     }
@@ -74,11 +75,12 @@
      */
     cAttrsLeft = pThis->UnauthenticatedAttributes.cItems;
-    pAttr      = pThis->UnauthenticatedAttributes.paItems;
+    ppAttr     = pThis->UnauthenticatedAttributes.papItems;
     while (cAttrsLeft-- > 0)
     {
+        PCRTCRPKCS7ATTRIBUTE pAttr = *ppAttr;
         if (pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_COUNTER_SIGNATURES)
         {
-            uint32_t              cSignatures = pAttr->uValues.pCounterSignatures->cItems;
-            PCRTCRPKCS7SIGNERINFO pSignature  = pAttr->uValues.pCounterSignatures->paItems;
+            uint32_t               cSignatures = pAttr->uValues.pCounterSignatures->cItems;
+            PRTCRPKCS7SIGNERINFO  *ppSignature = pAttr->uValues.pCounterSignatures->papItems;
 
             /* Skip past the previous counter signature. */
@@ -87,11 +89,11 @@
                 {
                     cSignatures--;
-                    if (pSignature == *ppSignerInfo)
+                    if (*ppSignature == *ppSignerInfo)
                     {
                         *ppSignerInfo = NULL;
-                        pSignature++;
+                        ppSignature++;
                         break;
                     }
-                    pSignature++;
+                    ppSignature++;
                 }
 
@@ -99,8 +101,10 @@
             while (cSignatures-- > 0)
             {
-                uint32_t                cCounterAttrsLeft = pSignature->AuthenticatedAttributes.cItems;
-                PCRTCRPKCS7ATTRIBUTE    pCounterAttr      = pSignature->AuthenticatedAttributes.paItems;
+                PCRTCRPKCS7SIGNERINFO       pSignature        = *ppSignature;
+                uint32_t                    cCounterAttrsLeft = pSignature->AuthenticatedAttributes.cItems;
+                PRTCRPKCS7ATTRIBUTE const  *ppCounterAttr     = pSignature->AuthenticatedAttributes.papItems;
                 while (cCounterAttrsLeft-- > 0)
                 {
+                    PCRTCRPKCS7ATTRIBUTE pCounterAttr = *ppCounterAttr;
                     if (   pCounterAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_SIGNING_TIME
                         && pCounterAttr->uValues.pSigningTime->cItems > 0)
@@ -108,12 +112,12 @@
                         if (ppSignerInfo)
                             *ppSignerInfo = pSignature;
-                        return &pCounterAttr->uValues.pSigningTime->paItems[0];
+                        return pCounterAttr->uValues.pSigningTime->papItems[0];
                     }
-                    pCounterAttr++;
+                    ppCounterAttr++;
                 }
-                pSignature++;
+                ppSignature++;
             }
         }
-        pAttr++;
+        ppAttr++;
     }
 
@@ -128,19 +132,21 @@
 
 
-RTDECL(PCRTASN1TIME) RTCrPkcs7SignerInfo_GetMsTimestamp(PCRTCRPKCS7SIGNERINFO pThis, PCRTCRPKCS7CONTENTINFO *ppContentInfo)
+RTDECL(PCRTASN1TIME) RTCrPkcs7SignerInfo_GetMsTimestamp(PCRTCRPKCS7SIGNERINFO pThis, PCRTCRPKCS7CONTENTINFO *ppContentInfoRet)
 {
     /*
      * Assume there is only one, so no need to enumerate anything here.
      */
-    uint32_t             cAttrsLeft = pThis->UnauthenticatedAttributes.cItems;
-    PCRTCRPKCS7ATTRIBUTE pAttr      = pThis->UnauthenticatedAttributes.paItems;
+    uint32_t                    cAttrsLeft  = pThis->UnauthenticatedAttributes.cItems;
+    PRTCRPKCS7ATTRIBUTE const  *ppAttr      = pThis->UnauthenticatedAttributes.papItems;
     while (cAttrsLeft-- > 0)
     {
+        PCRTCRPKCS7ATTRIBUTE pAttr = *ppAttr;
         if (pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_MS_TIMESTAMP)
         {
-            uint32_t                cLeft        = pAttr->uValues.pContentInfos->cItems;
-            PCRTCRPKCS7CONTENTINFO  pContentInfo = &pAttr->uValues.pContentInfos->paItems[0];
+            uint32_t                     cLeft         = pAttr->uValues.pContentInfos->cItems;
+            PRTCRPKCS7CONTENTINFO const *ppContentInfo = pAttr->uValues.pContentInfos->papItems;
             while (cLeft-- > 0)
             {
+                PCRTCRPKCS7CONTENTINFO pContentInfo = *ppContentInfo;
                 if (RTAsn1ObjId_CompareWithString(&pContentInfo->ContentType, RTCRPKCS7SIGNEDDATA_OID) == 0)
                 {
@@ -148,6 +154,6 @@
                                                       RTCRTSPTSTINFO_OID) == 0)
                     {
-                        if (ppContentInfo)
-                            *ppContentInfo = pContentInfo;
+                        if (ppContentInfoRet)
+                            *ppContentInfoRet = pContentInfo;
                         return &pContentInfo->u.pSignedData->ContentInfo.u.pTstInfo->GenTime;
                     }
@@ -157,5 +163,5 @@
             }
         }
-        pAttr++;
+        ppAttr++;
     }
 
@@ -163,6 +169,6 @@
      * No signature was found.
      */
-    if (ppContentInfo)
-        *ppContentInfo = NULL;
+    if (ppContentInfoRet)
+        *ppContentInfoRet = NULL;
 
     return NULL;
@@ -189,7 +195,10 @@
 {
     for (uint32_t i = 0; i < pCertificates->cItems; i++)
-        if (   pCertificates->paItems[i].enmChoice == RTCRPKCS7CERTCHOICE_X509
-            && RTCrX509Certificate_MatchIssuerAndSerialNumber(pCertificates->paItems[i].u.pX509Cert, pIssuer, pSerialNumber))
-            return pCertificates->paItems[i].u.pX509Cert;
+    {
+        PCRTCRPKCS7CERT pCert = pCertificates->papItems[i];
+        if (   pCert->enmChoice == RTCRPKCS7CERTCHOICE_X509
+            && RTCrX509Certificate_MatchIssuerAndSerialNumber(pCert->u.pX509Cert, pIssuer, pSerialNumber))
+            return pCert->u.pX509Cert;
+    }
     return NULL;
 }
Index: /trunk/src/VBox/Runtime/common/crypto/pkcs7-sanity.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/pkcs7-sanity.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/common/crypto/pkcs7-sanity.cpp	(revision 64883)
@@ -68,12 +68,12 @@
         for (uint32_t i = 0; i < pSignedData->DigestAlgorithms.cItems; i++)
         {
-            if (RTCrX509AlgorithmIdentifier_QueryDigestType(&pSignedData->DigestAlgorithms.paItems[i]) == RTDIGESTTYPE_INVALID)
+            if (RTCrX509AlgorithmIdentifier_QueryDigestType(pSignedData->DigestAlgorithms.papItems[i]) == RTDIGESTTYPE_INVALID)
                 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_UNKNOWN_DIGEST_ALGORITHM,
                                      "%s: SignedData.DigestAlgorithms[%i] is not known: %s",
-                                     pszErrorTag, i, pSignedData->DigestAlgorithms.paItems[i].Algorithm.szObjId);
-            if (pSignedData->DigestAlgorithms.paItems[i].Parameters.enmType != RTASN1TYPE_NULL)
+                                     pszErrorTag, i, pSignedData->DigestAlgorithms.papItems[i]->Algorithm.szObjId);
+            if (pSignedData->DigestAlgorithms.papItems[i]->Parameters.enmType != RTASN1TYPE_NULL)
                 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_DIGEST_PARAMS_NOT_IMPL,
                                      "%s: SignedData.DigestAlgorithms[%i] has parameters: tag=%u",
-                                     pszErrorTag, i, pSignedData->DigestAlgorithms.paItems[i].Parameters.u.Core.uTag);
+                                     pszErrorTag, i, pSignedData->DigestAlgorithms.papItems[i]->Parameters.u.Core.uTag);
         }
 
@@ -106,5 +106,5 @@
     for (uint32_t i = 0; i < pSignedData->SignerInfos.cItems; i++)
     {
-        PCRTCRPKCS7SIGNERINFO pSignerInfo = &pSignedData->SignerInfos.paItems[i];
+        PCRTCRPKCS7SIGNERINFO pSignerInfo = pSignedData->SignerInfos.papItems[i];
 
         if (RTAsn1Integer_UnsignedCompareWithU32(&pSignerInfo->Version, RTCRPKCS7SIGNERINFO_V1) != 0)
@@ -136,5 +136,5 @@
         uint32_t j = 0;
         while (   j < pSignedData->DigestAlgorithms.cItems
-               && RTCrX509AlgorithmIdentifier_Compare(&pSignedData->DigestAlgorithms.paItems[j],
+               && RTCrX509AlgorithmIdentifier_Compare(pSignedData->DigestAlgorithms.papItems[j],
                                                       &pSignerInfo->DigestAlgorithm) != 0)
             j++;
@@ -162,5 +162,5 @@
             for (j = 0; j < pSignerInfo->AuthenticatedAttributes.cItems; j++)
             {
-                PCRTCRPKCS7ATTRIBUTE pAttrib = &pSignerInfo->AuthenticatedAttributes.paItems[j];
+                PCRTCRPKCS7ATTRIBUTE pAttrib = pSignerInfo->AuthenticatedAttributes.papItems[j];
                 if (RTAsn1ObjId_CompareWithString(&pAttrib->Type, RTCR_PKCS9_ID_CONTENT_TYPE_OID) == 0)
                 {
Index: /trunk/src/VBox/Runtime/common/crypto/pkcs7-verify.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/pkcs7-verify.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/common/crypto/pkcs7-verify.cpp	(revision 64883)
@@ -75,6 +75,6 @@
             PCRTCRPKCS7SETOFCERTS pCerts = &pContentInfo->u.pSignedData->Certificates;
             for (uint32_t i = 0; i < pCerts->cItems; i++)
-                if (pCerts->paItems[i].enmChoice == RTCRPKCS7CERTCHOICE_X509)
-                    rtCrOpenSslAddX509CertToStack(pAddCerts, pCerts->paItems[i].u.pX509Cert);
+                if (pCerts->papItems[i]->enmChoice == RTCRPKCS7CERTCHOICE_X509)
+                    rtCrOpenSslAddX509CertToStack(pAddCerts, pCerts->papItems[i]->u.pX509Cert);
 
 
@@ -238,5 +238,5 @@
     while (i-- > 0)
     {
-        PCRTCRPKCS7ATTRIBUTE pAttrib = &pSignerInfo->AuthenticatedAttributes.paItems[i];
+        PCRTCRPKCS7ATTRIBUTE pAttrib = pSignerInfo->AuthenticatedAttributes.papItems[i];
 
         if (RTAsn1ObjId_CompareWithString(&pAttrib->Type, RTCR_PKCS9_ID_CONTENT_TYPE_OID) == 0)
@@ -247,8 +247,8 @@
 
             if (   !(fFlags & RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE) /* See note about microsoft below. */
-                && RTAsn1ObjId_Compare(&pAttrib->uValues.pObjIds->paItems[0], &pSignedData->ContentInfo.ContentType) != 0)
+                && RTAsn1ObjId_Compare(pAttrib->uValues.pObjIds->papItems[0], &pSignedData->ContentInfo.ContentType) != 0)
                    return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_CONTENT_TYPE_ATTRIB_MISMATCH,
-                                        "Expected content-type %s, found %s",
-                                        &pAttrib->uValues.pObjIds->paItems[0], pSignedData->ContentInfo.ContentType.szObjId);
+                                        "Expected content-type %s, found %s", pAttrib->uValues.pObjIds->papItems[0]->szObjId,
+                                        pSignedData->ContentInfo.ContentType.szObjId);
             cContentTypes++;
         }
@@ -260,12 +260,12 @@
 
             if (!RTCrDigestMatch(*phDigest,
-                                 pAttrib->uValues.pOctetStrings->paItems[0].Asn1Core.uData.pv,
-                                 pAttrib->uValues.pOctetStrings->paItems[0].Asn1Core.cb))
+                                 pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.uData.pv,
+                                 pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.cb))
             {
                 size_t cbHash = RTCrDigestGetHashSize(*phDigest);
-                if (cbHash != pAttrib->uValues.pOctetStrings->paItems[0].Asn1Core.cb)
+                if (cbHash != pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.cb)
                     return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_MESSAGE_DIGEST_ATTRIB_MISMATCH,
                                          "Authenticated message-digest attribute mismatch: cbHash=%#zx cbValue=%#x",
-                                         cbHash, pAttrib->uValues.pOctetStrings->paItems[0].Asn1Core.cb);
+                                         cbHash, pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.cb);
                 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_MESSAGE_DIGEST_ATTRIB_MISMATCH,
                                      "Authenticated message-digest attribute mismatch (cbHash=%#zx):\n"
@@ -273,5 +273,5 @@
                                      "our:    %.*Rhxs\n",
                                      cbHash,
-                                     cbHash, pAttrib->uValues.pOctetStrings->paItems[0].Asn1Core.uData.pv,
+                                     cbHash, pAttrib->uValues.pOctetStrings->papItems[0]->Asn1Core.uData.pv,
                                      cbHash, RTCrDigestGetHash(*phDigest));
             }
@@ -342,5 +342,5 @@
     uint32_t iDigest = pSignedData->DigestAlgorithms.cItems;
     while (iDigest-- > 0)
-        if (RTCrX509AlgorithmIdentifier_Compare(&pSignedData->DigestAlgorithms.paItems[iDigest],
+        if (RTCrX509AlgorithmIdentifier_Compare(pSignedData->DigestAlgorithms.papItems[iDigest],
                                                 &pSignerInfo->DigestAlgorithm) == 0)
         {
@@ -620,9 +620,9 @@
     for (i = 0; i < cDigests; i++)
     {
-        rc = RTCrDigestCreateByObjId(&ahDigests[i], &pSignedData->DigestAlgorithms.paItems[i].Algorithm);
+        rc = RTCrDigestCreateByObjId(&ahDigests[i], &pSignedData->DigestAlgorithms.papItems[i]->Algorithm);
         if (RT_FAILURE(rc))
         {
             rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_DIGEST_CREATE_ERROR, "Error creating digest for '%s': %Rrc",
-                               pSignedData->DigestAlgorithms.paItems[i].Algorithm.szObjId, rc);
+                               pSignedData->DigestAlgorithms.papItems[i]->Algorithm.szObjId, rc);
             break;
         }
@@ -647,5 +647,5 @@
             for (i = 0; i < pSignedData->SignerInfos.cItems; i++)
             {
-                PCRTCRPKCS7SIGNERINFO   pSignerInfo = &pSignedData->SignerInfos.paItems[i];
+                PCRTCRPKCS7SIGNERINFO   pSignerInfo = pSignedData->SignerInfos.papItems[i];
                 RTCRDIGEST              hThisDigest = NIL_RTCRDIGEST; /* (gcc maybe incredible stupid.) */
                 rc = rtCrPkcs7VerifyFindDigest(&hThisDigest, pSignedData, pSignerInfo, ahDigests, pErrInfo);
Index: /trunk/src/VBox/Runtime/common/crypto/spc-core.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/spc-core.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/common/crypto/spc-core.cpp	(revision 64883)
@@ -69,6 +69,6 @@
                 if (pData)
                     for (uint32_t i = 0; i < pData->cItems; i++)
-                        if (pData->paItems[i].enmType == enmType)
-                            return &pData->paItems[i];
+                        if (pData->papItems[i]->enmType == enmType)
+                            return pData->papItems[i];
             }
         }
Index: /trunk/src/VBox/Runtime/common/crypto/spc-sanity.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/spc-sanity.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/common/crypto/spc-sanity.cpp	(revision 64883)
@@ -57,16 +57,16 @@
 
     if (RTCrX509AlgorithmIdentifier_Compare(&pIndData->DigestInfo.DigestAlgorithm, /** @todo not entirely sure about this check... */
-                                            &pSignedData->SignerInfos.paItems[0].DigestAlgorithm) != 0)
+                                            &pSignedData->SignerInfos.papItems[0]->DigestAlgorithm) != 0)
         return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_SIGNED_IND_DATA_DIGEST_ALGO_MISMATCH,
                              "SpcIndirectDataContent DigestInfo and SignerInfos algorithms mismatch: %s vs %s",
                              pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId,
-                             pSignedData->SignerInfos.paItems[0].DigestAlgorithm.Algorithm.szObjId);
+                             pSignedData->SignerInfos.papItems[0]->DigestAlgorithm.Algorithm.szObjId);
 
     if (RTCrX509AlgorithmIdentifier_Compare(&pIndData->DigestInfo.DigestAlgorithm,
-                                            &pSignedData->DigestAlgorithms.paItems[0]) != 0)
+                                            pSignedData->DigestAlgorithms.papItems[0]) != 0)
         return RTErrInfoSetF(pErrInfo, VERR_CR_SPC_IND_DATA_DIGEST_ALGO_NOT_IN_DIGEST_ALGOS,
                              "SpcIndirectDataContent DigestInfo and SignedData.DigestAlgorithms[0] mismatch: %s vs %s",
                              pIndData->DigestInfo.DigestAlgorithm.Algorithm.szObjId,
-                             pSignedData->DigestAlgorithms.paItems[0].Algorithm.szObjId);
+                             pSignedData->DigestAlgorithms.papItems[0]->Algorithm.szObjId);
 
     if (fFlags & RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH)
@@ -126,5 +126,5 @@
             for (uint32_t i = 0; i < pObj->u.pData->cItems; i++)
             {
-                PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttr = &pObj->u.pData->paItems[i];
+                PCRTCRSPCSERIALIZEDOBJECTATTRIBUTE pAttr = pObj->u.pData->papItems[i];
                 if (   RTAsn1ObjId_CompareWithString(&pAttr->Type, RTCRSPC_PE_IMAGE_HASHES_V1_OID) == 0
                     || RTAsn1ObjId_CompareWithString(&pAttr->Type, RTCRSPC_PE_IMAGE_HASHES_V2_OID) == 0 )
Index: /trunk/src/VBox/Runtime/common/crypto/x509-certpaths.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/x509-certpaths.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/common/crypto/x509-certpaths.cpp	(revision 64883)
@@ -723,10 +723,13 @@
     if (pThis->pUntrustedCertsSet)
     {
-        uint32_t const  cCerts  = pThis->pUntrustedCertsSet->cItems;
-        PCRTCRPKCS7CERT paCerts = pThis->pUntrustedCertsSet->paItems;
+        uint32_t const        cCerts   = pThis->pUntrustedCertsSet->cItems;
+        PRTCRPKCS7CERT const *papCerts = pThis->pUntrustedCertsSet->papItems;
         for (uint32_t i = 0; i < cCerts; i++)
-            if (   paCerts[i].enmChoice == RTCRPKCS7CERTCHOICE_X509
-                && RTCrX509Certificate_MatchSubjectOrAltSubjectByRfc5280(paCerts[i].u.pX509Cert, pIssuer))
-                rtCrX509CertPathsAddIssuer(pThis, pNode, paCerts[i].u.pX509Cert, NULL, RTCRX509CERTPATHNODE_SRC_UNTRUSTED_SET);
+        {
+            PCRTCRPKCS7CERT pCert = papCerts[i];
+            if (   pCert->enmChoice == RTCRPKCS7CERTCHOICE_X509
+                && RTCrX509Certificate_MatchSubjectOrAltSubjectByRfc5280(pCert->u.pX509Cert, pIssuer))
+                rtCrX509CertPathsAddIssuer(pThis, pNode, pCert->u.pX509Cert, NULL, RTCRX509CERTPATHNODE_SRC_UNTRUSTED_SET);
+        }
     }
 }
@@ -1057,7 +1060,9 @@
 {
     for (uint32_t i = 0; i < pName->cItems; i++)
-        for (uint32_t j = 0; j < pName->paItems[i].cItems; j++)
-        {
-            PRTCRX509ATTRIBUTETYPEANDVALUE pAttrib = &pName->paItems[i].paItems[j];
+    {
+        PCRTCRX509RELATIVEDISTINGUISHEDNAME const pRdn = pName->papItems[i];
+        for (uint32_t j = 0; j < pRdn->cItems; j++)
+        {
+            PRTCRX509ATTRIBUTETYPEANDVALUE pAttrib = pRdn->papItems[j];
 
             const char *pszType = pAttrib->Type.szObjId;
@@ -1118,4 +1123,5 @@
                 rtDumpPrintf(pfnPrintfV, pvUser, "<not-string: uTag=%#x>", pAttrib->Value.u.Core.uTag);
         }
+    }
 }
 
@@ -1350,7 +1356,8 @@
  * @param   pThis               The validator instance.
  * @param   cSubtrees           The number of sub-trees to add.
- * @param   paSubtrees          Array of sub-trees to add.
- */
-static bool rtCrX509CpvAddPermittedSubtrees(PRTCRX509CERTPATHSINT pThis, uint32_t cSubtrees, PCRTCRX509GENERALSUBTREE paSubtrees)
+ * @param   papSubtrees         Array of sub-trees to add.
+ */
+static bool rtCrX509CpvAddPermittedSubtrees(PRTCRX509CERTPATHSINT pThis, uint32_t cSubtrees,
+                                            PRTCRX509GENERALSUBTREE const *papSubtrees)
 {
     /*
@@ -1375,7 +1382,7 @@
     for (uint32_t iSrc = 0; iSrc < cSubtrees; iSrc++)
     {
-        if (!rtCrX509CpvCheckSubtreeValidity(pThis, &paSubtrees[iSrc]))
+        if (!rtCrX509CpvCheckSubtreeValidity(pThis, papSubtrees[iSrc]))
             return false;
-        pThis->v.papPermittedSubtrees[iDst] = &paSubtrees[iSrc];
+        pThis->v.papPermittedSubtrees[iDst] = papSubtrees[iSrc];
         iDst++;
     }
@@ -1383,4 +1390,20 @@
 
     return true;
+}
+
+
+/**
+ * Adds a one permitted sub-tree.
+ *
+ * We store reference to each individual sub-tree because we must support
+ * intersection calculation.
+ *
+ * @returns success indiciator.
+ * @param   pThis               The validator instance.
+ * @param   pSubtree            Array of sub-trees to add.
+ */
+static bool rtCrX509CpvAddPermittedSubtree(PRTCRX509CERTPATHSINT pThis, PCRTCRX509GENERALSUBTREE pSubtree)
+{
+    return rtCrX509CpvAddPermittedSubtrees(pThis, 1, (PRTCRX509GENERALSUBTREE const *)&pSubtree);
 }
 
@@ -1405,6 +1428,6 @@
     }
 
-    uint32_t                    cRight  = pSubtrees->cItems;
-    PCRTCRX509GENERALSUBTREE    paRight = pSubtrees->paItems;
+    uint32_t                       cRight   = pSubtrees->cItems;
+    PRTCRX509GENERALSUBTREE const *papRight = pSubtrees->papItems;
     if (cRight == 0)
     {
@@ -1417,5 +1440,5 @@
     PCRTCRX509GENERALSUBTREE   *papLeft = pThis->v.papPermittedSubtrees;
     if (!cLeft) /* first name constraint, no initial constraint */
-        return rtCrX509CpvAddPermittedSubtrees(pThis, cRight, paRight);
+        return rtCrX509CpvAddPermittedSubtrees(pThis, cRight, papRight);
 
     /*
@@ -1431,8 +1454,8 @@
     for (uint32_t iRight = 0; iRight < cRight; iRight++)
     {
-        if (!rtCrX509CpvCheckSubtreeValidity(pThis, &paRight[iRight]))
+        if (!rtCrX509CpvCheckSubtreeValidity(pThis, papRight[iRight]))
             return false;
 
-        RTCRX509GENERALNAMECHOICE const enmRightChoice = paRight[iRight].Base.enmChoice;
+        RTCRX509GENERALNAMECHOICE const enmRightChoice = papRight[iRight]->Base.enmChoice;
         afRightTags[enmRightChoice] = true;
 
@@ -1441,22 +1464,22 @@
             if (papLeft[iLeft]->Base.enmChoice == enmRightChoice)
             {
-                if (RTCrX509GeneralSubtree_Compare(papLeft[iLeft], &paRight[iRight]) == 0)
+                if (RTCrX509GeneralSubtree_Compare(papLeft[iLeft], papRight[iRight]) == 0)
                 {
                     if (!fHaveRight)
                     {
                         fHaveRight = true;
-                        rtCrX509CpvAddPermittedSubtrees(pThis, 1, papLeft[iLeft]);
+                        rtCrX509CpvAddPermittedSubtree(pThis, papLeft[iLeft]);
                     }
                 }
-                else if (RTCrX509GeneralSubtree_ConstraintMatch(papLeft[iLeft], &paRight[iRight]))
+                else if (RTCrX509GeneralSubtree_ConstraintMatch(papLeft[iLeft], papRight[iRight]))
                 {
                     if (!fHaveRight)
                     {
                         fHaveRight = true;
-                        rtCrX509CpvAddPermittedSubtrees(pThis, 1, &paRight[iRight]);
+                        rtCrX509CpvAddPermittedSubtree(pThis, papRight[iRight]);
                     }
                 }
-                else if (RTCrX509GeneralSubtree_ConstraintMatch(&paRight[iRight], papLeft[iLeft]))
-                    rtCrX509CpvAddPermittedSubtrees(pThis, 1, papLeft[iLeft]);
+                else if (RTCrX509GeneralSubtree_ConstraintMatch(papRight[iRight], papLeft[iLeft]))
+                    rtCrX509CpvAddPermittedSubtree(pThis, papLeft[iLeft]);
             }
     }
@@ -1467,5 +1490,5 @@
     for (uint32_t iLeft = 0; iLeft < cLeft; iLeft++)
         if (!afRightTags[papLeft[iLeft]->Base.enmChoice])
-            rtCrX509CpvAddPermittedSubtrees(pThis, 1, papLeft[iLeft]);
+            rtCrX509CpvAddPermittedSubtree(pThis, papLeft[iLeft]);
 
     /*
@@ -1541,7 +1564,10 @@
         uint32_t j = pSubTrees->cItems;
         while (j-- > 0)
-            if (   RTCRX509GENERALNAME_IS_DIRECTORY_NAME(&pSubTrees->paItems[j].Base)
-                && RTCrX509Name_ConstraintMatch(&pSubTrees->paItems[j].Base.u.pT4->DirectoryName, pName))
+        {
+            PCRTCRX509GENERALSUBTREE const pSubTree = pSubTrees->papItems[j];
+            if (   RTCRX509GENERALNAME_IS_DIRECTORY_NAME(&pSubTree->Base)
+                && RTCrX509Name_ConstraintMatch(&pSubTree->Base.u.pT4->DirectoryName, pName))
                 return true;
+        }
     }
     return false;
@@ -1566,5 +1592,5 @@
         uint32_t j = pSubTrees->cItems;
         while (j-- > 0)
-            if (RTCrX509GeneralName_ConstraintMatch(&pSubTrees->paItems[j].Base, pGeneralName))
+            if (RTCrX509GeneralName_ConstraintMatch(&pSubTrees->papItems[j]->Base, pGeneralName))
                 return true;
     }
@@ -1951,5 +1977,5 @@
     if (pThis->pInitialPermittedSubtrees)
         rtCrX509CpvAddPermittedSubtrees(pThis, pThis->pInitialPermittedSubtrees->cItems,
-                                        pThis->pInitialPermittedSubtrees->paItems);
+                                        pThis->pInitialPermittedSubtrees->papItems);
     if (pThis->pInitialExcludedSubtrees)
         rtCrX509CpvAddExcludedSubtrees(pThis, pThis->pInitialExcludedSubtrees);
@@ -2053,6 +2079,6 @@
         uint32_t i = pAltSubjectName->cItems;
         while (i-- > 0)
-            if (   !rtCrX509CpvIsGeneralNamePermitted(pThis, &pAltSubjectName->paItems[i])
-                || rtCrX509CpvIsGeneralNameExcluded(pThis, &pAltSubjectName->paItems[i]))
+            if (   !rtCrX509CpvIsGeneralNamePermitted(pThis, pAltSubjectName->papItems[i])
+                || rtCrX509CpvIsGeneralNameExcluded(pThis, pAltSubjectName->papItems[i]))
                 return rtCrX509CpvFailed(pThis, VERR_CR_X509_CPV_ALT_NAME_NOT_PERMITTED,
                                          "Alternative name #%u is is not permitted by current name constraints", i);
@@ -2081,6 +2107,6 @@
         while (i-- > 0)
         {
-            PCRTCRX509POLICYQUALIFIERINFOS const    pQualifiers = &pPolicies->paItems[i].PolicyQualifiers;
-            PCRTASN1OBJID const                     pIdP        = &pPolicies->paItems[i].PolicyIdentifier;
+            PCRTCRX509POLICYQUALIFIERINFOS const    pQualifiers = &pPolicies->papItems[i]->PolicyQualifiers;
+            PCRTASN1OBJID const                     pIdP        = &pPolicies->papItems[i]->PolicyIdentifier;
             if (RTAsn1ObjId_CompareWithString(pIdP, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0)
             {
@@ -2132,5 +2158,5 @@
                 || (pNode->pParent && fSelfIssued) ) )
         {
-            PCRTCRX509POLICYQUALIFIERINFOS pApQ = &pPolicies->paItems[iAnyPolicy].PolicyQualifiers;
+            PCRTCRX509POLICYQUALIFIERINFOS pApQ = &pPolicies->papItems[iAnyPolicy]->PolicyQualifiers;
             RTListForEach(pListAbove, pCur, RTCRX509CERTPATHSPOLICYNODE, DepthEntry)
             {
@@ -2183,9 +2209,10 @@
     while (i-- > 0)
     {
-        if (RTAsn1ObjId_CompareWithString(&pPolicyMappings->paItems[i].IssuerDomainPolicy, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0)
+        PCRTCRX509POLICYMAPPING const pOne = pPolicyMappings->papItems[i];
+        if (RTAsn1ObjId_CompareWithString(&pOne->IssuerDomainPolicy, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0)
             return rtCrX509CpvFailed(pThis, VERR_CR_X509_CPV_INVALID_POLICY_MAPPING,
                                      "Invalid policy mapping %#u: IssuerDomainPolicy is anyPolicy.", i);
 
-        if (RTAsn1ObjId_CompareWithString(&pPolicyMappings->paItems[i].SubjectDomainPolicy, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0)
+        if (RTAsn1ObjId_CompareWithString(&pOne->SubjectDomainPolicy, RTCRX509_ID_CE_CP_ANY_POLICY_OID) == 0)
             return rtCrX509CpvFailed(pThis, VERR_CR_X509_CPV_INVALID_POLICY_MAPPING,
                                      "Invalid policy mapping %#u: SubjectDomainPolicy is anyPolicy.", i);
@@ -2201,13 +2228,15 @@
         while (i-- > 0)
         {
+            PCRTCRX509POLICYMAPPING const pOne = pPolicyMappings->papItems[i];
+
             uint32_t cFound = 0;
             RTListForEach(&pThis->v.paValidPolicyDepthLists[iDepth], pCur, RTCRX509CERTPATHSPOLICYNODE, DepthEntry)
             {
-                if (RTAsn1ObjId_Compare(pCur->pValidPolicy, &pPolicyMappings->paItems[i].IssuerDomainPolicy))
+                if (RTAsn1ObjId_Compare(pCur->pValidPolicy, &pOne->IssuerDomainPolicy))
                 {
                     if (!pCur->fAlreadyMapped)
                     {
                         pCur->fAlreadyMapped = true;
-                        pCur->pExpectedPolicyFirst = &pPolicyMappings->paItems[i].SubjectDomainPolicy;
+                        pCur->pExpectedPolicyFirst = &pOne->SubjectDomainPolicy;
                     }
                     else
@@ -2221,5 +2250,5 @@
                                                      pCur->cMoreExpectedPolicySet, iDepth);
                         pCur->papMoreExpectedPolicySet = (PCRTASN1OBJID *)pvNew;
-                        pCur->papMoreExpectedPolicySet[iExpected] = &pPolicyMappings->paItems[i].SubjectDomainPolicy;
+                        pCur->papMoreExpectedPolicySet[iExpected] = &pOne->SubjectDomainPolicy;
                         pCur->cMoreExpectedPolicySet = iExpected  + 1;
                     }
@@ -2238,7 +2267,7 @@
                     {
                         if (!rtCrX509CpvPolicyTreeInsertNew(pThis, pCur->pParent, iDepth,
-                                                            &pPolicyMappings->paItems[i].IssuerDomainPolicy,
+                                                            &pOne->IssuerDomainPolicy,
                                                             pCur->pPolicyQualifiers,
-                                                            &pPolicyMappings->paItems[i].SubjectDomainPolicy))
+                                                            &pOne->SubjectDomainPolicy))
                             return false;
                         break;
@@ -2258,7 +2287,8 @@
         while (i-- > 0)
         {
+            PCRTCRX509POLICYMAPPING const pOne = pPolicyMappings->papItems[i];
             RTListForEachSafe(&pThis->v.paValidPolicyDepthLists[iDepth], pCur, pNext, RTCRX509CERTPATHSPOLICYNODE, DepthEntry)
             {
-                if (RTAsn1ObjId_Compare(pCur->pValidPolicy, &pPolicyMappings->paItems[i].IssuerDomainPolicy))
+                if (RTAsn1ObjId_Compare(pCur->pValidPolicy, &pOne->IssuerDomainPolicy))
                 {
                     rtCrX509CpvPolicyTreeDestroyNode(pThis, pCur);
@@ -2410,8 +2440,9 @@
 static bool rtCrX509CpvCheckCriticalExtensions(PRTCRX509CERTPATHSINT pThis, PRTCRX509CERTPATHNODE pNode)
 {
-    uint32_t                cLeft = pNode->pCert->TbsCertificate.T3.Extensions.cItems;
-    PCRTCRX509EXTENSION     pCur  = pNode->pCert->TbsCertificate.T3.Extensions.paItems;
+    uint32_t                  cLeft = pNode->pCert->TbsCertificate.T3.Extensions.cItems;
+    PRTCRX509EXTENSION const *ppCur = pNode->pCert->TbsCertificate.T3.Extensions.papItems;
     while (cLeft-- > 0)
     {
+        PCRTCRX509EXTENSION const pCur = *ppCur;
         if (pCur->Critical.fValue)
         {
@@ -2431,5 +2462,5 @@
         }
 
-        pCur++;
+        ppCur++;
     }
 
Index: /trunk/src/VBox/Runtime/common/crypto/x509-core.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/x509-core.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/common/crypto/x509-core.cpp	(revision 64883)
@@ -608,8 +608,8 @@
         for (uint32_t iLeft = 0; iLeft < cItems; iLeft++)
         {
-            PCRTCRX509ATTRIBUTETYPEANDVALUE pLeftAttr = &pLeft->paItems[iLeft];
+            PCRTCRX509ATTRIBUTETYPEANDVALUE pLeftAttr = pLeft->papItems[iLeft];
             bool fFound = false;
             for (uint32_t iRight = 0; iRight < cItems; iRight++)
-                if (RTCrX509AttributeTypeAndValue_MatchAsRdnByRfc5280(pLeftAttr, &pRight->paItems[iRight]))
+                if (RTCrX509AttributeTypeAndValue_MatchAsRdnByRfc5280(pLeftAttr, pRight->papItems[iRight]))
                 {
                     fFound = true;
@@ -637,5 +637,5 @@
         /* Require exact order. */
         for (uint32_t iRdn = 0; iRdn < cItems; iRdn++)
-            if (!RTCrX509RelativeDistinguishedName_MatchByRfc5280(&pLeft->paItems[iRdn], &pRight->paItems[iRdn]))
+            if (!RTCrX509RelativeDistinguishedName_MatchByRfc5280(pLeft->papItems[iRdn], pRight->papItems[iRdn]))
                 return false;
         return true;
@@ -658,6 +658,6 @@
         for (uint32_t i = 0; pConstraint->cItems; i++)
         {
-            PCRTCRX509RELATIVEDISTINGUISHEDNAME pConstrRdns = &pConstraint->paItems[i];
-            PCRTCRX509RELATIVEDISTINGUISHEDNAME pNameRdns   = &pName->paItems[i];
+            PCRTCRX509RELATIVEDISTINGUISHEDNAME pConstrRdns = pConstraint->papItems[i];
+            PCRTCRX509RELATIVEDISTINGUISHEDNAME pNameRdns   = pName->papItems[i];
 
             /*
@@ -666,5 +666,5 @@
             for (uint32_t iConstrAttrib = 0; iConstrAttrib < pConstrRdns->cItems; iConstrAttrib++)
             {
-                PCRTCRX509ATTRIBUTETYPEANDVALUE pConstrAttrib = &pConstrRdns->paItems[iConstrAttrib];
+                PCRTCRX509ATTRIBUTETYPEANDVALUE pConstrAttrib = pConstrRdns->papItems[iConstrAttrib];
 
                 /*
@@ -673,5 +673,5 @@
                 bool fFound = false;
                 for (uint32_t iNameAttrib = 0; iNameAttrib < pNameRdns->cItems; iNameAttrib++)
-                    if (RTCrX509AttributeTypeAndValue_MatchAsRdnByRfc5280(pConstrAttrib, &pNameRdns->paItems[iNameAttrib]))
+                    if (RTCrX509AttributeTypeAndValue_MatchAsRdnByRfc5280(pConstrAttrib, pNameRdns->papItems[iNameAttrib]))
                     {
                         fFound = true;
@@ -737,8 +737,8 @@
     for (uint32_t i = 0; i < pThis->cItems; i++)
     {
-        PCRTCRX509RELATIVEDISTINGUISHEDNAME pRdn = &pThis->paItems[i];
+        PCRTCRX509RELATIVEDISTINGUISHEDNAME pRdn = pThis->papItems[i];
         for (uint32_t j = 0; j < pRdn->cItems; j++)
         {
-            PCRTCRX509ATTRIBUTETYPEANDVALUE pComponent = &pRdn->paItems[j];
+            PCRTCRX509ATTRIBUTETYPEANDVALUE pComponent = pRdn->papItems[j];
 
             /*
@@ -816,8 +816,8 @@
     for (uint32_t i = 0; i < pThis->cItems; i++)
     {
-        PCRTCRX509RELATIVEDISTINGUISHEDNAME pRdn = &pThis->paItems[i];
+        PCRTCRX509RELATIVEDISTINGUISHEDNAME pRdn = pThis->papItems[i];
         for (uint32_t j = 0; j < pRdn->cItems; j++)
         {
-            PCRTCRX509ATTRIBUTETYPEANDVALUE pComponent = &pRdn->paItems[j];
+            PCRTCRX509ATTRIBUTETYPEANDVALUE pComponent = pRdn->papItems[j];
 
             /*
@@ -1332,10 +1332,10 @@
     {
 
-        if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_ANY_EXTENDED_KEY_USAGE_OID) == 0)
+        if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_ANY_EXTENDED_KEY_USAGE_OID) == 0)
             pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_ANY;
-        else if (RTAsn1ObjId_StartsWith(&pObjIds->paItems[i], RTCRX509_ID_KP_OID))
-        {
-            if (RTAsn1ObjIdCountComponents(&pObjIds->paItems[i]) == 9)
-                switch (RTAsn1ObjIdGetLastComponentsAsUInt32(&pObjIds->paItems[i]))
+        else if (RTAsn1ObjId_StartsWith(pObjIds->papItems[i], RTCRX509_ID_KP_OID))
+        {
+            if (RTAsn1ObjIdCountComponents(pObjIds->papItems[i]) == 9)
+                switch (RTAsn1ObjIdGetLastComponentsAsUInt32(pObjIds->papItems[i]))
                 {
                     case  1: pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_SERVER_AUTH; break;
@@ -1357,38 +1357,38 @@
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_OTHER;
         }
-        else if (RTAsn1ObjId_StartsWith(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_APPLE_EXTENDED_KEY_USAGE_OID))
-        {
-            if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_OID) == 0)
+        else if (RTAsn1ObjId_StartsWith(pObjIds->papItems[i], RTCRX509_APPLE_EKU_APPLE_EXTENDED_KEY_USAGE_OID))
+        {
+            if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_CODE_SIGNING;
-            else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_DEVELOPMENT_OID) == 0)
+            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_DEVELOPMENT_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_CODE_SIGNING_DEVELOPMENT;
-            else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_SOFTWARE_UPDATE_SIGNING_OID) == 0)
+            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_SOFTWARE_UPDATE_SIGNING_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_SOFTWARE_UPDATE_SIGNING;
-            else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_THRID_PARTY_OID) == 0)
+            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_CODE_SIGNING_THRID_PARTY_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_CODE_SIGNING_THIRD_PARTY;
-            else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_RESOURCE_SIGNING_OID) == 0)
+            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_RESOURCE_SIGNING_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_RESOURCE_SIGNING;
-            else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_APPLE_EKU_SYSTEM_IDENTITY_OID) == 0)
+            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_APPLE_EKU_SYSTEM_IDENTITY_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_APPLE_SYSTEM_IDENTITY;
             else
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_OTHER;
         }
-        else if (RTAsn1ObjId_StartsWith(&pObjIds->paItems[i], "1.3.6.1.4.1.311"))
-        {
-            if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_TIMESTAMP_SIGNING_OID) == 0)
+        else if (RTAsn1ObjId_StartsWith(pObjIds->papItems[i], "1.3.6.1.4.1.311"))
+        {
+            if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_TIMESTAMP_SIGNING_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_TIMESTAMP_SIGNING;
-            else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_NT5_CRYPTO_OID) == 0)
+            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_NT5_CRYPTO_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_NT5_CRYPTO;
-            else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_OEM_WHQL_CRYPTO_OID) == 0)
+            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_OEM_WHQL_CRYPTO_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_OEM_WHQL_CRYPTO;
-            else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_EMBEDDED_NT_CRYPTO_OID) == 0)
+            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_EMBEDDED_NT_CRYPTO_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_EMBEDDED_NT_CRYPTO;
-            else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_KERNEL_MODE_CODE_SIGNING_OID) == 0)
+            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_KERNEL_MODE_CODE_SIGNING_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_KERNEL_MODE_CODE_SIGNING;
-            else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_LIFETIME_SIGNING_OID) == 0)
+            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_LIFETIME_SIGNING_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_LIFETIME_SIGNING;
-            else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_DRM_OID) == 0)
+            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_DRM_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_DRM;
-            else if (RTAsn1ObjId_CompareWithString(&pObjIds->paItems[i], RTCRX509_MS_EKU_DRM_INDIVIDUALIZATION_OID) == 0)
+            else if (RTAsn1ObjId_CompareWithString(pObjIds->papItems[i], RTCRX509_MS_EKU_DRM_INDIVIDUALIZATION_OID) == 0)
                 pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_MS_DRM_INDIVIDUALIZATION;
             else
@@ -1443,17 +1443,17 @@
     for (uint32_t i = 0; i < pThis->T3.Extensions.cItems; i++)
     {
-        PCRTASN1OBJID       pExtnId   = &pThis->T3.Extensions.paItems[i].ExtnId;
-        PCRTASN1OCTETSTRING pExtValue = &pThis->T3.Extensions.paItems[i].ExtnValue;
+        PCRTASN1OBJID       pExtnId   = &pThis->T3.Extensions.papItems[i]->ExtnId;
+        PCRTASN1OCTETSTRING pExtValue = &pThis->T3.Extensions.papItems[i]->ExtnValue;
         if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_KEY_USAGE_OID) == 0)
         {
             CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_KEY_USAGE);
-            rtCrx509TbsCertificate_AddKeyUsageFlags(pThis, &pThis->T3.Extensions.paItems[i]);
-            Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_BIT_STRING);
+            rtCrx509TbsCertificate_AddKeyUsageFlags(pThis, pThis->T3.Extensions.papItems[i]);
+            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_BIT_STRING);
         }
         else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_EXT_KEY_USAGE_OID) == 0)
         {
             CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_EXT_KEY_USAGE);
-            rtCrx509TbsCertificate_AddExtKeyUsageFlags(pThis, &pThis->T3.Extensions.paItems[i]);
-            Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_SEQ_OF_OBJ_IDS);
+            rtCrx509TbsCertificate_AddExtKeyUsageFlags(pThis, pThis->T3.Extensions.papItems[i]);
+            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_SEQ_OF_OBJ_IDS);
         }
         else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_AUTHORITY_KEY_IDENTIFIER_OID) == 0)
@@ -1461,5 +1461,5 @@
             CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_AUTHORITY_KEY_IDENTIFIER);
             pThis->T3.pAuthorityKeyIdentifier = (PCRTCRX509AUTHORITYKEYIDENTIFIER)pExtValue->pEncapsulated;
-            Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_AUTHORITY_KEY_IDENTIFIER);
+            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_AUTHORITY_KEY_IDENTIFIER);
         }
         else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_OLD_AUTHORITY_KEY_IDENTIFIER_OID) == 0)
@@ -1467,5 +1467,5 @@
             CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_OLD_AUTHORITY_KEY_IDENTIFIER);
             pThis->T3.pOldAuthorityKeyIdentifier = (PCRTCRX509OLDAUTHORITYKEYIDENTIFIER)pExtValue->pEncapsulated;
-            Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_OLD_AUTHORITY_KEY_IDENTIFIER);
+            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_OLD_AUTHORITY_KEY_IDENTIFIER);
         }
         else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_SUBJECT_KEY_IDENTIFIER_OID) == 0)
@@ -1473,5 +1473,5 @@
             CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_SUBJECT_KEY_IDENTIFIER);
             pThis->T3.pSubjectKeyIdentifier = (PCRTASN1OCTETSTRING)pExtValue->pEncapsulated;
-            Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_OCTET_STRING);
+            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_OCTET_STRING);
         }
         else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_SUBJECT_ALT_NAME_OID) == 0)
@@ -1479,5 +1479,5 @@
             CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_SUBJECT_ALT_NAME);
             pThis->T3.pAltSubjectName = (PCRTCRX509GENERALNAMES)pExtValue->pEncapsulated;
-            Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES);
+            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES);
         }
         else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_ISSUER_ALT_NAME_OID) == 0)
@@ -1485,5 +1485,5 @@
             CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_ISSUER_ALT_NAME);
             pThis->T3.pAltIssuerName = (PCRTCRX509GENERALNAMES)pExtValue->pEncapsulated;
-            Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES);
+            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES);
         }
         else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_CERTIFICATE_POLICIES_OID) == 0)
@@ -1491,5 +1491,5 @@
             CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_CERTIFICATE_POLICIES);
             pThis->T3.pCertificatePolicies = (PCRTCRX509CERTIFICATEPOLICIES)pExtValue->pEncapsulated;
-            Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_CERTIFICATE_POLICIES);
+            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_CERTIFICATE_POLICIES);
         }
         else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_POLICY_MAPPINGS_OID) == 0)
@@ -1497,5 +1497,5 @@
             CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_POLICY_MAPPINGS);
             pThis->T3.pPolicyMappings = (PCRTCRX509POLICYMAPPINGS)pExtValue->pEncapsulated;
-            Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_POLICY_MAPPINGS);
+            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_POLICY_MAPPINGS);
         }
         else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_BASIC_CONSTRAINTS_OID) == 0)
@@ -1503,5 +1503,5 @@
             CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_BASIC_CONSTRAINTS);
             pThis->T3.pBasicConstraints = (PCRTCRX509BASICCONSTRAINTS)pExtValue->pEncapsulated;
-            Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_BASIC_CONSTRAINTS);
+            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_BASIC_CONSTRAINTS);
         }
         else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_NAME_CONSTRAINTS_OID) == 0)
@@ -1509,5 +1509,5 @@
             CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_NAME_CONSTRAINTS);
             pThis->T3.pNameConstraints = (PCRTCRX509NAMECONSTRAINTS)pExtValue->pEncapsulated;
-            Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_NAME_CONSTRAINTS);
+            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_NAME_CONSTRAINTS);
         }
         else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_POLICY_CONSTRAINTS_OID) == 0)
@@ -1515,5 +1515,5 @@
             CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_POLICY_CONSTRAINTS);
             pThis->T3.pPolicyConstraints = (PCRTCRX509POLICYCONSTRAINTS)pExtValue->pEncapsulated;
-            Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_POLICY_CONSTRAINTS);
+            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_POLICY_CONSTRAINTS);
         }
         else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_INHIBIT_ANY_POLICY_OID) == 0)
@@ -1521,5 +1521,5 @@
             CHECK_SET_PRESENT_RET_ON_DUP(pThis, pErrInfo, RTCRX509TBSCERTIFICATE_F_PRESENT_INHIBIT_ANY_POLICY);
             pThis->T3.pInhibitAnyPolicy = (PCRTASN1INTEGER)pExtValue->pEncapsulated;
-            Assert(pThis->T3.Extensions.paItems[i].enmValue == RTCRX509EXTENSIONVALUE_INTEGER);
+            Assert(pThis->T3.Extensions.papItems[i]->enmValue == RTCRX509EXTENSIONVALUE_INTEGER);
         }
         else if (RTAsn1ObjId_CompareWithString(pExtnId, RTCRX509_ID_CE_ACCEPTABLE_CERT_POLICIES_OID) == 0)
@@ -1560,5 +1560,5 @@
         for (uint32_t i = 0; i < pThis->TbsCertificate.T3.Extensions.cItems; i++)
         {
-            PCRTCRX509EXTENSION pExt = &pThis->TbsCertificate.T3.Extensions.paItems[i];
+            PCRTCRX509EXTENSION pExt = pThis->TbsCertificate.T3.Extensions.papItems[i];
             if (   pExt->enmValue == RTCRX509EXTENSIONVALUE_GENERAL_NAMES
                 && RTAsn1ObjId_CompareWithString(&pExt->ExtnId, RTCRX509_ID_CE_SUBJECT_ALT_NAME_OID))
@@ -1566,6 +1566,6 @@
                 PCRTCRX509GENERALNAMES pGeneralNames = (PCRTCRX509GENERALNAMES)pExt->ExtnValue.pEncapsulated;
                 for (uint32_t j = 0; j < pGeneralNames->cItems; j++)
-                    if (   RTCRX509GENERALNAME_IS_DIRECTORY_NAME(&pGeneralNames->paItems[j])
-                        && RTCrX509Name_MatchByRfc5280(&pGeneralNames->paItems[j].u.pT4->DirectoryName, pName))
+                    if (   RTCRX509GENERALNAME_IS_DIRECTORY_NAME(pGeneralNames->papItems[j])
+                        && RTCrX509Name_MatchByRfc5280(&pGeneralNames->papItems[j]->u.pT4->DirectoryName, pName))
                         return true;
             }
@@ -1595,6 +1595,6 @@
 {
     for (uint32_t i = 0; i < pCertificates->cItems; i++)
-        if (RTCrX509Certificate_MatchIssuerAndSerialNumber(&pCertificates->paItems[i], pIssuer, pSerialNumber))
-            return &pCertificates->paItems[i];
+        if (RTCrX509Certificate_MatchIssuerAndSerialNumber(pCertificates->papItems[i], pIssuer, pSerialNumber))
+            return pCertificates->papItems[i];
     return NULL;
 }
Index: /trunk/src/VBox/Runtime/common/crypto/x509-init.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/x509-init.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/common/crypto/x509-init.cpp	(revision 64883)
@@ -49,11 +49,13 @@
 {
     uint32_t                            cRdns = pThis->cItems;
-    PRTCRX509RELATIVEDISTINGUISHEDNAME  pRdn   = &pThis->paItems[0];
+    PRTCRX509RELATIVEDISTINGUISHEDNAME *ppRdn = pThis->papItems;
     while (cRdns-- > 0)
     {
-        uint32_t                        cAttribs = pRdn->cItems;
-        PRTCRX509ATTRIBUTETYPEANDVALUE  pAttrib  = &pRdn->paItems[0];
+        PRTCRX509RELATIVEDISTINGUISHEDNAME const pRdn     = *ppRdn;
+        uint32_t                                 cAttribs = pRdn->cItems;
+        PRTCRX509ATTRIBUTETYPEANDVALUE          *ppAttrib = pRdn->papItems;
         while (cAttribs-- > 0)
         {
+            PRTCRX509ATTRIBUTETYPEANDVALUE const pAttrib = *ppAttrib;
             if (pAttrib->Value.enmType == RTASN1TYPE_STRING)
             {
@@ -62,7 +64,7 @@
                     return rc;
             }
-            pAttrib++;
+            ppAttrib++;
         }
-        pRdn++;
+        ppRdn++;
     }
     return VINF_SUCCESS;
Index: /trunk/src/VBox/Runtime/common/crypto/x509-sanity.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/x509-sanity.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/common/crypto/x509-sanity.cpp	(revision 64883)
@@ -59,18 +59,21 @@
     for (uint32_t i = 0; i < pThis->cItems; i++)
     {
-        if (pThis->cItems == 0)
+        PCRTCRX509RELATIVEDISTINGUISHEDNAME const pRdn = pThis->papItems[i];
+        if (pRdn->cItems == 0)
             return RTErrInfoSetF(pErrInfo, VERR_CR_X509_NAME_EMPTY_SUB_SET,
                                  "%s: Items[%u] has no sub components.", pszErrorTag, i);
 
-        for (uint32_t j = 0; j < pThis->paItems[i].cItems; j++)
+        for (uint32_t j = 0; j < pRdn->cItems; j++)
         {
-            if (pThis->paItems[i].paItems[j].Value.enmType != RTASN1TYPE_STRING)
+            PCRTCRX509ATTRIBUTETYPEANDVALUE const pAttr = pRdn->papItems[j];
+
+            if (pAttr->Value.enmType != RTASN1TYPE_STRING)
                 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_NAME_NOT_STRING,
                                      "%s: Items[%u].paItems[%u].enmType is %d instead of string (%d).",
-                                     pszErrorTag, i, j, pThis->paItems[i].paItems[j].Value.enmType, RTASN1TYPE_STRING);
-            if (pThis->paItems[i].paItems[j].Value.u.String.Asn1Core.cb == 0)
+                                     pszErrorTag, i, j, pAttr->Value.enmType, RTASN1TYPE_STRING);
+            if (pAttr->Value.u.String.Asn1Core.cb == 0)
                 return RTErrInfoSetF(pErrInfo, VERR_CR_X509_NAME_EMPTY_STRING,
                                      "%s: Items[%u].paItems[%u] is an empty string", pszErrorTag, i, j);
-            switch (pThis->paItems[i].paItems[j].Value.u.String.Asn1Core.uTag)
+            switch (pAttr->Value.u.String.Asn1Core.uTag)
             {
                 case ASN1_TAG_PRINTABLE_STRING:
@@ -86,5 +89,5 @@
                     return RTErrInfoSetF(pErrInfo, VERR_CR_X509_INVALID_NAME_STRING_TAG,
                                          "%s: Items[%u].paItems[%u] invalid string type: %u",  pszErrorTag, i, j,
-                                         pThis->paItems[i].paItems[j].Value.u.String.Asn1Core.uTag);
+                                         pAttr->Value.u.String.Asn1Core.uTag);
             }
         }
Index: /trunk/src/VBox/Runtime/tools/RTSignTool.cpp
===================================================================
--- /trunk/src/VBox/Runtime/tools/RTSignTool.cpp	(revision 64882)
+++ /trunk/src/VBox/Runtime/tools/RTSignTool.cpp	(revision 64883)
@@ -63,11 +63,15 @@
 
 
-typedef struct SHOWEXEPKCS7
-{
-    uint8_t const              *pbBuf;
+/**
+ * PKCS\#7 signature data.
+ */
+typedef struct SIGNTOOLPKCS7
+{
+    /** The raw signature. */
+    uint8_t                    *pbBuf;
+    /** Size of the raw signature. */
     size_t                      cbBuf;
+    /** The filename.   */
     const char                 *pszFilename;
-    unsigned                    cVerbosity;
-    RTLDRMOD                    hLdrMod;
     /** The outer content info wrapper. */
     RTCRPKCS7CONTENTINFO        ContentInfo;
@@ -76,6 +80,29 @@
     /** Pointer to the indirect data content. */
     PRTCRSPCINDIRECTDATACONTENT pIndData;
-
+} SIGNTOOLPKCS7;
+typedef SIGNTOOLPKCS7 *PSIGNTOOLPKCS7;
+
+
+/**
+ * PKCS\#7 signature data for executable.
+ */
+typedef struct SIGNTOOLPKCS7EXE : public SIGNTOOLPKCS7
+{
+    /** The module handle. */
+    RTLDRMOD                    hLdrMod;
+} SIGNTOOLPKCS7EXE;
+typedef SIGNTOOLPKCS7EXE *PSIGNTOOLPKCS7EXE;
+
+
+/**
+ * Data for the show exe (signature) command.
+ */
+typedef struct SHOWEXEPKCS7 : public SIGNTOOLPKCS7EXE
+{
+    /** The verbosity. */
+    unsigned                    cVerbosity;
+    /** The prefix buffer. */
     char                        szPrefix[256];
+    /** Temporary buffer. */
     char                        szTmp[4096];
 } SHOWEXEPKCS7;
@@ -94,567 +121,36 @@
 
 
-
-
-/*
- * The 'extract-exe-signer-cert' command.
- */
-static RTEXITCODE HelpExtractExeSignerCert(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
-{
-    RT_NOREF_PV(enmLevel);
-    RTStrmPrintf(pStrm, "extract-exe-signer-cert [--ber|--cer|--der] [--exe|-e] <exe> [--output|-o] <outfile.cer>\n");
-    return RTEXITCODE_SUCCESS;
-}
-
-static RTEXITCODE HandleExtractExeSignerCert(int cArgs, char **papszArgs)
-{
-    /*
-     * Parse arguments.
-     */
-    static const RTGETOPTDEF s_aOptions[] =
-    {
-        { "--ber",    'b', RTGETOPT_REQ_NOTHING },
-        { "--cer",    'c', RTGETOPT_REQ_NOTHING },
-        { "--der",    'd', RTGETOPT_REQ_NOTHING },
-        { "--exe",    'e', RTGETOPT_REQ_STRING },
-        { "--output", 'o', RTGETOPT_REQ_STRING },
-    };
-
-    const char *pszExe = NULL;
-    const char *pszOut = NULL;
-    RTLDRARCH   enmLdrArch   = RTLDRARCH_WHATEVER;
-    uint32_t    fCursorFlags = RTASN1CURSOR_FLAGS_DER;
-
-    RTGETOPTSTATE GetState;
-    int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
-    AssertRCReturn(rc, RTEXITCODE_FAILURE);
-    RTGETOPTUNION ValueUnion;
-    int ch;
-    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
-    {
-        switch (ch)
-        {
-            case 'e':   pszExe = ValueUnion.psz; break;
-            case 'o':   pszOut = ValueUnion.psz; break;
-            case 'b':   fCursorFlags = 0; break;
-            case 'c':   fCursorFlags = RTASN1CURSOR_FLAGS_CER; break;
-            case 'd':   fCursorFlags = RTASN1CURSOR_FLAGS_DER; break;
-            case 'V':   return HandleVersion(cArgs, papszArgs);
-            case 'h':   return HelpExtractExeSignerCert(g_pStdOut, RTSIGNTOOLHELP_FULL);
-
-            case VINF_GETOPT_NOT_OPTION:
-                if (!pszExe)
-                    pszExe = ValueUnion.psz;
-                else if (!pszOut)
-                    pszOut = ValueUnion.psz;
-                else
-                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many file arguments: %s", ValueUnion.psz);
-                break;
-
-            default:
-                return RTGetOptPrintError(ch, &ValueUnion);
-        }
-    }
-    if (!pszExe)
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No executable given.");
-    if (!pszOut)
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No output file given.");
-    if (RTPathExists(pszOut))
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "The output file '%s' exists.", pszOut);
-
-    /*
-     * Do it.
-     */
-
-    /* Open the executable image and query the PKCS7 info. */
-    RTLDRMOD hLdrMod;
-    rc = RTLdrOpen(pszExe, RTLDR_O_FOR_VALIDATION, enmLdrArch, &hLdrMod);
-    if (RT_FAILURE(rc))
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszExe, rc);
-
-    RTEXITCODE rcExit = RTEXITCODE_FAILURE;
-#ifdef DEBUG
-    size_t     cbBuf = 64;
-#else
-    size_t     cbBuf = _512K;
-#endif
-    void      *pvBuf = RTMemAlloc(cbBuf);
-    size_t     cbRet = 0;
-    rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbRet);
-    if (rc == VERR_BUFFER_OVERFLOW && cbRet < _4M && cbRet > 0)
-    {
-        RTMemFree(pvBuf);
-        cbBuf = cbRet;
-        pvBuf = RTMemAlloc(cbBuf);
-        rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbRet);
-    }
-    if (RT_SUCCESS(rc))
-    {
-        static RTERRINFOSTATIC s_StaticErrInfo;
-        RTErrInfoInitStatic(&s_StaticErrInfo);
-
-        /*
-         * Decode the output.
-         */
-        RTASN1CURSORPRIMARY PrimaryCursor;
-        RTAsn1CursorInitPrimary(&PrimaryCursor, pvBuf, (uint32_t)cbRet, &s_StaticErrInfo.Core,
-                                &g_RTAsn1DefaultAllocator, fCursorFlags, "exe");
-        RTCRPKCS7CONTENTINFO Pkcs7Ci;
-        rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &Pkcs7Ci, "pkcs7");
-        if (RT_SUCCESS(rc))
-        {
-            if (RTCrPkcs7ContentInfo_IsSignedData(&Pkcs7Ci))
-            {
-                PCRTCRPKCS7SIGNEDDATA pSd = Pkcs7Ci.u.pSignedData;
-                if (pSd->SignerInfos.cItems == 1)
-                {
-                    PCRTCRPKCS7ISSUERANDSERIALNUMBER pISN = &pSd->SignerInfos.paItems[0].IssuerAndSerialNumber;
-                    PCRTCRX509CERTIFICATE pCert;
-                    pCert = RTCrPkcs7SetOfCerts_FindX509ByIssuerAndSerialNumber(&pSd->Certificates,
-                                                                                &pISN->Name, &pISN->SerialNumber);
-                    if (pCert)
-                    {
-                        /*
-                         * Write it out.
-                         */
-                        RTFILE hFile;
-                        rc = RTFileOpen(&hFile, pszOut, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE);
-                        if (RT_SUCCESS(rc))
-                        {
-                            uint32_t cbCert = pCert->SeqCore.Asn1Core.cbHdr + pCert->SeqCore.Asn1Core.cb;
-                            rc = RTFileWrite(hFile, pCert->SeqCore.Asn1Core.uData.pu8 - pCert->SeqCore.Asn1Core.cbHdr,
-                                             cbCert, NULL);
-                            if (RT_SUCCESS(rc))
-                            {
-                                rc = RTFileClose(hFile);
-                                if (RT_SUCCESS(rc))
-                                {
-                                    hFile  = NIL_RTFILE;
-                                    rcExit = RTEXITCODE_SUCCESS;
-                                    RTMsgInfo("Successfully wrote %u bytes to '%s'", cbCert, pszOut);
-                                }
-                                else
-                                    RTMsgError("RTFileClose failed: %Rrc", rc);
-                            }
-                            else
-                                RTMsgError("RTFileWrite failed: %Rrc", rc);
-                            RTFileClose(hFile);
-                        }
-                        else
-                            RTMsgError("Error opening '%s': %Rrc", pszOut, rc);
-                    }
-                    else
-                        RTMsgError("Certificate not found.");
-                }
-                else
-                    RTMsgError("SignerInfo count: %u", pSd->SignerInfos.cItems);
-            }
-            else
-                RTMsgError("No PKCS7 content: ContentType=%s", Pkcs7Ci.ContentType.szObjId);
-            RTAsn1VtDelete(&Pkcs7Ci.SeqCore.Asn1Core);
-        }
-        else
-            RTMsgError("RTPkcs7ContentInfoDecodeAsn1 failed: %Rrc - %s", rc, s_StaticErrInfo.szMsg);
-    }
-    else
-        RTMsgError("RTLDRPROP_PKCS7_SIGNED_DATA failed on '%s': %Rrc", pszExe, rc);
-    RTMemFree(pvBuf);
-    rc = RTLdrClose(hLdrMod);
-    if (RT_FAILURE(rc))
-        rcExit = RTMsgErrorExit(RTEXITCODE_FAILURE, "RTLdrClose failed: %Rrc\n", rc);
-    return rcExit;
-}
-
-#ifndef IPRT_IN_BUILD_TOOL
-
-/*
- * The 'verify-exe' command.
- */
-static RTEXITCODE HelpVerifyExe(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
-{
-    RT_NOREF_PV(enmLevel);
-    RTStrmPrintf(pStrm,
-                 "verify-exe [--verbose|--quiet] [--kernel] [--root <root-cert.der>] [--additional <supp-cert.der>]\n"
-                 "        [--type <win|osx>] <exe1> [exe2 [..]]\n");
-    return RTEXITCODE_SUCCESS;
-}
-
-typedef struct VERIFYEXESTATE
-{
-    RTCRSTORE   hRootStore;
-    RTCRSTORE   hKernelRootStore;
-    RTCRSTORE   hAdditionalStore;
-    bool        fKernel;
-    int         cVerbose;
-    enum { kSignType_Windows, kSignType_OSX } enmSignType;
-    uint64_t    uTimestamp;
-    RTLDRARCH   enmLdrArch;
-} VERIFYEXESTATE;
-
-# ifdef VBOX
-/** Certificate store load set.
- * Declared outside HandleVerifyExe because of braindead gcc visibility crap. */
-struct STSTORESET
-{
-    RTCRSTORE       hStore;
-    PCSUPTAENTRY    paTAs;
-    unsigned        cTAs;
-};
-# endif
-
 /**
- * @callback_method_impl{FNRTCRPKCS7VERIFYCERTCALLBACK,
- * Standard code signing.  Use this for Microsoft SPC.}
- */
-static DECLCALLBACK(int) VerifyExecCertVerifyCallback(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags,
-                                                      void *pvUser, PRTERRINFO pErrInfo)
-{
-    VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser;
-    uint32_t        cPaths = hCertPaths != NIL_RTCRX509CERTPATHS ? RTCrX509CertPathsGetPathCount(hCertPaths) : 0;
-
-    /*
-     * Dump all the paths.
-     */
-    if (pState->cVerbose > 0)
-    {
-        for (uint32_t iPath = 0; iPath < cPaths; iPath++)
-        {
-            RTPrintf("---\n");
-            RTCrX509CertPathsDumpOne(hCertPaths, iPath, pState->cVerbose, RTStrmDumpPrintfV, g_pStdOut);
-            *pErrInfo->pszMsg = '\0';
-        }
-        RTPrintf("---\n");
-    }
-
-    /*
-     * Test signing certificates normally doesn't have all the necessary
-     * features required below.  So, treat them as special cases.
-     */
-    if (   hCertPaths == NIL_RTCRX509CERTPATHS
-        && RTCrX509Name_Compare(&pCert->TbsCertificate.Issuer, &pCert->TbsCertificate.Subject) == 0)
-    {
-        RTMsgInfo("Test signed.\n");
-        return VINF_SUCCESS;
-    }
-
-    if (hCertPaths == NIL_RTCRX509CERTPATHS)
-        RTMsgInfo("Signed by trusted certificate.\n");
-
-    /*
-     * Standard code signing capabilites required.
-     */
-    int rc = RTCrPkcs7VerifyCertCallbackCodeSigning(pCert, hCertPaths, fFlags, NULL, pErrInfo);
-    if (   RT_SUCCESS(rc)
-        && (fFlags & RTCRPKCS7VCC_F_SIGNED_DATA))
-    {
-        /*
-         * If kernel signing, a valid certificate path must be anchored by the
-         * microsoft kernel signing root certificate.  The only alternative is
-         * test signing.
-         */
-        if (pState->fKernel && hCertPaths != NIL_RTCRX509CERTPATHS)
-        {
-            uint32_t cFound = 0;
-            uint32_t cValid = 0;
-            for (uint32_t iPath = 0; iPath < cPaths; iPath++)
-            {
-                bool                            fTrusted;
-                PCRTCRX509NAME                  pSubject;
-                PCRTCRX509SUBJECTPUBLICKEYINFO  pPublicKeyInfo;
-                int                             rcVerify;
-                rc = RTCrX509CertPathsQueryPathInfo(hCertPaths, iPath, &fTrusted, NULL /*pcNodes*/, &pSubject, &pPublicKeyInfo,
-                                                    NULL, NULL /*pCertCtx*/, &rcVerify);
-                AssertRCBreak(rc);
-
-                if (RT_SUCCESS(rcVerify))
-                {
-                    Assert(fTrusted);
-                    cValid++;
-
-                    /* Search the kernel signing root store for a matching anchor. */
-                    RTCRSTORECERTSEARCH Search;
-                    rc = RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280(pState->hKernelRootStore, pSubject, &Search);
-                    AssertRCBreak(rc);
-                    PCRTCRCERTCTX pCertCtx;
-                    while ((pCertCtx = RTCrStoreCertSearchNext(pState->hKernelRootStore, &Search)) != NULL)
-                    {
-                        PCRTCRX509SUBJECTPUBLICKEYINFO pPubKeyInfo;
-                        if (pCertCtx->pCert)
-                            pPubKeyInfo = &pCertCtx->pCert->TbsCertificate.SubjectPublicKeyInfo;
-                        else if (pCertCtx->pTaInfo)
-                            pPubKeyInfo = &pCertCtx->pTaInfo->PubKey;
-                        else
-                            pPubKeyInfo = NULL;
-                        if (RTCrX509SubjectPublicKeyInfo_Compare(pPubKeyInfo, pPublicKeyInfo) == 0)
-                            cFound++;
-                        RTCrCertCtxRelease(pCertCtx);
-                    }
-
-                    int rc2 = RTCrStoreCertSearchDestroy(pState->hKernelRootStore, &Search); AssertRC(rc2);
-                }
-            }
-            if (RT_SUCCESS(rc) && cFound == 0)
-                rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "Not valid kernel code signature.");
-            if (RT_SUCCESS(rc) && cValid != 2)
-                RTMsgWarning("%u valid paths, expected 2", cValid);
-        }
-    }
-
-    return rc;
-}
-
-
-/** @callback_method_impl{FNRTLDRVALIDATESIGNEDDATA}  */
-static DECLCALLBACK(int) VerifyExeCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
-                                           void const *pvSignature, size_t cbSignature,
-                                           PRTERRINFO pErrInfo, void *pvUser)
-{
-    VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser;
-    RT_NOREF_PV(hLdrMod); RT_NOREF_PV(cbSignature);
-
-    switch (enmSignature)
-    {
-        case RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA:
-        {
-            PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pvSignature;
-
-            RTTIMESPEC ValidationTime;
-            RTTimeSpecSetSeconds(&ValidationTime, pState->uTimestamp);
-
-            /*
-             * Dump the signed data if so requested.
-             */
-            if (pState->cVerbose)
-                RTAsn1Dump(&pContentInfo->SeqCore.Asn1Core, 0, 0, RTStrmDumpPrintfV, g_pStdOut);
-
-
-            /*
-             * Do the actual verification.  Will have to modify this so it takes
-             * the authenticode policies into account.
-             */
-            return RTCrPkcs7VerifySignedData(pContentInfo,
-                                             RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY
-                                             | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
-                                             | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT,
-                                             pState->hAdditionalStore, pState->hRootStore, &ValidationTime,
-                                             VerifyExecCertVerifyCallback, pState, pErrInfo);
-        }
-
-        default:
-            return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", enmSignature);
-    }
-}
-
-/** Worker for HandleVerifyExe. */
-static RTEXITCODE HandleVerifyExeWorker(VERIFYEXESTATE *pState, const char *pszFilename, PRTERRINFOSTATIC pStaticErrInfo)
-{
-    /*
-     * Open the executable image and verify it.
-     */
-    RTLDRMOD hLdrMod;
-    int rc = RTLdrOpen(pszFilename, RTLDR_O_FOR_VALIDATION, pState->enmLdrArch, &hLdrMod);
-    if (RT_FAILURE(rc))
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszFilename, rc);
-
-
-    rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &pState->uTimestamp, sizeof(pState->uTimestamp));
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
-        if (RT_SUCCESS(rc))
-            RTMsgInfo("'%s' is valid.\n", pszFilename);
-        else if (rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME)
-        {
-            RTTIMESPEC Now;
-            pState->uTimestamp = RTTimeSpecGetSeconds(RTTimeNow(&Now));
-            rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
-            if (RT_SUCCESS(rc))
-                RTMsgInfo("'%s' is valid now, but not at link time.\n", pszFilename);
-        }
-        if (RT_FAILURE(rc))
-            RTMsgError("RTLdrVerifySignature failed on '%s': %Rrc - %s\n", pszFilename, rc, pStaticErrInfo->szMsg);
-    }
-    else
-        RTMsgError("RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on '%s': %Rrc\n", pszFilename, rc);
-
-    int rc2 = RTLdrClose(hLdrMod);
-    if (RT_FAILURE(rc2))
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTLdrClose failed: %Rrc\n", rc2);
-    if (RT_FAILURE(rc))
-        return rc != VERR_LDRVI_NOT_SIGNED ? RTEXITCODE_FAILURE : RTEXITCODE_SKIPPED;
-
-    return RTEXITCODE_SUCCESS;
-}
-
-
-static RTEXITCODE HandleVerifyExe(int cArgs, char **papszArgs)
-{
-    RTERRINFOSTATIC StaticErrInfo;
-
-    /* Note! This code does not try to clean up the crypto stores on failure.
-             This is intentional as the code is only expected to be used in a
-             one-command-per-process environment where we do exit() upon
-             returning from this function. */
-
-    /*
-     * Parse arguments.
-     */
-    static const RTGETOPTDEF s_aOptions[] =
-    {
-        { "--kernel",       'k', RTGETOPT_REQ_NOTHING },
-        { "--root",         'r', RTGETOPT_REQ_STRING },
-        { "--additional",   'a', RTGETOPT_REQ_STRING },
-        { "--add",          'a', RTGETOPT_REQ_STRING },
-        { "--type",         't', RTGETOPT_REQ_STRING },
-        { "--verbose",      'v', RTGETOPT_REQ_NOTHING },
-        { "--quiet",        'q', RTGETOPT_REQ_NOTHING },
-    };
-
-    VERIFYEXESTATE State =
-    {
-        NIL_RTCRSTORE, NIL_RTCRSTORE, NIL_RTCRSTORE, false, false,
-        VERIFYEXESTATE::kSignType_Windows, 0, RTLDRARCH_WHATEVER
-    };
-    int rc = RTCrStoreCreateInMem(&State.hRootStore, 0);
-    if (RT_SUCCESS(rc))
-        rc = RTCrStoreCreateInMem(&State.hKernelRootStore, 0);
-    if (RT_SUCCESS(rc))
-        rc = RTCrStoreCreateInMem(&State.hAdditionalStore, 0);
-    if (RT_FAILURE(rc))
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error creating in-memory certificate store: %Rrc", rc);
-
-    RTGETOPTSTATE GetState;
-    rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
-    AssertRCReturn(rc, RTEXITCODE_FAILURE);
-    RTGETOPTUNION ValueUnion;
-    int ch;
-    while ((ch = RTGetOpt(&GetState, &ValueUnion)) && ch != VINF_GETOPT_NOT_OPTION)
-    {
-        switch (ch)
-        {
-            case 'r': case 'a':
-                rc = RTCrStoreCertAddFromFile(ch == 'r' ? State.hRootStore : State.hAdditionalStore,
-                                              RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR,
-                                              ValueUnion.psz, RTErrInfoInitStatic(&StaticErrInfo));
-                if (RT_FAILURE(rc))
-                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error loading certificate '%s': %Rrc - %s",
-                                          ValueUnion.psz, rc, StaticErrInfo.szMsg);
-                if (RTErrInfoIsSet(&StaticErrInfo.Core))
-                    RTMsgWarning("Warnings loading certificate '%s': %s", ValueUnion.psz, StaticErrInfo.szMsg);
-                break;
-
-            case 't':
-                if (!strcmp(ValueUnion.psz, "win") || !strcmp(ValueUnion.psz, "windows"))
-                    State.enmSignType = VERIFYEXESTATE::kSignType_Windows;
-                else if (!strcmp(ValueUnion.psz, "osx") || !strcmp(ValueUnion.psz, "apple"))
-                    State.enmSignType = VERIFYEXESTATE::kSignType_OSX;
-                else
-                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown signing type: '%s'", ValueUnion.psz);
-                break;
-
-            case 'k': State.fKernel = true; break;
-            case 'v': State.cVerbose++; break;
-            case 'q': State.cVerbose = 0; break;
-            case 'V': return HandleVersion(cArgs, papszArgs);
-            case 'h': return HelpVerifyExe(g_pStdOut, RTSIGNTOOLHELP_FULL);
-            default:  return RTGetOptPrintError(ch, &ValueUnion);
-        }
-    }
-    if (ch != VINF_GETOPT_NOT_OPTION)
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No executable given.");
-
-    /*
-     * Populate the certificate stores according to the signing type.
-     */
-#ifdef VBOX
-    unsigned          cSets = 0;
-    struct STSTORESET aSets[6];
-#endif
-
-    switch (State.enmSignType)
-    {
-        case VERIFYEXESTATE::kSignType_Windows:
-#ifdef VBOX
-            aSets[cSets].hStore  = State.hRootStore;
-            aSets[cSets].paTAs   = g_aSUPTimestampTAs;
-            aSets[cSets].cTAs    = g_cSUPTimestampTAs;
-            cSets++;
-            aSets[cSets].hStore  = State.hRootStore;
-            aSets[cSets].paTAs   = g_aSUPSpcRootTAs;
-            aSets[cSets].cTAs    = g_cSUPSpcRootTAs;
-            cSets++;
-            aSets[cSets].hStore  = State.hRootStore;
-            aSets[cSets].paTAs   = g_aSUPNtKernelRootTAs;
-            aSets[cSets].cTAs    = g_cSUPNtKernelRootTAs;
-            cSets++;
-            aSets[cSets].hStore  = State.hKernelRootStore;
-            aSets[cSets].paTAs   = g_aSUPNtKernelRootTAs;
-            aSets[cSets].cTAs    = g_cSUPNtKernelRootTAs;
-            cSets++;
-#endif
-            break;
-
-        case VERIFYEXESTATE::kSignType_OSX:
-            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Mac OS X executable signing is not implemented.");
-    }
-
-#ifdef VBOX
-    for (unsigned i = 0; i < cSets; i++)
-        for (unsigned j = 0; j < aSets[i].cTAs; j++)
-        {
-            rc = RTCrStoreCertAddEncoded(aSets[i].hStore, RTCRCERTCTX_F_ENC_TAF_DER, aSets[i].paTAs[j].pch,
-                                         aSets[i].paTAs[j].cb, RTErrInfoInitStatic(&StaticErrInfo));
-            if (RT_FAILURE(rc))
-                return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTCrStoreCertAddEncoded failed (%u/%u): %s",
-                                      i, j, StaticErrInfo.szMsg);
-        }
-#endif
-
-    /*
-     * Do it.
-     */
-    RTEXITCODE rcExit;
-    for (;;)
-    {
-        rcExit = HandleVerifyExeWorker(&State, ValueUnion.psz, &StaticErrInfo);
-        if (rcExit != RTEXITCODE_SUCCESS)
-            break;
-
-        /*
-         * Next file
-         */
-        ch = RTGetOpt(&GetState, &ValueUnion);
-        if (ch == 0)
-            break;
-        if (ch != VINF_GETOPT_NOT_OPTION)
-        {
-            rcExit = RTGetOptPrintError(ch, &ValueUnion);
-            break;
-        }
-    }
-
-    /*
-     * Clean up.
-     */
-    uint32_t cRefs;
-    cRefs = RTCrStoreRelease(State.hRootStore);       Assert(cRefs == 0);
-    cRefs = RTCrStoreRelease(State.hKernelRootStore); Assert(cRefs == 0);
-    cRefs = RTCrStoreRelease(State.hAdditionalStore); Assert(cRefs == 0);
-
-    return rcExit;
-}
-
-#endif /* !IPRT_IN_BUILD_TOOL */
-////
-#ifndef IPRT_IN_BUILD_TOOL
-
-/*
- * The 'show-exe' command.
- */
-static RTEXITCODE HelpShowExe(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
-{
-    RT_NOREF_PV(enmLevel);
-    RTStrmPrintf(pStrm,
-                 "show-exe [--verbose|-v] [--quiet|-q] <exe1> [exe2 [..]]\n");
-    return RTEXITCODE_SUCCESS;
+ * Deletes the structure.
+ *
+ * @param   pThis               The structure to initialize.
+ */
+static void SignToolPkcs7_Delete(PSIGNTOOLPKCS7 pThis)
+{
+    RTCrPkcs7ContentInfo_Delete(&pThis->ContentInfo);
+    pThis->pIndData    = NULL;
+    pThis->pSignedData = NULL;
+    pThis->pIndData    = NULL;
+    RTMemFree(pThis->pbBuf);
+    pThis->pbBuf       = NULL;
+    pThis->cbBuf       = 0;
+}
+
+
+/**
+ * Deletes the structure.
+ *
+ * @param   pThis               The structure to initialize.
+ */
+static void SignToolPkcs7Exe_Delete(PSIGNTOOLPKCS7EXE pThis)
+{
+    if (pThis->hLdrMod != NIL_RTLDRMOD)
+    {
+        int rc2 = RTLdrClose(pThis->hLdrMod);
+        if (RT_FAILURE(rc2))
+            RTMsgError("RTLdrClose failed: %Rrc\n", rc2);
+        pThis->hLdrMod = NIL_RTLDRMOD;
+    }
+    SignToolPkcs7_Delete(pThis);
 }
 
@@ -663,8 +159,8 @@
  * Decodes the PKCS #7 blob pointed to by pThis->pbBuf.
  *
- * @returns IPRT status code.
- * @param   pThis               The show exe instance data.
- */
-static int HandleShowExeWorkerPkcs7Decode(PSHOWEXEPKCS7 pThis)
+ * @returns IPRT status code (error message already shown on failure).
+ * @param   pThis               The PKCS\#7 signature to decode.
+ */
+static int SignToolPkcs7_Decode(PSIGNTOOLPKCS7 pThis)
 {
     RTERRINFOSTATIC     ErrInfo;
@@ -724,4 +220,760 @@
 
 /**
+ * Reads and decodes PKCS\#7 signature from the given executable.
+ *
+ * @returns RTEXITCODE_SUCCESS on success, RTEXITCODE_FAILURE with error message
+ *          on failure.
+ * @param   pThis               The structure to initialize.
+ * @param   pszFilename         The executable filename.
+ * @param   cVerbosity          The verbosity.
+ * @param   enmLdrArch          For FAT binaries.
+ */
+static RTEXITCODE SignToolPkcs7Exe_InitFromFile(PSIGNTOOLPKCS7EXE pThis, const char *pszFilename,
+                                                unsigned cVerbosity, RTLDRARCH enmLdrArch = RTLDRARCH_WHATEVER)
+{
+    /*
+     * Init the return structure.
+     */
+    RT_ZERO(*pThis);
+    pThis->hLdrMod = NIL_RTLDRMOD;
+    pThis->pszFilename = pszFilename;
+
+    /*
+     * Open the image and check if it's signed.
+     */
+    int rc = RTLdrOpen(pszFilename, RTLDR_O_FOR_VALIDATION, enmLdrArch, &pThis->hLdrMod);
+    if (RT_SUCCESS(rc))
+    {
+        bool fIsSigned = false;
+        rc = RTLdrQueryProp(pThis->hLdrMod, RTLDRPROP_IS_SIGNED, &fIsSigned, sizeof(fIsSigned));
+        if (RT_SUCCESS(rc) && fIsSigned)
+        {
+            /*
+             * Query the PKCS#7 data (assuming M$ style signing) and hand it to a worker.
+             */
+            size_t cbActual = 0;
+#ifdef DEBUG
+            size_t cbBuf    = 64;
+#else
+            size_t cbBuf    = _512K;
+#endif
+            void  *pvBuf    = RTMemAllocZ(cbBuf);
+            if (pvBuf)
+            {
+                rc = RTLdrQueryPropEx(pThis->hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbActual);
+                if (rc == VERR_BUFFER_OVERFLOW)
+                {
+                    RTMemFree(pvBuf);
+                    cbBuf = cbActual;
+                    pvBuf = RTMemAllocZ(cbActual);
+                    if (pvBuf)
+                        rc = RTLdrQueryPropEx(pThis->hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/,
+                                              pvBuf, cbBuf, &cbActual);
+                    else
+                        rc = VERR_NO_MEMORY;
+                }
+            }
+            else
+                rc = VERR_NO_MEMORY;
+
+            pThis->pbBuf = (uint8_t *)pvBuf;
+            pThis->cbBuf = cbActual;
+            if (RT_SUCCESS(rc))
+            {
+                if (cVerbosity > 2)
+                    RTPrintf("PKCS#7 signature: %u bytes\n", cbActual);
+
+                /*
+                 * Decode it.
+                 */
+                rc = SignToolPkcs7_Decode(pThis);
+                if (RT_SUCCESS(rc))
+                    return RTEXITCODE_SUCCESS;
+            }
+            else
+                RTMsgError("RTLdrQueryPropEx/RTLDRPROP_PKCS7_SIGNED_DATA failed on '%s': %Rrc\n", pszFilename, rc);
+        }
+        else if (RT_SUCCESS(rc))
+            RTMsgInfo("'%s': not signed\n", pszFilename);
+        else
+            RTMsgError("RTLdrQueryProp/RTLDRPROP_IS_SIGNED failed on '%s': %Rrc\n", pszFilename, rc);
+    }
+    else
+        RTMsgError("Error opening executable image '%s': %Rrc", pszFilename, rc);
+
+    SignToolPkcs7Exe_Delete(pThis);
+    return RTEXITCODE_FAILURE;
+
+}
+
+
+/*
+ * The 'extract-exe-signer-cert' command.
+ */
+static RTEXITCODE HelpExtractExeSignerCert(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
+{
+    RT_NOREF_PV(enmLevel);
+    RTStrmPrintf(pStrm, "extract-exe-signer-cert [--ber|--cer|--der] [--exe|-e] <exe> [--output|-o] <outfile.cer>\n");
+    return RTEXITCODE_SUCCESS;
+}
+
+static RTEXITCODE HandleExtractExeSignerCert(int cArgs, char **papszArgs)
+{
+    /*
+     * Parse arguments.
+     */
+    static const RTGETOPTDEF s_aOptions[] =
+    {
+        { "--ber",    'b', RTGETOPT_REQ_NOTHING },
+        { "--cer",    'c', RTGETOPT_REQ_NOTHING },
+        { "--der",    'd', RTGETOPT_REQ_NOTHING },
+        { "--exe",    'e', RTGETOPT_REQ_STRING },
+        { "--output", 'o', RTGETOPT_REQ_STRING },
+    };
+
+    const char *pszExe = NULL;
+    const char *pszOut = NULL;
+    RTLDRARCH   enmLdrArch   = RTLDRARCH_WHATEVER;
+    unsigned    cVerbosity   = 0;
+    uint32_t    fCursorFlags = RTASN1CURSOR_FLAGS_DER;
+
+    RTGETOPTSTATE GetState;
+    int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+    AssertRCReturn(rc, RTEXITCODE_FAILURE);
+    RTGETOPTUNION ValueUnion;
+    int ch;
+    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
+    {
+        switch (ch)
+        {
+            case 'e':   pszExe = ValueUnion.psz; break;
+            case 'o':   pszOut = ValueUnion.psz; break;
+            case 'b':   fCursorFlags = 0; break;
+            case 'c':   fCursorFlags = RTASN1CURSOR_FLAGS_CER; break;
+            case 'd':   fCursorFlags = RTASN1CURSOR_FLAGS_DER; break;
+            case 'V':   return HandleVersion(cArgs, papszArgs);
+            case 'h':   return HelpExtractExeSignerCert(g_pStdOut, RTSIGNTOOLHELP_FULL);
+
+            case VINF_GETOPT_NOT_OPTION:
+                if (!pszExe)
+                    pszExe = ValueUnion.psz;
+                else if (!pszOut)
+                    pszOut = ValueUnion.psz;
+                else
+                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many file arguments: %s", ValueUnion.psz);
+                break;
+
+            default:
+                return RTGetOptPrintError(ch, &ValueUnion);
+        }
+    }
+    if (!pszExe)
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No executable given.");
+    if (!pszOut)
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No output file given.");
+    if (RTPathExists(pszOut))
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "The output file '%s' exists.", pszOut);
+
+    /*
+     * Do it.
+     */
+    /* Read & decode the PKCS#7 signature. */
+    SIGNTOOLPKCS7EXE This;
+    RTEXITCODE rcExit = SignToolPkcs7Exe_InitFromFile(&This, pszExe, cVerbosity, enmLdrArch);
+    if (rcExit == RTEXITCODE_SUCCESS)
+    {
+        /* Find the signing certificate (ASSUMING there's only one signer and that
+           the certificate used is shipped in the set of certificates). */
+        rcExit = RTEXITCODE_FAILURE;
+        if (This.pSignedData->SignerInfos.cItems == 1)
+        {
+            PCRTCRPKCS7ISSUERANDSERIALNUMBER pISN = &This.pSignedData->SignerInfos.papItems[0]->IssuerAndSerialNumber;
+            PCRTCRX509CERTIFICATE pCert;
+            pCert = RTCrPkcs7SetOfCerts_FindX509ByIssuerAndSerialNumber(&This.pSignedData->Certificates,
+                                                                        &pISN->Name, &pISN->SerialNumber);
+            if (pCert)
+            {
+                /*
+                 * Write it out.
+                 */
+                RTFILE hFile;
+                rc = RTFileOpen(&hFile, pszOut, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE);
+                if (RT_SUCCESS(rc))
+                {
+                    uint32_t cbCert = pCert->SeqCore.Asn1Core.cbHdr + pCert->SeqCore.Asn1Core.cb;
+                    rc = RTFileWrite(hFile, pCert->SeqCore.Asn1Core.uData.pu8 - pCert->SeqCore.Asn1Core.cbHdr,
+                                     cbCert, NULL);
+                    if (RT_SUCCESS(rc))
+                    {
+                        rc = RTFileClose(hFile);
+                        if (RT_SUCCESS(rc))
+                        {
+                            hFile  = NIL_RTFILE;
+                            rcExit = RTEXITCODE_SUCCESS;
+                            RTMsgInfo("Successfully wrote %u bytes to '%s'", cbCert, pszOut);
+                        }
+                        else
+                            RTMsgError("RTFileClose failed: %Rrc", rc);
+                    }
+                    else
+                        RTMsgError("RTFileWrite failed: %Rrc", rc);
+                    RTFileClose(hFile);
+                }
+                else
+                    RTMsgError("Error opening '%s' for writing: %Rrc", pszOut, rc);
+            }
+            else
+                RTMsgError("Certificate not found.");
+        }
+        else
+            RTMsgError("SignerInfo count: %u", This.pSignedData->SignerInfos.cItems);
+
+
+        /* Delete the signature data. */
+        SignToolPkcs7Exe_Delete(&This);
+    }
+    return rcExit;
+}
+
+
+/*
+ * The 'add-nested-exe-signature' command.
+ */
+static RTEXITCODE HelpAddNestedExeSignature(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
+{
+    RT_NOREF_PV(enmLevel);
+    RTStrmPrintf(pStrm, "add-nested-exe-signature [-v|--verbose] <destination-exe> <source-exe>\n");
+    return RTEXITCODE_SUCCESS;
+}
+
+
+static RTEXITCODE HandleAddNestedExeSignature(int cArgs, char **papszArgs)
+{
+    /*
+     * Parse arguments.
+     */
+    static const RTGETOPTDEF s_aOptions[] =
+    {
+        { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
+    };
+
+    const char *pszDst = NULL;
+    const char *pszSrc = NULL;
+    unsigned    cVerbosity = 0;
+
+    RTGETOPTSTATE GetState;
+    int rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+    AssertRCReturn(rc, RTEXITCODE_FAILURE);
+    RTGETOPTUNION ValueUnion;
+    int ch;
+    while ((ch = RTGetOpt(&GetState, &ValueUnion)))
+    {
+        switch (ch)
+        {
+            case 'v':   cVerbosity++; break;
+            case 'V':   return HandleVersion(cArgs, papszArgs);
+            case 'h':   return HelpExtractExeSignerCert(g_pStdOut, RTSIGNTOOLHELP_FULL);
+
+            case VINF_GETOPT_NOT_OPTION:
+                if (!pszDst)
+                    pszDst = ValueUnion.psz;
+                else if (!pszSrc)
+                    pszSrc = ValueUnion.psz;
+                else
+                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "Too many file arguments: %s", ValueUnion.psz);
+                break;
+
+            default:
+                return RTGetOptPrintError(ch, &ValueUnion);
+        }
+    }
+    if (!pszDst)
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No destination excutable given.");
+    if (!pszSrc)
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No source executable file given.");
+
+    /*
+     * Do it.
+     */
+    /* Read & decode the source PKCS#7 signature. */
+    SIGNTOOLPKCS7EXE Src;
+    RTEXITCODE rcExit = SignToolPkcs7Exe_InitFromFile(&Src, pszSrc, cVerbosity);
+    if (rcExit == RTEXITCODE_SUCCESS)
+    {
+        /* Ditto for the destination PKCS#7 signature. */
+        SIGNTOOLPKCS7EXE Dst;
+        RTEXITCODE rcExit = SignToolPkcs7Exe_InitFromFile(&Dst, pszSrc, cVerbosity);
+        if (rcExit == RTEXITCODE_SUCCESS)
+        {
+            /* Add the source to the destination as a nested signature. */
+            //Src.pSignedData->SignerInfos.paItems
+
+
+            SignToolPkcs7Exe_Delete(&Dst);
+        }
+        SignToolPkcs7Exe_Delete(&Src);
+    }
+
+    return rcExit;
+}
+
+#ifndef IPRT_IN_BUILD_TOOL
+
+/*
+ * The 'verify-exe' command.
+ */
+static RTEXITCODE HelpVerifyExe(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
+{
+    RT_NOREF_PV(enmLevel);
+    RTStrmPrintf(pStrm,
+                 "verify-exe [--verbose|--quiet] [--kernel] [--root <root-cert.der>] [--additional <supp-cert.der>]\n"
+                 "        [--type <win|osx>] <exe1> [exe2 [..]]\n");
+    return RTEXITCODE_SUCCESS;
+}
+
+typedef struct VERIFYEXESTATE
+{
+    RTCRSTORE   hRootStore;
+    RTCRSTORE   hKernelRootStore;
+    RTCRSTORE   hAdditionalStore;
+    bool        fKernel;
+    int         cVerbose;
+    enum { kSignType_Windows, kSignType_OSX } enmSignType;
+    uint64_t    uTimestamp;
+    RTLDRARCH   enmLdrArch;
+} VERIFYEXESTATE;
+
+# ifdef VBOX
+/** Certificate store load set.
+ * Declared outside HandleVerifyExe because of braindead gcc visibility crap. */
+struct STSTORESET
+{
+    RTCRSTORE       hStore;
+    PCSUPTAENTRY    paTAs;
+    unsigned        cTAs;
+};
+# endif
+
+/**
+ * @callback_method_impl{FNRTCRPKCS7VERIFYCERTCALLBACK,
+ * Standard code signing.  Use this for Microsoft SPC.}
+ */
+static DECLCALLBACK(int) VerifyExecCertVerifyCallback(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags,
+                                                      void *pvUser, PRTERRINFO pErrInfo)
+{
+    VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser;
+    uint32_t        cPaths = hCertPaths != NIL_RTCRX509CERTPATHS ? RTCrX509CertPathsGetPathCount(hCertPaths) : 0;
+
+    /*
+     * Dump all the paths.
+     */
+    if (pState->cVerbose > 0)
+    {
+        for (uint32_t iPath = 0; iPath < cPaths; iPath++)
+        {
+            RTPrintf("---\n");
+            RTCrX509CertPathsDumpOne(hCertPaths, iPath, pState->cVerbose, RTStrmDumpPrintfV, g_pStdOut);
+            *pErrInfo->pszMsg = '\0';
+        }
+        RTPrintf("---\n");
+    }
+
+    /*
+     * Test signing certificates normally doesn't have all the necessary
+     * features required below.  So, treat them as special cases.
+     */
+    if (   hCertPaths == NIL_RTCRX509CERTPATHS
+        && RTCrX509Name_Compare(&pCert->TbsCertificate.Issuer, &pCert->TbsCertificate.Subject) == 0)
+    {
+        RTMsgInfo("Test signed.\n");
+        return VINF_SUCCESS;
+    }
+
+    if (hCertPaths == NIL_RTCRX509CERTPATHS)
+        RTMsgInfo("Signed by trusted certificate.\n");
+
+    /*
+     * Standard code signing capabilites required.
+     */
+    int rc = RTCrPkcs7VerifyCertCallbackCodeSigning(pCert, hCertPaths, fFlags, NULL, pErrInfo);
+    if (   RT_SUCCESS(rc)
+        && (fFlags & RTCRPKCS7VCC_F_SIGNED_DATA))
+    {
+        /*
+         * If kernel signing, a valid certificate path must be anchored by the
+         * microsoft kernel signing root certificate.  The only alternative is
+         * test signing.
+         */
+        if (pState->fKernel && hCertPaths != NIL_RTCRX509CERTPATHS)
+        {
+            uint32_t cFound = 0;
+            uint32_t cValid = 0;
+            for (uint32_t iPath = 0; iPath < cPaths; iPath++)
+            {
+                bool                            fTrusted;
+                PCRTCRX509NAME                  pSubject;
+                PCRTCRX509SUBJECTPUBLICKEYINFO  pPublicKeyInfo;
+                int                             rcVerify;
+                rc = RTCrX509CertPathsQueryPathInfo(hCertPaths, iPath, &fTrusted, NULL /*pcNodes*/, &pSubject, &pPublicKeyInfo,
+                                                    NULL, NULL /*pCertCtx*/, &rcVerify);
+                AssertRCBreak(rc);
+
+                if (RT_SUCCESS(rcVerify))
+                {
+                    Assert(fTrusted);
+                    cValid++;
+
+                    /* Search the kernel signing root store for a matching anchor. */
+                    RTCRSTORECERTSEARCH Search;
+                    rc = RTCrStoreCertFindBySubjectOrAltSubjectByRfc5280(pState->hKernelRootStore, pSubject, &Search);
+                    AssertRCBreak(rc);
+                    PCRTCRCERTCTX pCertCtx;
+                    while ((pCertCtx = RTCrStoreCertSearchNext(pState->hKernelRootStore, &Search)) != NULL)
+                    {
+                        PCRTCRX509SUBJECTPUBLICKEYINFO pPubKeyInfo;
+                        if (pCertCtx->pCert)
+                            pPubKeyInfo = &pCertCtx->pCert->TbsCertificate.SubjectPublicKeyInfo;
+                        else if (pCertCtx->pTaInfo)
+                            pPubKeyInfo = &pCertCtx->pTaInfo->PubKey;
+                        else
+                            pPubKeyInfo = NULL;
+                        if (RTCrX509SubjectPublicKeyInfo_Compare(pPubKeyInfo, pPublicKeyInfo) == 0)
+                            cFound++;
+                        RTCrCertCtxRelease(pCertCtx);
+                    }
+
+                    int rc2 = RTCrStoreCertSearchDestroy(pState->hKernelRootStore, &Search); AssertRC(rc2);
+                }
+            }
+            if (RT_SUCCESS(rc) && cFound == 0)
+                rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "Not valid kernel code signature.");
+            if (RT_SUCCESS(rc) && cValid != 2)
+                RTMsgWarning("%u valid paths, expected 2", cValid);
+        }
+    }
+
+    return rc;
+}
+
+
+/** @callback_method_impl{FNRTLDRVALIDATESIGNEDDATA}  */
+static DECLCALLBACK(int) VerifyExeCallback(RTLDRMOD hLdrMod, RTLDRSIGNATURETYPE enmSignature,
+                                           void const *pvSignature, size_t cbSignature,
+                                           PRTERRINFO pErrInfo, void *pvUser)
+{
+    VERIFYEXESTATE *pState = (VERIFYEXESTATE *)pvUser;
+    RT_NOREF_PV(hLdrMod); RT_NOREF_PV(cbSignature);
+
+    switch (enmSignature)
+    {
+        case RTLDRSIGNATURETYPE_PKCS7_SIGNED_DATA:
+        {
+            PCRTCRPKCS7CONTENTINFO pContentInfo = (PCRTCRPKCS7CONTENTINFO)pvSignature;
+
+            RTTIMESPEC ValidationTime;
+            RTTimeSpecSetSeconds(&ValidationTime, pState->uTimestamp);
+
+            /*
+             * Dump the signed data if so requested.
+             */
+            if (pState->cVerbose)
+                RTAsn1Dump(&pContentInfo->SeqCore.Asn1Core, 0, 0, RTStrmDumpPrintfV, g_pStdOut);
+
+
+            /*
+             * Do the actual verification.  Will have to modify this so it takes
+             * the authenticode policies into account.
+             */
+            return RTCrPkcs7VerifySignedData(pContentInfo,
+                                             RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY
+                                             | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT
+                                             | RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT,
+                                             pState->hAdditionalStore, pState->hRootStore, &ValidationTime,
+                                             VerifyExecCertVerifyCallback, pState, pErrInfo);
+        }
+
+        default:
+            return RTErrInfoSetF(pErrInfo, VERR_NOT_SUPPORTED, "Unsupported signature type: %d", enmSignature);
+    }
+}
+
+/** Worker for HandleVerifyExe. */
+static RTEXITCODE HandleVerifyExeWorker(VERIFYEXESTATE *pState, const char *pszFilename, PRTERRINFOSTATIC pStaticErrInfo)
+{
+    /*
+     * Open the executable image and verify it.
+     */
+    RTLDRMOD hLdrMod;
+    int rc = RTLdrOpen(pszFilename, RTLDR_O_FOR_VALIDATION, pState->enmLdrArch, &hLdrMod);
+    if (RT_FAILURE(rc))
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszFilename, rc);
+
+
+    rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_TIMESTAMP_SECONDS, &pState->uTimestamp, sizeof(pState->uTimestamp));
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
+        if (RT_SUCCESS(rc))
+            RTMsgInfo("'%s' is valid.\n", pszFilename);
+        else if (rc == VERR_CR_X509_CPV_NOT_VALID_AT_TIME)
+        {
+            RTTIMESPEC Now;
+            pState->uTimestamp = RTTimeSpecGetSeconds(RTTimeNow(&Now));
+            rc = RTLdrVerifySignature(hLdrMod, VerifyExeCallback, pState, RTErrInfoInitStatic(pStaticErrInfo));
+            if (RT_SUCCESS(rc))
+                RTMsgInfo("'%s' is valid now, but not at link time.\n", pszFilename);
+        }
+        if (RT_FAILURE(rc))
+            RTMsgError("RTLdrVerifySignature failed on '%s': %Rrc - %s\n", pszFilename, rc, pStaticErrInfo->szMsg);
+    }
+    else
+        RTMsgError("RTLdrQueryProp/RTLDRPROP_TIMESTAMP_SECONDS failed on '%s': %Rrc\n", pszFilename, rc);
+
+    int rc2 = RTLdrClose(hLdrMod);
+    if (RT_FAILURE(rc2))
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTLdrClose failed: %Rrc\n", rc2);
+    if (RT_FAILURE(rc))
+        return rc != VERR_LDRVI_NOT_SIGNED ? RTEXITCODE_FAILURE : RTEXITCODE_SKIPPED;
+
+    return RTEXITCODE_SUCCESS;
+}
+
+
+static RTEXITCODE HandleVerifyExe(int cArgs, char **papszArgs)
+{
+    RTERRINFOSTATIC StaticErrInfo;
+
+    /* Note! This code does not try to clean up the crypto stores on failure.
+             This is intentional as the code is only expected to be used in a
+             one-command-per-process environment where we do exit() upon
+             returning from this function. */
+
+    /*
+     * Parse arguments.
+     */
+    static const RTGETOPTDEF s_aOptions[] =
+    {
+        { "--kernel",       'k', RTGETOPT_REQ_NOTHING },
+        { "--root",         'r', RTGETOPT_REQ_STRING },
+        { "--additional",   'a', RTGETOPT_REQ_STRING },
+        { "--add",          'a', RTGETOPT_REQ_STRING },
+        { "--type",         't', RTGETOPT_REQ_STRING },
+        { "--verbose",      'v', RTGETOPT_REQ_NOTHING },
+        { "--quiet",        'q', RTGETOPT_REQ_NOTHING },
+    };
+
+    VERIFYEXESTATE State =
+    {
+        NIL_RTCRSTORE, NIL_RTCRSTORE, NIL_RTCRSTORE, false, false,
+        VERIFYEXESTATE::kSignType_Windows, 0, RTLDRARCH_WHATEVER
+    };
+    int rc = RTCrStoreCreateInMem(&State.hRootStore, 0);
+    if (RT_SUCCESS(rc))
+        rc = RTCrStoreCreateInMem(&State.hKernelRootStore, 0);
+    if (RT_SUCCESS(rc))
+        rc = RTCrStoreCreateInMem(&State.hAdditionalStore, 0);
+    if (RT_FAILURE(rc))
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error creating in-memory certificate store: %Rrc", rc);
+
+    RTGETOPTSTATE GetState;
+    rc = RTGetOptInit(&GetState, cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
+    AssertRCReturn(rc, RTEXITCODE_FAILURE);
+    RTGETOPTUNION ValueUnion;
+    int ch;
+    while ((ch = RTGetOpt(&GetState, &ValueUnion)) && ch != VINF_GETOPT_NOT_OPTION)
+    {
+        switch (ch)
+        {
+            case 'r': case 'a':
+                rc = RTCrStoreCertAddFromFile(ch == 'r' ? State.hRootStore : State.hAdditionalStore,
+                                              RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ADD_CONTINUE_ON_ERROR,
+                                              ValueUnion.psz, RTErrInfoInitStatic(&StaticErrInfo));
+                if (RT_FAILURE(rc))
+                    return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error loading certificate '%s': %Rrc - %s",
+                                          ValueUnion.psz, rc, StaticErrInfo.szMsg);
+                if (RTErrInfoIsSet(&StaticErrInfo.Core))
+                    RTMsgWarning("Warnings loading certificate '%s': %s", ValueUnion.psz, StaticErrInfo.szMsg);
+                break;
+
+            case 't':
+                if (!strcmp(ValueUnion.psz, "win") || !strcmp(ValueUnion.psz, "windows"))
+                    State.enmSignType = VERIFYEXESTATE::kSignType_Windows;
+                else if (!strcmp(ValueUnion.psz, "osx") || !strcmp(ValueUnion.psz, "apple"))
+                    State.enmSignType = VERIFYEXESTATE::kSignType_OSX;
+                else
+                    return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Unknown signing type: '%s'", ValueUnion.psz);
+                break;
+
+            case 'k': State.fKernel = true; break;
+            case 'v': State.cVerbose++; break;
+            case 'q': State.cVerbose = 0; break;
+            case 'V': return HandleVersion(cArgs, papszArgs);
+            case 'h': return HelpVerifyExe(g_pStdOut, RTSIGNTOOLHELP_FULL);
+            default:  return RTGetOptPrintError(ch, &ValueUnion);
+        }
+    }
+    if (ch != VINF_GETOPT_NOT_OPTION)
+        return RTMsgErrorExit(RTEXITCODE_FAILURE, "No executable given.");
+
+    /*
+     * Populate the certificate stores according to the signing type.
+     */
+#ifdef VBOX
+    unsigned          cSets = 0;
+    struct STSTORESET aSets[6];
+#endif
+
+    switch (State.enmSignType)
+    {
+        case VERIFYEXESTATE::kSignType_Windows:
+#ifdef VBOX
+            aSets[cSets].hStore  = State.hRootStore;
+            aSets[cSets].paTAs   = g_aSUPTimestampTAs;
+            aSets[cSets].cTAs    = g_cSUPTimestampTAs;
+            cSets++;
+            aSets[cSets].hStore  = State.hRootStore;
+            aSets[cSets].paTAs   = g_aSUPSpcRootTAs;
+            aSets[cSets].cTAs    = g_cSUPSpcRootTAs;
+            cSets++;
+            aSets[cSets].hStore  = State.hRootStore;
+            aSets[cSets].paTAs   = g_aSUPNtKernelRootTAs;
+            aSets[cSets].cTAs    = g_cSUPNtKernelRootTAs;
+            cSets++;
+            aSets[cSets].hStore  = State.hKernelRootStore;
+            aSets[cSets].paTAs   = g_aSUPNtKernelRootTAs;
+            aSets[cSets].cTAs    = g_cSUPNtKernelRootTAs;
+            cSets++;
+#endif
+            break;
+
+        case VERIFYEXESTATE::kSignType_OSX:
+            return RTMsgErrorExit(RTEXITCODE_FAILURE, "Mac OS X executable signing is not implemented.");
+    }
+
+#ifdef VBOX
+    for (unsigned i = 0; i < cSets; i++)
+        for (unsigned j = 0; j < aSets[i].cTAs; j++)
+        {
+            rc = RTCrStoreCertAddEncoded(aSets[i].hStore, RTCRCERTCTX_F_ENC_TAF_DER, aSets[i].paTAs[j].pch,
+                                         aSets[i].paTAs[j].cb, RTErrInfoInitStatic(&StaticErrInfo));
+            if (RT_FAILURE(rc))
+                return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTCrStoreCertAddEncoded failed (%u/%u): %s",
+                                      i, j, StaticErrInfo.szMsg);
+        }
+#endif
+
+    /*
+     * Do it.
+     */
+    RTEXITCODE rcExit;
+    for (;;)
+    {
+        rcExit = HandleVerifyExeWorker(&State, ValueUnion.psz, &StaticErrInfo);
+        if (rcExit != RTEXITCODE_SUCCESS)
+            break;
+
+        /*
+         * Next file
+         */
+        ch = RTGetOpt(&GetState, &ValueUnion);
+        if (ch == 0)
+            break;
+        if (ch != VINF_GETOPT_NOT_OPTION)
+        {
+            rcExit = RTGetOptPrintError(ch, &ValueUnion);
+            break;
+        }
+    }
+
+    /*
+     * Clean up.
+     */
+    uint32_t cRefs;
+    cRefs = RTCrStoreRelease(State.hRootStore);       Assert(cRefs == 0);
+    cRefs = RTCrStoreRelease(State.hKernelRootStore); Assert(cRefs == 0);
+    cRefs = RTCrStoreRelease(State.hAdditionalStore); Assert(cRefs == 0);
+
+    return rcExit;
+}
+
+#endif /* !IPRT_IN_BUILD_TOOL */
+#ifndef IPRT_IN_BUILD_TOOL
+
+/*
+ * The 'show-exe' command.
+ */
+static RTEXITCODE HelpShowExe(PRTSTREAM pStrm, RTSIGNTOOLHELP enmLevel)
+{
+    RT_NOREF_PV(enmLevel);
+    RTStrmPrintf(pStrm,
+                 "show-exe [--verbose|-v] [--quiet|-q] <exe1> [exe2 [..]]\n");
+    return RTEXITCODE_SUCCESS;
+}
+
+
+/**
+ * Decodes the PKCS #7 blob pointed to by pThis->pbBuf.
+ *
+ * @returns IPRT status code.
+ * @param   pThis               The show exe instance data.
+ */
+static int HandleShowExeWorkerPkcs7Decode(PSHOWEXEPKCS7 pThis)
+{
+    RTERRINFOSTATIC     ErrInfo;
+    RTASN1CURSORPRIMARY PrimaryCursor;
+    RTAsn1CursorInitPrimary(&PrimaryCursor, pThis->pbBuf, (uint32_t)pThis->cbBuf, RTErrInfoInitStatic(&ErrInfo),
+                            &g_RTAsn1DefaultAllocator, 0, "WinCert");
+
+    int rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &pThis->ContentInfo, "CI");
+    if (RT_SUCCESS(rc))
+    {
+        if (RTCrPkcs7ContentInfo_IsSignedData(&pThis->ContentInfo))
+        {
+            pThis->pSignedData = pThis->ContentInfo.u.pSignedData;
+
+            /*
+             * Decode the authenticode bits.
+             */
+            if (!strcmp(pThis->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID))
+            {
+                pThis->pIndData = pThis->pSignedData->ContentInfo.u.pIndirectDataContent;
+                Assert(pThis->pIndData);
+
+                /*
+                 * Check that things add up.
+                 */
+                rc = RTCrPkcs7SignedData_CheckSanity(pThis->pSignedData,
+                                                     RTCRPKCS7SIGNEDDATA_SANITY_F_AUTHENTICODE
+                                                     | RTCRPKCS7SIGNEDDATA_SANITY_F_ONLY_KNOWN_HASH
+                                                     | RTCRPKCS7SIGNEDDATA_SANITY_F_SIGNING_CERT_PRESENT,
+                                                     RTErrInfoInitStatic(&ErrInfo), "SD");
+                if (RT_FAILURE(rc))
+                    RTMsgError("PKCS#7 sanity check failed for '%s': %Rrc - %s\n", pThis->pszFilename, rc, ErrInfo.szMsg);
+                if (RT_SUCCESS(rc))
+                {
+                    rc = RTCrSpcIndirectDataContent_CheckSanityEx(pThis->pIndData,
+                                                                  pThis->pSignedData,
+                                                                  RTCRSPCINDIRECTDATACONTENT_SANITY_F_ONLY_KNOWN_HASH,
+                                                                  RTErrInfoInitStatic(&ErrInfo));
+                    if (RT_FAILURE(rc))
+                        RTMsgError("SPC indirect data content sanity check failed for '%s': %Rrc - %s\n",
+                                   pThis->pszFilename, rc, ErrInfo.szMsg);
+                }
+            }
+            else
+                RTMsgError("Unexpected the signed content in '%s': %s (expected %s)", pThis->pszFilename,
+                           pThis->pSignedData->ContentInfo.ContentType.szObjId, RTCRSPCINDIRECTDATACONTENT_OID);
+        }
+        else
+            RTMsgError("PKCS#7 content is inside '%s' is not 'signedData': %s\n",
+                       pThis->pszFilename, pThis->ContentInfo.ContentType.szObjId);
+    }
+    else
+        RTMsgError("RTCrPkcs7ContentInfo_DecodeAsn1 failed on '%s': %Rrc - %s\n", pThis->pszFilename, rc, ErrInfo.szMsg);
+    return rc;
+}
+
+
+/**
  * Display an object ID.
  *
@@ -802,5 +1054,5 @@
                 else
                     RTPrintf("%s ObjId[%u]: ", pThis->szPrefix, i);
-                HandleShowExeWorkerDisplayObjIdSimple(pThis, &pAttr->uValues.pObjIds->paItems[i], "\n");
+                HandleShowExeWorkerDisplayObjIdSimple(pThis, pAttr->uValues.pObjIds->papItems[i], "\n");
             }
             break;
@@ -812,5 +1064,5 @@
             for (unsigned i = 0; i < pAttr->uValues.pObjIdSeqs->cItems; i++)
             {
-                uint32_t const cObjIds = pAttr->uValues.pObjIdSeqs->paItems[i].cItems;
+                uint32_t const cObjIds = pAttr->uValues.pObjIdSeqs->papItems[i]->cItems;
                 for (unsigned j = 0; j < cObjIds; j++)
                 {
@@ -821,5 +1073,5 @@
                     if (cObjIds != 1)
                         RTPrintf(" ObjId[%u]: ", j);
-                    HandleShowExeWorkerDisplayObjIdSimple(pThis, &pAttr->uValues.pObjIdSeqs->paItems[i].paItems[i], "\n");
+                    HandleShowExeWorkerDisplayObjIdSimple(pThis, pAttr->uValues.pObjIdSeqs->papItems[i]->papItems[i], "\n");
                 }
             }
@@ -832,5 +1084,5 @@
             for (unsigned i = 0; i < pAttr->uValues.pOctetStrings->cItems; i++)
             {
-                PCRTASN1OCTETSTRING pOctetString = &pAttr->uValues.pOctetStrings->paItems[i];
+                PCRTASN1OCTETSTRING pOctetString = pAttr->uValues.pOctetStrings->papItems[i];
                 uint32_t cbContent = pOctetString->Asn1Core.cb;
                 if (cbContent > 0 && (cbContent <= 128 || pThis->cVerbosity >= 2))
@@ -879,5 +1131,5 @@
                     offPrefix2 += RTStrPrintf(&pThis->szPrefix[offPrefix], sizeof(pThis->szPrefix) - offPrefix, "  ");
                 //    offPrefix2 += RTStrPrintf(&pThis->szPrefix[offPrefix], sizeof(pThis->szPrefix) - offPrefix, "NestedSig: ", i);
-                PCRTCRPKCS7CONTENTINFO pContentInfo = &pAttr->uValues.pContentInfos->paItems[i];
+                PCRTCRPKCS7CONTENTINFO pContentInfo = pAttr->uValues.pContentInfos->papItems[i];
                 int rc2;
                 if (RTCrPkcs7ContentInfo_IsSignedData(pContentInfo))
@@ -960,11 +1212,11 @@
                                                 "MonikerAttrib[%u]: ", i);
 
-                                    switch (pData->paItems[i].enmType)
+                                    switch (pData->papItems[i]->enmType)
                                     {
                                         case RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V2:
                                         case RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V1:
                                         {
-                                            PCRTCRSPCSERIALIZEDPAGEHASHES pPgHashes = pData->paItems[i].u.pPageHashes;
-                                            uint32_t const cbHash =    pData->paItems[i].enmType
+                                            PCRTCRSPCSERIALIZEDPAGEHASHES pPgHashes = pData->papItems[i]->u.pPageHashes;
+                                            uint32_t const cbHash =    pData->papItems[i]->enmType
                                                                     == RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V1
                                                                   ? 160/8 /*SHA-1*/ : 256/8 /*SHA-256*/;
@@ -972,5 +1224,5 @@
 
                                             RTPrintf("%sPage Hashes version %u - %u pages (%u bytes total)\n", pThis->szPrefix,
-                                                        pData->paItems[i].enmType
+                                                        pData->papItems[i]->enmType
                                                      == RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_PAGE_HASHES_V1 ? 1 : 2,
                                                      cPages, pPgHashes->RawData.Asn1Core.cb);
@@ -1006,5 +1258,5 @@
 
                                         case RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_UNKNOWN:
-                                            HandleShowExeWorkerDisplayObjIdSimple(pThis, &pData->paItems[i].Type, "\n");
+                                            HandleShowExeWorkerDisplayObjIdSimple(pThis, &pData->papItems[i]->Type, "\n");
                                             break;
                                         case RTCRSPCSERIALIZEDOBJECTATTRIBUTETYPE_NOT_PRESENT:
@@ -1012,5 +1264,5 @@
                                             break;
                                         default:
-                                            RTPrintf("%senmType=%d!\n", pThis->szPrefix, pData->paItems[i].enmType);
+                                            RTPrintf("%senmType=%d!\n", pThis->szPrefix, pData->papItems[i]->enmType);
                                             break;
                                     }
@@ -1099,5 +1351,5 @@
     for (unsigned i = 0; i < pSignedData->DigestAlgorithms.cItems; i++)
     {
-        PCRTCRX509ALGORITHMIDENTIFIER pAlgoId = &pSignedData->DigestAlgorithms.paItems[i];
+        PCRTCRX509ALGORITHMIDENTIFIER pAlgoId = pSignedData->DigestAlgorithms.papItems[i];
         const char *pszDigestType = RTCrDigestTypeToName(RTCrX509AlgorithmIdentifier_QueryDigestType(pAlgoId));
         if (!pszDigestType)
@@ -1121,9 +1373,15 @@
     }
     else
-        RTPrintf("%s     ContentType: %s\n", pThis->szPrefix, pSignedData->ContentInfo.ContentType.szObjId);
+        HandleShowExeWorkerDisplayObjId(pThis, &pSignedData->ContentInfo.ContentType, "     ContentType: ", " - not implemented.\n");
 
     /*
      * Display certificates (Certificates).
      */
+    if (pSignedData->Certificates.cItems > 0)
+        RTPrintf("%s    Certificates: %u\n", pThis->szPrefix, pSignedData->Certificates.cItems);
+        /** @todo display certificates. */
+
+    if (pSignedData->Crls.cb > 0)
+        RTPrintf("%s            CRLs: %u bytes\n", pThis->szPrefix, pSignedData->Crls.cb);
 
     /*
@@ -1134,5 +1392,5 @@
     for (unsigned i = 0; i < cSigInfos; i++)
     {
-        PRTCRPKCS7SIGNERINFO pSigInfo = &pSignedData->SignerInfos.paItems[i];
+        PRTCRPKCS7SIGNERINFO pSigInfo = pSignedData->SignerInfos.papItems[i];
         size_t offPrefix2 = offPrefix;
         if (cSigInfos != 1)
@@ -1170,5 +1428,5 @@
             for (unsigned j = 0; j < pSigInfo->AuthenticatedAttributes.cItems; j++)
             {
-                PRTCRPKCS7ATTRIBUTE pAttr = &pSigInfo->AuthenticatedAttributes.paItems[j];
+                PRTCRPKCS7ATTRIBUTE pAttr = pSigInfo->AuthenticatedAttributes.papItems[j];
                 size_t offPrefix3 = offPrefix2 + RTStrPrintf(&pThis->szPrefix[offPrefix2], sizeof(pThis->szPrefix) - offPrefix2,
                                                              "              AuthAttrib[%u]: ", j);
@@ -1186,5 +1444,5 @@
             for (unsigned j = 0; j < pSigInfo->UnauthenticatedAttributes.cItems; j++)
             {
-                PRTCRPKCS7ATTRIBUTE pAttr = &pSigInfo->UnauthenticatedAttributes.paItems[j];
+                PRTCRPKCS7ATTRIBUTE pAttr = pSigInfo->UnauthenticatedAttributes.papItems[j];
                 size_t offPrefix3 = offPrefix2 + RTStrPrintf(&pThis->szPrefix[offPrefix2], sizeof(pThis->szPrefix) - offPrefix2,
                                                              "            UnauthAttrib[%u]: ", j);
@@ -1212,68 +1470,18 @@
 static RTEXITCODE HandleShowExeWorker(const char *pszFilename, unsigned cVerbosity, RTLDRARCH enmLdrArch)
 {
-    /*
-     * Open the image and check if it's signed.
-     */
-    RTLDRMOD hLdrMod;
-    int rc = RTLdrOpen(pszFilename, RTLDR_O_FOR_VALIDATION, enmLdrArch, &hLdrMod);
-    if (RT_FAILURE(rc))
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Error opening executable image '%s': %Rrc", pszFilename, rc);
-
-    bool fIsSigned = false;
-    rc = RTLdrQueryProp(hLdrMod, RTLDRPROP_IS_SIGNED, &fIsSigned, sizeof(fIsSigned));
-    if (RT_SUCCESS(rc) && fIsSigned)
-    {
-        /*
-         * Query the PKCS#7 data (assuming M$ style signing) and hand it to a worker.
-         */
-        size_t cbActual = 0;
-        size_t cbBuf = _64K;
-        void  *pvBuf = RTMemAllocZ(cbBuf);
-        if (pvBuf)
-        {
-            rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbActual);
-            if (rc == VERR_BUFFER_OVERFLOW)
-            {
-                RTMemFree(pvBuf);
-                cbBuf = cbActual;
-                pvBuf = RTMemAllocZ(cbActual);
-                if (pvBuf)
-                    rc = RTLdrQueryPropEx(hLdrMod, RTLDRPROP_PKCS7_SIGNED_DATA, NULL /*pvBits*/, pvBuf, cbBuf, &cbActual);
-                else
-                    rc = VERR_NO_MEMORY;
-            }
-        }
-        else
-            rc = VERR_NO_MEMORY;
-        if (RT_SUCCESS(rc))
-        {
-            SHOWEXEPKCS7 This;
-            RT_ZERO(This);
-            This.pbBuf       = (uint8_t const *)pvBuf;
-            This.cbBuf       = cbActual;
-            This.cVerbosity  = cVerbosity;
-            This.pszFilename = pszFilename;
-            This.hLdrMod     = hLdrMod;
-            rc = HandleShowExeWorkerPkcs7Decode(&This);
-            if (RT_SUCCESS(rc))
-                rc = HandleShowExeWorkerPkcs7Display(&This, This.pSignedData, 0);
-            RTCrPkcs7ContentInfo_Delete(&This.ContentInfo);
-        }
-        else
-            RTMsgError("RTLdrQueryPropEx/RTLDRPROP_PKCS7_SIGNED_DATA failed on '%s': %Rrc\n", pszFilename, rc);
-        RTMemFree(pvBuf);
-    }
-    else if (RT_SUCCESS(rc))
-        RTMsgInfo("'%s': not signed\n", pszFilename);
-    else
-        RTMsgError("RTLdrQueryProp/RTLDRPROP_IS_SIGNED failed on '%s': %Rrc\n", pszFilename, rc);
-
-    int rc2 = RTLdrClose(hLdrMod);
-    if (RT_FAILURE(rc2))
-        return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTLdrClose failed: %Rrc\n", rc2);
-    if (RT_FAILURE(rc))
-        return rc != VERR_LDRVI_NOT_SIGNED ? RTEXITCODE_FAILURE : RTEXITCODE_SKIPPED;
-
-    return RTEXITCODE_SUCCESS;
+    SHOWEXEPKCS7 This;
+    RT_ZERO(This);
+    This.cVerbosity = cVerbosity;
+
+    RTEXITCODE rcExit = SignToolPkcs7Exe_InitFromFile(&This, pszFilename, cVerbosity, enmLdrArch);
+    if (rcExit == RTEXITCODE_SUCCESS)
+    {
+        int rc = HandleShowExeWorkerPkcs7Display(&This, This.pSignedData, 0);
+        if (RT_FAILURE(rc))
+            rcExit = RTEXITCODE_FAILURE;
+        SignToolPkcs7Exe_Delete(&This);
+    }
+
+    return rcExit;
 }
 
@@ -1599,4 +1807,5 @@
     { "extract-exe-signer-cert",        HandleExtractExeSignerCert,         HelpExtractExeSignerCert },
 #ifndef IPRT_IN_BUILD_TOOL
+    { "add-nested-exe-signature",       HandleAddNestedExeSignature,        HelpAddNestedExeSignature },
     { "verify-exe",                     HandleVerifyExe,                    HelpVerifyExe },
     { "show-exe",                       HandleShowExe,                      HelpShowExe },
