]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw: sse-s3: Introducing SSE-S3 RGW options and using them
authorMarcus Watts <mwatts@redhat.com>
Sat, 12 Jun 2021 07:43:13 +0000 (03:43 -0400)
committerMarcus Watts <mwatts@redhat.com>
Tue, 19 Apr 2022 21:35:39 +0000 (17:35 -0400)
+configuration options
+kms support for sse-s3 operations.
+support to create and delete vault keys.

Signed-off-by: Marcus Watts <mwatts@redhat.com>
doc/radosgw/config-ref.rst
src/common/options/rgw.yaml.in
src/rgw/rgw_kms.cc
src/rgw/rgw_kms.h

index 295fa8ce2d77e64693e7fe32dc7879303c414189..9d127aa04cff37524aff66914c697cc575047fbd 100644 (file)
@@ -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
 ------------
index 1e17bc04a2d3b3cb0b0feb6271d8c39f8ad45e20..6e5d74444a88247f52cf0531cf7ac0ebadd421a7 100644 (file)
@@ -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
index dc23f450bdcd1adcdc143316aaac6a2fa136db19..0195d8764fb08e9fd55ff0fb3456eaaaf1c84fed 100644 (file)
@@ -149,6 +149,17 @@ add_name_val_to_obj(std::string &n, std::string &v, rapidjson::GenericValue<E,A>
   d.AddMember(name, val, allocator);
 }
 
+template<typename E, typename A = ZeroPoolAllocator>
+static inline void
+add_name_val_to_obj(std::string &n, bool v, rapidjson::GenericValue<E,A> &d,
+  A &allocator)
+{
+  rapidjson::GenericValue<E,A> name, val;
+  name.SetString(n.c_str(), n.length(), allocator);
+  val.SetBool(v);
+  d.AddMember(name, val, allocator);
+}
+
 template<typename E, typename A = ZeroPoolAllocator>
 static inline void
 add_name_val_to_obj(const char *n, std::string &v, rapidjson::GenericValue<E,A> &d,
@@ -158,18 +169,46 @@ add_name_val_to_obj(const char *n, std::string &v, rapidjson::GenericValue<E,A>
   add_name_val_to_obj(ns, v, d, allocator);
 }
 
+template<typename E, typename A = ZeroPoolAllocator>
+static inline void
+add_name_val_to_obj(const char *n, bool v, rapidjson::GenericValue<E,A> &d,
+  A &allocator)
+{
+  std::string ns{n, strlen(n) };
+  add_name_val_to_obj(ns, v, d, allocator);
+}
+
 typedef std::map<std::string, std::string> 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<rapidjson::StringBuffer> 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/<keyname>/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<rapidjson::StringBuffer> 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<string, bufferlist>& 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<string, bufferlist>& 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<string, bufferlist>& 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<string, bufferlist>& 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<string, bufferlist>& 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<string, bufferlist>& 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<string, bufferlist>& 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;
+  }
+}
index 3d714ee3adc284f82f482374f324e5577017d855..ba9b436139ed76be67eaaa1904975b371d47279f 100644 (file)
@@ -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<std::string, bufferlist>& attrs,
                             std::string& actual_key);
+int make_actual_key_from_sse_s3(const DoutPrefixProvider *dpp, CephContext *cct,
+                            std::map<std::string, bufferlist>& attrs,
+                            std::string& actual_key);
+int reconstitute_actual_key_from_sse_s3(const DoutPrefixProvider *dpp, CephContext *cct,
+                            std::map<std::string, bufferlist>& 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