mirror of
https://gitlab.gnome.org/GNOME/libsecret.git
synced 2024-12-22 04:38:55 +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 "secret-retrievable.h"
|
||||||
|
|
||||||
#include "egg/egg-secure-memory.h"
|
#include "egg/egg-secure-memory.h"
|
||||||
|
#include "egg/egg-tpm2.h"
|
||||||
|
|
||||||
EGG_SECURE_DECLARE (secret_file_backend);
|
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_task_set_task_data (task, init, init_closure_free);
|
||||||
g_bus_get (G_BUS_TYPE_SESSION, cancellable, on_bus_get, task);
|
g_bus_get (G_BUS_TYPE_SESSION, cancellable, on_bus_get, task);
|
||||||
} else {
|
} 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_task_return_new_error (task,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_INVALID_ARGUMENT,
|
G_IO_ERROR_INVALID_ARGUMENT,
|
||||||
"master password is not retrievable");
|
"master password is not retrievable");
|
||||||
g_object_unref (task);
|
g_object_unref (task);
|
||||||
return;
|
return;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,3 +17,11 @@ if get_option('gcrypt') and host_machine.system() != 'windows'
|
|||||||
suite: 'secret-tool',
|
suite: 'secret-tool',
|
||||||
)
|
)
|
||||||
endif
|
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