From: Matt Benjamin Date: Thu, 5 Sep 2019 15:38:56 +0000 (-0400) Subject: rgw: crypt: permit RGW-AUTO/default with SSE-S3 headers X-Git-Tag: v12.2.13~12^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=a26fb4d72bb19c80327417be4cb9a2697825e57a;p=ceph.git rgw: crypt: permit RGW-AUTO/default with SSE-S3 headers Permit the existing logic for encrypton by a global master key to take effect when a client has requested AES256 server-side encryption with S3 managed keys, as well as SSE-KMS. Fixes: https://tracker.ceph.com/issues/41670 Signed-off-by: Matt Benjamin (cherry picked from commit 80bffd9ae12f6b5846cf8efbffda71e9f921e18f) --- diff --git a/src/rgw/rgw_crypt.cc b/src/rgw/rgw_crypt.cc index cf4e38995eb9c..836919fe55c62 100644 --- a/src/rgw/rgw_crypt.cc +++ b/src/rgw/rgw_crypt.cc @@ -1153,58 +1153,65 @@ int rgw_s3_prepare_encrypt(struct req_state* s, boost::string_view req_sse = get_crypt_attribute(s->info.env, parts, X_AMZ_SERVER_SIDE_ENCRYPTION); if (! req_sse.empty()) { - if (req_sse != "aws:kms") { - ldout(s->cct, 5) << "ERROR: Invalid value for header x-amz-server-side-encryption" - << dendl; - s->err.message = "Server Side Encryption with KMS managed key requires " - "HTTP header x-amz-server-side-encryption : aws:kms"; - return -EINVAL; - } + if (s->cct->_conf->rgw_crypt_require_ssl && !rgw_transport_is_secure(s->cct, *s->info.env)) { ldout(s->cct, 5) << "ERROR: insecure request, rgw_crypt_require_ssl is set" << dendl; return -ERR_INVALID_REQUEST; } - boost::string_view key_id = + + if (req_sse == "aws:kms") { + boost::string_view key_id = get_crypt_attribute(s->info.env, parts, X_AMZ_SERVER_SIDE_ENCRYPTION_AWS_KMS_KEY_ID); - if (key_id.empty()) { - ldout(s->cct, 5) << "ERROR: not provide a valid key id" << dendl; - s->err.message = "Server Side Encryption with KMS managed key requires " - "HTTP header x-amz-server-side-encryption-aws-kms-key-id"; - return -ERR_INVALID_ACCESS_KEY; - } - /* try to retrieve actual key */ - std::string key_selector = create_random_key_selector(s->cct); - std::string actual_key; - res = get_actual_key_from_kms(s->cct, key_id, key_selector, actual_key); - if (res != 0) { - ldout(s->cct, 5) << "ERROR: failed to retrieve actual key from key_id: " << key_id << dendl; - s->err.message = "Failed to retrieve the actual key, kms-keyid: " + key_id.to_string(); - return res; - } - if (actual_key.size() != AES_256_KEYSIZE) { - ldout(s->cct, 5) << "ERROR: key obtained from key_id:" << + if (key_id.empty()) { + ldout(s->cct, 5) << "ERROR: not provide a valid key id" << dendl; + s->err.message = "Server Side Encryption with KMS managed key requires " + "HTTP header x-amz-server-side-encryption-aws-kms-key-id"; + return -ERR_INVALID_ACCESS_KEY; + } + /* try to retrieve actual key */ + std::string key_selector = create_random_key_selector(s->cct); + std::string actual_key; + res = get_actual_key_from_kms(s->cct, key_id, key_selector, actual_key); + if (res != 0) { + ldout(s->cct, 5) << "ERROR: failed to retrieve actual key from key_id: " << key_id << dendl; + s->err.message = "Failed to retrieve the actual key, kms-keyid: " + key_id.to_string(); + return res; + } + if (actual_key.size() != AES_256_KEYSIZE) { + ldout(s->cct, 5) << "ERROR: key obtained from key_id:" << key_id << " is not 256 bit size" << dendl; - s->err.message = "KMS provided an invalid key for the given kms-keyid."; - return -ERR_INVALID_ACCESS_KEY; - } - set_attr(attrs, RGW_ATTR_CRYPT_MODE, "SSE-KMS"); - set_attr(attrs, RGW_ATTR_CRYPT_KEYID, key_id); - set_attr(attrs, RGW_ATTR_CRYPT_KEYSEL, key_selector); - - if (block_crypt) { - auto aes = std::unique_ptr(new AES_256_CBC(s->cct)); - aes->set_key(reinterpret_cast(actual_key.c_str()), AES_256_KEYSIZE); - *block_crypt = std::move(aes); + s->err.message = "KMS provided an invalid key for the given kms-keyid."; + return -ERR_INVALID_ACCESS_KEY; + } + set_attr(attrs, RGW_ATTR_CRYPT_MODE, "SSE-KMS"); + set_attr(attrs, RGW_ATTR_CRYPT_KEYID, key_id); + set_attr(attrs, RGW_ATTR_CRYPT_KEYSEL, key_selector); + + if (block_crypt) { + auto aes = std::unique_ptr(new AES_256_CBC(s->cct)); + aes->set_key(reinterpret_cast(actual_key.c_str()), AES_256_KEYSIZE); + *block_crypt = std::move(aes); + } + actual_key.replace(0, actual_key.length(), actual_key.length(), '\000'); + + crypt_http_responses["x-amz-server-side-encryption"] = "aws:kms"; + crypt_http_responses["x-amz-server-side-encryption-aws-kms-key-id"] = key_id.to_string(); + return 0; + } else if (req_sse == "AES256") { + /* if a default encryption key was provided, we will use it for SSE-S3 */ + } else { + ldout(s->cct, 5) << "ERROR: Invalid value for header x-amz-server-side-encryption" + << dendl; + s->err.message = "Server Side Encryption with KMS managed key requires " + "HTTP header x-amz-server-side-encryption : aws:kms or AES256"; + return -EINVAL; } - actual_key.replace(0, actual_key.length(), actual_key.length(), '\000'); - - crypt_http_responses["x-amz-server-side-encryption"] = "aws:kms"; - crypt_http_responses["x-amz-server-side-encryption-aws-kms-key-id"] = key_id.to_string(); - return 0; } else { + /* x-amz-server-side-encryption not present or empty */ boost::string_view key_id = - get_crypt_attribute(s->info.env, parts, X_AMZ_SERVER_SIDE_ENCRYPTION_AWS_KMS_KEY_ID); + get_crypt_attribute(s->info.env, parts, + X_AMZ_SERVER_SIDE_ENCRYPTION_AWS_KMS_KEY_ID); if (!key_id.empty()) { ldout(s->cct, 5) << "ERROR: SSE-KMS encryption request is missing the header " << "x-amz-server-side-encryption"