13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/* $Id$ */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** @file
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * IPRT - ASN.1, Octet String.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * @remarks This file should remain very similar to asn1-ut-bitstring.cpp.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Copyright (C) 2006-2014 Oracle Corporation
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * available from http://www.virtualbox.org. This file is free software;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * you can redistribute it and/or modify it under the terms of the GNU
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * General Public License (GPL) as published by the Free Software
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * The contents of this file may alternatively be used under the terms
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * of the Common Development and Distribution License Version 1.0
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * VirtualBox OSE distribution, in which case the provisions of the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * CDDL are applicable instead of those of the GPL.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * You may elect to license modified versions of this file under the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * terms and conditions of either the GPL or the CDDL or both.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*******************************************************************************
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync* Header Files *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync*******************************************************************************/
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include "internal/iprt.h"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/asn1.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/alloca.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/bignum.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/ctype.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/err.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/string.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/uni.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/formats/asn1.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*******************************************************************************
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync* Structures and Typedefs *
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync*******************************************************************************/
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsynctypedef struct RTASN1OCTETSTRINGWRITERCTX
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /** Pointer to the output buffer. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint8_t *pbBuf;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /** The current buffer offset. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t offBuf;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /** The size of the buffer. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t cbBuf;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync} RTASN1OCTETSTRINGWRITERCTX;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** @callback_method_impl{FNRTASN1ENCODEWRITER,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Used to refresh the content of octet and bit strings. } */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncstatic DECLCALLBACK(int) rtAsn1OctetStringEncodeWriter(const void *pvBuf, size_t cbToWrite, void *pvUser, PRTERRINFO pErrInfo)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1OCTETSTRINGWRITERCTX *pCtx = (RTASN1OCTETSTRINGWRITERCTX *)pvUser;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(cbToWrite <= pCtx->cbBuf - pCtx->offBuf,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTErrInfoSetF(pErrInfo, VERR_BUFFER_OVERFLOW,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync "cbToWrite=%#x offBuf=%#x cbBuf=%#x", cbToWrite, pCtx->cbBuf, pCtx->offBuf));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync memcpy(&pCtx->pbBuf[pCtx->offBuf], pvBuf, cbToWrite);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pCtx->offBuf += (uint32_t)cbToWrite;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** @callback_method_impl{FNRTASN1ENCODEWRITER,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Used to compare the encoded raw content of an octet or bit string with the
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * encapsulated object. } */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncstatic DECLCALLBACK(int) rtAsn1OctetStringEncodeCompare(const void *pvBuf, size_t cbToWrite, void *pvUser, PRTERRINFO pErrInfo)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1OCTETSTRINGWRITERCTX *pCtx = (RTASN1OCTETSTRINGWRITERCTX *)pvUser;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(cbToWrite <= pCtx->cbBuf - pCtx->offBuf, VERR_BUFFER_OVERFLOW);
a118ea84f7f14ee4c253a7f584f0b592caf74c4fvboxsync if (memcmp(&pCtx->pbBuf[pCtx->offBuf], pvBuf, cbToWrite) != 0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return VERR_NOT_EQUAL;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pCtx->offBuf += (uint32_t)cbToWrite;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * ASN.1 OCTET STRING - Specific Methods
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1OctetString_RefreshContent(PRTASN1OCTETSTRING pThis, uint32_t fFlags,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PCRTASN1ALLOCATORVTABLE pAllocator, PRTERRINFO pErrInfo)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(pThis->pEncapsulated, VERR_INVALID_STATE);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t cbEncoded;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = RTAsn1EncodePrepare(pThis->pEncapsulated, fFlags, &cbEncoded, pErrInfo);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_SUCCESS(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pThis->Asn1Core.cb = cbEncoded;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTAsn1ContentReallocZ(&pThis->Asn1Core, cbEncoded, pAllocator);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_SUCCESS(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Initialize the writer context. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1OCTETSTRINGWRITERCTX Ctx;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Ctx.pbBuf = (uint8_t *)pThis->Asn1Core.uData.pu8;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Ctx.cbBuf = cbEncoded;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Ctx.offBuf = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTAsn1EncodeWrite(pThis->pEncapsulated, fFlags, rtAsn1OctetStringEncodeWriter, &Ctx, pErrInfo);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_SUCCESS(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (Ctx.offBuf == cbEncoded)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTErrInfoSetF(pErrInfo, rc, "Expected %#x bytes, got %#x", cbEncoded, Ctx.offBuf);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTErrInfoSetF(pErrInfo, rc, "Error allocating %#x bytes for storing content\n", cbEncoded);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(bool) RTAsn1OctetString_AreContentBytesValid(PCRTASN1OCTETSTRING pThis, uint32_t fFlags)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pThis->pEncapsulated)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Check the encoded length of the octets. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t cbEncoded;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = RTAsn1EncodePrepare(pThis->pEncapsulated, fFlags, &cbEncoded, NULL);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_FAILURE(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return false;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pThis->Asn1Core.cb != cbEncoded)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return false;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Check the encoded bytes, if there are any. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (cbEncoded)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (!pThis->Asn1Core.uData.pv)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return false;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Check the other bytes. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1OCTETSTRINGWRITERCTX Ctx;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Ctx.pbBuf = (uint8_t *)pThis->Asn1Core.uData.pu8;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Ctx.cbBuf = cbEncoded;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Ctx.offBuf = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTAsn1EncodeWrite(pThis->pEncapsulated, fFlags, rtAsn1OctetStringEncodeCompare, &Ctx, NULL);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_FAILURE(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return false;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return true;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * ASN.1 OCTET STRING - Standard Methods.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** @interface_method_impl{FNRTASN1COREVTENCODEPREP} */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncstatic DECLCALLBACK(int) RTAsn1OctetString_EncodePrep(PRTASN1CORE pThisCore, uint32_t fFlags, PRTERRINFO pErrInfo)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PRTASN1OCTETSTRING pThis = (PRTASN1OCTETSTRING)pThisCore;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (!pThis->pEncapsulated)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(pThis->Asn1Core.cb == 0 || pThis->Asn1Core.uData.pv);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Figure out the size of the encapsulated content. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync uint32_t cbEncoded;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = RTAsn1EncodePrepare(pThis->pEncapsulated, fFlags, &cbEncoded, pErrInfo);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_SUCCESS(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Free the bytes if they don't match up. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pThis->Asn1Core.uData.pv)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync bool fMustFree = pThis->Asn1Core.cb != cbEncoded;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (!fMustFree)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTASN1OCTETSTRINGWRITERCTX Ctx;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Ctx.pbBuf = (uint8_t *)pThis->Asn1Core.uData.pu8;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Ctx.cbBuf = cbEncoded;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Ctx.offBuf = 0;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTAsn1EncodeWrite(pThis->pEncapsulated, fFlags, rtAsn1OctetStringEncodeCompare, &Ctx, NULL);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync fMustFree = RT_FAILURE_NP(rc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (fMustFree)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTAsn1ContentFree(&pThis->Asn1Core);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pThis->Asn1Core.cb = cbEncoded;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTAsn1EncodeRecalcHdrSize(&pThis->Asn1Core, fFlags, pErrInfo);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/** @interface_method_impl{FNRTASN1COREVTENCODEWRITE} */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncstatic DECLCALLBACK(int) RTAsn1OctetString_EncodeWrite(PRTASN1CORE pThisCore, uint32_t fFlags, PFNRTASN1ENCODEWRITER pfnWriter,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync void *pvUser, PRTERRINFO pErrInfo)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PRTASN1OCTETSTRING pThis = (PRTASN1OCTETSTRING)pThisCore;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * First the header.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = RTAsnEncodeWriteHeader(&pThis->Asn1Core, fFlags, pfnWriter, pvUser, pErrInfo);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_SUCCESS(rc) && rc != VINF_ASN1_NOT_ENCODED)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * If nothing is encapsulated, the core points to the content (if we have any).
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (!pThis->pEncapsulated)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pThis->Asn1Core.cb > 0)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = pfnWriter(pThis->Asn1Core.uData.pu8, pThis->Asn1Core.cb, pvUser, pErrInfo);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Call upon the encapsulated content to serialize itself.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTAsn1EncodeWrite(pThis->pEncapsulated, fFlags, pfnWriter, pvUser, pErrInfo);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRT_DECL_DATA_CONST(RTASN1COREVTABLE const) g_RTAsn1OctetString_Vtable =
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync "OctetString",
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync sizeof(RTASN1OCTETSTRING),
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ASN1_TAG_OCTET_STRING,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_PRIMITIVE,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync 0,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync (PFNRTASN1COREVTDTOR)RTAsn1OctetString_Delete,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync (PFNRTASN1COREVTENUM)RTAsn1OctetString_Enum,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync (PFNRTASN1COREVTCLONE)RTAsn1OctetString_Clone,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync (PFNRTASN1COREVTCOMPARE)RTAsn1OctetString_Compare,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync (PFNRTASN1COREVTCHECKSANITY)RTAsn1OctetString_CheckSanity,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTAsn1OctetString_EncodePrep,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTAsn1OctetString_EncodeWrite
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync};
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1OctetString_Init(PRTASN1OCTETSTRING pThis, PCRTASN1ALLOCATORVTABLE pAllocator)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RT_ZERO(*pThis);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTAsn1Core_InitEx(&pThis->Asn1Core, ASN1_TAG_OCTET_STRING, ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_PRIMITIVE,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync &g_RTAsn1OctetString_Vtable, RTASN1CORE_F_PRESENT | RTASN1CORE_F_PRIMITE_TAG_STRUCT);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*pThis->pEncapsulated = NULL;*/
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTAsn1MemInitAllocation(&pThis->EncapsulatedAllocation, pAllocator);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1OctetString_Clone(PRTASN1OCTETSTRING pThis, PCRTASN1OCTETSTRING pSrc, PCRTASN1ALLOCATORVTABLE pAllocator)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertPtr(pSrc); AssertPtr(pThis); AssertPtr(pAllocator);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RT_ZERO(*pThis);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RTAsn1OctetString_IsPresent(pSrc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertReturn(pSrc->Asn1Core.pOps == &g_RTAsn1OctetString_Vtable, VERR_INTERNAL_ERROR_3);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (!pSrc->pEncapsulated)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTAsn1Core_CloneContent(&pThis->Asn1Core, &pSrc->Asn1Core, pAllocator);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTAsn1Core_CloneNoContent(&pThis->Asn1Core, &pSrc->Asn1Core);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_FAILURE(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTAsn1MemInitAllocation(&pThis->EncapsulatedAllocation, pAllocator);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pSrc->pEncapsulated)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync PCRTASN1COREVTABLE pOps = pSrc->pEncapsulated->pOps;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(!pOps || pOps->pfnClone);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pOps && pOps->pfnClone)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* We can clone the decoded encapsulated object. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTAsn1MemAllocZ(&pThis->EncapsulatedAllocation, (void **)&pThis->pEncapsulated, pOps->cbStruct);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_SUCCESS(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = pOps->pfnClone(pThis->pEncapsulated, pSrc->pEncapsulated, pAllocator);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_FAILURE(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTAsn1MemFree(&pThis->EncapsulatedAllocation, pThis->pEncapsulated);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Borrow the encapsulated pointer and use RTAsn1OctetString_RefreshContent
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync to get an accurate copy of the bytes. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pThis->pEncapsulated = pSrc->pEncapsulated;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync rc = RTAsn1OctetString_RefreshContent(pThis, RTASN1ENCODE_F_DER, pAllocator, NULL);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pThis->pEncapsulated = NULL;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_FAILURE(rc))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTAsn1ContentFree(&pThis->Asn1Core);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RT_ZERO(*pThis);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return rc;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(void) RTAsn1OctetString_Delete(PRTASN1OCTETSTRING pThis)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( pThis
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && RTAsn1OctetString_IsPresent(pThis))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(pThis->Asn1Core.pOps == &g_RTAsn1OctetString_Vtable);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Destroy the encapsulated object. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pThis->pEncapsulated)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTAsn1VtDelete(pThis->pEncapsulated);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pThis->EncapsulatedAllocation.cbAllocated)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTAsn1MemFree(&pThis->EncapsulatedAllocation, pThis->pEncapsulated);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Delete content and wipe the content. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RTAsn1ContentFree(&pThis->Asn1Core);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync RT_ZERO(*pThis);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1OctetString_Enum(PRTASN1OCTETSTRING pThis, PFNRTASN1ENUMCALLBACK pfnCallback, uint32_t uDepth, void *pvUser)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(pThis && (!RTAsn1OctetString_IsPresent(pThis) || pThis->Asn1Core.pOps == &g_RTAsn1OctetString_Vtable));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Enumerate the encapsulated object if present. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pThis->pEncapsulated)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return pfnCallback(pThis->pEncapsulated, "Encapsulated", uDepth + 1, pvUser);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1OctetString_Compare(PCRTASN1OCTETSTRING pLeft, PCRTASN1OCTETSTRING pRight)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(pLeft && (!RTAsn1OctetString_IsPresent(pLeft) || pLeft->Asn1Core.pOps == &g_RTAsn1OctetString_Vtable));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync Assert(pRight && (!RTAsn1OctetString_IsPresent(pRight) || pRight->Asn1Core.pOps == &g_RTAsn1OctetString_Vtable));
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int iDiff;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RTAsn1OctetString_IsPresent(pLeft))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RTAsn1OctetString_IsPresent(pRight))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Since it's really hard to tell whether encapsulated objects have
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync been modified or not, we might have to refresh both objects
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync while doing this compare. We'll try our best to avoid it though. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pLeft->pEncapsulated || pRight->pEncapsulated)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( pLeft->pEncapsulated
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pRight->pEncapsulated
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && pLeft->pEncapsulated->pOps == pRight->pEncapsulated->pOps)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync iDiff = pLeft->pEncapsulated->pOps->pfnCompare(pLeft->pEncapsulated, pRight->pEncapsulated);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* No direct comparison of encapsulated objects possible,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync make sure we've got the rigth bytes then. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( pLeft->pEncapsulated
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && !RTAsn1OctetString_AreContentBytesValid(pLeft, RTASN1ENCODE_F_DER))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = RTAsn1OctetString_RefreshContent((PRTASN1OCTETSTRING)pLeft, RTASN1ENCODE_F_DER,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pLeft->EncapsulatedAllocation.pAllocator, NULL);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertRC(rc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if ( pRight->pEncapsulated
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync && !RTAsn1OctetString_AreContentBytesValid(pRight, RTASN1ENCODE_F_DER))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync {
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync int rc = RTAsn1OctetString_RefreshContent((PRTASN1OCTETSTRING)pRight, RTASN1ENCODE_F_DER,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pRight->EncapsulatedAllocation.pAllocator, NULL);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync AssertRC(rc);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /* Compare the content bytes. */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync iDiff = RTAsn1Core_CompareEx(&pLeft->Asn1Core, &pRight->Asn1Core, true /*fIgnoreTagAndClass*/);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync /*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * No encapsulated object, just compare the raw content bytes.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync iDiff = RTAsn1Core_CompareEx(&pLeft->Asn1Core, &pRight->Asn1Core, true /*fIgnoreTagAndClass*/);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync iDiff = -1;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync }
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync else
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync iDiff = 0 - (int)RTAsn1OctetString_IsPresent(pRight);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return iDiff;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsyncRTDECL(int) RTAsn1OctetString_CheckSanity(PCRTASN1OCTETSTRING pThis, uint32_t fFlags, PRTERRINFO pErrInfo, const char *pszErrorTag)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync{
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (RT_UNLIKELY(!RTAsn1OctetString_IsPresent(pThis)))
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return RTErrInfoSetF(pErrInfo, VERR_ASN1_NOT_PRESENT, "%s: Missing (OCTET STRING).", pszErrorTag);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync if (pThis->pEncapsulated)
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return pThis->pEncapsulated->pOps->pfnCheckSanity(pThis->pEncapsulated, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK,
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync pErrInfo, pszErrorTag);
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync return VINF_SUCCESS;
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync}
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync/*
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync * Generate code for the associated collection types.
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync */
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#define RTASN1TMPL_TEMPLATE_FILE "../common/asn1/asn1-ut-octetstring-template.h"
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/asn1-generator-internal-header.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/asn1-generator-core.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/asn1-generator-init.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync#include <iprt/asn1-generator-sanity.h>
13493ab7596e827b8d0caab2c89e635dd65f78f9vboxsync