mirror of
https://gitlab.gnome.org/GNOME/libsecret.git
synced 2024-12-21 20:28:52 +00:00
Add TPM2 API and its implementations to egg
These changes define the TPM2 API and add its implementations to the incubation area (egg/). Summary of the public API: `egg_tpm2_initialize`: Start a TPM context. `egg_tpm2_finalize`: End a TPM context. `egg_tpm2_generate_master_password`: Generate and returns an encrypted master password in `GBytes` format. TSS Marshaling, GVariant serialization is used. `egg_tpm2_decrypt_master_password`: Decrypts a master password generated from `egg_tpm2_generate_master_password`. TSS Unmarshaling, GVariant deserialization is used. TPM2 API: TSS Enhanced System API (ESAPI) Proposal: [extend file backend to use TPM2 derived encryption keys](https://gitlab.gnome.org/Teams/Engagement/gsoc-2021/-/issues/13) Related MRs: [#86](https://gitlab.gnome.org/GNOME/libsecret/-/merge_requests/86) Related Issues: [#63](https://gitlab.gnome.org/GNOME/libsecret/-/issues/63)
This commit is contained in:
parent
10e5e7abe3
commit
63907d907e
@ -3,7 +3,7 @@ stages:
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
DEPENDENCIES: dbus-x11 diffutils gcc gjs meson ninja-build python3-dbus python3-gobject redhat-rpm-config
|
||||
DEPENDENCIES: dbus-x11 diffutils gcc gjs meson ninja-build python3-dbus python3-gobject redhat-rpm-config tpm2-tss-devel
|
||||
CPPCHECK_OPTIONS: "--enable=warning --enable=style --enable=performance --enable=portability --std=c99 --template='{id}:{file}:{line},{severity},{message}'"
|
||||
|
||||
fedora:Werror:
|
||||
@ -24,7 +24,7 @@ fedora:Werror:
|
||||
- eval `dbus-launch --sh-syntax`
|
||||
- 'tpm2-abrmd --logger=stdout --tcti=swtpm: --session --allow-root --flush-all &'
|
||||
- 'export TCTI=tabrmd:bus_type=session'
|
||||
- meson _build -Dwerror=true -Dc_args=-Wno-error=deprecated-declarations
|
||||
- meson _build -Dwerror=true -Dc_args=-Wno-error=deprecated-declarations -Dtpm2=true
|
||||
- meson compile -C _build
|
||||
- meson test -C _build
|
||||
artifacts:
|
||||
|
484
egg/egg-tpm2.c
Normal file
484
egg/egg-tpm2.c
Normal file
@ -0,0 +1,484 @@
|
||||
/* libsecret - TSS interface implementations for libsecret
|
||||
*
|
||||
* Copyright (C) 2021 Dhanuka Warusadura
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*
|
||||
* Author: Dhanuka Warusadura
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "egg-tpm2.h"
|
||||
#include <tss2/tss2_esys.h>
|
||||
#include <tss2/tss2_mu.h>
|
||||
#include <tss2/tss2_rc.h>
|
||||
#include <tss2/tss2_tctildr.h>
|
||||
|
||||
#define MAX_BYTE_SIZE 64
|
||||
|
||||
struct EggTpm2Context {
|
||||
TSS2_TCTI_CONTEXT *tcti_context;
|
||||
ESYS_CONTEXT *esys_context;
|
||||
ESYS_TR primary_key;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
egg_tpm2_generate_primary_key(EggTpm2Context *context,
|
||||
GError **error)
|
||||
{
|
||||
TSS2_RC ret;
|
||||
|
||||
TPM2B_SENSITIVE_CREATE sensitive_params = {
|
||||
.size = 0,
|
||||
.sensitive = {
|
||||
.userAuth = {
|
||||
.size = 0,
|
||||
.buffer = {0},
|
||||
},
|
||||
.data = {
|
||||
.size = 0,
|
||||
.buffer = {0},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
TPM2B_PUBLIC public_key_param = {
|
||||
.size = 0,
|
||||
.publicArea = {
|
||||
.type = TPM2_ALG_RSA,
|
||||
.nameAlg = TPM2_ALG_SHA256,
|
||||
.objectAttributes = (
|
||||
TPMA_OBJECT_USERWITHAUTH |
|
||||
TPMA_OBJECT_RESTRICTED |
|
||||
TPMA_OBJECT_DECRYPT |
|
||||
TPMA_OBJECT_FIXEDTPM |
|
||||
TPMA_OBJECT_FIXEDPARENT |
|
||||
TPMA_OBJECT_SENSITIVEDATAORIGIN),
|
||||
.authPolicy = {
|
||||
.size = 0,
|
||||
},
|
||||
.parameters.rsaDetail = {
|
||||
.symmetric = {
|
||||
.algorithm = TPM2_ALG_AES,
|
||||
.keyBits.aes = 128,
|
||||
.mode.aes = TPM2_ALG_CFB
|
||||
},
|
||||
.scheme = {
|
||||
.scheme = TPM2_ALG_NULL
|
||||
},
|
||||
.keyBits = 2048,
|
||||
.exponent = 0,
|
||||
},
|
||||
.unique.rsa = {
|
||||
.size = 0,
|
||||
.buffer = {},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
TPM2B_DATA outside_info = {
|
||||
.size = 0,
|
||||
.buffer = {},
|
||||
};
|
||||
|
||||
TPML_PCR_SELECTION pcrs = {
|
||||
.count = 0,
|
||||
};
|
||||
|
||||
TPM2B_PUBLIC *public;
|
||||
TPM2B_CREATION_DATA *creation_data;
|
||||
TPM2B_DIGEST *hash;
|
||||
TPMT_TK_CREATION *ticket;
|
||||
|
||||
ret = Esys_CreatePrimary(context->esys_context, ESYS_TR_RH_OWNER,
|
||||
ESYS_TR_PASSWORD, ESYS_TR_NONE,
|
||||
ESYS_TR_NONE, &sensitive_params,
|
||||
&public_key_param, &outside_info,
|
||||
&pcrs, &context->primary_key, &public,
|
||||
&creation_data, &hash, &ticket);
|
||||
|
||||
if (ret != TSS2_RC_SUCCESS) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Esys_CreatePrimary: %s", Tss2_RC_Decode(ret));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Esys_Free(public);
|
||||
Esys_Free(creation_data);
|
||||
Esys_Free(hash);
|
||||
Esys_Free(ticket);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
egg_tpm2_generate_random_data(EggTpm2Context *context,
|
||||
GError **error)
|
||||
{
|
||||
gboolean status = FALSE;
|
||||
TSS2_RC ret;
|
||||
TPM2B_DIGEST *random_data;
|
||||
GBytes *bytes;
|
||||
|
||||
status = egg_tpm2_generate_primary_key(context, error);
|
||||
if (!status)
|
||||
return NULL;
|
||||
|
||||
ret = Esys_GetRandom(context->esys_context, ESYS_TR_NONE,
|
||||
ESYS_TR_NONE, ESYS_TR_NONE, MAX_BYTE_SIZE,
|
||||
&random_data);
|
||||
|
||||
if (ret != TSS2_RC_SUCCESS) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Esys_GetRandom: %s", Tss2_RC_Decode(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bytes = g_bytes_new(random_data->buffer, random_data->size);
|
||||
Esys_Free(random_data);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
EggTpm2Context *
|
||||
egg_tpm2_initialize(GError **error)
|
||||
{
|
||||
TSS2_RC ret;
|
||||
EggTpm2Context *context;
|
||||
gsize n_context;
|
||||
const gchar *tcti_conf;
|
||||
|
||||
n_context = 1;
|
||||
context = g_new(EggTpm2Context, n_context);
|
||||
tcti_conf = g_getenv("TCTI");
|
||||
ret = Tss2_TctiLdr_Initialize(tcti_conf, &context->tcti_context);
|
||||
|
||||
if (ret != TSS2_RC_SUCCESS) {
|
||||
egg_tpm2_finalize(context);
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Tss2_TctiLdr_Initialize: %s",
|
||||
Tss2_RC_Decode(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = Esys_Initialize(&context->esys_context,
|
||||
context->tcti_context, NULL);
|
||||
if (ret != TSS2_RC_SUCCESS) {
|
||||
egg_tpm2_finalize(context);
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Esys_Initialize: %s", Tss2_RC_Decode(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = Esys_Startup(context->esys_context, TPM2_SU_CLEAR);
|
||||
if (ret != TSS2_RC_SUCCESS) {
|
||||
egg_tpm2_finalize(context);
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Esys_Startup: %s", Tss2_RC_Decode(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void
|
||||
egg_tpm2_finalize(EggTpm2Context *context)
|
||||
{
|
||||
if (context->esys_context)
|
||||
Esys_Finalize(&context->esys_context);
|
||||
|
||||
if (context->tcti_context)
|
||||
Tss2_TctiLdr_Finalize(&context->tcti_context);
|
||||
|
||||
g_free(context);
|
||||
}
|
||||
|
||||
GBytes *
|
||||
egg_tpm2_generate_master_password(EggTpm2Context *context,
|
||||
GError **error)
|
||||
{
|
||||
TSS2_RC ret;
|
||||
TPM2B_PRIVATE *out_private;
|
||||
TPM2B_PUBLIC *out_public;
|
||||
TPM2B_CREATION_DATA *creation_data;
|
||||
TPM2B_DIGEST *hash;
|
||||
TPMT_TK_CREATION *ticket;
|
||||
gconstpointer data;
|
||||
gsize size;
|
||||
GBytes *input;
|
||||
GBytes *output;
|
||||
|
||||
TPM2B_SENSITIVE_CREATE in_sensitive = {
|
||||
.size = 0,
|
||||
.sensitive = {
|
||||
.data = {
|
||||
.size = MAX_BYTE_SIZE
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TPM2B_PUBLIC in_public = {
|
||||
.size = 0,
|
||||
.publicArea = {
|
||||
.type = TPM2_ALG_KEYEDHASH,
|
||||
.nameAlg = TPM2_ALG_SHA256,
|
||||
.objectAttributes = (
|
||||
TPMA_OBJECT_USERWITHAUTH |
|
||||
TPMA_OBJECT_FIXEDTPM |
|
||||
TPMA_OBJECT_FIXEDPARENT),
|
||||
.authPolicy = {
|
||||
.size = 0,
|
||||
},
|
||||
.parameters.keyedHashDetail = {
|
||||
.scheme = {
|
||||
.scheme = TPM2_ALG_NULL,
|
||||
.details = {
|
||||
.hmac = {
|
||||
.hashAlg =
|
||||
TPM2_ALG_SHA256
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
.unique.keyedHash = {
|
||||
.size = 0,
|
||||
.buffer = {},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
TPM2B_DATA outside_info = {
|
||||
.size = 0,
|
||||
.buffer = {}
|
||||
};
|
||||
|
||||
TPML_PCR_SELECTION pcrs = {
|
||||
.count = 0
|
||||
};
|
||||
|
||||
input = egg_tpm2_generate_random_data(context, error);
|
||||
if (!input) {
|
||||
g_bytes_unref(input);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = g_bytes_get_data(input, &size);
|
||||
g_bytes_unref(input);
|
||||
|
||||
if (size > sizeof(in_sensitive.sensitive.data.buffer)) {
|
||||
g_set_error_literal(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_ARGUMENT,
|
||||
"Input is too long");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(in_sensitive.sensitive.data.buffer, data, size);
|
||||
in_sensitive.sensitive.data.size = size;
|
||||
|
||||
ret = Esys_Create(context->esys_context, context->primary_key,
|
||||
ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
|
||||
&in_sensitive, &in_public, &outside_info,
|
||||
&pcrs, &out_private, &out_public, &creation_data,
|
||||
&hash, &ticket);
|
||||
if (ret != TSS2_RC_SUCCESS) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Esys_Create: %s", Tss2_RC_Decode(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gsize out_private_offset = 0;
|
||||
gsize out_public_offset = 0;
|
||||
GVariant *out_private_variant;
|
||||
GVariant *out_public_variant;
|
||||
GVariant *variant;
|
||||
|
||||
guint8 marshaled_out_private[sizeof(*out_private)];
|
||||
guint8 marshaled_out_public[sizeof(*out_public)];
|
||||
|
||||
ret = Tss2_MU_TPM2B_PRIVATE_Marshal(out_private,
|
||||
marshaled_out_private,
|
||||
sizeof(marshaled_out_private),
|
||||
&out_private_offset);
|
||||
if (ret != TSS2_RC_SUCCESS) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Tss2_MU_TPM2B_PRIVATE_Marshal: %s",
|
||||
Tss2_RC_Decode(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out_private_variant = g_variant_new_fixed_array(
|
||||
G_VARIANT_TYPE_BYTE,
|
||||
marshaled_out_private,
|
||||
out_private_offset,
|
||||
sizeof(guint8));
|
||||
|
||||
ret = Tss2_MU_TPM2B_PUBLIC_Marshal(out_public,
|
||||
marshaled_out_public,
|
||||
sizeof(marshaled_out_public),
|
||||
&out_public_offset);
|
||||
if (ret != TSS2_RC_SUCCESS) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Tss2_MU_TPM2B_PUBLIC_Marshal: %s",
|
||||
Tss2_RC_Decode(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out_public_variant = g_variant_new_fixed_array(
|
||||
G_VARIANT_TYPE_BYTE,
|
||||
marshaled_out_public,
|
||||
out_public_offset,
|
||||
sizeof(guint8));
|
||||
|
||||
variant = g_variant_new("(u@ayu@ay)",
|
||||
out_private_offset, out_private_variant,
|
||||
out_public_offset, out_public_variant);
|
||||
|
||||
output = g_variant_get_data_as_bytes(variant);
|
||||
|
||||
g_variant_unref(variant);
|
||||
Esys_Free(out_public);
|
||||
Esys_Free(out_private);
|
||||
Esys_Free(creation_data);
|
||||
Esys_Free(hash);
|
||||
Esys_Free(ticket);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
GBytes *
|
||||
egg_tpm2_decrypt_master_password(EggTpm2Context *context,
|
||||
GBytes *input,
|
||||
GError **error)
|
||||
{
|
||||
TSS2_RC ret;
|
||||
GBytes *output;
|
||||
TPM2B_SENSITIVE_DATA *out_data;
|
||||
GVariant *variant;
|
||||
gconstpointer data;
|
||||
gsize out_private_offset = 0;
|
||||
gsize out_public_offset = 0;
|
||||
gsize count = 0;
|
||||
gsize offset = 0;
|
||||
GVariant *out_private_variant;
|
||||
GVariant *out_public_variant;
|
||||
ESYS_TR out_key;
|
||||
|
||||
variant = g_variant_new_from_bytes(G_VARIANT_TYPE(
|
||||
"(uayuay)"),
|
||||
input,
|
||||
TRUE);
|
||||
|
||||
g_variant_get(variant, "(u@ayu@ay)",
|
||||
&out_private_offset, &out_private_variant,
|
||||
&out_public_offset, &out_public_variant);
|
||||
g_variant_unref(variant);
|
||||
|
||||
data = g_variant_get_fixed_array(out_private_variant,
|
||||
&count,
|
||||
sizeof(guint8));
|
||||
guint8 *marshaled_out_private = g_memdup(data, count);
|
||||
count = 0;
|
||||
|
||||
TPM2B_PRIVATE out_private = {
|
||||
.size = 0
|
||||
};
|
||||
ret = Tss2_MU_TPM2B_PRIVATE_Unmarshal(marshaled_out_private,
|
||||
out_private_offset,
|
||||
&offset,
|
||||
&out_private);
|
||||
|
||||
g_variant_unref(out_private_variant);
|
||||
g_free(marshaled_out_private);
|
||||
|
||||
if (ret != TSS2_RC_SUCCESS) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Tss2_MU_TPM2B_PRIVATE_Unmarshal: %s",
|
||||
Tss2_RC_Decode(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
data = g_variant_get_fixed_array(out_public_variant,
|
||||
&count,
|
||||
sizeof(guint8));
|
||||
guint8 *marshaled_out_public = g_memdup(data, count);
|
||||
|
||||
TPM2B_PUBLIC out_public = {
|
||||
.size = 0
|
||||
};
|
||||
ret = Tss2_MU_TPM2B_PUBLIC_Unmarshal(marshaled_out_public,
|
||||
out_public_offset,
|
||||
&offset,
|
||||
&out_public);
|
||||
|
||||
g_variant_unref(out_public_variant);
|
||||
g_free(marshaled_out_public);
|
||||
|
||||
if (ret != TSS2_RC_SUCCESS) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Tss2_MU_TPM2B_PUBLIC_Unmarshal: %s",
|
||||
Tss2_RC_Decode(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = Esys_Load(context->esys_context, context->primary_key,
|
||||
ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
|
||||
&out_private, &out_public, &out_key);
|
||||
if (ret != TSS2_RC_SUCCESS) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Esys_Load: %s", Tss2_RC_Decode(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = Esys_Unseal(context->esys_context, out_key,
|
||||
ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
|
||||
&out_data);
|
||||
if (ret != TSS2_RC_SUCCESS) {
|
||||
g_set_error(error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Esys_Unseal: %s", Tss2_RC_Decode(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
output = g_bytes_new(out_data->buffer, out_data->size);
|
||||
Esys_Free(out_data);
|
||||
|
||||
return output;
|
||||
}
|
39
egg/egg-tpm2.h
Normal file
39
egg/egg-tpm2.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* libsecret - TSS interface for libsecret
|
||||
*
|
||||
* Copyright (C) 2021 Dhanuka Warusadura
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*
|
||||
* Author: Dhanuka Warusadura
|
||||
*/
|
||||
|
||||
#ifndef EGG_TPM2_H_
|
||||
#define EGG_TPM2_H_
|
||||
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
typedef struct EggTpm2Context EggTpm2Context;
|
||||
|
||||
EggTpm2Context *egg_tpm2_initialize (GError **);
|
||||
void egg_tpm2_finalize (EggTpm2Context *);
|
||||
GBytes *egg_tpm2_generate_master_password (EggTpm2Context *,
|
||||
GError **);
|
||||
GBytes *egg_tpm2_decrypt_master_password (EggTpm2Context *,
|
||||
GBytes *,
|
||||
GError **);
|
||||
|
||||
#endif
|
@ -18,6 +18,14 @@ if get_option('gcrypt')
|
||||
libegg_deps += gcrypt_dep
|
||||
endif
|
||||
|
||||
if get_option('tpm2')
|
||||
libegg_sources += [
|
||||
'egg-tpm2.c',
|
||||
]
|
||||
|
||||
libegg_deps += tss2_deps
|
||||
endif
|
||||
|
||||
libegg = static_library('egg',
|
||||
libegg_sources,
|
||||
dependencies: libegg_deps,
|
||||
@ -37,6 +45,12 @@ if get_option('gcrypt')
|
||||
]
|
||||
endif
|
||||
|
||||
if get_option('tpm2')
|
||||
test_names += [
|
||||
'test-tpm2',
|
||||
]
|
||||
endif
|
||||
|
||||
foreach _test : test_names
|
||||
|
||||
test_bin = executable(_test,
|
||||
|
78
egg/test-tpm2.c
Normal file
78
egg/test-tpm2.c
Normal file
@ -0,0 +1,78 @@
|
||||
/* libsecret - Test TSS interface for libsecret
|
||||
*
|
||||
* Copyright (C) 2021 Dhanuka Warusadura
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*
|
||||
* Author: Dhanuka Warusadura
|
||||
*/
|
||||
|
||||
#include "egg-tpm2.h"
|
||||
|
||||
void
|
||||
test_egg_tpm2_generate_master_password(void)
|
||||
{
|
||||
EggTpm2Context *context;
|
||||
GBytes *result;
|
||||
|
||||
GError *error = NULL;
|
||||
g_assert_no_error(error);
|
||||
context = egg_tpm2_initialize(&error);
|
||||
g_assert_nonnull(context);
|
||||
result = egg_tpm2_generate_master_password(context, &error);
|
||||
g_assert_nonnull(result);
|
||||
egg_tpm2_finalize(context);
|
||||
g_bytes_unref(result);
|
||||
}
|
||||
|
||||
void
|
||||
test_egg_tpm2_decrypt_master_password(void)
|
||||
{
|
||||
EggTpm2Context *context;
|
||||
GBytes *result, *decrypted1, *decrypted2;
|
||||
|
||||
GError *error = NULL;
|
||||
g_assert_no_error(error);
|
||||
context = egg_tpm2_initialize(&error);
|
||||
g_assert_nonnull(context);
|
||||
result = egg_tpm2_generate_master_password(context, &error);
|
||||
g_assert_nonnull(result);
|
||||
decrypted1 = egg_tpm2_decrypt_master_password(context, result,
|
||||
&error);
|
||||
g_assert_nonnull(decrypted1);
|
||||
decrypted2 = egg_tpm2_decrypt_master_password(context, result,
|
||||
&error);
|
||||
g_assert_nonnull(decrypted2);
|
||||
g_assert(g_bytes_equal(decrypted1, decrypted2));
|
||||
egg_tpm2_finalize(context);
|
||||
g_bytes_unref(result);
|
||||
g_bytes_unref(decrypted1);
|
||||
g_bytes_unref(decrypted2);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
g_test_add_func(
|
||||
"/tpm/test_egg_tpm2_generate_master_password",
|
||||
test_egg_tpm2_generate_master_password);
|
||||
g_test_add_func(
|
||||
"/tpm/test_egg_tpm2_decrypt_master_password",
|
||||
test_egg_tpm2_decrypt_master_password);
|
||||
|
||||
return g_test_run();
|
||||
}
|
15
meson.build
15
meson.build
@ -36,6 +36,17 @@ gcrypt_dep = dependency('libgcrypt',
|
||||
required: get_option('gcrypt'),
|
||||
)
|
||||
|
||||
min_tss2_version = '3.0.3'
|
||||
tss2_esys = dependency('tss2-esys', version: '>=' + min_tss2_version, required: get_option('tpm2'))
|
||||
tss2_mu = dependency('tss2-mu', version: '>=' + min_tss2_version, required: get_option('tpm2'))
|
||||
tss2_rc = dependency('tss2-rc', version: '>=' + min_tss2_version, required: get_option('tpm2'))
|
||||
tss2_tctildr = dependency('tss2-tctildr', version: '>=' + min_tss2_version, required: get_option('tpm2'))
|
||||
|
||||
tss2_deps = []
|
||||
if tss2_esys.found() and tss2_mu.found() and tss2_rc.found() and tss2_tctildr.found()
|
||||
tss2_deps += [tss2_esys, tss2_mu, tss2_rc, tss2_tctildr]
|
||||
endif
|
||||
|
||||
# Libraries
|
||||
math = meson.get_compiler('c').find_library('m')
|
||||
|
||||
@ -48,9 +59,13 @@ conf.set_quoted('PACKAGE_NAME', meson.project_name())
|
||||
conf.set_quoted('PACKAGE_STRING', meson.project_name())
|
||||
conf.set_quoted('PACKAGE_VERSION', meson.project_version())
|
||||
conf.set('WITH_GCRYPT', get_option('gcrypt'))
|
||||
conf.set('WITH_TPM', get_option('tpm2'))
|
||||
if get_option('gcrypt')
|
||||
conf.set_quoted('LIBGCRYPT_VERSION', min_libgcrypt_version)
|
||||
endif
|
||||
if get_option('tpm2')
|
||||
conf.set_quoted('TSS2_VERSION', min_tss2_version)
|
||||
endif
|
||||
conf.set('WITH_DEBUG', get_option('debugging'))
|
||||
conf.set('_DEBUG', get_option('debugging'))
|
||||
conf.set('HAVE_MLOCK', meson.get_compiler('c').has_function('mlock'))
|
||||
|
@ -6,3 +6,4 @@ option('gtk_doc', type: 'boolean', value: true, description: 'Build reference do
|
||||
option('introspection', type: 'boolean', value: true, description: 'Create GIR file.')
|
||||
option('bashcompdir', type: 'string', value: '', description: 'Override default location for bash completion files')
|
||||
option('bash_completion', type: 'feature', value: 'auto', description: 'Install bash completion files')
|
||||
option('tpm2', type: 'boolean', value: false, description: 'With TPM2 Software Stack')
|
||||
|
Loading…
Reference in New Issue
Block a user