Index: trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 60242)
+++ trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 60243)
@@ -2986,5 +2986,5 @@
   <interface
     name="ICertificate" extends="$unknown"
-    uuid="c2b34d6f-7a10-4901-803e-05d5ef946567"
+    uuid="336064ce-c853-4bd0-ad6c-b42d8ed99e5e"
     wsmap="managed"
     reservedAttributes="4" reservedMethods="2"
@@ -3020,4 +3020,7 @@
       <desc>Time stamp in milliseconds since 1970-01-01 UTC.</desc>
     </attribute>
+    <attribute name="publicKeyAlgorithmOID" type="wstring" readonly="yes">
+      <desc>The dotted OID of the public key algorithm.</desc>
+    </attribute>
     <attribute name="publicKeyAlgorithm" type="wstring" readonly="yes">
       <desc>The public key algorithm name (if known).</desc>
@@ -3026,9 +3029,9 @@
       <desc>The raw public key bytes.</desc>
     </attribute>
-    <attribute name="issuerUniqueIdentifier" type="octet" safearray="yes" readonly="yes">
-      <desc>Unique identifier of the issuer (optional).</desc>
-    </attribute>
-    <attribute name="subjectUniqueIdentifier" type="octet" safearray="yes" readonly="yes">
-      <desc>Unique identifier of this certificate (optional).</desc>
+    <attribute name="issuerUniqueIdentifier" type="wstring" readonly="yes">
+      <desc>Unique identifier of the issuer (empty string if not present).</desc>
+    </attribute>
+    <attribute name="subjectUniqueIdentifier" type="wstring" readonly="yes">
+      <desc>Unique identifier of this certificate (empty string if not present).</desc>
     </attribute>
     <attribute name="certificateAuthority" type="boolean" readonly="yes">
@@ -3037,5 +3040,5 @@
       </desc>
     </attribute>
-    <attribute name="keyUsage" type="unsigned long" safearray="yes" readonly="yes">
+    <attribute name="keyUsage" type="unsigned long" readonly="yes">
       <desc>Key usage mask.  Will return 0 if not present.</desc>
     </attribute>
Index: trunk/src/VBox/Main/include/CertificateImpl.h
===================================================================
--- trunk/src/VBox/Main/include/CertificateImpl.h	(revision 60242)
+++ trunk/src/VBox/Main/include/CertificateImpl.h	(revision 60243)
@@ -1,8 +1,9 @@
+/* $Id$ */
 /** @file
- * VirtualBox COM class implementation
+ * VirtualBox COM ICertificate implementation.
  */
 
 /*
- * Copyright (C) 2006-2013 Oracle Corporation
+ * Copyright (C) 2006-2016 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -18,17 +19,20 @@
 #define ____H_CERTIFICATEIMPL
 
+//#define DONT_DUPLICATE_ALL_THE_DATA
+
 /* VBox includes */
 #include <VBox/settings.h>
-
-
+#include <iprt/crypto/x509.h>
 #include "CertificateWrap.h"
 
 #include <vector>
 
+
 using namespace std;
 
+#ifndef DONT_DUPLICATE_ALL_THE_DATA
 /* VBox forward declarations */
 class Appliance;
-struct RTCRX509CERTIFICATE;
+#endif
 
 class ATL_NO_VTABLE Certificate :
@@ -40,5 +44,9 @@
     DECLARE_EMPTY_CTOR_DTOR(Certificate)
 
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    HRESULT init(PCRTCRX509CERTIFICATE a_pCert);
+#else
     HRESULT init(Appliance* appliance);
+#endif
     void uninit();
 
@@ -46,10 +54,14 @@
     void FinalRelease();
 
-    HRESULT setData(RTCRX509CERTIFICATE *inCert);
+#ifndef DONT_DUPLICATE_ALL_THE_DATA
+    HRESULT setData(RTCRX509CERTIFICATE const *inCert);
+#endif
 
 private:
+#ifndef DONT_DUPLICATE_ALL_THE_DATA /* This is a generic information object, not something that is exclusive to Appliance! */
+    const Appliance* m_appliance;
+#endif
 
-    const Appliance* m_appliance;
-
+#ifndef DONT_DUPLICATE_ALL_THE_DATA /* This is a generic information object, not something that is exclusive to Appliance! */
     HRESULT setVersionNumber(uint64_t inVersionNumber);
     HRESULT setSerialNumber(uint64_t inSerialNumber);
@@ -71,4 +83,5 @@
 //  HRESULT setExtendedKeyUsage(std::vector<com::Utf8Str> aExtendedKeyUsage);
 //  HRESULT setRawCertData(std::vector<BYTE> aRawCertData);
+#endif
 
     // wrapped ICertificate properties
@@ -77,4 +90,5 @@
     HRESULT getSignatureAlgorithmOID(com::Utf8Str &aSignatureAlgorithmOID);
     HRESULT getSignatureAlgorithmName(com::Utf8Str &aSignatureAlgorithmName);
+    HRESULT getPublicKeyAlgorithmOID(com::Utf8Str &aPublicKeyAlgorithmOID);
     HRESULT getPublicKeyAlgorithm(com::Utf8Str &aPublicKeyAlgorithm);
     HRESULT getIssuerName(std::vector<com::Utf8Str> &aIssuerName);
@@ -83,8 +97,8 @@
     HRESULT getValidityPeriodNotAfter(com::Utf8Str &aValidityPeriodNotAfter);
     HRESULT getSubjectPublicKey(std::vector<BYTE> &aSubjectPublicKey);
-    HRESULT getIssuerUniqueIdentifier(std::vector<BYTE> &aIssuerUniqueIdentifier);
-    HRESULT getSubjectUniqueIdentifier(std::vector<BYTE> &aSubjectUniqueIdentifier);
+    HRESULT getIssuerUniqueIdentifier(com::Utf8Str &aIssuerUniqueIdentifier);
+    HRESULT getSubjectUniqueIdentifier(com::Utf8Str &aSubjectUniqueIdentifier);
     HRESULT getCertificateAuthority(BOOL *aCertificateAuthority);
-    HRESULT getKeyUsage(std::vector<ULONG> &aKeyUsage);
+    HRESULT getKeyUsage(ULONG *aKeyUsage);
     HRESULT getExtendedKeyUsage(std::vector<com::Utf8Str> &aExtendedKeyUsage);
     HRESULT getRawCertData(std::vector<BYTE> &aRawCertData);
@@ -94,6 +108,19 @@
     // wrapped ICertificate methods
     HRESULT queryInfo(LONG aWhat, com::Utf8Str &aResult);
+#ifndef DONT_DUPLICATE_ALL_THE_DATA
     HRESULT checkExistence(BOOL *aPresence);
     HRESULT isVerified(BOOL *aVerified);
+#endif
+
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    /** @name Methods extracting COM data from the certificate object
+     * @{  */
+    HRESULT i_getAlgorithmName(PCRTCRX509ALGORITHMIDENTIFIER a_pAlgId, com::Utf8Str &a_rReturn);
+    HRESULT i_getX509Name(PCRTCRX509NAME a_pName, std::vector<com::Utf8Str> &a_rReturn);
+    HRESULT i_getTime(PCRTASN1TIME a_pTime, com::Utf8Str &a_rReturn);
+    HRESULT i_getUniqueIdentifier(PCRTCRX509UNIQUEIDENTIFIER a_pUniqueId, com::Utf8Str &a_rReturn);
+    HRESULT i_getEncodedBytes(PRTASN1CORE a_pAsn1Obj, std::vector<BYTE> &a_rReturn);
+    /** @} */
+#endif
     //data
     struct Data;
Index: trunk/src/VBox/Main/src-server/CertificateImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/CertificateImpl.cpp	(revision 60242)
+++ trunk/src/VBox/Main/src-server/CertificateImpl.cpp	(revision 60243)
@@ -1,3 +1,3 @@
-
+/* $Id$ */
 /** @file
  * ICertificate COM class implementations.
@@ -26,4 +26,5 @@
 #include "CertificateImpl.h"
 #include "AutoCaller.h"
+#include "Global.h"
 #include "Logging.h"
 
@@ -32,4 +33,34 @@
 struct CertificateData
 {
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    CertificateData()
+        : fTrusted(false)
+        , fValidX509(false)
+    {
+        RT_ZERO(X509);
+    }
+
+    ~CertificateData()
+    {
+        if (fValidX509)
+        {
+            RTCrX509Certificate_Delete(&X509);
+            RT_ZERO(X509);
+            fValidX509 = false;
+        }
+    }
+
+    /** Whether the certificate is trusted.  */
+    bool fTrusted;
+    /** Valid data in mX509. */
+    bool fValidX509;
+    /** Clone of the X.509 certificate. */
+    RTCRX509CERTIFICATE X509;
+
+private:
+    CertificateData(const CertificateData &rTodo) { AssertFailed(); NOREF(rTodo); }
+    CertificateData &operator=(const CertificateData &rTodo) { AssertFailed(); NOREF(rTodo); return *this; }
+
+#else
     CertificateData() :
         mVersionNumber(0),
@@ -60,5 +91,5 @@
     std::vector<Utf8Str> mExtendedKeyUsage;
     std::vector<BYTE> mRawCertData;
-
+#endif
 };
 
@@ -98,5 +129,9 @@
 }
 
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+HRESULT Certificate::init(PCRTCRX509CERTIFICATE a_pCert)
+#else
 HRESULT Certificate::init(Appliance* appliance)
+#endif
 {
     HRESULT rc = S_OK;
@@ -107,4 +142,5 @@
     AssertReturn(autoInitSpan.isOk(), E_FAIL);
 
+#ifndef DONT_DUPLICATE_ALL_THE_DATA
     if(appliance!=NULL)
     {
@@ -114,7 +150,15 @@
     else
         rc = E_FAIL;
+#endif
 
     mData = new Data();
     mData->m.allocate();
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    int vrc = RTCrX509Certificate_Clone(&mData->m->X509, a_pCert, &g_RTAsn1DefaultAllocator);
+    if (RT_SUCCESS(vrc))
+        mData->m->fValidX509 = true;
+    else
+        rc = Global::vboxStatusCodeToCOM(vrc);
+#else
     mData->m->mSignatureAlgorithmOID.setNull();
     mData->m->mSignatureAlgorithmName.setNull();
@@ -130,4 +174,5 @@
     mData->m->mExtendedKeyUsage.resize(0);
     mData->m->mRawCertData.resize(0);
+#endif
 
     /* Confirm a successful initialization when it's the case */
@@ -152,4 +197,7 @@
     mData = NULL;
 }
+
+#ifndef DONT_DUPLICATE_ALL_THE_DATA /* We'll query the data from the RTCrX509* API. */
+
 /**
  * Public method implementation.
@@ -157,5 +205,5 @@
  * @return
  */
-HRESULT Certificate::setData(RTCRX509CERTIFICATE *inCert)
+HRESULT Certificate::setData(PCRTCRX509CERTIFICATE inCert)
 {
 
@@ -452,4 +500,6 @@
 }
 
+#endif /* !DONT_DUPLICATE_ALL_THE_DATA */
+
 /**
  * Private method implementation.
@@ -460,6 +510,12 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    Assert(mData->m->fValidX509);
+    /** @todo make this ULONG, or better, an ENUM. */
+    aVersionNumber = Utf8StrFmt("%RU64", mData->m->X509.TbsCertificate.T0.Version.uValue.u + 1); /* version 1 has value 0, so +1. */
+#else
     Utf8StrFmt strVer("%Lu", mData->m->mVersionNumber);
     aVersionNumber = strVer;
+#endif
     return S_OK;
 }
@@ -473,6 +529,17 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    Assert(mData->m->fValidX509);
+
+    char szTmp[_2K];
+    int vrc = RTAsn1Integer_ToString(&mData->m->X509.TbsCertificate.SerialNumber, szTmp, sizeof(szTmp), 0, NULL);
+    if (RT_SUCCESS(vrc))
+        aSerialNumber = szTmp;
+    else
+        return Global::vboxStatusCodeToCOM(vrc);
+#else
     Utf8StrFmt strVer("%llx", mData->m->mSerialNumber);
     aSerialNumber = strVer;
+#endif
     return S_OK;
 }
@@ -486,7 +553,10 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    Assert(mData->m->fValidX509);
+    aSignatureAlgorithmOID = mData->m->X509.TbsCertificate.Signature.Algorithm.szObjId;
+#else
     aSignatureAlgorithmOID = mData->m->mSignatureAlgorithmOID;
-
+#endif
     return S_OK;
 }
@@ -500,8 +570,12 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    Assert(mData->m->fValidX509);
+    return i_getAlgorithmName(&mData->m->X509.TbsCertificate.Signature, aSignatureAlgorithmName);
+#else
     aSignatureAlgorithmName = mData->m->mSignatureAlgorithmName;
 
     return S_OK;
+#endif
 }
 
@@ -514,8 +588,12 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    Assert(mData->m->fValidX509);
+    return i_getX509Name(&mData->m->X509.TbsCertificate.Issuer, aIssuerName);
+#else
     aIssuerName = mData->m->mIssuerName;
 
     return S_OK;
+#endif
 }
 
@@ -528,8 +606,13 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    Assert(mData->m->fValidX509);
+    return i_getX509Name(&mData->m->X509.TbsCertificate.Subject, aSubjectName);
+#else
 
     aSubjectName = mData->m->mSubjectName;
 
     return S_OK;
+#endif
 }
 
@@ -542,5 +625,8 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    Assert(mData->m->fValidX509);
+    return i_getTime(&mData->m->X509.TbsCertificate.Validity.NotBefore, aValidityPeriodNotBefore);
+#else
     HRESULT rc = S_OK;
 
@@ -558,4 +644,5 @@
 
     return rc;
+#endif
 }
 
@@ -568,4 +655,8 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    Assert(mData->m->fValidX509);
+    return i_getTime(&mData->m->X509.TbsCertificate.Validity.NotAfter, aValidityPeriodNotAfter);
+#else
 
     HRESULT rc = S_OK;
@@ -582,4 +673,17 @@
     delete[] charArr;
     return rc;
+#endif
+}
+
+HRESULT Certificate::getPublicKeyAlgorithmOID(com::Utf8Str &aPublicKeyAlgorithmOID)
+{
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    Assert(mData->m->fValidX509);
+    aPublicKeyAlgorithmOID = mData->m->X509.TbsCertificate.SubjectPublicKeyInfo.Algorithm.Algorithm.szObjId;
+    return S_OK;
+#else
+    return E_NOTIMPL;
+#endif
 }
 
@@ -592,8 +696,12 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    Assert(mData->m->fValidX509);
+    return i_getAlgorithmName(&mData->m->X509.TbsCertificate.SubjectPublicKeyInfo.Algorithm, aPublicKeyAlgorithm);
+#else
     aPublicKeyAlgorithm = mData->m->mPublicKeyAlgorithmName;
 
     return S_OK;
+#endif
 }
 
@@ -605,7 +713,10 @@
 HRESULT Certificate::getSubjectPublicKey(std::vector<BYTE> &aSubjectPublicKey)
 {
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    return S_OK;
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); /* Getting encoded ASN.1 bytes may make changes to X509. */
+    return i_getEncodedBytes(&mData->m->X509.TbsCertificate.SubjectPublicKeyInfo.SubjectPublicKey.Asn1Core, aSubjectPublicKey);
+#else
+    return E_NOTIMPL;
+#endif
 }
 
@@ -615,9 +726,12 @@
  * @return
  */
-HRESULT Certificate::getIssuerUniqueIdentifier(std::vector<BYTE> &aIssuerUniqueIdentifier)
-{
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    return S_OK;
+HRESULT Certificate::getIssuerUniqueIdentifier(com::Utf8Str &aIssuerUniqueIdentifier)
+{
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    return i_getUniqueIdentifier(&mData->m->X509.TbsCertificate.T1.IssuerUniqueId, aIssuerUniqueIdentifier);
+#else
+    return E_NOTIMPL;
+#endif
 }
 
@@ -627,9 +741,12 @@
  * @return
  */
-HRESULT Certificate::getSubjectUniqueIdentifier(std::vector<BYTE> &aSubjectUniqueIdentifier)
-{
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    return S_OK;
+HRESULT Certificate::getSubjectUniqueIdentifier(com::Utf8Str &aSubjectUniqueIdentifier)
+{
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    return i_getUniqueIdentifier(&mData->m->X509.TbsCertificate.T2.SubjectUniqueId, aSubjectUniqueIdentifier);
+#else
+    return E_NOTIMPL;
+#endif
 }
 
@@ -642,7 +759,10 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    *aCertificateAuthority = mData->m->X509.TbsCertificate.T3.pBasicConstraints
+                          && mData->m->X509.TbsCertificate.T3.pBasicConstraints->CA.fValue;
+#else
     *aCertificateAuthority = mData->m->mCertificateAuthority;
-
+#endif
     return S_OK;
 }
@@ -653,9 +773,13 @@
  * @return
  */
-HRESULT Certificate::getKeyUsage(std::vector<ULONG> &aKeyUsage)
-{
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    return S_OK;
+HRESULT Certificate::getKeyUsage(ULONG *aKeyUsage)
+{
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    *aKeyUsage = mData->m->X509.TbsCertificate.T3.fKeyUsage;
+    return S_OK;
+#else
+    return E_NOTIMPL;
+#endif
 }
 
@@ -668,6 +792,6 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    return S_OK;
+    NOREF(aExtendedKeyUsage);
+    return E_NOTIMPL;
 }
 
@@ -679,7 +803,10 @@
 HRESULT Certificate::getRawCertData(std::vector<BYTE> &aRawCertData)
 {
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    return S_OK;
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); /* Getting encoded ASN.1 bytes may make changes to X509. */
+    return i_getEncodedBytes(&mData->m->X509.SeqCore.Asn1Core, aRawCertData);
+#else
+    return E_NOTIMPL;
+#endif
 }
 
@@ -692,7 +819,10 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    Assert(mData->m->fValidX509);
+    *aSelfSigned = RTCrX509Certificate_IsSelfSigned(&mData->m->X509);
+#else
     *aSelfSigned = mData->m->mSelfSigned;
-
+#endif
     return S_OK;
 }
@@ -706,7 +836,9 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
+#ifdef DONT_DUPLICATE_ALL_THE_DATA
+    *aTrusted = mData->m->fTrusted;
+#else
     *aTrusted = mData->m->mTrusted;
-
+#endif
     return S_OK;
 }
@@ -721,7 +853,10 @@
 {
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    return S_OK;
-}
+    /* Insurance. */
+    NOREF(aResult);
+    return setError(E_FAIL, "Unknown item %u", aWhat);
+}
+
+#ifndef DONT_DUPLICATE_ALL_THE_DATA  /* These are out of place. */
 
 /**
@@ -755,2 +890,77 @@
 }
 
+#else  /* DONT_DUPLICATE_ALL_THE_DATA */
+
+HRESULT Certificate::i_getAlgorithmName(PCRTCRX509ALGORITHMIDENTIFIER a_pAlgId, com::Utf8Str &a_rReturn)
+{
+    /** @todo  */
+    NOREF(a_pAlgId);
+    NOREF(a_rReturn);
+    return E_NOTIMPL;
+}
+
+HRESULT Certificate::i_getX509Name(PCRTCRX509NAME a_pName, std::vector<com::Utf8Str> &a_rReturn)
+{
+    /** @todo  */
+    NOREF(a_pName);
+    NOREF(a_rReturn);
+    return E_NOTIMPL;
+}
+
+HRESULT Certificate::i_getTime(PCRTASN1TIME a_pTime, com::Utf8Str &a_rReturn)
+{
+    char szTmp[128];
+    if (RTTimeToString(&a_pTime->Time, szTmp, sizeof(szTmp)))
+    {
+        a_rReturn = szTmp;
+        return S_OK;
+    }
+    AssertFailed();
+    return E_FAIL;
+}
+
+HRESULT Certificate::i_getUniqueIdentifier(PCRTCRX509UNIQUEIDENTIFIER a_pUniqueId, com::Utf8Str &a_rReturn)
+{
+    /* The a_pUniqueId may not be present! */
+    if (RTCrX509UniqueIdentifier_IsPresent(a_pUniqueId))
+    {
+        void const   *pvData = RTASN1BITSTRING_GET_BIT0_PTR(a_pUniqueId);
+        size_t const  cbData = RTASN1BITSTRING_GET_BYTE_SIZE(a_pUniqueId);
+        size_t const  cbFormatted = cbData * 3 - 1 + 1;
+        a_rReturn.reserve(cbFormatted); /* throws */
+        int vrc = RTStrPrintHexBytes(a_rReturn.mutableRaw(), cbFormatted, pvData, cbData, RTSTRPRINTHEXBYTES_F_SEP_COLON);
+        a_rReturn.jolt();
+        AssertRCReturn(vrc, Global::vboxStatusCodeToCOM(vrc));
+    }
+    else
+        Assert(a_rReturn.isEmpty());
+    return S_OK;
+}
+
+HRESULT Certificate::i_getEncodedBytes(PRTASN1CORE a_pAsn1Obj, std::vector<BYTE> &a_rReturn)
+{
+    HRESULT hrc = S_OK;
+    Assert(a_rReturn.size() == 0);
+    if (RTAsn1Core_IsPresent(a_pAsn1Obj))
+    {
+        uint32_t cbEncoded;
+        int vrc = RTAsn1EncodePrepare(a_pAsn1Obj, 0, &cbEncoded, NULL);
+        if (RT_SUCCESS(vrc))
+        {
+            a_rReturn.resize(cbEncoded);
+            Assert(a_rReturn.size() == cbEncoded);
+            if (cbEncoded)
+            {
+                vrc = RTAsn1EncodeToBuffer(a_pAsn1Obj, 0, &a_rReturn.front(), a_rReturn.size(), NULL);
+                if (RT_FAILURE(vrc))
+                    hrc = setErrorVrc(vrc, "RTAsn1EncodeToBuffer failed with %Rrc", vrc);
+            }
+        }
+        else
+            hrc = setErrorVrc(vrc, "RTAsn1EncodePrepare failed with %Rrc", vrc);
+    }
+    return hrc;
+}
+
+#endif /* DONT_DUPLICATE_ALL_THE_DATA */
+
