Support storing image encryption keys in Vault
This commit is contained in:
+8
-7
@@ -42,12 +42,13 @@ static const char* help_text =
|
||||
"\n"
|
||||
"vitastor-cli create -s|--size SIZE [OPTIONS] <name>\n"
|
||||
" Create an image. Options:\n"
|
||||
" -s|--size SIZE New image size in bytes or with a K/M/G/T unit suffix.\n"
|
||||
" -p|--pool POOL Specify pool for the new image (may be omitted if there is only 1 pool).\n"
|
||||
" --parent PARENT Create a copy-on-write image clone based on PARENT (or PARENT@SNAPSHOT).\n"
|
||||
" If parent is not a snapshot, it must be a read-only image.\n"
|
||||
" --enc-key random Generate a new random AES-256-XTS encryption key for the new image.\n"
|
||||
" --enc-key HEX Set a specified AES-256-XTS key (64 bytes in hex) for the new image.\n"
|
||||
" -s|--size SIZE New image size in bytes or with a K/M/G/T unit suffix.\n"
|
||||
" -p|--pool POOL Specify pool for the new image (may be omitted if there is only 1 pool).\n"
|
||||
" --parent PARENT Create a copy-on-write image clone based on PARENT (or PARENT@SNAPSHOT).\n"
|
||||
" If parent is not a snapshot, it must be a read-only image.\n"
|
||||
" --enc-key random Generate a new random AES-256-XTS encryption key for the new image.\n"
|
||||
" --enc-key HEX Set a specified AES-256-XTS key (64 bytes in hex) for the new image.\n"
|
||||
" --enc-key vault:ID Use an encryption key from an external Vault secret with specified ID.\n"
|
||||
"\n"
|
||||
"vitastor-cli create --snapshot <snapshot> [OPTIONS] <image>\n"
|
||||
"vitastor-cli snap-create [OPTIONS] <image>@<snapshot>\n"
|
||||
@@ -55,7 +56,7 @@ static const char* help_text =
|
||||
" Options:\n"
|
||||
" -p|--pool POOL Move image to pool POOL, leaving the snapshot in the old pool.\n"
|
||||
" --enc-key random Change image encryption key to a new random AES-256-XTS key.\n"
|
||||
" --enc-key HEX Change image encryption key to a specified key or to an empty key.\n"
|
||||
" --enc-key KEY Change image encryption key to a specified key, Vault key or to an empty key.\n"
|
||||
" By default, the image retains its old key when taking a snapshot.\n"
|
||||
"\n"
|
||||
"vitastor-cli modify <name> [--rename <new-name>] [--resize <size>] [--readonly | --readwrite] [-f|--force] [--down-ok]\n"
|
||||
|
||||
+17
-15
@@ -456,11 +456,12 @@ resume_3:
|
||||
};
|
||||
if (set_key)
|
||||
{
|
||||
new_cfg.enc_key.resize(enc_key.size()/2);
|
||||
fromhexstr(enc_key, new_cfg.enc_key.size(), new_cfg.enc_key.data());
|
||||
new_cfg.enc_key = enc_key;
|
||||
}
|
||||
else if (new_snap != "")
|
||||
{
|
||||
new_cfg.enc_key = cur_cfg.enc_key;
|
||||
}
|
||||
json11::Json::array checks = json11::Json::array {
|
||||
json11::Json::object {
|
||||
{ "target", "VERSION" },
|
||||
@@ -600,19 +601,6 @@ std::function<bool(cli_result_t &)> cli_tool_t::start_create(json11::Json cfg)
|
||||
if (!cfg["enc_key"].is_null())
|
||||
{
|
||||
image_creator->set_key = true;
|
||||
image_creator->enc_key = cfg["enc_key"].string_value();
|
||||
if (image_creator->enc_key != "" &&
|
||||
#ifdef WITH_OPENSSL
|
||||
image_creator->enc_key != "random" &&
|
||||
#endif
|
||||
(!ishexstr(image_creator->enc_key) || image_creator->enc_key.size() != 128))
|
||||
{
|
||||
return [](cli_result_t & result)
|
||||
{
|
||||
result = (cli_result_t){ .err = EINVAL, .text = "Encryption key is not a 512-bit hex string, not \"\" and not \"random\"" };
|
||||
return true;
|
||||
};
|
||||
}
|
||||
#ifdef WITH_OPENSSL
|
||||
if (image_creator->enc_key == "random")
|
||||
{
|
||||
@@ -621,6 +609,20 @@ std::function<bool(cli_result_t &)> cli_tool_t::start_create(json11::Json cfg)
|
||||
image_creator->enc_key = tohexstr(newkey, 64);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
image_creator->enc_key = cfg["enc_key"].string_value();
|
||||
if (image_creator->enc_key != "" &&
|
||||
image_creator->enc_key.substr(0, strlen(VAULT_KEY_PREFIX)) != VAULT_KEY_PREFIX &&
|
||||
(!ishexstr(image_creator->enc_key) || image_creator->enc_key.size() != 128))
|
||||
{
|
||||
return [](cli_result_t & result)
|
||||
{
|
||||
result = (cli_result_t){ .err = EINVAL, .text = "Encryption key is not a 512-bit hex string, not \"\" and not \"random\"" };
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
image_creator->new_parent = cfg["parent"].string_value();
|
||||
if (!cfg["size"].is_null())
|
||||
|
||||
@@ -159,14 +159,15 @@ resume_1:
|
||||
state = 100;
|
||||
return;
|
||||
}
|
||||
if (enc_key != "" && (!ishexstr(enc_key) || enc_key.size() != 128))
|
||||
if (enc_key != "" &&
|
||||
enc_key.substr(0, strlen(VAULT_KEY_PREFIX)) != VAULT_KEY_PREFIX &&
|
||||
(!ishexstr(enc_key) || enc_key.size() != 128))
|
||||
{
|
||||
result = (cli_result_t){ .err = EINVAL, .text = "Encryption key is not a 512-bit hex string and not \"\"" };
|
||||
state = 100;
|
||||
return;
|
||||
}
|
||||
cfg.enc_key.resize(enc_key.size()/2);
|
||||
fromhexstr(enc_key, cfg.enc_key.size(), cfg.enc_key.data());
|
||||
cfg.enc_key = enc_key;
|
||||
}
|
||||
{
|
||||
std::string cur_cfg_key = base64_encode(parent->cli->st_cli.etcd_prefix+
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
"description": "Encryption key for the new/cloned image",
|
||||
"oneOf": [
|
||||
{ "type": "string", "enum": [ "", "random" ] },
|
||||
{ "type": "string", "pattern": "^[0-9a-fA-F]{128}$" }
|
||||
{ "type": "string", "pattern": "^[0-9a-fA-F]{128}$|^vault:" }
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -143,7 +143,7 @@
|
||||
"description": "Change encryption key for the image",
|
||||
"oneOf": [
|
||||
{ "type": "string", "enum": [ "" ] },
|
||||
{ "type": "string", "pattern": "^[0-9a-fA-F]{128}$" }
|
||||
{ "type": "string", "pattern": "^[0-9a-fA-F]{128}$|^vault:" }
|
||||
]
|
||||
},
|
||||
"force": { "type": "boolean", "description": "Proceed with shrinking or setting readwrite flag even if the image has children" },
|
||||
|
||||
Reference in New Issue
Block a user