If user requests their virSecret value to be encrypted using
hosts' TPM we can now honour such request as we have all the APIs
ready. The value is still stored in a file (obj->base64File) but
because it was encrypted by TPM it's not readable (even though
it's still base64 encoded).
And since we can detect usability of host's TPM, let's do that
when a virSecret is defined and TPM is requested. This avoids
unpleasant surprises later on.
Resolves:
https://issues.redhat.com/browse/RHEL-7125
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/conf/virsecretobj.c | 32 +++++++++++++++++++++++++++++---
src/secret/secret_driver.c | 7 +++++++
2 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/src/conf/virsecretobj.c b/src/conf/virsecretobj.c
index 455798d414..b77d69649c 100644
--- a/src/conf/virsecretobj.c
+++ b/src/conf/virsecretobj.c
@@ -24,12 +24,13 @@
#include <sys/stat.h>
#include "datatypes.h"
-#include "virsecretobj.h"
#include "viralloc.h"
#include "virerror.h"
#include "virfile.h"
#include "virhash.h"
#include "virlog.h"
+#include "virsecret.h"
+#include "virsecretobj.h"
#include "virstring.h"
#define VIR_FROM_THIS VIR_FROM_SECRET
@@ -689,7 +690,19 @@ virSecretObjSaveData(virSecretObj *obj)
if (!obj->value)
return 0;
- base64 = g_base64_encode(obj->value, obj->value_size);
+ if (obj->def->tpm == VIR_TRISTATE_BOOL_YES) {
+ char uuidStr[VIR_UUID_STRING_BUFLEN] = { 0 };
+
+ virUUIDFormat(obj->def->uuid, uuidStr);
+
+ if (virSecretTPMEncrypt(uuidStr,
+ obj->value, obj->value_size,
+ &base64) < 0) {
+ return -1;
+ }
+ } else {
+ base64 = g_base64_encode(obj->value, obj->value_size);
+ }
if (virFileRewriteStr(obj->base64File, S_IRUSR | S_IWUSR, base64) < 0)
return -1;
@@ -847,7 +860,20 @@ virSecretLoadValue(virSecretObj *obj)
VIR_FORCE_CLOSE(fd);
- obj->value = g_base64_decode(contents, &obj->value_size);
+ if (obj->def->tpm == VIR_TRISTATE_BOOL_YES) {
+ char uuidStr[VIR_UUID_STRING_BUFLEN] = { 0 };
+
+ virUUIDFormat(obj->def->uuid, uuidStr);
+
+ if (virSecretTPMDecrypt(uuidStr,
+ contents,
+ &obj->value,
+ &obj->value_size) < 0) {
+ goto cleanup;
+ }
+ } else {
+ obj->value = g_base64_decode(contents, &obj->value_size);
+ }
ret = 0;
diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
index c7bd65b4e9..116d645243 100644
--- a/src/secret/secret_driver.c
+++ b/src/secret/secret_driver.c
@@ -234,6 +234,13 @@ secretDefineXML(virConnectPtr conn,
if (virSecretDefineXMLEnsureACL(conn, def) < 0)
goto cleanup;
+ if (def->tpm == VIR_TRISTATE_BOOL_YES &&
+ virSecretTPMAvailable() != 1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("TPM is unavailable or unusable on this host"));
+ goto cleanup;
+ }
+
if (!(obj = virSecretObjListAdd(driver->secrets, &def,
driver->configDir, &backup)))
goto cleanup;
--
2.43.0