2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/* $Id$ */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/** @file
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * IPRT - In Memory Cryptographic Certificate Store.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/*
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Copyright (C) 2006-2014 Oracle Corporation
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster *
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * This file is part of VirtualBox Open Source Edition (OSE), as
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * available from http://www.virtualbox.org. This file is free software;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * you can redistribute it and/or modify it under the terms of the GNU
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * General Public License (GPL) as published by the Free Software
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Foundation, in version 2 as it comes in the "COPYING" file of the
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster *
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * The contents of this file may alternatively be used under the terms
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * of the Common Development and Distribution License Version 1.0
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * VirtualBox OSE distribution, in which case the provisions of the
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * CDDL are applicable instead of those of the GPL.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster *
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * You may elect to license modified versions of this file under the
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * terms and conditions of either the GPL or the CDDL or both.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/*******************************************************************************
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster* Header Files *
a4544a5a0e622ef69e38641f87ab1b5685e05911Phill Cunnington*******************************************************************************/
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster#include "internal/iprt.h"
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster#include <iprt/crypto/store.h>
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster#include <iprt/asm.h>
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster#include <iprt/err.h>
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster#include <iprt/mem.h>
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster#include <iprt/string.h>
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster#include "store-internal.h"
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/*******************************************************************************
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster* Structures and Typedefs *
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster*******************************************************************************/
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/**
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * A certificate entry in the in-memory store.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fostertypedef struct RTCRSTOREINMEMCERT
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster /** The core certificate context. */
8d2daf3b9ecfc9b9b306bab966eda82fe2201b19jeff.schenk RTCRCERTCTXINT Core;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster /** Internal copy of the flag (paranoia). */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster uint32_t fFlags;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster /** Decoded data. */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster union
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster /** ASN.1 core structure for generic access. */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTASN1CORE Asn1Core;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster /** The decoded X.509 certificate (RTCRCERTCTX_F_ENC_X509_DER). */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTCRX509CERTIFICATE X509Cert;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster /** The decoded trust anchor info (RTCRCERTCTX_F_ENC_TAF_DER). */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTCRTAFTRUSTANCHORINFO TaInfo;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster } u;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster /** Pointer to the store if still in it (no reference). */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster struct RTCRSTOREINMEM *pStore;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster /** The DER encoding of the certificate. */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster uint8_t abEncoded[1];
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster} RTCRSTOREINMEMCERT;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan FosterAssertCompileMembersAtSameOffset(RTCRSTOREINMEMCERT, u.X509Cert.SeqCore.Asn1Core, RTCRSTOREINMEMCERT, u.Asn1Core);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan FosterAssertCompileMembersAtSameOffset(RTCRSTOREINMEMCERT, u.TaInfo.SeqCore.Asn1Core, RTCRSTOREINMEMCERT, u.Asn1Core);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/** Pointer to an in-memory store certificate entry. */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fostertypedef RTCRSTOREINMEMCERT *PRTCRSTOREINMEMCERT;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/**
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * The per instance data of a in-memory crypto store.
41202e15f589286770cacca433bbee5df379d00bAllan Foster *
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Currently we ASSUME we don't need serialization. Add that when needed!
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fostertypedef struct RTCRSTOREINMEM
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster /** The number of certificates. */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster uint32_t cCerts;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster /** The max number of certificates papCerts can store before growing it. */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster uint32_t cCertsAlloc;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster /** Array of certificates. */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster PRTCRSTOREINMEMCERT *papCerts;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster} RTCRSTOREINMEM;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/** Pointer to an in-memory crypto store. */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fostertypedef RTCRSTOREINMEM *PRTCRSTOREINMEM;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterstatic DECLCALLBACK(void) rtCrStoreInMemCertEntry_Dtor(PRTCRCERTCTXINT pCertCtx)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster PRTCRSTOREINMEMCERT pEntry = (PRTCRSTOREINMEMCERT)pCertCtx;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster AssertRelease(!pEntry->pStore);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pEntry->Core.pfnDtor = NULL;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTAsn1VtDelete(&pEntry->u.Asn1Core);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTMemFree(pEntry);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster}
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/**
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Internal method for allocating and initalizing a certificate entry in the
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * in-memory store.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster *
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @returns IPRT status code.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @param pThis The in-memory store instance.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @param fEnc RTCRCERTCTX_F_ENC_X509_DER or RTCRCERTCTX_F_ENC_TAF_DER.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @param pbSrc The DER encoded X.509 certificate to add.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @param cbSrc The size of the encoded certificate.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @param pErrInfo Where to return extended error info. Optional.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @param ppEntry Where to return the pointer to the new entry.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterstatic int rtCrStoreInMemCreateCertEntry(PRTCRSTOREINMEM pThis, uint32_t fEnc, uint8_t const *pbSrc, uint32_t cbSrc,
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster PRTERRINFO pErrInfo, PRTCRSTOREINMEMCERT *ppEntry)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster int rc;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster PRTCRSTOREINMEMCERT pEntry = (PRTCRSTOREINMEMCERT)RTMemAllocZ(RT_UOFFSETOF(RTCRSTOREINMEMCERT, abEncoded[cbSrc]));
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (pEntry)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
1f2a4423f81a4223af1cd9b3f9581dad542cb10csachiko memcpy(pEntry->abEncoded, pbSrc, cbSrc);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pEntry->Core.u32Magic = RTCRCERTCTXINT_MAGIC;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pEntry->Core.cRefs = 1;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pEntry->Core.pfnDtor = rtCrStoreInMemCertEntry_Dtor;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pEntry->Core.Public.fFlags = fEnc;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pEntry->Core.Public.cbEncoded = cbSrc;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pEntry->Core.Public.pabEncoded = &pEntry->abEncoded[0];
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (fEnc == RTCRCERTCTX_F_ENC_X509_DER)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pEntry->Core.Public.pCert = &pEntry->u.X509Cert;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pEntry->Core.Public.pTaInfo = NULL;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster }
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster else
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pEntry->Core.Public.pCert = NULL;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pEntry->Core.Public.pTaInfo = &pEntry->u.TaInfo;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster }
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pEntry->pStore = pThis;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTASN1CURSORPRIMARY Cursor;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTAsn1CursorInitPrimary(&Cursor, &pEntry->abEncoded[0], cbSrc, pErrInfo, &g_RTAsn1DefaultAllocator,
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTASN1CURSOR_FLAGS_DER, "InMem");
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (fEnc == RTCRCERTCTX_F_ENC_X509_DER)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rc = RTCrX509Certificate_DecodeAsn1(&Cursor.Cursor, 0, &pEntry->u.X509Cert, "Cert");
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster else
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rc = RTCrTafTrustAnchorInfo_DecodeAsn1(&Cursor.Cursor, 0, &pEntry->u.TaInfo, "TaInfo");
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (RT_SUCCESS(rc))
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (fEnc == RTCRCERTCTX_F_ENC_X509_DER)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rc = RTCrX509Certificate_CheckSanity(&pEntry->u.X509Cert, 0, pErrInfo, "Cert");
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster else
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rc = RTCrTafTrustAnchorInfo_CheckSanity(&pEntry->u.TaInfo, 0, pErrInfo, "TaInfo");
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (RT_SUCCESS(rc))
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster *ppEntry = pEntry;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return VINF_SUCCESS;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster }
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTAsn1VtDelete(&pEntry->u.Asn1Core);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster }
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTMemFree(pEntry);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster }
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster else
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rc = VERR_NO_MEMORY;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return rc;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster}
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/**
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Grows the certificate pointer array to at least @a cMin entries.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster *
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @returns IPRT status code.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @param pThis The in-memory store instance.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @param cMin The new minimum store size.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterstatic int rtCrStoreInMemGrow(PRTCRSTOREINMEM pThis, uint32_t cMin)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster AssertReturn(cMin <= _1M, VERR_OUT_OF_RANGE);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster AssertReturn(cMin > pThis->cCertsAlloc, VERR_INTERNAL_ERROR_3);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (cMin < 64)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster cMin = RT_ALIGN_32(cMin, 8);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster else
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster cMin = RT_ALIGN_32(cMin, 32);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster void *pv = RTMemRealloc(pThis->papCerts, cMin * sizeof(pThis->papCerts[0]));
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (pv)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pThis->papCerts = (PRTCRSTOREINMEMCERT *)pv;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster for (uint32_t i = pThis->cCertsAlloc; i < cMin; i++)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pThis->papCerts[i] = NULL;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pThis->cCertsAlloc = cMin;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return VINF_SUCCESS;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster }
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return VERR_NO_MEMORY;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster}
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/** @interface_method_impl{RTCRSTOREPROVIDER, pfnDestroyStore} */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterstatic DECLCALLBACK(void) rtCrStoreInMem_DestroyStore(void *pvProvider)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster PRTCRSTOREINMEM pThis = (PRTCRSTOREINMEM)pvProvider;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster while (pThis->cCerts > 0)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster uint32_t i = --pThis->cCerts;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster PRTCRSTOREINMEMCERT pEntry = pThis->papCerts[i];
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pThis->papCerts[i] = NULL;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster AssertPtr(pEntry);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pEntry->pStore = NULL;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTCrCertCtxRelease(&pEntry->Core.Public);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster }
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTMemFree(pThis->papCerts);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pThis->papCerts = NULL;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTMemFree(pThis);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster}
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/** @interface_method_impl{RTCRSTOREPROVIDER, pfnCertCtxQueryPrivateKey} */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterstatic DECLCALLBACK(int) rtCrStoreInMem_CertCtxQueryPrivateKey(void *pvProvider, PRTCRCERTCTXINT pCertCtx,
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster uint8_t *pbKey, size_t cbKey, size_t *pcbKeyRet)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster //PRTCRSTOREINMEM pThis = (PRTCRSTOREINMEM)pvProvider;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return VERR_NOT_FOUND;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster}
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/** @interface_method_impl{RTCRSTOREPROVIDER, pfnCertFindAll} */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterstatic DECLCALLBACK(int) rtCrStoreInMem_CertFindAll(void *pvProvider, PRTCRSTORECERTSEARCH pSearch)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster PRTCRSTOREINMEM pThis = (PRTCRSTOREINMEM)pvProvider;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pSearch->auOpaque[0] = ~(uintptr_t)pvProvider;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pSearch->auOpaque[1] = 0;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pSearch->auOpaque[2] = ~(uintptr_t)0; /* For the front-end API. */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pSearch->auOpaque[3] = ~(uintptr_t)0; /* For the front-end API. */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return VINF_SUCCESS;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster}
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/** @interface_method_impl{RTCRSTOREPROVIDER, pfnCertSearchNext} */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterstatic DECLCALLBACK(PCRTCRCERTCTX) rtCrStoreInMem_CertSearchNext(void *pvProvider, PRTCRSTORECERTSEARCH pSearch)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster PRTCRSTOREINMEM pThis = (PRTCRSTOREINMEM)pvProvider;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster AssertReturn(pSearch->auOpaque[0] == ~(uintptr_t)pvProvider, NULL);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster uintptr_t i = pSearch->auOpaque[1];
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (i < pThis->cCerts)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pSearch->auOpaque[1] = i + 1;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster PRTCRCERTCTXINT pCertCtx = &pThis->papCerts[i]->Core;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster ASMAtomicIncU32(&pCertCtx->cRefs);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return &pCertCtx->Public;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster }
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return NULL;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster}
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/** @interface_method_impl{RTCRSTOREPROVIDER, pfnCertSearchDestroy} */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterstatic DECLCALLBACK(void) rtCrStoreInMem_CertSearchDestroy(void *pvProvider, PRTCRSTORECERTSEARCH pSearch)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster NOREF(pvProvider);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster AssertReturnVoid(pSearch->auOpaque[0] == ~(uintptr_t)pvProvider);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pSearch->auOpaque[0] = 0;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pSearch->auOpaque[1] = 0;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pSearch->auOpaque[2] = 0;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pSearch->auOpaque[3] = 0;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster}
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/** @interface_method_impl{RTCRSTOREPROVIDER, pfnCertSearchDestroy} */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterstatic DECLCALLBACK(int) rtCrStoreInMem_CertAddEncoded(void *pvProvider, uint32_t fFlags,
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster uint8_t const *pbEncoded, uint32_t cbEncoded, PRTERRINFO pErrInfo)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster PRTCRSTOREINMEM pThis = (PRTCRSTOREINMEM)pvProvider;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster int rc;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster AssertMsgReturn( fFlags == RTCRCERTCTX_F_ENC_X509_DER
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster || fFlags == RTCRCERTCTX_F_ENC_TAF_DER
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster , ("Only X.509 and TAF DER are supported: %#x\n", fFlags), VERR_INVALID_FLAGS);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (pThis->cCerts + 1 > pThis->cCertsAlloc)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rc = rtCrStoreInMemGrow(pThis, pThis->cCerts + 1);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (RT_FAILURE(rc))
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return rc;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster }
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rc = rtCrStoreInMemCreateCertEntry(pThis, fFlags, pbEncoded, cbEncoded, pErrInfo, &pThis->papCerts[pThis->cCerts]);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (RT_SUCCESS(rc))
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pThis->cCerts++;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return VINF_SUCCESS;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster }
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return rc;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster}
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/**
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * In-memory store provider.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterstatic RTCRSTOREPROVIDER const g_rtCrStoreInMemProvider =
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster "in-memory",
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rtCrStoreInMem_DestroyStore,
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rtCrStoreInMem_CertCtxQueryPrivateKey,
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rtCrStoreInMem_CertFindAll,
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rtCrStoreInMem_CertSearchNext,
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rtCrStoreInMem_CertSearchDestroy,
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rtCrStoreInMem_CertAddEncoded,
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster NULL,
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster 42
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster};
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster/**
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * Common worker for RTCrStoreCreateInMem and future constructors...
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster *
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @returns IPRT status code.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster * @param ppStore Where to return the store instance.
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Fosterstatic int rtCrStoreInMemCreateInternal(PRTCRSTOREINMEM *ppStore)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster PRTCRSTOREINMEM pStore = (PRTCRSTOREINMEM)RTMemAlloc(sizeof(*pStore));
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (pStore)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pStore->cCerts = 0;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pStore->cCertsAlloc = 0;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster pStore->papCerts = NULL;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster *ppStore = pStore;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return VINF_SUCCESS;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster }
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster *ppStore = NULL; /* shut up gcc-maybe-pita warning. */
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return VERR_NO_MEMORY;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster}
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan FosterRTDECL(int) RTCrStoreCreateInMem(PRTCRSTORE phStore, uint32_t cSizeHint)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster{
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster PRTCRSTOREINMEM pStore;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster int rc = rtCrStoreInMemCreateInternal(&pStore);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (RT_SUCCESS(rc))
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (cSizeHint)
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rc = rtCrStoreInMemGrow(pStore, RT_MIN(cSizeHint, 512));
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (RT_SUCCESS(rc))
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster {
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster rc = rtCrStoreCreate(&g_rtCrStoreInMemProvider, pStore, phStore);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster if (RT_SUCCESS(rc))
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return VINF_SUCCESS;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster }
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster RTMemFree(pStore);
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster }
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster return rc;
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster}
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster
2d0a88b18a041738cfe635b45bd1db56af469c91Allan Foster