mirror of
https://gitlab.gnome.org/GNOME/libsecret.git
synced 2024-12-21 20:28:52 +00:00
Add TPM2 integration to secret file backend
These changes add TPM2 derived encryption key to secret file backend.
This commit is contained in:
parent
2f0558fe57
commit
ea57d26930
@ -22,6 +22,7 @@
|
||||
#include "secret-retrievable.h"
|
||||
|
||||
#include "egg/egg-secure-memory.h"
|
||||
#include "egg/egg-tpm2.h"
|
||||
|
||||
EGG_SECURE_DECLARE (secret_file_backend);
|
||||
|
||||
@ -494,12 +495,112 @@ secret_file_backend_real_init_async (GAsyncInitable *initable,
|
||||
g_task_set_task_data (task, init, init_closure_free);
|
||||
g_bus_get (G_BUS_TYPE_SESSION, cancellable, on_bus_get, task);
|
||||
} else {
|
||||
#ifdef WITH_TPM
|
||||
EggTpm2Context *context;
|
||||
GFile *tpm2_file;
|
||||
gchar *tpm2_file_path;
|
||||
gboolean status;
|
||||
GBytes *encrypted;
|
||||
GBytes *decrypted;
|
||||
|
||||
context = egg_tpm2_initialize (&error);
|
||||
if (!context) {
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
path = g_file_get_path (file);
|
||||
tpm2_file_path = g_strdup_printf ("%s.tpm2", path);
|
||||
g_free(path);
|
||||
tpm2_file = g_file_new_for_path (tpm2_file_path);
|
||||
status = g_file_test (tpm2_file_path, G_FILE_TEST_EXISTS);
|
||||
g_free (tpm2_file_path);
|
||||
|
||||
if (!status) {
|
||||
encrypted = egg_tpm2_generate_master_password (
|
||||
context,
|
||||
&error);
|
||||
if (!encrypted) {
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
gconstpointer contents;
|
||||
gsize size;
|
||||
contents = g_bytes_get_data (encrypted, &size);
|
||||
status = g_file_replace_contents (tpm2_file,
|
||||
contents,
|
||||
size,
|
||||
NULL,
|
||||
FALSE,
|
||||
G_FILE_CREATE_PRIVATE,
|
||||
NULL,
|
||||
cancellable,
|
||||
&error);
|
||||
if (!status) {
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
char *contents;
|
||||
gsize length;
|
||||
status = g_file_load_contents (tpm2_file,
|
||||
cancellable,
|
||||
&contents,
|
||||
&length,
|
||||
NULL,
|
||||
&error);
|
||||
if (!status) {
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
encrypted = g_bytes_new_take (contents, length);
|
||||
}
|
||||
|
||||
decrypted = egg_tpm2_decrypt_master_password (context,
|
||||
encrypted,
|
||||
&error);
|
||||
g_bytes_unref (encrypted);
|
||||
egg_tpm2_finalize (context);
|
||||
if (!decrypted) {
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
gconstpointer data;
|
||||
gsize size;
|
||||
data = g_bytes_get_data(decrypted, &size);
|
||||
password = secret_value_new (data,
|
||||
size,
|
||||
"text/plain");
|
||||
g_bytes_unref (decrypted);
|
||||
g_async_initable_new_async (SECRET_TYPE_FILE_COLLECTION,
|
||||
io_priority,
|
||||
cancellable,
|
||||
on_collection_new_async,
|
||||
task,
|
||||
"file", file,
|
||||
"password", password,
|
||||
NULL);
|
||||
|
||||
g_object_unref (tpm2_file);
|
||||
g_object_unref (file);
|
||||
secret_value_unref (password);
|
||||
#else
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_INVALID_ARGUMENT,
|
||||
"master password is not retrievable");
|
||||
g_object_unref (task);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,3 +17,11 @@ if get_option('gcrypt') and host_machine.system() != 'windows'
|
||||
suite: 'secret-tool',
|
||||
)
|
||||
endif
|
||||
|
||||
if get_option('tpm2')
|
||||
test('test-secret-tool-tpm2.sh',
|
||||
find_program('test-secret-tool-tpm2.sh'),
|
||||
env: test_env,
|
||||
suite: 'secret-tool',
|
||||
)
|
||||
endif
|
||||
|
101
tool/test-secret-tool-tpm2.sh
Executable file
101
tool/test-secret-tool-tpm2.sh
Executable file
@ -0,0 +1,101 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
testdir=$PWD/test-secret-tool-tpm2-$$
|
||||
test -d "$testdir" || mkdir "$testdir"
|
||||
|
||||
cleanup () {
|
||||
rm -rf "$testdir"
|
||||
}
|
||||
trap cleanup 0
|
||||
|
||||
cd "$testdir"
|
||||
|
||||
SECRET_BACKEND=file
|
||||
export SECRET_BACKEND
|
||||
|
||||
SECRET_FILE_TEST_PATH=$testdir/keyring
|
||||
export SECRET_FILE_TEST_PATH
|
||||
|
||||
: ${SECRET_TOOL="$abs_top_builddir"/tool/secret-tool}
|
||||
|
||||
: ${DIFF=diff}
|
||||
|
||||
echo 1..6
|
||||
|
||||
echo test1 | ${SECRET_TOOL} store --label label1 foo bar
|
||||
if test $? -eq 0; then
|
||||
echo "ok 1 /secret-tool/store1"
|
||||
else
|
||||
echo "not ok 1 /secret-tool/store1"
|
||||
fi
|
||||
|
||||
echo test2 | ${SECRET_TOOL} store --label label2 foo bar apple orange
|
||||
if test $? -eq 0; then
|
||||
echo "ok 2 /secret-tool/store2"
|
||||
else
|
||||
echo "not ok 2 /secret-tool/store2"
|
||||
fi
|
||||
|
||||
echo test1 > lookup.exp
|
||||
${SECRET_TOOL} lookup foo bar > lookup.out
|
||||
if ${DIFF} lookup.exp lookup.out > lookup.diff; then
|
||||
echo "ok 3 /secret-tool/lookup"
|
||||
else
|
||||
echo "not ok 3 /secret-tool/lookup"
|
||||
sed 's/^/# /' lookup.diff
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat > search.exp <<EOF
|
||||
[no path]
|
||||
label = label1
|
||||
secret = test1
|
||||
|
||||
[no path]
|
||||
label = label2
|
||||
secret = test2
|
||||
|
||||
EOF
|
||||
|
||||
${SECRET_TOOL} search foo bar | sed '/^created\|^modified/d' > search.out
|
||||
if test $? -ne 0; then
|
||||
echo "not ok 4 /secret-tool/search"
|
||||
exit 1
|
||||
fi
|
||||
if ${DIFF} search.exp search.out > search.diff; then
|
||||
echo "ok 4 /secret-tool/search"
|
||||
else
|
||||
echo "not ok 4 /secret-tool/search"
|
||||
sed 's/^/# /' search.diff
|
||||
exit 1
|
||||
fi
|
||||
|
||||
${SECRET_TOOL} clear apple orange
|
||||
if test $? -eq 0; then
|
||||
echo "ok 5 /secret-tool/clear"
|
||||
else
|
||||
echo "not ok 5 /secret-tool/clear"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat > search-after-clear.exp <<EOF
|
||||
[no path]
|
||||
label = label1
|
||||
secret = test1
|
||||
|
||||
EOF
|
||||
|
||||
${SECRET_TOOL} search foo bar | sed '/^created\|^modified/d' > search-after-clear.out
|
||||
if test $? -ne 0; then
|
||||
echo "not ok 6 /secret-tool/search-after-clear"
|
||||
exit 1
|
||||
fi
|
||||
if ${DIFF} search-after-clear.exp search-after-clear.out > search-after-clear.diff; then
|
||||
echo "ok 6 /secret-tool/search-after-clear"
|
||||
else
|
||||
echo "not ok 6 /secret-tool/search-after-clear"
|
||||
sed 's/^/# /' search-after-clear.diff
|
||||
exit 1
|
||||
fi
|
Loading…
Reference in New Issue
Block a user