From: Marcus Watts Date: Sun, 7 Sep 2025 07:42:06 +0000 (-0400) Subject: copy object encryption fixes - complete multipart upload attributes X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4c2ae826644910ab30965a2679d07581525a9ed3;p=ceph-ci.git copy object encryption fixes - complete multipart upload attributes complete multipart upload should return encryption attributes in its results. XXX fixup merge w/ copy object encryption fixes Fixes: https://tracker.ceph.com/issues/23264 Signed-off-by: Marcus Watts (cherry picked from commit 656214697d323638377dfb9375219a145efa7933) --- diff --git a/src/rgw/rgw_crypt.cc b/src/rgw/rgw_crypt.cc index bb8ee844253..0657c7a9f11 100644 --- a/src/rgw/rgw_crypt.cc +++ b/src/rgw/rgw_crypt.cc @@ -1516,6 +1516,39 @@ int rgw_s3_prepare_decrypt(req_state* s, optional_yield y, return res; } +// dummy routine does not really prepare for decrypt, juste sets +// crypt_http_responses (for RGWCompleteMultipart) +int rgw_s3_prepare_decrypt(req_state* s, + map& attrs, + std::map& crypt_http_responses) +{ + // RGWDecryptContext cb(s); + int res = 0; + std::string stored_mode = get_str_attribute(attrs, RGW_ATTR_CRYPT_MODE); + ldpp_dout(s, 15) << "Encryption mode: " << stored_mode << dendl; + if (stored_mode == "SSE-C-AES256") { + auto keymd5 = to_base64(get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYMD5)); + crypt_http_responses["x-amz-server-side-encryption-customer-algorithm"] = "AES256"; + crypt_http_responses["x-amz-server-side-encryption-customer-key-MD5"] = keymd5; + return 0; + } + if (stored_mode == "SSE-KMS") { + std::string key_id = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYID); + crypt_http_responses["x-amz-server-side-encryption"] = "aws:kms"; + crypt_http_responses["x-amz-server-side-encryption-aws-kms-key-id"] = key_id; + return 0; + } + if (stored_mode == "RGW-AUTO") { + return 0; + } + if (stored_mode == "AES256") { + crypt_http_responses["x-amz-server-side-encryption"] = "AES256"; + return 0; + } + /*no decryption*/ + return 0; +} + int rgw_remove_sse_s3_bucket_key(req_state *s, optional_yield y) { int res; diff --git a/src/rgw/rgw_crypt.h b/src/rgw/rgw_crypt.h index 37544bc3968..8cec301aa3d 100644 --- a/src/rgw/rgw_crypt.h +++ b/src/rgw/rgw_crypt.h @@ -218,6 +218,11 @@ int rgw_s3_prepare_decrypt(RGWDecryptContext &cb, optional_yield y, std::map& crypt_http_responses); +int rgw_s3_prepare_decrypt(req_state *s, + std::map& attrs, + std::map& crypt_http_responses); + static inline void set_attr(std::map& attrs, const char* key, std::string_view value) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 7055ce8d27e..6bbb9d0bdec 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -7575,6 +7575,8 @@ void RGWCompleteMultipart::execute(optional_yield y) auto& target_attrs = meta_obj->get_attrs(); + (void) rgw_s3_prepare_decrypt(s, target_attrs, crypt_http_responses); + if (cksum) { /* validate computed checksum against supplied checksum, if present */ auto [hdr_cksum, supplied_cksum] = diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index f53e7f97246..fd8a48b606a 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -1964,6 +1964,7 @@ protected: std::optional cksum; std::optional armored_cksum; off_t ofs = 0; + std::map crypt_http_responses; public: RGWCompleteMultipart() {} diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index ce3fb946c23..068a76d1e00 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -4618,6 +4618,8 @@ void RGWCompleteMultipart_ObjStore_S3::send_response() if (op_ret) set_req_state_err(s, op_ret); dump_errno(s); + for (auto &it : crypt_http_responses) + dump_header(s, it.first, it.second); dump_header_if_nonempty(s, "x-amz-version-id", version_id); end_header(s, this, to_mime_type(s->format)); if (op_ret == 0) {