mirror of
https://gitlab.gnome.org/GNOME/libsecret.git
synced 2024-12-22 04:38:55 +00:00
Merge branch 'tss-dev' into 'master'
Add TPM2 API and its implementations to egg See merge request GNOME/libsecret!83
This commit is contained in:
commit
301e3ce617
@ -3,7 +3,7 @@ stages:
|
|||||||
- deploy
|
- deploy
|
||||||
|
|
||||||
variables:
|
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}'"
|
CPPCHECK_OPTIONS: "--enable=warning --enable=style --enable=performance --enable=portability --std=c99 --template='{id}:{file}:{line},{severity},{message}'"
|
||||||
|
|
||||||
fedora:Werror:
|
fedora:Werror:
|
||||||
@ -24,7 +24,7 @@ fedora:Werror:
|
|||||||
- eval `dbus-launch --sh-syntax`
|
- eval `dbus-launch --sh-syntax`
|
||||||
- 'tpm2-abrmd --logger=stdout --tcti=swtpm: --session --allow-root --flush-all &'
|
- 'tpm2-abrmd --logger=stdout --tcti=swtpm: --session --allow-root --flush-all &'
|
||||||
- 'export TCTI=tabrmd:bus_type=session'
|
- '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 compile -C _build
|
||||||
- meson test -C _build
|
- meson test -C _build
|
||||||
artifacts:
|
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
|
libegg_deps += gcrypt_dep
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if get_option('tpm2')
|
||||||
|
libegg_sources += [
|
||||||
|
'egg-tpm2.c',
|
||||||
|
]
|
||||||
|
|
||||||
|
libegg_deps += tss2_deps
|
||||||
|
endif
|
||||||
|
|
||||||
libegg = static_library('egg',
|
libegg = static_library('egg',
|
||||||
libegg_sources,
|
libegg_sources,
|
||||||
dependencies: libegg_deps,
|
dependencies: libegg_deps,
|
||||||
@ -37,6 +45,12 @@ if get_option('gcrypt')
|
|||||||
]
|
]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if get_option('tpm2')
|
||||||
|
test_names += [
|
||||||
|
'test-tpm2',
|
||||||
|
]
|
||||||
|
endif
|
||||||
|
|
||||||
foreach _test : test_names
|
foreach _test : test_names
|
||||||
|
|
||||||
test_bin = executable(_test,
|
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'),
|
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
|
# Libraries
|
||||||
math = meson.get_compiler('c').find_library('m')
|
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_STRING', meson.project_name())
|
||||||
conf.set_quoted('PACKAGE_VERSION', meson.project_version())
|
conf.set_quoted('PACKAGE_VERSION', meson.project_version())
|
||||||
conf.set('WITH_GCRYPT', get_option('gcrypt'))
|
conf.set('WITH_GCRYPT', get_option('gcrypt'))
|
||||||
|
conf.set('WITH_TPM', get_option('tpm2'))
|
||||||
if get_option('gcrypt')
|
if get_option('gcrypt')
|
||||||
conf.set_quoted('LIBGCRYPT_VERSION', min_libgcrypt_version)
|
conf.set_quoted('LIBGCRYPT_VERSION', min_libgcrypt_version)
|
||||||
endif
|
endif
|
||||||
|
if get_option('tpm2')
|
||||||
|
conf.set_quoted('TSS2_VERSION', min_tss2_version)
|
||||||
|
endif
|
||||||
conf.set('WITH_DEBUG', get_option('debugging'))
|
conf.set('WITH_DEBUG', get_option('debugging'))
|
||||||
conf.set('_DEBUG', get_option('debugging'))
|
conf.set('_DEBUG', get_option('debugging'))
|
||||||
conf.set('HAVE_MLOCK', meson.get_compiler('c').has_function('mlock'))
|
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('introspection', type: 'boolean', value: true, description: 'Create GIR file.')
|
||||||
option('bashcompdir', type: 'string', value: '', description: 'Override default location for bash completion files')
|
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('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