Index: /trunk/include/iprt/asn1.h
===================================================================
--- /trunk/include/iprt/asn1.h	(revision 84309)
+++ /trunk/include/iprt/asn1.h	(revision 84310)
@@ -1631,4 +1631,26 @@
 RTDECL(int) RTAsn1EncodeToBuffer(PCRTASN1CORE pRoot, uint32_t fFlags, void *pvBuf, size_t cbBuf, PRTERRINFO pErrInfo);
 
+/**
+ * Helper for when DER encoded ASN.1 is needed for something.
+ *
+ * Handy when interfacing with OpenSSL and the many d2i_Xxxxx OpenSSL functions,
+ * but also handy when structures needs to be digested or similar during signing
+ * or verification.
+ *
+ * We sometimes can use the data we've decoded directly, but often we have
+ * encode it into a temporary heap buffer.
+ *
+ * @returns IPRT status code, details in @a pErrInfo if present.
+ * @param   pRoot       The ASN.1 root of the structure to be passed to OpenSSL.
+ * @param   ppbRaw      Where to return the pointer to raw encoded data.
+ * @param   pcbRaw      Where to return the size of the raw encoded data.
+ * @param   ppvFree     Where to return what to pass to RTMemTmpFree, i.e. NULL
+ *                      if we use the previously decoded data directly and
+ *                      non-NULL if we had to allocate heap and encode it.
+ * @param   pErrInfo    Where to return details about encoding issues. Optional.
+ */
+RTDECL(int) RTAsn1EncodeQueryRawBits(PRTASN1CORE pRoot, const uint8_t **ppbRaw, uint32_t *pcbRaw,
+                                     void **ppvFree, PRTERRINFO pErrInfo);
+
 /** @} */
 
Index: /trunk/include/iprt/crypto/pkcs7.h
===================================================================
--- /trunk/include/iprt/crypto/pkcs7.h	(revision 84309)
+++ /trunk/include/iprt/crypto/pkcs7.h	(revision 84310)
@@ -431,4 +431,20 @@
 /** @} */
 
+/** PKCS\#7/CMS (content info) markers. */
+extern RTDATADECL(RTCRPEMMARKER const) g_aRTCrPkcs7Markers[];
+/** Number of entries in g_aRTCrPkcs7Markers. */
+extern RTDATADECL(uint32_t const)      g_cRTCrPkcs7Markers;
+
+/** @name Flags for RTCrPkcs7ContentInfo_ReadFromBuffer
+ * @{ */
+/** Only allow PEM certificates, not binary ones.
+ * @sa RTCRPEMREADFILE_F_ONLY_PEM  */
+#define RTCRPKCS7_READ_F_PEM_ONLY        RT_BIT(1)
+/** @} */
+
+RTDECL(int) RTCrPkcs7_ReadFromBuffer(PRTCRPKCS7CONTENTINFO pContentInfo, const void *pvBuf, size_t cbBuf,
+                                     uint32_t fFlags, PCRTASN1ALLOCATORVTABLE pAllocator,
+                                     bool *pfCmsLabeled, PRTERRINFO pErrInfo, const char *pszErrorTag);
+
 
 /**
@@ -552,5 +568,6 @@
                                                       void const *pvData, size_t cbData, PRTERRINFO pErrInfo);
 
-/** @name RTCRPKCS7VERIFY_SD_F_XXX - Flags for RTCrPkcs7VerifySignedData
+/** @name RTCRPKCS7VERIFY_SD_F_XXX - Flags for RTCrPkcs7VerifySignedData and
+ *                                   RTCrPkcs7VerifySignedDataWithExternalData
  * @{ */
 /** Always use the signing time attribute if present, requiring it to be
@@ -559,5 +576,5 @@
 #define RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT     RT_BIT_32(0)
 /** Same as RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT for the MS
- *  timestamp counter sigantures. */
+ *  timestamp counter signatures. */
 #define RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_MS_TIMESTAMP_IF_PRESENT     RT_BIT_32(1)
 /** Only use signing time attributes from counter signatures. */
@@ -577,4 +594,7 @@
  * signatures. */
 #define RTCRPKCS7VERIFY_SD_F_USAGE_TIMESTAMPING                     RT_BIT_32(6)
+/** Skip the verification of the certificate trust paths, taking all
+ * certificates to be trustworthy. */
+#define RTCRPKCS7VERIFY_SD_F_TRUST_ALL_CERTS                        RT_BIT_32(7)
 
 /** Indicates internally that we're validating a counter signature and should
@@ -584,4 +604,8 @@
 /** @} */
 
+
+RTDECL(int) RTCrPkcs7SimpleSignSignedData(uint32_t fFlags, PCRTCRX509CERTIFICATE pSigner, RTCRKEY hPrivateKey,
+                                          void const *pvData, size_t cbData, RTDIGESTTYPE enmDigestType,
+                                          RTCRSTORE hAdditionalCerts, void *pvResult, size_t *pcbResult, PRTERRINFO pErrInfo);
 
 /** @name RTCRPKCS7SIGN_SD_F_XXX - Flags for RTCrPkcs7SimpleSign.
@@ -595,8 +619,4 @@
 /** @} */
 
-RTDECL(int) RTCrPkcs7SimpleSignSignedData(uint32_t fFlags, PCRTCRX509CERTIFICATE pSigner, RTCRKEY hPrivateKey,
-                                          void const *pvData, size_t cbData, RTDIGESTTYPE enmDigestType,
-                                          RTCRSTORE hAdditionalCerts, void *pvResult, size_t *pcbResult, PRTERRINFO pErrInfo);
-
 /** @} */
 
Index: /trunk/include/iprt/crypto/store.h
===================================================================
--- /trunk/include/iprt/crypto/store.h	(revision 84309)
+++ /trunk/include/iprt/crypto/store.h	(revision 84310)
@@ -182,4 +182,22 @@
 
 /**
+ * Add an X.509 packaged certificate to the store.
+ *
+ * @returns IPRT status code.
+ * @retval  VWRN_ALREADY_EXISTS if the certificate is already present and
+ *          RTCRCERTCTX_F_ADD_IF_NOT_FOUND was specified.
+ * @retval  VERR_WRITE_PROTECT if the store doesn't support adding.
+ * @param   hStore              The store to add the certificate to.
+ * @param   fFlags              RTCRCERTCTX_F_XXX. Encoding must is optional,
+ *                              but must be RTCRCERTCTX_F_ENC_X509_DER if given.
+ *                              RTCRCERTCTX_F_ADD_IF_NOT_FOUND is supported.
+ * @param   pCertificate        The certificate to add.  We may have to encode
+ *                              it, thus not const.
+ * @param   pErrInfo            Where to return additional error/warning info.
+ *                              Optional.
+ */
+RTDECL(int) RTCrStoreCertAddX509(RTCRSTORE hStore, uint32_t fFlags, PRTCRX509CERTIFICATE pCertificate, PRTERRINFO pErrInfo);
+
+/**
  * Adds certificates from files in the specified directory.
  *
Index: /trunk/include/iprt/mangling.h
===================================================================
--- /trunk/include/iprt/mangling.h	(revision 84309)
+++ /trunk/include/iprt/mangling.h	(revision 84310)
@@ -2939,4 +2939,5 @@
 # define RTAsn1EncodeRecalcHdrSize                      RT_MANGLER(RTAsn1EncodeRecalcHdrSize)
 # define RTAsn1EncodeToBuffer                           RT_MANGLER(RTAsn1EncodeToBuffer)
+# define RTAsn1EncodeQueryRawBits                       RT_MANGLER(RTAsn1EncodeQueryRawBits)
 # define RTAsn1EncodeWrite                              RT_MANGLER(RTAsn1EncodeWrite)
 # define RTAsn1EncodeWriteHeader                        RT_MANGLER(RTAsn1EncodeWriteHeader)
@@ -3364,4 +3365,5 @@
 # define RTCrPemWriteAsn1ToVfsFile                      RT_MANGLER(RTCrPemWriteAsn1ToVfsFile)
 # define RTCrPkcs5Pbkdf2Hmac                            RT_MANGLER(RTCrPkcs5Pbkdf2Hmac)
+# define RTCrPkcs7_ReadFromBuffer                       RT_MANGLER(RTCrPkcs7_ReadFromBuffer)
 # define RTCrPkcs7Attribute_DecodeAsn1                  RT_MANGLER(RTCrPkcs7Attribute_DecodeAsn1)
 # define RTCrPkcs7Attributes_DecodeAsn1                 RT_MANGLER(RTCrPkcs7Attributes_DecodeAsn1)
@@ -3857,4 +3859,5 @@
 # define RTCrCertCtxRetain                              RT_MANGLER(RTCrCertCtxRetain)
 # define RTCrStoreCertAddEncoded                        RT_MANGLER(RTCrStoreCertAddEncoded)
+# define RTCrStoreCertAddX509                           RT_MANGLER(RTCrStoreCertAddX509)
 # define RTCrStoreCertByIssuerAndSerialNo               RT_MANGLER(RTCrStoreCertByIssuerAndSerialNo)
 # define RTCrStoreCertCount                             RT_MANGLER(RTCrStoreCertCount)
@@ -4046,4 +4049,6 @@
 # define g_RTAsn1EFenceAllocator                        RT_MANGLER(g_RTAsn1EFenceAllocator)
 # define g_RTAsn1SaferAllocator                         RT_MANGLER(g_RTAsn1SaferAllocator)
+# define g_aRTCrPkcs7Markers                            RT_MANGLER(g_aRTCrPkcs7Markers)
+# define g_cRTCrPkcs7Markers                            RT_MANGLER(g_cRTCrPkcs7Markers)
 # define g_aRTCrX509CertificateMarkers                  RT_MANGLER(g_aRTCrX509CertificateMarkers)
 # define g_cRTCrX509CertificateMarkers                  RT_MANGLER(g_cRTCrX509CertificateMarkers)
Index: /trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Runtime/Makefile.kmk	(revision 84309)
+++ /trunk/src/VBox/Runtime/Makefile.kmk	(revision 84310)
@@ -397,4 +397,5 @@
 	common/crypto/pkcs7-asn1-decoder.cpp \
 	common/crypto/pkcs7-core.cpp \
+	common/crypto/pkcs7-file.cpp \
 	common/crypto/pkcs7-init.cpp \
 	common/crypto/pkcs7-sanity.cpp \
Index: /trunk/src/VBox/Runtime/common/asn1/asn1-encode.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/asn1/asn1-encode.cpp	(revision 84309)
+++ /trunk/src/VBox/Runtime/common/asn1/asn1-encode.cpp	(revision 84310)
@@ -36,4 +36,5 @@
 #include <iprt/ctype.h>
 #include <iprt/err.h>
+#include <iprt/mem.h>
 #include <iprt/string.h>
 
@@ -475,2 +476,50 @@
 }
 
+
+RTDECL(int) RTAsn1EncodeQueryRawBits(PRTASN1CORE pRoot, const uint8_t **ppbRaw, uint32_t *pcbRaw,
+                                     void **ppvFree, PRTERRINFO pErrInfo)
+{
+    /*
+     * ASSUME that if we've got pointers here, they are valid...
+     */
+    if (   pRoot->uData.pv
+        && !(pRoot->fFlags & RTASN1CORE_F_INDEFINITE_LENGTH) /* BER, not DER. */
+        && (pRoot->fFlags & RTASN1CORE_F_DECODED_CONTENT) )
+    {
+        /** @todo Check that it's DER encoding. */
+        *ppbRaw  = RTASN1CORE_GET_RAW_ASN1_PTR(pRoot);
+        *pcbRaw  = RTASN1CORE_GET_RAW_ASN1_SIZE(pRoot);
+        *ppvFree = NULL;
+        return VINF_SUCCESS;
+    }
+
+    /*
+     * Encode it into a temporary heap buffer.
+     */
+    uint32_t cbEncoded = 0;
+    int rc = RTAsn1EncodePrepare(pRoot, RTASN1ENCODE_F_DER, &cbEncoded, pErrInfo);
+    if (RT_SUCCESS(rc))
+    {
+        void *pvEncoded = RTMemTmpAllocZ(cbEncoded);
+        if (pvEncoded)
+        {
+            rc = RTAsn1EncodeToBuffer(pRoot, RTASN1ENCODE_F_DER, pvEncoded, cbEncoded, pErrInfo);
+            if (RT_SUCCESS(rc))
+            {
+                *ppvFree = pvEncoded;
+                *ppbRaw  = (unsigned char *)pvEncoded;
+                *pcbRaw  = cbEncoded;
+                return VINF_SUCCESS;
+            }
+            RTMemTmpFree(pvEncoded);
+        }
+        else
+            rc = RTErrInfoSetF(pErrInfo, VERR_NO_TMP_MEMORY, "RTMemTmpAllocZ(%u)", cbEncoded);
+    }
+
+    *ppvFree = NULL;
+    *ppbRaw  = NULL;
+    *pcbRaw  = 0;
+    return rc;
+}
+
Index: /trunk/src/VBox/Runtime/common/crypto/iprt-openssl.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/iprt-openssl.cpp	(revision 84309)
+++ /trunk/src/VBox/Runtime/common/crypto/iprt-openssl.cpp	(revision 84310)
@@ -70,55 +70,23 @@
 {
     const unsigned char *pabEncoded;
-
-    /*
-     * ASSUME that if the certificate has data pointers, it's been parsed out
-     * of a binary blob and we can safely access that here.
-     */
-    if (pCert->SeqCore.Asn1Core.uData.pv)
+    uint32_t             cbEncoded;
+    void                *pvFree;
+    int rc = RTAsn1EncodeQueryRawBits(RTCrX509Certificate_GetAsn1Core(pCert),
+                                      (const uint8_t **)&pabEncoded, &cbEncoded, &pvFree, pErrInfo);
+    if (RT_SUCCESS(rc))
     {
-        pabEncoded = (const unsigned char *)RTASN1CORE_GET_RAW_ASN1_PTR(&pCert->SeqCore.Asn1Core);
-        uint32_t cbEncoded  = RTASN1CORE_GET_RAW_ASN1_SIZE(&pCert->SeqCore.Asn1Core);
-        X509    *pOsslCert  = NULL;
-        if (d2i_X509(&pOsslCert, &pabEncoded, cbEncoded) == pOsslCert)
+        X509 *pOsslCert = NULL;
+        X509 *pOsslCertRet = d2i_X509(&pOsslCert, &pabEncoded, cbEncoded);
+        RTMemTmpFree(pvFree);
+        if (pOsslCertRet == pOsslCert)
         {
             *ppvOsslCert = pOsslCert;
             return VINF_SUCCESS;
         }
+        rc = RTErrInfoSet(pErrInfo, VERR_CR_X509_OSSL_D2I_FAILED, "d2i_X509");
+
     }
-    /*
-     * Otherwise, we'll have to encode it into a temporary buffer that openssl
-     * can decode into its structures.
-     */
-    else
-    {
-        PRTASN1CORE pNonConstCore = (PRTASN1CORE)&pCert->SeqCore.Asn1Core;
-        uint32_t    cbEncoded     = 0;
-        int rc = RTAsn1EncodePrepare(pNonConstCore, RTASN1ENCODE_F_DER, &cbEncoded, pErrInfo);
-        AssertRCReturn(rc, rc);
-
-        void * const pvEncoded = RTMemTmpAllocZ(cbEncoded);
-        AssertReturn(pvEncoded, VERR_NO_TMP_MEMORY);
-
-        rc = RTAsn1EncodeToBuffer(pNonConstCore, RTASN1ENCODE_F_DER, pvEncoded, cbEncoded, pErrInfo);
-        if (RT_SUCCESS(rc))
-        {
-            pabEncoded = (const unsigned char *)pvEncoded;
-            X509 *pOsslCert = NULL;
-            if (d2i_X509(&pOsslCert, &pabEncoded, cbEncoded) == pOsslCert)
-            {
-                *ppvOsslCert = pOsslCert;
-                RTMemTmpFree(pvEncoded);
-                return VINF_SUCCESS;
-            }
-        }
-        else
-        {
-            RTMemTmpFree(pvEncoded);
-            return rc;
-        }
-    }
-
     *ppvOsslCert = NULL;
-    return RTErrInfoSet(pErrInfo, VERR_CR_X509_OSSL_D2I_FAILED, "d2i_X509");
+    return rc;
 }
 
Index: /trunk/src/VBox/Runtime/common/crypto/pkcs7-file.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/pkcs7-file.cpp	(revision 84310)
+++ /trunk/src/VBox/Runtime/common/crypto/pkcs7-file.cpp	(revision 84310)
@@ -0,0 +1,109 @@
+/* $Id$ */
+/** @file
+ * IPRT - Crypto - PKCS\#7/CMS, File related APIs.
+ */
+
+/*
+ * Copyright (C) 2006-2020 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include "internal/iprt.h"
+#include <iprt/crypto/pkcs7.h>
+
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/crypto/pem.h>
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+static RTCRPEMMARKERWORD const g_aWords_Cms[]   = { { RT_STR_TUPLE("CMS") } };
+static RTCRPEMMARKERWORD const g_aWords_Pkcs7[] = { { RT_STR_TUPLE("PKCS7") } };
+/** X509 Certificate markers. */
+RT_DECL_DATA_CONST(RTCRPEMMARKER const) g_aRTCrPkcs7Markers[] =
+{
+    { g_aWords_Cms,   RT_ELEMENTS(g_aWords_Cms) },
+    { g_aWords_Pkcs7, RT_ELEMENTS(g_aWords_Pkcs7) }
+};
+/** Number of entries in g_aRTCrPkcs7Markers. */
+RT_DECL_DATA_CONST(uint32_t const) g_cRTCrPkcs7Markers = RT_ELEMENTS(g_aRTCrPkcs7Markers);
+
+
+/** @name Flags for RTCrPkcs7ContentInfo_ReadFromBuffer
+ * @{ */
+/** Only allow PEM certificates, not binary ones.
+ * @sa RTCRPEMREADFILE_F_ONLY_PEM  */
+#define RTCRPKCS7_READ_F_PEM_ONLY        RT_BIT(1)
+/** @} */
+
+
+RTDECL(int) RTCrPkcs7_ReadFromBuffer(PRTCRPKCS7CONTENTINFO pContentInfo, const void *pvBuf, size_t cbBuf,
+                                     uint32_t fFlags, PCRTASN1ALLOCATORVTABLE pAllocator,
+                                     bool *pfCmsLabeled, PRTERRINFO pErrInfo, const char *pszErrorTag)
+{
+    if (pfCmsLabeled)
+        *pfCmsLabeled = false;
+    AssertReturn(!(fFlags & ~RTCRX509CERT_READ_F_PEM_ONLY), VERR_INVALID_FLAGS);
+
+    PCRTCRPEMSECTION pSectionHead;
+    int rc = RTCrPemParseContent(pvBuf, cbBuf,
+                                 fFlags & RTCRX509CERT_READ_F_PEM_ONLY ? RTCRPEMREADFILE_F_ONLY_PEM : 0,
+                                 g_aRTCrPkcs7Markers, g_cRTCrPkcs7Markers,
+                                 &pSectionHead, pErrInfo);
+    if (RT_SUCCESS(rc))
+    {
+        if (pSectionHead)
+        {
+            if (pfCmsLabeled)
+                *pfCmsLabeled = pSectionHead->pMarker == &g_aRTCrPkcs7Markers[0];
+
+            RTASN1CURSORPRIMARY PrimaryCursor;
+            RTAsn1CursorInitPrimary(&PrimaryCursor, pSectionHead->pbData, (uint32_t)RT_MIN(pSectionHead->cbData, UINT32_MAX),
+                                    pErrInfo, pAllocator, RTASN1CURSOR_FLAGS_DER, pszErrorTag);
+
+            RTCRPKCS7CONTENTINFO TmpContentInfo;
+            rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, &TmpContentInfo, "CI");
+            if (RT_SUCCESS(rc))
+            {
+                rc = RTCrPkcs7ContentInfo_CheckSanity(&TmpContentInfo, 0, pErrInfo, "CI");
+                if (RT_SUCCESS(rc))
+                {
+                    rc = RTCrPkcs7ContentInfo_Clone(pContentInfo, &TmpContentInfo, pAllocator);
+                    if (RT_SUCCESS(rc))
+                    {
+                        if (pSectionHead->pNext || PrimaryCursor.Cursor.cbLeft)
+                            rc = VINF_ASN1_MORE_DATA;
+                    }
+                }
+                RTCrPkcs7ContentInfo_Delete(&TmpContentInfo);
+            }
+            RTCrPemFreeSections(pSectionHead);
+        }
+        else
+            rc = rc != VINF_SUCCESS ? -rc : VERR_INTERNAL_ERROR_2;
+    }
+    return rc;
+}
+
Index: /trunk/src/VBox/Runtime/common/crypto/pkcs7-verify.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/pkcs7-verify.cpp	(revision 84309)
+++ /trunk/src/VBox/Runtime/common/crypto/pkcs7-verify.cpp	(revision 84310)
@@ -33,4 +33,5 @@
 
 #include <iprt/err.h>
+#include <iprt/mem.h>
 #include <iprt/string.h>
 #include <iprt/crypto/digest.h>
@@ -59,10 +60,17 @@
      * Verify using OpenSSL.          ERR_PUT_error
      */
-    int rcOssl;
-    unsigned char const *pbRawContent = RTASN1CORE_GET_RAW_ASN1_PTR(&pContentInfo->SeqCore.Asn1Core);
-    uint32_t             cbRawContent = RTASN1CORE_GET_RAW_ASN1_SIZE(&pContentInfo->SeqCore.Asn1Core)
-                                      + (pContentInfo->SeqCore.Asn1Core.fFlags & RTASN1CORE_F_INDEFINITE_LENGTH ? 2 : 0);
-    PKCS7 *pOsslPkcs7 = NULL;
-    if (d2i_PKCS7(&pOsslPkcs7, &pbRawContent, cbRawContent) != NULL)
+    unsigned char const *pbRawContent;
+    uint32_t             cbRawContent;
+    void                *pvFree;
+    int rcOssl = RTAsn1EncodeQueryRawBits(RTCrPkcs7ContentInfo_GetAsn1Core(pContentInfo),
+                                          (const uint8_t **)&pbRawContent, &cbRawContent, &pvFree, pErrInfo);
+    AssertRCReturn(rcOssl, rcOssl);
+
+    PKCS7 *pOsslPkcs7   = NULL;
+    PKCS7 *pOsslPkcs7Ret = d2i_PKCS7(&pOsslPkcs7, &pbRawContent, cbRawContent);
+
+    RTMemTmpFree(pvFree);
+
+    if (pOsslPkcs7Ret != NULL)
     {
         STACK_OF(X509) *pAddCerts = NULL;
@@ -317,12 +325,19 @@
 
         /* ASSUMES that the attributes are encoded according to DER. */
-        uint8_t const  *pbData = (uint8_t const *)RTASN1CORE_GET_RAW_ASN1_PTR(&pSignerInfo->AuthenticatedAttributes.SetCore.Asn1Core);
-        uint32_t        cbData = RTASN1CORE_GET_RAW_ASN1_SIZE(&pSignerInfo->AuthenticatedAttributes.SetCore.Asn1Core);
-        uint8_t         bSetOfTag = ASN1_TAG_SET | ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED;
-        rc = RTCrDigestUpdate(hDigest, &bSetOfTag, sizeof(bSetOfTag)); /* Replace the implict tag with a SET-OF tag. */
+        uint8_t const  *pbData;
+        uint32_t        cbData;
+        void           *pvFree = NULL;
+        rc = RTAsn1EncodeQueryRawBits(RTCrPkcs7Attributes_GetAsn1Core(&pSignerInfo->AuthenticatedAttributes),
+                                      &pbData, &cbData, &pvFree, pErrInfo);
         if (RT_SUCCESS(rc))
-            rc = RTCrDigestUpdate(hDigest, pbData + sizeof(bSetOfTag), cbData - sizeof(bSetOfTag)); /* Skip the implicit tag. */
-        if (RT_SUCCESS(rc))
-            rc = RTCrDigestFinal(hDigest, NULL, 0);
+        {
+            uint8_t bSetOfTag = ASN1_TAG_SET | ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED;
+            rc = RTCrDigestUpdate(hDigest, &bSetOfTag, sizeof(bSetOfTag)); /* Replace the implict tag with a SET-OF tag. */
+            if (RT_SUCCESS(rc))
+                rc = RTCrDigestUpdate(hDigest, pbData + sizeof(bSetOfTag), cbData - sizeof(bSetOfTag)); /* Skip the implicit tag. */
+            if (RT_SUCCESS(rc))
+                rc = RTCrDigestFinal(hDigest, NULL, 0);
+            RTMemTmpFree(pvFree);
+        }
     }
     return rc;
@@ -425,6 +440,7 @@
      */
     int rc = VINF_SUCCESS;
-    if (   hSignerCertSrc == NIL_RTCRSTORE
-        || hSignerCertSrc != hTrustedCerts)
+    if (   (   hSignerCertSrc == NIL_RTCRSTORE
+            || hSignerCertSrc != hTrustedCerts)
+        && !(fFlags & RTCRPKCS7VERIFY_SD_F_TRUST_ALL_CERTS) )
     {
         RTCRX509CERTPATHS hCertPaths;
Index: /trunk/src/VBox/Runtime/common/crypto/store.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/store.cpp	(revision 84309)
+++ /trunk/src/VBox/Runtime/common/crypto/store.cpp	(revision 84310)
@@ -37,4 +37,5 @@
 #include <iprt/string.h>
 
+#include <iprt/crypto/pkcs7.h>
 #include <iprt/crypto/x509.h>
 
@@ -188,4 +189,78 @@
 }
 
+
+RTDECL(int) RTCrStoreCertAddX509(RTCRSTORE hStore, uint32_t fFlags, PRTCRX509CERTIFICATE pCertificate, PRTERRINFO pErrInfo)
+{
+    /*
+     * Validate.
+     */
+    PRTCRSTOREINT pThis = (PRTCRSTOREINT)hStore;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->u32Magic == RTCRSTOREINT_MAGIC, VERR_INVALID_HANDLE);
+
+    AssertPtrReturn(pCertificate, VERR_INVALID_POINTER);
+    AssertReturn(RTCrX509Certificate_IsPresent(pCertificate), VERR_INVALID_PARAMETER);
+    int rc = RTCrX509Certificate_CheckSanity(pCertificate, 0, pErrInfo, "Cert");
+    AssertRCReturn(rc, rc);
+
+    AssertReturn(!(fFlags & ~(RTCRCERTCTX_F_ADD_IF_NOT_FOUND | RTCRCERTCTX_F_ENC_MASK)), VERR_INVALID_FLAGS);
+    AssertCompile(RTCRCERTCTX_F_ENC_X509_DER == 0);
+    AssertMsgReturn((fFlags & RTCRCERTCTX_F_ENC_MASK) == RTCRCERTCTX_F_ENC_X509_DER,
+                    ("Invalid encoding: %#x\n", fFlags), VERR_INVALID_FLAGS);
+
+    /*
+     * Encode and add it using pfnCertAddEncoded.
+     */
+    if (pThis->pProvider->pfnCertAddEncoded)
+    {
+        PRTASN1CORE pCore     = RTCrX509Certificate_GetAsn1Core(pCertificate);
+        uint32_t    cbEncoded = 0;
+        rc = RTAsn1EncodePrepare(pCore, RTASN1ENCODE_F_DER, &cbEncoded, pErrInfo);
+        if (RT_SUCCESS(rc))
+        {
+            uint8_t * const pbEncoded = (uint8_t *)RTMemTmpAllocZ(cbEncoded);
+            if (pbEncoded)
+            {
+                rc = RTAsn1EncodeToBuffer(pCore, RTASN1ENCODE_F_DER, pbEncoded, cbEncoded, pErrInfo);
+                if (RT_SUCCESS(rc))
+                    rc = pThis->pProvider->pfnCertAddEncoded(pThis->pvProvider, fFlags, pbEncoded, cbEncoded, pErrInfo);
+                RTMemTmpFree(pbEncoded);
+            }
+            else
+                rc = VERR_NO_TMP_MEMORY;
+        }
+    }
+    else
+        rc = VERR_WRITE_PROTECT;
+
+    return rc;
+}
+
+
+RTDECL(int) RTCrStoreCertAddPkcs7(RTCRSTORE hStore, uint32_t fFlags, PRTCRPKCS7CERT pCertificate, PRTERRINFO pErrInfo)
+{
+    AssertPtrReturn(pCertificate, VERR_INVALID_POINTER);
+    AssertReturn(RTCrPkcs7Cert_IsPresent(pCertificate), VERR_INVALID_PARAMETER);
+    switch (pCertificate->enmChoice)
+    {
+        case RTCRPKCS7CERTCHOICE_X509:
+            return RTCrStoreCertAddX509(hStore, fFlags, pCertificate->u.pX509Cert, pErrInfo);
+
+        case RTCRPKCS7CERTCHOICE_EXTENDED_PKCS6:
+            return RTErrInfoSetF(pErrInfo, VERR_NOT_IMPLEMENTED, "RTCrStoreCertAddPkcs7 does not implement EXTENDED_PKCS6");
+        case RTCRPKCS7CERTCHOICE_AC_V1:
+            return RTErrInfoSetF(pErrInfo, VERR_NOT_IMPLEMENTED, "RTCrStoreCertAddPkcs7 does not implement AC_V1");
+        case RTCRPKCS7CERTCHOICE_AC_V2:
+            return RTErrInfoSetF(pErrInfo, VERR_NOT_IMPLEMENTED, "RTCrStoreCertAddPkcs7 does not implement AC_V2");
+        case RTCRPKCS7CERTCHOICE_OTHER:
+            return RTErrInfoSetF(pErrInfo, VERR_NOT_IMPLEMENTED, "RTCrStoreCertAddPkcs7 does not implement OTHER");
+        case RTCRPKCS7CERTCHOICE_END:
+        case RTCRPKCS7CERTCHOICE_INVALID:
+        case RTCRPKCS7CERTCHOICE_32BIT_HACK:
+            break;
+        /* no default */
+    }
+    return RTErrInfoSetF(pErrInfo, VERR_INVALID_PARAMETER, "Invalid RTCRPKCS7CERT enmChoice value: %d", pCertificate->enmChoice);
+}
 
 
Index: /trunk/src/VBox/Runtime/common/crypto/x509-verify.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/crypto/x509-verify.cpp	(revision 84309)
+++ /trunk/src/VBox/Runtime/common/crypto/x509-verify.cpp	(revision 84310)
@@ -89,31 +89,13 @@
      * encoded bits are missing.
      */
-    if (   pThis->TbsCertificate.SeqCore.Asn1Core.uData.pu8
-        && pThis->TbsCertificate.SeqCore.Asn1Core.cb > 0)
+    const uint8_t  *pbRaw;
+    uint32_t        cbRaw;
+    void           *pvFree = NULL;
+    rc = RTAsn1EncodeQueryRawBits(RTCrX509TbsCertificate_GetAsn1Core(&pThis->TbsCertificate), &pbRaw, &cbRaw, &pvFree, pErrInfo);
+    if (RT_SUCCESS(rc))
+    {
         rc = RTCrPkixPubKeyVerifySignature(&pThis->SignatureAlgorithm.Algorithm, hPubKey, pParameters, &pThis->SignatureValue,
-                                           RTASN1CORE_GET_RAW_ASN1_PTR(&pThis->TbsCertificate.SeqCore.Asn1Core),
-                                           RTASN1CORE_GET_RAW_ASN1_SIZE(&pThis->TbsCertificate.SeqCore.Asn1Core),
-                                           pErrInfo);
-    else
-    {
-        uint32_t cbEncoded;
-        rc = RTAsn1EncodePrepare((PRTASN1CORE)&pThis->TbsCertificate.SeqCore.Asn1Core, RTASN1ENCODE_F_DER, &cbEncoded, pErrInfo);
-        if (RT_SUCCESS(rc))
-        {
-            void *pvTbsBits = RTMemTmpAlloc(cbEncoded);
-            if (pvTbsBits)
-            {
-                rc = RTAsn1EncodeToBuffer(&pThis->TbsCertificate.SeqCore.Asn1Core, RTASN1ENCODE_F_DER,
-                                          pvTbsBits, cbEncoded, pErrInfo);
-                if (RT_SUCCESS(rc))
-                    rc = RTCrPkixPubKeyVerifySignature(&pThis->SignatureAlgorithm.Algorithm, hPubKey, pParameters,
-                                                       &pThis->SignatureValue, pvTbsBits, cbEncoded, pErrInfo);
-                else
-                    AssertRC(rc);
-                RTMemTmpFree(pvTbsBits);
-            }
-            else
-                rc = VERR_NO_TMP_MEMORY;
-        }
+                                           pbRaw, cbRaw, pErrInfo);
+        RTMemTmpFree(pvFree);
     }
 
