Migrate some meaty zfs funxions out

This commit is contained in:
наб 2020-10-23 01:05:55 +02:00
parent 1d032923c0
commit 92f6927a08
No known key found for this signature in database
GPG Key ID: BCFD0B018D2658F1
9 changed files with 100 additions and 103 deletions

View File

@ -40,40 +40,7 @@ int main(int argc, char ** argv) {
REQUIRE_KEY_LOADED(dataset);
// TSS_RESULT Tspi_Context_Create(TSS_HCONTEXT* phContext);
// TSS_RESULT Tspi_Context_Connect(TSS_HCONTEXT hLocalContext, UNICODE* wszDestination);
// TSS_RESULT Tspi_Context_GetTpmObject(TSS_HCONTEXT hContext, TSS_HTPM* phTPM);
//
// TSS_RESULT Tspi_TPM_GetRandom(TSS_HTPM hTPM, UINT32 size, BYTE** random);
//
//
// TSS_RESULT Tspi_Context_LoadKeyByUUID(TSS_HCONTEXT hContext, TSS_FLAG persistentStorageType,
// TSS_UUID uuidData, TSS_HKEY* phKey);
//
//
// TSS_RESULT Tspi_Context_CreateObject(TSS_HCONTEXT hContext, TSS_FLAG objectType,
// TSS_FLAG initFlags, TSS_HOBJECT* phObject);
// TSS_RESULT Tspi_Key_CreateKey(TSS_HKEY hKey, TSS_HKEY hWrappingKey, TSS_HPCRS hPcrComposite);
//
//
// TSS_RESULT Tspi_Data_Seal(TSS_HENCDATA hEncData, TSS_HKEY hEncKey,
// UINT32 ulDataLength, BYTE* rgbDataToSeal,
// TSS_HPCRS hPcrComposite);
//
//
// TSS_RESULT Tspi_Policy_SetSecret(TSS_HPOLICY hPolicy, TSS_FLAG secretMode,
// UINT32 ulSecretLength, BYTE* rgbSecret);
//
// TSS_RESULT Tspi_Policy_AssignToObject(TSS_HPOLICY hPolicy, TSS_HOBJECT hObject);
//
// TSS_RESULT Tspi_Context_FreeMemory(TSS_HCONTEXT hContext, BYTE* rgbMemory);
// TSS_RESULT Tspi_Context_Close(TSS_HCONTEXT hLocalContext);
//
//
// TSS_RESULT Tspi_GetAttribData(TSS_HOBJECT hObject, TSS_FLAG attribFlag,
// TSS_FLAG subFlag, UINT32* pulAttribDataSize,
// BYTE** prgbAttribData);
/// Mostly based on See tpm_sealdata(1) from tpm-tools.
// All memory lives as long as this does
TSS_HCONTEXT ctx{};
@ -230,29 +197,13 @@ int main(int argc, char ** argv) {
*cur++ = ':';
for(auto i = 0u; i < sealed_object_blob_len; ++i, cur += 2)
sprintf(cur, "%02X", sealed_object_blob[i]);
*cur++ = '\0';
*cur++ = '\0';
}
fprintf(stderr, "%s\n", handle);
TRY_MAIN(set_key_props(dataset, THIS_BACKEND, handle));
/// zfs_crypto_rewrap() with "prompt" reads from stdin, but not if it's a TTY;
/// this user-proofs the set-up, and means we don't have to touch the filesysten:
/// instead, get an FD, write the raw key data there, dup() it onto stdin,
/// let libzfs read it, then restore stdin
int key_fd;
TRY_MAIN(filled_fd(key_fd, wrap_key, WRAPPING_KEY_LEN));
quickscope_wrapper key_fd_deleter{[=] { close(key_fd); }};
TRY_MAIN(with_stdin_at(key_fd, [&] {
if(zfs_crypto_rewrap(dataset, TRY_PTR("get rewrap args", rewrap_args()), B_FALSE))
return __LINE__; // Error printed by libzfs
else
printf("Key for %s changed\n", zfs_get_name(dataset));
return 0;
}));
TRY_MAIN(change_key(dataset, wrap_key));
// ok = true;
// return 0;

View File

@ -89,24 +89,7 @@ int main(int argc, char ** argv) {
TRY_MAIN(set_key_props(dataset, THIS_BACKEND, persistent_handle_s));
}
/// zfs_crypto_rewrap() with "prompt" reads from stdin, but not if it's a TTY;
/// this user-proofs the set-up, and means we don't have to touch the filesysten:
/// instead, get an FD, write the raw key data there, dup() it onto stdin,
/// let libzfs read it, then restore stdin
int key_fd;
TRY_MAIN(filled_fd(key_fd, wrap_key, WRAPPING_KEY_LEN));
quickscope_wrapper key_fd_deleter{[=] { close(key_fd); }};
TRY_MAIN(with_stdin_at(key_fd, [&] {
if(zfs_crypto_rewrap(dataset, TRY_PTR("get rewrap args", rewrap_args()), B_FALSE))
return __LINE__; // Error printed by libzfs
else
printf("Key for %s changed\n", zfs_get_name(dataset));
return 0;
}));
TRY_MAIN(change_key(dataset, wrap_key));
ok = true;
return 0;

View File

@ -19,8 +19,12 @@ int main(int argc, char ** argv) {
[&](auto dataset) {
REQUIRE_KEY_LOADED(dataset);
char * persistent_handle_s{};
TRY_MAIN(parse_key_props(dataset, THIS_BACKEND, persistent_handle_s));
TPMI_DH_PERSISTENT persistent_handle{};
TRY_MAIN(parse_key_props(dataset, THIS_BACKEND, persistent_handle));
TRY_MAIN(tpm2_parse_handle(zfs_get_name(dataset), persistent_handle_s, persistent_handle));
if(zfs_crypto_rewrap(dataset, TRY_PTR("get clear rewrap args", clear_rewrap_args()), B_FALSE))
return __LINE__; // Error printed by libzfs

View File

@ -17,12 +17,15 @@
int main(int argc, char ** argv) {
auto noop = B_FALSE;
auto noop = false;
return do_main(
argc, argv, "n", "[-n]", [&](auto) { noop = B_TRUE; },
argc, argv, "n", "[-n]", [&](auto) { noop = true; },
[&](auto dataset) {
char * handle_s{};
TRY_MAIN(parse_key_props(dataset, THIS_BACKEND, handle_s));
TPMI_DH_PERSISTENT handle{};
TRY_MAIN(parse_key_props(dataset, THIS_BACKEND, handle));
TRY_MAIN(tpm2_parse_handle(zfs_get_name(dataset), handle_s, handle));
uint8_t wrap_key[WRAPPING_KEY_LEN];
@ -32,20 +35,7 @@ int main(int argc, char ** argv) {
}));
int key_fd;
TRY_MAIN(filled_fd(key_fd, (void *)wrap_key, sizeof(wrap_key)));
quickscope_wrapper key_fd_deleter{[=] { close(key_fd); }};
TRY_MAIN(with_stdin_at(key_fd, [&] {
if(zfs_crypto_load_key(dataset, noop, nullptr))
return __LINE__; // Error printed by libzfs
else
printf("Key for %s %s\n", zfs_get_name(dataset), noop ? "OK" : "loaded");
return 0;
}));
TRY_MAIN(load_key(dataset, wrap_key, noop));
return 0;
});
}

View File

@ -3,6 +3,7 @@
#include "tpm2.hpp"
#include "main.hpp"
#include "parse.hpp"
#include <algorithm>
#include <time.h>
@ -24,6 +25,16 @@ TPM2B_DATA tpm2_creation_metadata(const char * dataset_name) {
}
int tpm2_parse_handle(const char * dataset_name, const char * handle_s, TPMI_DH_PERSISTENT & handle) {
if(parse_int(handle_s, handle)) {
fprintf(stderr, "Dataset %s's handle %s not valid.\n", dataset_name, handle_s);
return __LINE__;
}
return 0;
}
int tpm2_generate_rand(ESYS_CONTEXT * tpm2_ctx, void * into, size_t length) {
TPM2B_DIGEST * rand{};
TRY_TPM2("get random data from TPM", Esys_GetRandom(tpm2_ctx, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, length, &rand));
@ -42,7 +53,7 @@ int tpm2_generate_rand(ESYS_CONTEXT * tpm2_ctx, void * into, size_t length) {
static int tpm2_find_unused_persistent_non_platform(ESYS_CONTEXT * tpm2_ctx, TPMI_DH_PERSISTENT & persistent_handle) {
TPMS_CAPABILITY_DATA * cap; // TODO: check for more data?
TRY_TPM2("Read used persistent TPM handles", Esys_GetCapability(tpm2_ctx, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, TPM2_CAP_HANDLES, TPM2_PERSISTENT_FIRST,
TPM2_MAX_CAP_HANDLES, nullptr, &cap));
TPM2_MAX_CAP_HANDLES, nullptr, &cap));
quickscope_wrapper cap_deleter{[=] { Esys_Free(cap); }};
persistent_handle = 0;
@ -94,8 +105,9 @@ int tpm2_seal(ESYS_CONTEXT * tpm2_ctx, ESYS_TR tpm2_session, TPMI_DH_PERSISTENT
TPM2B_CREATION_DATA * creation_data{};
TPM2B_DIGEST * creation_hash{};
TPMT_TK_CREATION * creation_ticket{};
TRY_TPM2("create primary encryption key", Esys_CreatePrimary(tpm2_ctx, ESYS_TR_RH_OWNER, tpm2_session, ESYS_TR_NONE, ESYS_TR_NONE, &primary_sens, &pub, &metadata,
&pcrs, &primary_handle, &public_ret, &creation_data, &creation_hash, &creation_ticket));
TRY_TPM2("create primary encryption key",
Esys_CreatePrimary(tpm2_ctx, ESYS_TR_RH_OWNER, tpm2_session, ESYS_TR_NONE, ESYS_TR_NONE, &primary_sens, &pub, &metadata, &pcrs, &primary_handle,
&public_ret, &creation_data, &creation_hash, &creation_ticket));
quickscope_wrapper creation_ticket_deleter{[=] { Esys_Free(creation_ticket); }};
quickscope_wrapper creation_hash_deleter{[=] { Esys_Free(creation_hash); }};
quickscope_wrapper creation_data_deleter{[=] { Esys_Free(creation_data); }};
@ -141,7 +153,7 @@ int tpm2_seal(ESYS_CONTEXT * tpm2_ctx, ESYS_TR tpm2_session, TPMI_DH_PERSISTENT
TPM2B_DIGEST * creation_hash{};
TPMT_TK_CREATION * creation_ticket{};
TRY_TPM2("create key seal", Esys_Create(tpm2_ctx, primary_handle, tpm2_session, ESYS_TR_NONE, ESYS_TR_NONE, &secret_sens, &pub, &metadata, &pcrs,
&sealant_private, &sealant_public, &creation_data, &creation_hash, &creation_ticket));
&sealant_private, &sealant_public, &creation_data, &creation_hash, &creation_ticket));
quickscope_wrapper creation_ticket_deleter{[=] { Esys_Free(creation_ticket); }};
quickscope_wrapper creation_hash_deleter{[=] { Esys_Free(creation_hash); }};
quickscope_wrapper creation_data_deleter{[=] { Esys_Free(creation_data); }};

View File

@ -46,6 +46,9 @@ int with_tpm2_session(F && func) {
extern TPM2B_DATA tpm2_creation_metadata(const char * dataset_name);
/// Parse a persistent handle name as stored in a ZFS property
extern int tpm2_parse_handle(const char * dataset_name, const char * handle_s, TPMI_DH_PERSISTENT & handle);
extern int tpm2_generate_rand(ESYS_CONTEXT * tpm2_ctx, void * into, size_t length);
extern int tpm2_seal(ESYS_CONTEXT * tpm2_ctx, ESYS_TR tpm2_session, TPMI_DH_PERSISTENT & persistent_handle, const TPM2B_DATA & metadata, void * data, size_t data_len);
extern int tpm2_unseal(ESYS_CONTEXT * tpm2_ctx, ESYS_TR tpm2_session, TPMI_DH_PERSISTENT persistent_handle, void * data, size_t data_len);

View File

@ -4,7 +4,6 @@
#include "zfs.hpp"
#include "common.hpp"
#include "main.hpp"
#include "parse.hpp"
#include <libzfs.h>
@ -102,8 +101,8 @@ int clear_key_props(zfs_handle_t * from) {
}
int parse_key_props(zfs_handle_t * in, const char * our_backend, uint32_t & handle) {
char *backend{}, *handle_s{};
int parse_key_props(zfs_handle_t * in, const char * our_backend, char *& handle) {
char *backend{};
TRY_MAIN(lookup_userprop(in, PROPNAME_BACKEND, backend));
if(!backend) {
@ -115,16 +114,11 @@ int parse_key_props(zfs_handle_t * in, const char * our_backend, uint32_t & hand
return __LINE__;
}
TRY_MAIN(lookup_userprop(in, PROPNAME_KEY, handle_s));
if(!handle_s) {
TRY_MAIN(lookup_userprop(in, PROPNAME_KEY, handle));
if(!handle) {
fprintf(stderr, "Dataset %s missing key data.\n", zfs_get_name(in));
return __LINE__;
}
if(parse_int(handle_s, handle)) {
fprintf(stderr, "Dataset %s's handle %s not valid.\n", zfs_get_name(in), handle_s);
return __LINE__;
}
return 0;
}

View File

@ -42,4 +42,15 @@ extern int set_key_props(zfs_handle_t * on, const char * backend, const char * h
extern int clear_key_props(zfs_handle_t * from);
/// Read in decoding props from the dataset
extern int parse_key_props(zfs_handle_t * in, const char * our_backend, uint32_t & handle);
extern int parse_key_props(zfs_handle_t * in, const char * our_backend, char *& handle);
/// Rewrap key on on to wrap_key.
///
/// wrap_key must be WRAPPING_KEY_LEN long.
extern int change_key(zfs_handle_t * on, const uint8_t * wrap_key);
/// (Try to) load key wrap_key for for_d.
///
/// wrap_key must be WRAPPING_KEY_LEN long.
extern int load_key(zfs_handle_t * for_d, const uint8_t * wrap_key, bool noop);

49
src/zfs_meat.cpp Normal file
View File

@ -0,0 +1,49 @@
/* SPDX-License-Identifier: MIT */
#include "fd.hpp"
#include "main.hpp"
#include "zfs.hpp"
#include <libzfs.h>
// #include <sys/zio_crypt.h>
#define WRAPPING_KEY_LEN 32
template <class F>
static int with_stdin_at_buffer(const void * buf, size_t buf_len, F && func) {
int key_fd;
TRY_MAIN(filled_fd(key_fd, buf, buf_len));
quickscope_wrapper key_fd_deleter{[=] { close(key_fd); }};
return with_stdin_at(key_fd, func);
}
int change_key(zfs_handle_t * on, const uint8_t * wrap_key) {
/// zfs_crypto_rewrap() with "prompt" reads from stdin, but not if it's a TTY;
/// this user-proofs the set-up, and means we don't have to touch the filesysten:
/// instead, get an FD, write the raw key data there, dup() it onto stdin,
/// let libzfs read it, then restore stdin
return with_stdin_at_buffer(wrap_key, WRAPPING_KEY_LEN, [&] {
if(zfs_crypto_rewrap(on, TRY_PTR("get rewrap args", rewrap_args()), B_FALSE))
return __LINE__; // Error printed by libzfs
else
printf("Key for %s changed\n", zfs_get_name(on));
return 0;
});
}
int load_key(zfs_handle_t * for_d, const uint8_t * wrap_key, bool noop) {
return with_stdin_at_buffer(wrap_key, WRAPPING_KEY_LEN, [&] {
if(zfs_crypto_load_key(for_d, noop ? B_TRUE : B_FALSE, nullptr))
return __LINE__; // Error printed by libzfs
else
printf("Key for %s %s\n", zfs_get_name(for_d), noop ? "OK" : "loaded");
return 0;
});
}