From daada7af01a6588a3beb652761df831ee56b07fb Mon Sep 17 00:00:00 2001 From: Marcus Watts Date: Sat, 12 Jun 2021 03:43:13 -0400 Subject: [PATCH] rgw: sse-s3: Introducing SSE-S3 RGW options and using them +configuration options +kms support for sse-s3 operations. +support to create and delete vault keys. Signed-off-by: Marcus Watts --- doc/radosgw/config-ref.rst | 16 ++ src/common/options/rgw.yaml.in | 149 ++++++++++++++ src/rgw/rgw_kms.cc | 348 ++++++++++++++++++++++++++++++--- src/rgw/rgw_kms.h | 12 ++ 4 files changed, 498 insertions(+), 27 deletions(-) diff --git a/doc/radosgw/config-ref.rst b/doc/radosgw/config-ref.rst index 295fa8ce2d7..9d127aa04cf 100644 --- a/doc/radosgw/config-ref.rst +++ b/doc/radosgw/config-ref.rst @@ -229,6 +229,22 @@ HashiCorp Vault Settings .. confval:: rgw_crypt_vault_secret_engine .. confval:: rgw_crypt_vault_namespace +SSE-S3 Settings +=============== + +.. confval:: rgw_crypt_sse_s3_backend +.. confval:: rgw_crypt_sse_s3_vault_secret_engine +.. confval:: rgw_crypt_sse_s3_key_template +.. confval:: rgw_crypt_sse_s3_vault_auth +.. confval:: rgw_crypt_sse_s3_vault_token_file +.. confval:: rgw_crypt_sse_s3_vault_addr +.. confval:: rgw_crypt_sse_s3_vault_prefix +.. confval:: rgw_crypt_sse_s3_vault_namespace +.. confval:: rgw_crypt_sse_s3_vault_verify_ssl +.. confval:: rgw_crypt_sse_s3_vault_ssl_cacert +.. confval:: rgw_crypt_sse_s3_vault_ssl_clientcert +.. confval:: rgw_crypt_sse_s3_vault_ssl_clientkey + QoS settings ------------ diff --git a/src/common/options/rgw.yaml.in b/src/common/options/rgw.yaml.in index 1e17bc04a2d..6e5d74444a8 100644 --- a/src/common/options/rgw.yaml.in +++ b/src/common/options/rgw.yaml.in @@ -2734,6 +2734,155 @@ options: services: - rgw with_legacy: true +- name: rgw_crypt_sse_s3_backend + type: str + level: advanced + desc: Where the SSE-S3 encryption keys are stored. The only valid choice here is + HashiCorp Vault ('vault'). + fmt_desc: Where the SSE-S3 encryption keys are stored. The only valid + choice is HashiCorp Vault (``vault``). + default: vault + services: + - rgw + enum_values: + - vault + with_legacy: true + +- name: rgw_crypt_sse_s3_vault_secret_engine + type: str + level: advanced + desc: Vault Secret Engine to be used to retrieve encryption keys. + fmt_desc: | + Vault Secret Engine to be used to retrieve encryption keys. The + only valid choice here is transit. + default: transit + services: + - rgw + see_also: + - rgw_crypt_sse_s3_backend + - rgw_crypt_sse_s3_vault_auth + - rgw_crypt_sse_s3_vault_addr + with_legacy: true +- name: rgw_crypt_sse_s3_key_template + type: str + level: advanced + desc: template for per-bucket sse-s3 keys in vault. + long_desc: This is the template for per-bucket sse-s3 keys. + This string may include ``%bucket_id`` which will be expanded out to + the bucket marker, a unique uuid assigned to that bucket. + It could contain ``%owner_id``, which will expand out to the owner's id. + Any other use of % is reserved and should not be used. + If the template contains ``%bucket_id``, associated bucket keys + will be automatically removed when the bucket is removed. + services: + - rgw + default: "%bucket_id" + see_also: + - rgw_crypt_sse_s3_backend + - rgw_crypt_sse_s3_vault_auth + - rgw_crypt_sse_s3_vault_addr + with_legacy: true +- name: rgw_crypt_sse_s3_vault_auth + type: str + level: advanced + desc: Type of authentication method to be used with SSE-S3 and Vault. + fmt_desc: Type of authentication method to be used. The only method + currently supported is ``token``. + default: token + services: + - rgw + see_also: + - rgw_crypt_sse_s3_backend + - rgw_crypt_sse_s3_vault_addr + - rgw_crypt_sse_s3_vault_token_file + enum_values: + - token + - agent + with_legacy: true +- name: rgw_crypt_sse_s3_vault_token_file + type: str + level: advanced + desc: If authentication method is 'token', provide a path to the token file, which + for security reasons should readable only by Rados Gateway. + services: + - rgw + see_also: + - rgw_crypt_sse_s3_backend + - rgw_crypt_sse_s3_vault_auth + - rgw_crypt_sse_s3_vault_addr + with_legacy: true +- name: rgw_crypt_sse_s3_vault_addr + type: str + level: advanced + desc: SSE-S3 Vault server base address. + fmt_desc: Vault server base address, e.g. ``http://vaultserver:8200``. + services: + - rgw + see_also: + - rgw_crypt_sse_s3_backend + - rgw_crypt_sse_s3_vault_auth + - rgw_crypt_sse_s3_vault_prefix + with_legacy: true +# Optional URL prefix to Vault secret path +- name: rgw_crypt_sse_s3_vault_prefix + type: str + level: advanced + desc: SSE-S3 Vault secret URL prefix, which can be used to restrict access to a particular + subset of the Vault secret space. + fmt_desc: The Vault secret URL prefix, which can be used to restrict access + to a particular subset of the secret space, e.g. ``/v1/secret/data``. + services: + - rgw + see_also: + - rgw_crypt_sse_s3_backend + - rgw_crypt_sse_s3_vault_addr + - rgw_crypt_sse_s3_vault_auth + with_legacy: true +# Vault Namespace (only availabe in Vault Enterprise Version) +- name: rgw_crypt_sse_s3_vault_namespace + type: str + level: advanced + desc: Vault Namespace to be used to select your tenant + fmt_desc: If set, Vault Namespace provides tenant isolation for teams and individuals + on the same Vault Enterprise instance, e.g. ``acme/tenant1`` + services: + - rgw + see_also: + - rgw_crypt_sse_s3_backend + - rgw_crypt_sse_s3_vault_auth + - rgw_crypt_sse_s3_vault_addr + with_legacy: true +# Enable TLS authentication rgw and vault +- name: rgw_crypt_sse_s3_vault_verify_ssl + type: bool + level: advanced + desc: Should RGW verify the vault server SSL certificate. + default: true + services: + - rgw + with_legacy: true +# TLS certs options +- name: rgw_crypt_sse_s3_vault_ssl_cacert + type: str + level: advanced + desc: Path for custom ca certificate for accessing vault server + services: + - rgw + with_legacy: true +- name: rgw_crypt_sse_s3_vault_ssl_clientcert + type: str + level: advanced + desc: Path for custom client certificate for accessing vault server + services: + - rgw + with_legacy: true +- name: rgw_crypt_sse_s3_vault_ssl_clientkey + type: str + level: advanced + desc: Path for private key required for client cert + services: + - rgw + with_legacy: true - name: rgw_list_bucket_min_readahead type: int level: advanced diff --git a/src/rgw/rgw_kms.cc b/src/rgw/rgw_kms.cc index dc23f450bdc..0195d8764fb 100644 --- a/src/rgw/rgw_kms.cc +++ b/src/rgw/rgw_kms.cc @@ -149,6 +149,17 @@ add_name_val_to_obj(std::string &n, std::string &v, rapidjson::GenericValue d.AddMember(name, val, allocator); } +template +static inline void +add_name_val_to_obj(std::string &n, bool v, rapidjson::GenericValue &d, + A &allocator) +{ + rapidjson::GenericValue name, val; + name.SetString(n.c_str(), n.length(), allocator); + val.SetBool(v); + d.AddMember(name, val, allocator); +} + template static inline void add_name_val_to_obj(const char *n, std::string &v, rapidjson::GenericValue &d, @@ -158,18 +169,46 @@ add_name_val_to_obj(const char *n, std::string &v, rapidjson::GenericValue add_name_val_to_obj(ns, v, d, allocator); } +template +static inline void +add_name_val_to_obj(const char *n, bool v, rapidjson::GenericValue &d, + A &allocator) +{ + std::string ns{n, strlen(n) }; + add_name_val_to_obj(ns, v, d, allocator); +} + typedef std::map EngineParmMap; + +class SSEContext { +protected: + virtual ~SSEContext(){}; +public: + virtual std::string & backend() = 0; + virtual std::string & addr() = 0; + virtual std::string & auth() = 0; + virtual std::string & k_namespace() = 0; + virtual std::string & prefix() = 0; + virtual const std::string & secret_engine() = 0; + virtual std::string & ssl_cacert() = 0; + virtual std::string & ssl_clientcert() = 0; + virtual std::string & ssl_clientkey() = 0; + virtual std::string & token_file() = 0; + virtual bool verify_ssl() = 0; +}; + class VaultSecretEngine: public SecretEngine { protected: CephContext *cct; + SSEContext & kctx; int load_token_from_file(const DoutPrefixProvider *dpp, std::string *vault_token) { int res = 0; - std::string token_file = cct->_conf->rgw_crypt_vault_token_file; + std::string token_file = kctx.token_file(); if (token_file.empty()) { ldpp_dout(dpp, 0) << "ERROR: Vault token file not set in rgw_crypt_vault_token_file" << dendl; return -EINVAL; @@ -216,7 +255,7 @@ protected: { int res; string vault_token = ""; - if (RGW_SSE_KMS_VAULT_AUTH_TOKEN == cct->_conf->rgw_crypt_vault_auth){ + if (RGW_SSE_KMS_VAULT_AUTH_TOKEN == kctx.auth()){ ldpp_dout(dpp, 0) << "Loading Vault Token from filesystem" << dendl; res = load_token_from_file(dpp, &vault_token); if (res < 0){ @@ -224,13 +263,13 @@ protected: } } - std::string secret_url = cct->_conf->rgw_crypt_vault_addr; + std::string secret_url = kctx.addr(); if (secret_url.empty()) { ldpp_dout(dpp, 0) << "ERROR: Vault address not set in rgw_crypt_vault_addr" << dendl; return -EINVAL; } - concat_url(secret_url, cct->_conf->rgw_crypt_vault_prefix); + concat_url(secret_url, kctx.prefix()); concat_url(secret_url, std::string(infix)); concat_url(secret_url, std::string(key_id)); @@ -247,23 +286,23 @@ protected: vault_token.replace(0, vault_token.length(), vault_token.length(), '\000'); } - string vault_namespace = cct->_conf->rgw_crypt_vault_namespace; + string vault_namespace = kctx.k_namespace(); if (!vault_namespace.empty()){ ldpp_dout(dpp, 20) << "Vault Namespace: " << vault_namespace << dendl; secret_req.append_header("X-Vault-Namespace", vault_namespace); } - secret_req.set_verify_ssl(cct->_conf->rgw_crypt_vault_verify_ssl); + secret_req.set_verify_ssl(kctx.verify_ssl()); - if (!cct->_conf->rgw_crypt_vault_ssl_cacert.empty()) { - secret_req.set_ca_path(cct->_conf->rgw_crypt_vault_ssl_cacert); + if (!kctx.ssl_cacert().empty()) { + secret_req.set_ca_path(kctx.ssl_cacert()); } - if (!cct->_conf->rgw_crypt_vault_ssl_clientcert.empty()) { - secret_req.set_client_cert(cct->_conf->rgw_crypt_vault_ssl_clientcert); + if (!kctx.ssl_clientcert().empty()) { + secret_req.set_client_cert(kctx.ssl_clientcert()); } - if (!cct->_conf->rgw_crypt_vault_ssl_clientkey.empty()) { - secret_req.set_client_key(cct->_conf->rgw_crypt_vault_ssl_clientkey); + if (!kctx.ssl_clientkey().empty()) { + secret_req.set_client_key(kctx.ssl_clientkey()); } res = secret_req.process(null_yield); @@ -302,8 +341,7 @@ protected: public: - VaultSecretEngine(CephContext *cct) { - this->cct = cct; + VaultSecretEngine(CephContext *_c, SSEContext & _k) : cct(_c), kctx(_k) { } }; @@ -334,7 +372,7 @@ private: } public: - TransitSecretEngine(CephContext *cct, EngineParmMap parms): VaultSecretEngine(cct), parms(parms) { + TransitSecretEngine(CephContext *cct, SSEContext & kctx, EngineParmMap parms): VaultSecretEngine(cct, kctx), parms(parms) { compat = COMPAT_UNSET; for (auto& e: parms) { if (e.first == "compat") { @@ -355,7 +393,7 @@ public: << e.first << "=" << e.second << " ignored" << dendl; } if (compat == COMPAT_UNSET) { - std::string_view v { cct->_conf->rgw_crypt_vault_prefix }; + std::string_view v { kctx.prefix() }; if (string_ends_maybe_slash(v,"/export/encryption-key")) { compat = COMPAT_ONLY_OLD; } else { @@ -573,13 +611,102 @@ public: return decode_secret(dpp, plaintext_v.GetString(), actual_key); } } + + int create_bucket_key(const DoutPrefixProvider *dpp, const std::string& key_name) + { +/* + .data.ciphertext <- (to-be) named attribute + data: {"type": "chacha20-poly1305", "derived": true} + post to prefix + key_name + empty output. +*/ + ZeroPoolDocument d { rapidjson::kObjectType }; + auto &allocator { d.GetAllocator() }; + bufferlist dummy_bl; + std::string chacha20_poly1305 { "chacha20-poly1305" }; + + add_name_val_to_obj("type", chacha20_poly1305, d, allocator); + add_name_val_to_obj("derived", true, d, allocator); + rapidjson::StringBuffer buf; + rapidjson::Writer writer(buf); + if (!d.Accept(writer)) { + ldpp_dout(dpp, 0) << "ERROR: can't make json for vault" << dendl; + return -EINVAL; + } + std::string post_data { buf.GetString() }; + + int res = send_request(dpp, "POST", "/keys/", key_name, + post_data, dummy_bl); + if (res < 0) { + return res; + } + if (dummy_bl.length() != 0) { + ldpp_dout(dpp, 0) << "ERROR: unexpected response from Vault making a key: " + << dummy_bl + << dendl; + } + return 0; + } + + int delete_bucket_key(const DoutPrefixProvider *dpp, const std::string& key_name) + { +/* + /keys//config + data: {"deletion_allowed": true} + post to prefix + key_name + empty output. +*/ + ZeroPoolDocument d { rapidjson::kObjectType }; + auto &allocator { d.GetAllocator() }; + bufferlist dummy_bl; + std::ostringstream path_temp; + path_temp << "/keys/"; + path_temp << key_name; + std::string delete_path { path_temp.str() }; + path_temp << "/config"; + std::string config_path { path_temp.str() }; + + add_name_val_to_obj("deletion_allowed", true, d, allocator); + rapidjson::StringBuffer buf; + rapidjson::Writer writer(buf); + if (!d.Accept(writer)) { + ldpp_dout(dpp, 0) << "ERROR: can't make json for vault" << dendl; + return -EINVAL; + } + std::string post_data { buf.GetString() }; + + int res = send_request(dpp, "POST", "", config_path, + post_data, dummy_bl); + if (res < 0) { + return res; + } + if (dummy_bl.length() != 0) { + ldpp_dout(dpp, 0) << "ERROR: unexpected response from Vault marking key to delete: " + << dummy_bl + << dendl; + return -EINVAL; + } + + res = send_request(dpp, "DELETE", "", delete_path, + string{}, dummy_bl); + if (res < 0) { + return res; + } + if (dummy_bl.length() != 0) { + ldpp_dout(dpp, 0) << "ERROR: unexpected response from Vault deleting key: " + << dummy_bl + << dendl; + return -EINVAL; + } + return 0; + } }; class KvSecretEngine: public VaultSecretEngine { public: - KvSecretEngine(CephContext *cct, EngineParmMap parms): VaultSecretEngine(cct){ + KvSecretEngine(CephContext *cct, SSEContext & kctx, EngineParmMap parms): VaultSecretEngine(cct, kctx){ if (!parms.empty()) { lderr(cct) << "ERROR: vault kv secrets engine takes no parameters (ignoring them)" << dendl; } @@ -876,24 +1003,25 @@ std::string config_to_engine_and_parms(CephContext *cct, static int get_actual_key_from_vault(const DoutPrefixProvider *dpp, CephContext *cct, + SSEContext & kctx, map& attrs, std::string& actual_key, bool make_it) { - std::string secret_engine_str = cct->_conf->rgw_crypt_vault_secret_engine; + std::string secret_engine_str = kctx.secret_engine(); EngineParmMap secret_engine_parms; auto secret_engine { config_to_engine_and_parms( cct, "rgw_crypt_vault_secret_engine", secret_engine_str, secret_engine_parms) }; - ldpp_dout(dpp, 20) << "Vault authentication method: " << cct->_conf->rgw_crypt_vault_auth << dendl; + ldpp_dout(dpp, 20) << "Vault authentication method: " << kctx.auth() << dendl; ldpp_dout(dpp, 20) << "Vault Secrets Engine: " << secret_engine << dendl; if (RGW_SSE_KMS_VAULT_SE_KV == secret_engine){ std::string key_id = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYID); - KvSecretEngine engine(cct, std::move(secret_engine_parms)); + KvSecretEngine engine(cct, kctx, std::move(secret_engine_parms)); return engine.get_key(dpp, key_id, actual_key); } else if (RGW_SSE_KMS_VAULT_SE_TRANSIT == secret_engine){ - TransitSecretEngine engine(cct, std::move(secret_engine_parms)); + TransitSecretEngine engine(cct, kctx, std::move(secret_engine_parms)); std::string key_id = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYID); return make_it ? engine.make_actual_key(dpp, attrs, actual_key) @@ -908,19 +1036,21 @@ static int get_actual_key_from_vault(const DoutPrefixProvider *dpp, static int make_actual_key_from_vault(const DoutPrefixProvider *dpp, CephContext *cct, + SSEContext & kctx, map& attrs, std::string& actual_key) { - return get_actual_key_from_vault(dpp, cct, attrs, actual_key, true); + return get_actual_key_from_vault(dpp, cct, kctx, attrs, actual_key, true); } static int reconstitute_actual_key_from_vault(const DoutPrefixProvider *dpp, CephContext *cct, + SSEContext & kctx, map& attrs, std::string& actual_key) { - return get_actual_key_from_vault(dpp, cct, attrs, actual_key, false); + return get_actual_key_from_vault(dpp, cct, kctx, attrs, actual_key, false); } @@ -940,14 +1070,95 @@ static int get_actual_key_from_kmip(const DoutPrefixProvider *dpp, return -EINVAL; } } +class KMSContext : public SSEContext { + CephContext *cct; +public: + KMSContext(CephContext*_cct) : cct{_cct} {}; + ~KMSContext() override {}; + std::string & backend() override { + return cct->_conf->rgw_crypt_s3_kms_backend; + }; + std::string & addr() override { + return cct->_conf->rgw_crypt_vault_addr; + }; + std::string & auth() override { + return cct->_conf->rgw_crypt_vault_auth; + }; + std::string & k_namespace() override { + return cct->_conf->rgw_crypt_vault_namespace; + }; + std::string & prefix() override { + return cct->_conf->rgw_crypt_vault_prefix; + }; + const std::string & secret_engine() override { + return cct->_conf->rgw_crypt_vault_secret_engine; + }; + std::string & ssl_cacert() override { + return cct->_conf->rgw_crypt_vault_ssl_cacert; + }; + std::string & ssl_clientcert() override { + return cct->_conf->rgw_crypt_vault_ssl_clientcert; + }; + std::string & ssl_clientkey() override { + return cct->_conf->rgw_crypt_vault_ssl_clientkey; + }; + std::string & token_file() override { + return cct->_conf->rgw_crypt_vault_token_file; + }; + bool verify_ssl() override { + return cct->_conf->rgw_crypt_vault_verify_ssl; + }; +}; +class SseS3Context : public SSEContext { + CephContext *cct; +public: + static const std::string sse_s3_secret_engine; + SseS3Context(CephContext*_cct) : cct{_cct} {}; + ~SseS3Context(){}; + std::string & backend() override { + return cct->_conf->rgw_crypt_sse_s3_backend; + }; + std::string & addr() override { + return cct->_conf->rgw_crypt_sse_s3_vault_addr; + }; + std::string & auth() override { + return cct->_conf->rgw_crypt_sse_s3_vault_auth; + }; + std::string & k_namespace() override { + return cct->_conf->rgw_crypt_sse_s3_vault_namespace; + }; + std::string & prefix() override { + return cct->_conf->rgw_crypt_sse_s3_vault_prefix; + }; + const std::string & secret_engine() override { + return sse_s3_secret_engine; + }; + std::string & ssl_cacert() override { + return cct->_conf->rgw_crypt_sse_s3_vault_ssl_cacert; + }; + std::string & ssl_clientcert() override { + return cct->_conf->rgw_crypt_sse_s3_vault_ssl_clientcert; + }; + std::string & ssl_clientkey() override { + return cct->_conf->rgw_crypt_sse_s3_vault_ssl_clientkey; + }; + std::string & token_file() override { + return cct->_conf->rgw_crypt_sse_s3_vault_token_file; + }; + bool verify_ssl() override { + return cct->_conf->rgw_crypt_sse_s3_vault_verify_ssl; + }; +}; +const std::string SseS3Context::sse_s3_secret_engine = "transit"; int reconstitute_actual_key_from_kms(const DoutPrefixProvider *dpp, CephContext *cct, map& attrs, std::string& actual_key) { std::string key_id = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYID); - std::string kms_backend { cct->_conf->rgw_crypt_s3_kms_backend }; + KMSContext kctx { cct }; + std::string &kms_backend { kctx.backend() }; ldpp_dout(dpp, 20) << "Getting KMS encryption key for key " << key_id << dendl; ldpp_dout(dpp, 20) << "SSE-KMS backend is " << kms_backend << dendl; @@ -957,7 +1168,7 @@ int reconstitute_actual_key_from_kms(const DoutPrefixProvider *dpp, CephContext } if (RGW_SSE_KMS_BACKEND_VAULT == kms_backend) { - return reconstitute_actual_key_from_vault(dpp, cct, attrs, actual_key); + return reconstitute_actual_key_from_vault(dpp, cct, kctx, attrs, actual_key); } if (RGW_SSE_KMS_BACKEND_KMIP == kms_backend) { @@ -977,8 +1188,91 @@ int make_actual_key_from_kms(const DoutPrefixProvider *dpp, CephContext *cct, map& attrs, std::string& actual_key) { - std::string kms_backend { cct->_conf->rgw_crypt_s3_kms_backend }; + KMSContext kctx { cct }; + std::string &kms_backend { kctx.backend() }; if (RGW_SSE_KMS_BACKEND_VAULT == kms_backend) - return make_actual_key_from_vault(dpp, cct, attrs, actual_key); + return make_actual_key_from_vault(dpp, cct, kctx, attrs, actual_key); return reconstitute_actual_key_from_kms(dpp, cct, attrs, actual_key); } + +int reconstitute_actual_key_from_sse_s3(const DoutPrefixProvider *dpp, + CephContext *cct, + map& attrs, + std::string& actual_key) +{ + std::string key_id = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYID); + SseS3Context kctx { cct }; + std::string &kms_backend { kctx.backend() }; + + ldpp_dout(dpp, 20) << "Getting SSE-S3 encryption key for key " << key_id << dendl; + ldpp_dout(dpp, 20) << "SSE-KMS backend is " << kms_backend << dendl; + + if (RGW_SSE_KMS_BACKEND_VAULT == kms_backend) { + return reconstitute_actual_key_from_vault(dpp, cct, kctx, attrs, actual_key); + } + + ldpp_dout(dpp, 0) << "ERROR: Invalid rgw_crypt_sse_s3_backend: " << kms_backend << dendl; + return -EINVAL; +} + +int make_actual_key_from_sse_s3(const DoutPrefixProvider *dpp, + CephContext *cct, + map& attrs, + std::string& actual_key) +{ + SseS3Context kctx { cct }; + std::string kms_backend { kctx.backend() }; + if (RGW_SSE_KMS_BACKEND_VAULT != kms_backend) { + ldpp_dout(dpp, 0) << "ERROR: Unsupported rgw_crypt_sse_s3_backend: " << kms_backend << dendl; + return -EINVAL; + } + return make_actual_key_from_vault(dpp, cct, kctx, attrs, actual_key); +} + + +int create_ss3_s3_bucket_key(const DoutPrefixProvider *dpp, + CephContext *cct, + const std::string& bucket_key) +{ + SseS3Context kctx { cct }; + + const std::string kms_backend { kctx.backend() }; + if (RGW_SSE_KMS_BACKEND_VAULT != kms_backend) { + ldpp_dout(dpp, 0) << "ERROR: Unsupported rgw_crypt_sse_s3_backend: " << kms_backend << dendl; + return -EINVAL; + } + + std::string secret_engine_str = kctx.secret_engine(); + EngineParmMap secret_engine_parms; + auto secret_engine { config_to_engine_and_parms( + cct, "rgw_crypt_vault_secret_engine", // XXX wrong, but... + secret_engine_str, secret_engine_parms) }; + if (RGW_SSE_KMS_VAULT_SE_TRANSIT == secret_engine){ + TransitSecretEngine engine(cct, kctx, std::move(secret_engine_parms)); + return engine.create_bucket_key(dpp, bucket_key); + } + else { + ldpp_dout(dpp, 0) << "Missing or invalid secret engine" << dendl; + return -EINVAL; + } +} + +int remove_ss3_s3_bucket_key(const DoutPrefixProvider *dpp, + CephContext *cct, + const std::string& bucket_key) +{ + SseS3Context kctx { cct }; + std::string secret_engine_str = kctx.secret_engine(); + EngineParmMap secret_engine_parms; + auto secret_engine { config_to_engine_and_parms( + cct, "rgw_crypt_vault_secret_engine", // XXX wrong, but... + secret_engine_str, secret_engine_parms) }; + if (RGW_SSE_KMS_VAULT_SE_TRANSIT == secret_engine){ + TransitSecretEngine engine(cct, kctx, std::move(secret_engine_parms)); + return engine.delete_bucket_key(dpp, bucket_key); + } + else { + ldpp_dout(dpp, 0) << "Missing or invalid secret engine" << dendl; + return -EINVAL; + } +} diff --git a/src/rgw/rgw_kms.h b/src/rgw/rgw_kms.h index 3d714ee3adc..ba9b436139e 100644 --- a/src/rgw/rgw_kms.h +++ b/src/rgw/rgw_kms.h @@ -39,6 +39,18 @@ int make_actual_key_from_kms(const DoutPrefixProvider *dpp, CephContext *cct, int reconstitute_actual_key_from_kms(const DoutPrefixProvider *dpp, CephContext *cct, std::map& attrs, std::string& actual_key); +int make_actual_key_from_sse_s3(const DoutPrefixProvider *dpp, CephContext *cct, + std::map& attrs, + std::string& actual_key); +int reconstitute_actual_key_from_sse_s3(const DoutPrefixProvider *dpp, CephContext *cct, + std::map& attrs, + std::string& actual_key); + +int create_sse_s3_bucket_key(const DoutPrefixProvider *dpp, CephContext *cct, + const std::string& actual_key); + +int remove_sse_s3_bucket_key(const DoutPrefixProvider *dpp, CephContext *cct, + const std::string& actual_key); /** * SecretEngine Interface -- 2.39.5