Index: trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- trunk/src/VBox/Main/Makefile.kmk	(revision 91395)
+++ trunk/src/VBox/Main/Makefile.kmk	(revision 91396)
@@ -401,4 +401,35 @@
 
 testschemadefs: $(VBOX_XML_SCHEMADEFS_H) $(VBOX_XML_SCHEMADEFS_CPP)
+
+
+#
+# Trust anchors and certificates -> .cpp
+#
+VBOX_SVC_CERTS_FILE = $(VBoxSVC_0_OUTDIR)/TrustAnchorsAndCerts.cpp
+VBOX_SVC_CERTS := \
+       UefiMicrosoftKek=MicCorKEKCA2011_2011-06-24.crt \
+       UefiMicrosoftCa=MicCorUEFCA2011_2011-06-27.crt \
+       UefiMicrosoftProPca=MicWinProPCA2011_2011-10-19.crt
+
+VBOX_SVC_CERT_NAMES := $(foreach cert,$(VBOX_SVC_CERTS),$(firstword $(subst =,$(SPACE) ,$(cert))))
+VBOX_SVC_PATH_CERTIFICATES := $(PATH_SUB_CURRENT)/Certificates
+
+$$(VBOX_SVC_CERTS_FILE): $(MAKEFILE_CURRENT) \
+		$(foreach cert,$(VBOX_SVC_CERTS),$(VBOX_SVC_PATH_CERTIFICATES)/$(lastword $(subst =,$(SPACE) ,$(cert)))) \
+		$(VBOX_BIN2C) \
+		| $$(dir $$@)
+	$(QUIET)$(RM) -f -- $@
+	$(QUIET)$(APPEND) -n "$@" \
+       	'' \
+       	'#include "TrustAnchorsAndCerts.h"' \
+               ''
+	$(foreach cert,$(VBOX_SVC_CERTS), $(NLTAB)$(VBOX_BIN2C) -ascii --append \
+		"$(firstword $(subst =,$(SP) ,$(cert)))" \
+		"$(VBOX_SVC_PATH_CERTIFICATES)/$(lastword $(subst =,$(SP) ,$(cert)))" \
+		"$@")
+
+OTHER_CLEAN += $(VBOX_SVC_CERTS_FILE)
+
+tst-main-certificates: $(VBOX_SVC_CERTS_FILE)
 
 
@@ -542,4 +573,5 @@
 
 VBoxSVC_SOURCES = \
+	$(VBOX_SVC_CERTS_FILE) \
 	$(VBoxAPIWrap_0_OUTDIR)/VBoxAPI.d \
 	src-all/AuthLibrary.cpp \
@@ -615,4 +647,5 @@
 	src-server/TokenImpl.cpp \
 	src-server/TrustedPlatformModuleImpl.cpp \
+	src-server/UefiVariableStoreImpl.cpp \
 	$(if $(VBOX_WITH_UNATTENDED), \
 	src-server/UnattendedImpl.cpp \
Index: trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 91395)
+++ trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 91396)
@@ -5897,4 +5897,159 @@
   </interface>
 
+   <enum
+    name="SignatureType"
+    uuid="6f6e67ef-9a32-4084-af84-5702679f882a"
+    >
+    <desc>
+      UEFI signature type enumeration.
+    </desc>
+
+    <const name="X509"                  value="0">
+      <desc>X.509 certificate.</desc>
+    </const>
+    <const name="Sha256"                value="1">
+      <desc>SHA256 hash.</desc>
+    </const>
+  </enum>
+
+  <interface
+    name="IUefiVariableStore" extends="$unknown"
+    uuid="f39d5888-9009-4e77-94b5-9cdcfc1859c3"
+    wsmap="managed"
+    reservedMethods="10" reservedAttributes="5"
+    >
+    <desc>
+        The IUefiVariableStore interface allows inspecting and manipulating the content
+        of an existing UEFI variable store in a NVRAM file. This is used only in the
+        <link to="INvramStore::uefiVariableStore" /> attribute.
+    </desc>
+
+    <method name="addVariable">
+      <desc>Adds a new variable to the non volatile storage area.</desc>
+      <param name="name" type="wstring" dir="in">
+        <desc>Name of the variable.</desc>
+      </param>
+      <param name="owner" type="uuid" mod="string" dir="in">
+        <desc>UUID of the variable owner.</desc>
+      </param>
+      <param name="data" type="octet" dir="in" safearray="yes">
+        <desc>The variable data.</desc>
+      </param>
+    </method>
+
+    <method name="deleteVariable">
+      <desc>Deletes the given variable from the non volatile storage area.</desc>
+      <param name="name" type="wstring" dir="in">
+        <desc>Name of the variable.</desc>
+      </param>
+      <param name="owner" type="uuid" mod="string" dir="in">
+        <desc>UUID of the variable owner.</desc>
+      </param>
+    </method>
+
+    <method name="changeVariable">
+      <desc>Changes the data of the given variable.</desc>
+      <param name="name" type="wstring" dir="in">
+        <desc>Name of the variable.</desc>
+      </param>
+      <param name="owner" type="uuid" mod="string" dir="in">
+        <desc>UUID of the variable owner.</desc>
+      </param>
+      <param name="data" type="octet" dir="in" safearray="yes">
+        <desc>The new variable data.</desc>
+      </param>
+    </method>
+
+    <method name="queryVariableByName">
+      <desc>Queries the variable content variable by the given name.</desc>
+      <param name="name" type="wstring" dir="in">
+        <desc>Name of the variable to look for.</desc>
+      </param>
+      <param name="owner" type="uuid" mod="string" dir="out">
+        <desc>UUID of the variable owner returned on success.</desc>
+      </param>
+      <param name="data" type="octet" dir="out" safearray="yes">
+        <desc>The variable data returned on success.</desc>
+      </param>
+    </method>
+
+    <method name="queryVariables">
+      <desc>
+        Queries all variables in the non volatile storage and returns their names.
+      </desc>
+      <param name="names" type="wstring" dir="out" safearray="yes">
+        <desc>The variable names returned on success.</desc>
+      </param>
+      <param name="owners" type="uuid" mod="string" dir="out" safearray="yes">
+        <desc>UUID of the variable owners returned on success.</desc>
+      </param>
+    </method>
+
+    <method name="enrollPlatformKey">
+      <desc>
+        Convenience method to enroll a new platform key (PK) for enabling Secure Boot.
+      </desc>
+      <param name="platformKey" type="octet" safearray="yes" dir="in">
+        <desc>The platform key (PK) to enroll.</desc>
+      </param>
+      <param name="owner" type="uuid" mod="string" dir="in">
+        <desc>UUID of the PK owner.</desc>
+      </param>
+    </method>
+
+    <method name="addKek">
+      <desc>
+        Convenience method to add a new Key Encryption Key (KEK) for Secure Boot.
+      </desc>
+      <param name="keyEncryptionKey" type="octet" safearray="yes" dir="in">
+        <desc>The Key Encryption Key (KEK) to add.</desc>
+      </param>
+      <param name="owner" type="uuid" mod="string" dir="in">
+        <desc>UUID of the KEK owner.</desc>
+      </param>
+      <param name="signatureType" type="SignatureType" dir="in">
+        <desc>Type of the signature.</desc>
+      </param>
+    </method>
+
+    <method name="addSignatureToDb">
+      <desc>
+        Convenience method to add a new entry to the signature database.
+      </desc>
+      <param name="signature" type="octet" safearray="yes" dir="in">
+        <desc>The signature to add.</desc>
+      </param>
+      <param name="owner" type="uuid" mod="string" dir="in">
+        <desc>UUID of the signature owner.</desc>
+      </param>
+      <param name="signatureType" type="SignatureType" dir="in">
+        <desc>Type of the signature.</desc>
+      </param>
+    </method>
+
+    <method name="addSignatureToDbx">
+      <desc>
+        Convenience method to add a new entry to the forbidden signature database.
+      </desc>
+      <param name="signature" type="octet" safearray="yes" dir="in">
+        <desc>The signature to add.</desc>
+      </param>
+      <param name="owner" type="uuid" mod="string" dir="in">
+        <desc>UUID of the signature owner.</desc>
+      </param>
+      <param name="signatureType" type="SignatureType" dir="in">
+        <desc>Type of the signature.</desc>
+      </param>
+    </method>
+
+    <method name="enrollDefaultMsSignatures">
+      <desc>
+        Convenience method to enroll the standard Microsoft KEK and signatures
+        in the signature databases.
+      </desc>
+    </method>
+
+  </interface>
+
   <interface
     name="INvramStore" extends="$unknown"
@@ -5914,4 +6069,18 @@
       </desc>
     </attribute>
+
+    <attribute name="uefiVariableStore" type="IUefiVariableStore" readonly="yes">
+      <desc>Object to manipulate the data in an existing UEFI variable store.</desc>
+    </attribute>
+
+    <method name="initUefiVariableStore">
+      <desc>Initializes the UEFI variable store.</desc>
+      <param name="size" type="unsigned long" dir="in">
+        <desc>
+          Size in bytes of the UEFI variable store. Must be 0 for now to initialize to the
+          default size.
+        </desc>
+      </param>
+    </method>
 
   </interface>
Index: trunk/src/VBox/Main/include/NvramStoreImpl.h
===================================================================
--- trunk/src/VBox/Main/include/NvramStoreImpl.h	(revision 91395)
+++ trunk/src/VBox/Main/include/NvramStoreImpl.h	(revision 91396)
@@ -80,7 +80,8 @@
     // Wrapped NVRAM store properties
     HRESULT getNonVolatileStorageFile(com::Utf8Str &aNonVolatileStorageFile);
+    HRESULT getUefiVariableStore(ComPtr<IUefiVariableStore> &aUefiVarStore);
 
     // Wrapped NVRAM store members
-    /** @todo */
+    HRESULT initUefiVariableStore(ULONG aSize);
 
 #ifdef VBOX_COM_INPROC
Index: trunk/src/VBox/Main/include/TrustAnchorsAndCerts.h
===================================================================
--- trunk/src/VBox/Main/include/TrustAnchorsAndCerts.h	(revision 91396)
+++ trunk/src/VBox/Main/include/TrustAnchorsAndCerts.h	(revision 91396)
@@ -0,0 +1,38 @@
+/* $Id$ */
+/** @file
+ * Main - Collection of trust anchors and certificates included in VBoxSVC.
+ */
+
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#ifndef MAIN_INCLUDED_TrustAnchorsAndCerts_h
+#define MAIN_INCLUDED_TrustAnchorsAndCerts_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+RT_C_DECLS_BEGIN
+
+extern const unsigned char g_abUefiMicrosoftKek[];
+extern const unsigned g_cbUefiMicrosoftKek;
+
+extern const unsigned char g_abUefiMicrosoftCa[];
+extern const unsigned g_cbUefiMicrosoftCa;
+
+extern const unsigned char g_abUefiMicrosoftProPca[];
+extern const unsigned g_cbUefiMicrosoftProPca;
+
+RT_C_DECLS_END
+
+#endif /* !MAIN_INCLUDED_TrustAnchorsAndCerts_h */
+
Index: trunk/src/VBox/Main/include/UefiVariableStoreImpl.h
===================================================================
--- trunk/src/VBox/Main/include/UefiVariableStoreImpl.h	(revision 91396)
+++ trunk/src/VBox/Main/include/UefiVariableStoreImpl.h	(revision 91396)
@@ -0,0 +1,78 @@
+/* $Id$ */
+/** @file
+ * VirtualBox COM UEFI variable store class implementation
+ */
+
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#ifndef MAIN_INCLUDED_UefiVariableStoreImpl_h
+#define MAIN_INCLUDED_UefiVariableStoreImpl_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "UefiVariableStoreWrap.h"
+#include <iprt/types.h>
+
+#include <iprt/formats/efi-common.h>
+
+class NvramStore;
+class Machine;
+
+class ATL_NO_VTABLE UefiVariableStore :
+    public UefiVariableStoreWrap
+{
+public:
+
+    DECLARE_COMMON_CLASS_METHODS(UefiVariableStore)
+
+    HRESULT FinalConstruct();
+    void FinalRelease();
+
+    // public initializer/uninitializer for internal purposes only
+    HRESULT init(NvramStore *aParent, Machine *pMachine, RTVFS hVfsUefiVarStore);
+    void uninit();
+
+    // public methods for internal purposes only
+
+private:
+
+    // Wrapped NVRAM store properties
+
+    // Wrapped NVRAM store members
+    HRESULT addVariable(const com::Utf8Str &aName, const com::Guid &aOwnerUuid, const std::vector<BYTE> &aData);
+    HRESULT deleteVariable(const com::Utf8Str &aName, const com::Guid &aOwnerUuid);
+    HRESULT changeVariable(const com::Utf8Str &aName, const com::Guid &aOwnerUuid, const std::vector<BYTE> &aData);
+    HRESULT queryVariableByName(const com::Utf8Str &aName, com::Guid &aOwnerUuid, std::vector<BYTE> &aData);
+    HRESULT queryVariables(std::vector<com::Utf8Str> &aNames, std::vector<com::Guid> &aOwnerUuids);
+    HRESULT enrollPlatformKey(const std::vector<BYTE> &aData, const com::Guid &aOwnerUuid);
+    HRESULT addKek(const std::vector<BYTE> &aData, const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType);
+    HRESULT addSignatureToDb(const std::vector<BYTE> &aData, const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType);
+    HRESULT addSignatureToDbx(const std::vector<BYTE> &aData, const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType);
+    HRESULT enrollDefaultMsSignatures(void);
+
+    int i_uefiVarStoreSetVarAttr(const char *pszVar, uint32_t fAttr);
+
+    HRESULT i_uefiVarStoreAddVar(PCEFI_GUID pGuid, const char *pszVar, uint32_t fAttr, PRTVFSFILE phVfsFile);
+    HRESULT i_uefiSigDbAddSig(RTEFISIGDB hEfiSigDb, const void *pvData, size_t cbData, const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType);
+    HRESULT i_uefiVarStoreAddSignatureToDbVec(PCEFI_GUID pGuid, const char *pszDb, const std::vector<BYTE> &aData,
+                                              const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType);
+    HRESULT i_uefiVarStoreAddSignatureToDb(PCEFI_GUID pGuid, const char *pszDb, const void *pvData, size_t cbData,
+                                           const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType);
+
+    struct Data;            // opaque data struct, defined in UefiVariableStoreImpl.cpp
+    Data *m;
+};
+
+#endif /* !MAIN_INCLUDED_UefiVariableStoreImpl_h */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Index: trunk/src/VBox/Main/src-all/NvramStoreImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-all/NvramStoreImpl.cpp	(revision 91395)
+++ trunk/src/VBox/Main/src-all/NvramStoreImpl.cpp	(revision 91396)
@@ -24,5 +24,7 @@
 #else
 # include "MachineImpl.h"
+# include "AutoStateDep.h"
 #endif
+#include "UefiVariableStoreImpl.h"
 
 #include "AutoCaller.h"
@@ -94,7 +96,9 @@
 #else
     /** The Machine object owning this NVRAM store. */
-    Machine * const         pParent;
+    Machine * const                    pParent;
     /** The peer NVRAM store object. */
-    ComObjPtr<NvramStore>   pPeer;
+    ComObjPtr<NvramStore>              pPeer;
+    /** The UEFI variable store. */
+    const ComObjPtr<UefiVariableStore> pUefiVarStore;
 #endif
 
@@ -299,4 +303,66 @@
 
     return S_OK;
+}
+
+
+HRESULT NvramStore::getUefiVariableStore(ComPtr<IUefiVariableStore> &aUefiVarStore)
+{
+#ifndef VBOX_COM_INPROC
+    /* the machine needs to be mutable */
+    AutoMutableStateDependency adep(m->pParent);
+    if (FAILED(adep.rc())) return adep.rc();
+
+    /* We need a write lock because of the lazy initialization. */
+    AutoWriteLock wlock(this COMMA_LOCKVAL_SRC_POS);
+
+    /* Check if we have to create the UEFI variabel store object */
+    HRESULT hrc = S_OK;
+    if (!m->pUefiVarStore)
+    {
+        /* Load the NVRAM file first if it isn't already. */
+        if (!m->bd->mapNvram.size())
+        {
+            int vrc = i_loadStore();
+            if (RT_FAILURE(vrc))
+                hrc = setError(E_FAIL, tr("Loading the NVRAM store failed (%Rrc)\n"), vrc);
+        }
+
+        if (SUCCEEDED(hrc))
+        {
+            NvramStoreIter it = m->bd->mapNvram.find("efi/nvram");
+            if (it != m->bd->mapNvram.end())
+            {
+                RTVFSFILE hVfsFileNvram = it->second;
+                RTVFS hVfsEfiVarStore;
+                int vrc = RTEfiVarStoreOpenAsVfs(hVfsFileNvram, 0 /*fMntFlags*/, 0 /*fVarStoreFlags*/, &hVfsEfiVarStore,
+                                                 NULL /*pErrInfo*/);
+                if (RT_SUCCESS(vrc))
+                {
+                    unconst(m->pUefiVarStore).createObject();
+                    m->pUefiVarStore->init(this, m->pParent, hVfsEfiVarStore);
+                }
+                else
+                    hrc = setError(E_FAIL, tr("Opening the UEFI variable store failed (%Rrc)."), vrc);
+            }
+            else
+                hrc = setError(VBOX_E_OBJECT_NOT_FOUND, tr("The UEFI NVRAM file is not existing for this machine."));
+        }
+    }
+
+    if (SUCCEEDED(hrc))
+        m->pUefiVarStore.queryInterfaceTo(aUefiVarStore.asOutParam());
+
+    return hrc;
+#else
+    NOREF(aUefiVarStore);
+    return E_NOTIMPL;
+#endif
+}
+
+
+HRESULT NvramStore::initUefiVariableStore(ULONG aSize)
+{
+    NOREF(aSize);
+    return E_NOTIMPL;
 }
 
Index: trunk/src/VBox/Main/src-server/UefiVariableStoreImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/UefiVariableStoreImpl.cpp	(revision 91396)
+++ trunk/src/VBox/Main/src-server/UefiVariableStoreImpl.cpp	(revision 91396)
@@ -0,0 +1,437 @@
+/* $Id$ */
+/** @file
+ * VirtualBox COM NVRAM store class implementation
+ */
+
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#define LOG_GROUP LOG_GROUP_MAIN_UEFIVARIABLESTORE
+#include "LoggingNew.h"
+
+#include "UefiVariableStoreImpl.h"
+#include "NvramStoreImpl.h"
+#include "MachineImpl.h"
+
+#include "AutoStateDep.h"
+#include "AutoCaller.h"
+
+#include "TrustAnchorsAndCerts.h"
+
+#include <VBox/com/array.h>
+
+#include <iprt/cpp/utils.h>
+#include <iprt/efi.h>
+#include <iprt/file.h>
+#include <iprt/vfs.h>
+
+#include <iprt/formats/efi-varstore.h>
+#include <iprt/formats/efi-signature.h>
+
+// defines
+////////////////////////////////////////////////////////////////////////////////
+
+// globals
+////////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// UefiVariableStore::Data structure
+/////////////////////////////////////////////////////////////////////////////
+
+struct UefiVariableStore::Data
+{
+    Data()
+        : pParent(NULL),
+          pMachine(NULL),
+          hVfsUefiVarStore(NIL_RTVFS)
+    { }
+
+    /** The NVRAM store owning this UEFI variable store intstance. */
+    NvramStore * const      pParent;
+    /** The machine this UEFI variable store belongs to. */
+    Machine    * const      pMachine;
+    /** VFS handle to the UEFI variable store. */
+    RTVFS                   hVfsUefiVarStore;
+};
+
+// constructor / destructor
+////////////////////////////////////////////////////////////////////////////////
+
+DEFINE_EMPTY_CTOR_DTOR(UefiVariableStore)
+
+HRESULT UefiVariableStore::FinalConstruct()
+{
+    return BaseFinalConstruct();
+}
+
+void UefiVariableStore::FinalRelease()
+{
+    uninit();
+    BaseFinalRelease();
+}
+
+// public initializer/uninitializer for internal purposes only
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Initializes the UEFI variable store object.
+ *
+ * @returns COM result indicator.
+ * @param   aParent                     The NVRAM store owning the UEFI NVRAM content.
+ * @param   hVfsUefiVarStore            The UEFI variable store VFS handle.
+ */
+HRESULT UefiVariableStore::init(NvramStore *aParent, Machine *pMachine, RTVFS hVfsUefiVarStore)
+{
+    LogFlowThisFuncEnter();
+    LogFlowThisFunc(("aParent: %p\n", aParent));
+
+    ComAssertRet(aParent, E_INVALIDARG);
+
+    /* Enclose the state transition NotReady->InInit->Ready */
+    AutoInitSpan autoInitSpan(this);
+    AssertReturn(autoInitSpan.isOk(), E_FAIL);
+
+    m = new Data();
+
+    /* share the parent weakly */
+    unconst(m->pParent) = aParent;
+    unconst(m->pMachine) = pMachine;
+    m->hVfsUefiVarStore = hVfsUefiVarStore;
+
+    autoInitSpan.setSucceeded();
+
+    LogFlowThisFuncLeave();
+    return S_OK;
+}
+
+
+/**
+ *  Uninitializes the instance and sets the ready flag to FALSE.
+ *  Called either from FinalRelease() or by the parent when it gets destroyed.
+ */
+void UefiVariableStore::uninit()
+{
+    LogFlowThisFuncEnter();
+
+    /* Enclose the state transition Ready->InUninit->NotReady */
+    AutoUninitSpan autoUninitSpan(this);
+    if (autoUninitSpan.uninitDone())
+        return;
+
+    RTVfsRelease(m->hVfsUefiVarStore);
+
+    unconst(m->pParent) = NULL;
+    unconst(m->pMachine) = NULL;
+
+    delete m;
+    m = NULL;
+
+    LogFlowThisFuncLeave();
+}
+
+
+HRESULT UefiVariableStore::addVariable(const com::Utf8Str &aName, const com::Guid &aOwnerUuid, const std::vector<BYTE> &aData)
+{
+    RT_NOREF(aName, aOwnerUuid, aData);
+    return E_NOTIMPL;
+}
+
+
+HRESULT UefiVariableStore::deleteVariable(const com::Utf8Str &aName, const com::Guid &aOwnerUuid)
+{
+    RT_NOREF(aName, aOwnerUuid);
+    return E_NOTIMPL;
+}
+
+
+HRESULT UefiVariableStore::changeVariable(const com::Utf8Str &aName, const com::Guid &aOwnerUuid, const std::vector<BYTE> &aData)
+{
+    RT_NOREF(aName, aOwnerUuid, aData);
+    return E_NOTIMPL;
+}
+
+
+HRESULT UefiVariableStore::queryVariableByName(const com::Utf8Str &aName, com::Guid &aOwnerUuid, std::vector<BYTE> &aData)
+{
+    RT_NOREF(aName, aOwnerUuid, aData);
+    return E_NOTIMPL;
+}
+
+
+HRESULT UefiVariableStore::queryVariables(std::vector<com::Utf8Str> &aNames, std::vector<com::Guid> &aOwnerUuids)
+{
+    RT_NOREF(aNames, aOwnerUuids);
+    return E_NOTIMPL;
+}
+
+
+HRESULT UefiVariableStore::enrollPlatformKey(const std::vector<BYTE> &aData, const com::Guid &aOwnerUuid)
+{
+    /* the machine needs to be mutable */
+    AutoMutableStateDependency adep(m->pMachine);
+    if (FAILED(adep.rc())) return adep.rc();
+
+    AutoWriteLock wlock(this COMMA_LOCKVAL_SRC_POS);
+
+    EFI_GUID GuidGlobalVar = EFI_GLOBAL_VARIABLE_GUID;
+    return i_uefiVarStoreAddSignatureToDbVec(&GuidGlobalVar, "PK", aData, aOwnerUuid, SignatureType_X509);
+}
+
+
+HRESULT UefiVariableStore::addKek(const std::vector<BYTE> &aData, const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType)
+{
+    /* the machine needs to be mutable */
+    AutoMutableStateDependency adep(m->pMachine);
+    if (FAILED(adep.rc())) return adep.rc();
+
+    AutoWriteLock wlock(this COMMA_LOCKVAL_SRC_POS);
+
+    EFI_GUID GuidGlobalVar = EFI_GLOBAL_VARIABLE_GUID;
+    return i_uefiVarStoreAddSignatureToDbVec(&GuidGlobalVar, "KEK", aData, aOwnerUuid, enmSignatureType);
+}
+
+
+HRESULT UefiVariableStore::addSignatureToDb(const std::vector<BYTE> &aData, const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType)
+{
+    /* the machine needs to be mutable */
+    AutoMutableStateDependency adep(m->pMachine);
+    if (FAILED(adep.rc())) return adep.rc();
+
+    AutoWriteLock wlock(this COMMA_LOCKVAL_SRC_POS);
+
+    EFI_GUID GuidSecurityDb = EFI_GLOBAL_VARIABLE_GUID;
+    return i_uefiVarStoreAddSignatureToDbVec(&GuidSecurityDb, "db", aData, aOwnerUuid, enmSignatureType);
+}
+
+
+HRESULT UefiVariableStore::addSignatureToDbx(const std::vector<BYTE> &aData, const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType)
+{
+    /* the machine needs to be mutable */
+    AutoMutableStateDependency adep(m->pMachine);
+    if (FAILED(adep.rc())) return adep.rc();
+
+    AutoWriteLock wlock(this COMMA_LOCKVAL_SRC_POS);
+
+    EFI_GUID GuidSecurityDb = EFI_IMAGE_SECURITY_DATABASE_GUID;
+    return i_uefiVarStoreAddSignatureToDbVec(&GuidSecurityDb, "dbx", aData, aOwnerUuid, enmSignatureType);
+}
+
+
+HRESULT UefiVariableStore::enrollDefaultMsSignatures(void)
+{
+    AutoMutableStateDependency adep(m->pMachine);
+    if (FAILED(adep.rc())) return adep.rc();
+
+    AutoWriteLock wlock(this COMMA_LOCKVAL_SRC_POS);
+
+    EFI_GUID EfiGuidSecurityDb = EFI_IMAGE_SECURITY_DATABASE_GUID;
+    EFI_GUID EfiGuidGlobalVar  = EFI_GLOBAL_VARIABLE_GUID;
+
+    /** @todo This conversion from EFI GUID -> IPRT UUID -> Com GUID is nuts... */
+    EFI_GUID EfiGuidMs      = EFI_SIGNATURE_OWNER_GUID_MICROSOFT;
+    RTUUID   UuidMs;
+    RTEfiGuidToUuid(&UuidMs, &EfiGuidMs);
+
+    const com::Guid GuidMs(UuidMs);
+
+    HRESULT hrc = i_uefiVarStoreAddSignatureToDb(&EfiGuidGlobalVar, "KEK", g_abUefiMicrosoftKek, g_cbUefiMicrosoftKek,
+                                                 GuidMs, SignatureType_X509);
+    if (SUCCEEDED(hrc))
+    {
+        hrc = i_uefiVarStoreAddSignatureToDb(&EfiGuidSecurityDb, "db", g_abUefiMicrosoftCa, g_cbUefiMicrosoftCa,
+                                             GuidMs, SignatureType_X509);
+        if (SUCCEEDED(hrc))
+            hrc = i_uefiVarStoreAddSignatureToDb(&EfiGuidSecurityDb, "db", g_abUefiMicrosoftProPca, g_cbUefiMicrosoftProPca,
+                                                 GuidMs, SignatureType_X509);
+    }
+
+    return hrc;
+}
+
+
+/**
+ * Sets the given attributes for the given EFI variable store variable.
+ *
+ * @returns IPRT status code.
+ * @param   hVfsVarStore        Handle of the EFI variable store VFS.
+ * @param   pszVar              The variable to set the attributes for.
+ * @param   fAttr               The attributes to set, see EFI_VAR_HEADER_ATTR_XXX.
+ */
+int UefiVariableStore::i_uefiVarStoreSetVarAttr(const char *pszVar, uint32_t fAttr)
+{
+    char szVarPath[_1K];
+    ssize_t cch = RTStrPrintf2(szVarPath, sizeof(szVarPath), "/raw/%s/attr", pszVar);
+    Assert(cch > 0); RT_NOREF(cch);
+
+    RTVFSFILE hVfsFileAttr = NIL_RTVFSFILE;
+    int vrc = RTVfsFileOpen(m->hVfsUefiVarStore, szVarPath,
+                           RTFILE_O_READWRITE | RTFILE_O_DENY_NONE | RTFILE_O_OPEN,
+                           &hVfsFileAttr);
+    if (RT_SUCCESS(vrc))
+    {
+        uint32_t fAttrLe = RT_H2LE_U32(fAttr);
+        vrc = RTVfsFileWrite(hVfsFileAttr, &fAttrLe, sizeof(fAttrLe), NULL /*pcbWritten*/);
+        RTVfsFileRelease(hVfsFileAttr);
+    }
+
+    return vrc;
+}
+
+
+/**
+ * Adds the given variable to the variable store.
+ *
+ * @returns IPRT status code.
+ * @param   hVfsVarStore        Handle of the EFI variable store VFS.
+ * @param   pGuid               The EFI GUID of the variable.
+ * @param   pszVar              The variable name.
+ * @param   fAttr               Attributes for the variable.
+ * @param   phVfsFile           Where to return the VFS file handle to the created variable on success.
+ */
+HRESULT UefiVariableStore::i_uefiVarStoreAddVar(PCEFI_GUID pGuid, const char *pszVar, uint32_t fAttr, PRTVFSFILE phVfsFile)
+{
+    RTUUID UuidVar;
+    RTEfiGuidToUuid(&UuidVar, pGuid);
+
+    char szVarPath[_1K];
+    ssize_t cch = RTStrPrintf2(szVarPath, sizeof(szVarPath), "/by-uuid/%RTuuid/%s", &UuidVar, pszVar);
+    Assert(cch > 0); RT_NOREF(cch);
+
+    HRESULT hrc = S_OK;
+    int vrc = RTVfsFileOpen(m->hVfsUefiVarStore, szVarPath,
+                            RTFILE_O_READWRITE | RTFILE_O_DENY_NONE | RTFILE_O_OPEN,
+                            phVfsFile);
+    if (   vrc == VERR_PATH_NOT_FOUND
+        || vrc == VERR_FILE_NOT_FOUND)
+    {
+        /*
+         * Try to create the owner GUID of the variable by creating the appropriate directory,
+         * ignore error if it exists already.
+         */
+        RTVFSDIR hVfsDirRoot = NIL_RTVFSDIR;
+        vrc = RTVfsOpenRoot(m->hVfsUefiVarStore, &hVfsDirRoot);
+        if (RT_SUCCESS(vrc))
+        {
+            char szGuidPath[_1K];
+            cch = RTStrPrintf2(szGuidPath, sizeof(szGuidPath), "by-uuid/%RTuuid", &UuidVar);
+            Assert(cch > 0);
+
+            RTVFSDIR hVfsDirGuid = NIL_RTVFSDIR;
+            vrc = RTVfsDirCreateDir(hVfsDirRoot, szGuidPath, 0755, 0 /*fFlags*/, &hVfsDirGuid);
+            if (RT_SUCCESS(vrc))
+                RTVfsDirRelease(hVfsDirGuid);
+            else if (vrc == VERR_ALREADY_EXISTS)
+                vrc = VINF_SUCCESS;
+
+            RTVfsDirRelease(hVfsDirRoot);
+        }
+        else
+            hrc = setError(E_FAIL, tr("Opening variable storage root directory failed: %Rrc"), vrc);
+
+        if (RT_SUCCESS(vrc))
+        {
+            vrc = RTVfsFileOpen(m->hVfsUefiVarStore, szVarPath,
+                               RTFILE_O_READWRITE | RTFILE_O_DENY_NONE | RTFILE_O_CREATE,
+                               phVfsFile);
+            if (RT_SUCCESS(vrc))
+                vrc = i_uefiVarStoreSetVarAttr(pszVar, fAttr);
+        }
+
+        if (RT_FAILURE(vrc))
+            hrc = setError(E_FAIL, tr("Creating the variable '%s' failed: %Rrc"), pszVar, vrc);
+    }
+
+    return hrc;
+}
+
+
+HRESULT UefiVariableStore::i_uefiSigDbAddSig(RTEFISIGDB hEfiSigDb, const void *pvData, size_t cbData,
+                                             const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType)
+{
+    RTEFISIGTYPE enmSigType = RTEFISIGTYPE_INVALID;
+
+    switch (enmSignatureType)
+    {
+        case SignatureType_X509:
+            enmSigType = RTEFISIGTYPE_X509;
+            break;
+        case SignatureType_Sha256:
+            enmSigType = RTEFISIGTYPE_SHA256;
+            break;
+        default:
+            return setError(E_FAIL, tr("The given signature type is not supported"));
+    }
+
+    int vrc = RTEfiSigDbAddSignatureFromBuf(hEfiSigDb, enmSigType, aOwnerUuid.raw(), pvData, cbData);
+    if (RT_SUCCESS(vrc))
+        return S_OK;
+
+    return setError(E_FAIL, tr("Failed to add signature to the database (%Rrc)"), vrc);
+}
+
+
+HRESULT UefiVariableStore::i_uefiVarStoreAddSignatureToDb(PCEFI_GUID pGuid, const char *pszDb, const void *pvData, size_t cbData,
+                                                          const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType)
+{
+    HRESULT hrc = S_OK;
+    RTVFSFILE hVfsFileSigDb = NIL_RTVFSFILE;
+
+    int vrc = i_uefiVarStoreAddVar(pGuid, pszDb,
+                                     EFI_VAR_HEADER_ATTR_NON_VOLATILE
+                                   | EFI_VAR_HEADER_ATTR_BOOTSERVICE_ACCESS
+                                   | EFI_VAR_HEADER_ATTR_RUNTIME_ACCESS
+                                   | EFI_AUTH_VAR_HEADER_ATTR_TIME_BASED_AUTH_WRITE_ACCESS,
+                                   &hVfsFileSigDb);
+    if (RT_SUCCESS(vrc))
+    {
+        RTEFISIGDB hEfiSigDb;
+        vrc = RTEfiSigDbCreate(&hEfiSigDb);
+        if (RT_SUCCESS(vrc))
+        {
+            vrc = RTEfiSigDbAddFromExistingDb(hEfiSigDb, hVfsFileSigDb);
+            if (RT_SUCCESS(vrc))
+            {
+                hrc = i_uefiSigDbAddSig(hEfiSigDb, pvData, cbData, aOwnerUuid, enmSignatureType);
+                if (SUCCEEDED(hrc))
+                {
+                    vrc = RTVfsFileSeek(hVfsFileSigDb, 0 /*offSeek*/, RTFILE_SEEK_BEGIN, NULL /*poffActual*/);
+                    AssertRC(vrc);
+
+                    vrc = RTEfiSigDbWriteToFile(hEfiSigDb, hVfsFileSigDb);
+                    if (RT_FAILURE(vrc))
+                        hrc = setError(E_FAIL, tr("Writing updated signature database failed: %Rrc"), vrc);
+                }
+            }
+            else
+                hrc = setError(E_FAIL, tr("Loading signature database failed: %Rrc"), vrc);
+
+            RTEfiSigDbDestroy(hEfiSigDb);
+        }
+        else
+            hrc = setError(E_FAIL, tr("Creating signature database failed: %Rrc"), vrc);
+
+        RTVfsFileRelease(hVfsFileSigDb);
+    }
+    else
+        hrc = setError(E_FAIL, tr("Opening signature database '%s' failed: %Rrc"), pszDb, vrc);
+
+    return hrc;
+}
+
+
+HRESULT UefiVariableStore::i_uefiVarStoreAddSignatureToDbVec(PCEFI_GUID pGuid, const char *pszDb, const std::vector<BYTE> &aData,
+                                                             const com::Guid &aOwnerUuid, SignatureType_T enmSignatureType)
+{
+    return i_uefiVarStoreAddSignatureToDb(pGuid, pszDb, &aData.front(), aData.size(), aOwnerUuid, enmSignatureType);
+}
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
