From: Radoslaw Zarzynski Date: Thu, 13 Apr 2017 02:38:28 +0000 (+0200) Subject: rgw: rework interfaces of AWSv4 helper primitives. X-Git-Tag: v12.1.0~155^2~67 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=98e153fe8b7e4b1fdbb8bd6211dfec32de0aaccf;p=ceph.git rgw: rework interfaces of AWSv4 helper primitives. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/rgw/rgw_auth_s3.cc b/src/rgw/rgw_auth_s3.cc index 56ce96b33354..785d2ce560f8 100644 --- a/src/rgw/rgw_auth_s3.cc +++ b/src/rgw/rgw_auth_s3.cc @@ -162,11 +162,6 @@ int rgw_get_s3_header_digest(const string& auth_hdr, const string& key, string& return 0; } -void rgw_hash_s3_string_sha256(const char *data, int len, string& dest) -{ - calc_hash_sha256(data, len, dest); -} - static inline bool is_base64_for_content_md5(unsigned char c) { return (isalnum(c) || isspace(c) || (c == '+') || (c == '/') || (c == '=')); } @@ -239,14 +234,30 @@ bool rgw_create_s3_canonical_header(const req_info& info, return true; } + +namespace rgw { +namespace auth { +namespace s3 { + +std::string hash_string_sha256(const char* const data, const int len) +{ + std::string dest; + calc_hash_sha256(data, len, dest); + return dest; +} + /* * assemble canonical request for signature version 4 */ -void rgw_assemble_s3_v4_canonical_request(const char *method, const char *canonical_uri, const char *canonical_qs, - const char *canonical_hdrs, const char *signed_hdrs, const char *request_payload_hash, - string& dest_str) +static std::string assemble_v4_canonical_request( + const char* const method, + const char* const canonical_uri, + const char* const canonical_qs, + const char* const canonical_hdrs, + const char* const signed_hdrs, + const char* const request_payload_hash) { - string dest; + std::string dest; if (method) dest = method; @@ -273,15 +284,19 @@ void rgw_assemble_s3_v4_canonical_request(const char *method, const char *canoni if (request_payload_hash) dest.append(request_payload_hash); - dest_str = dest; + return dest; } /* * create canonical request for signature version 4 */ -void rgw_create_s3_v4_canonical_request(struct req_state *s, const string& canonical_uri, const string& canonical_qs, - const string& canonical_hdrs, const string& signed_hdrs, const string& request_payload, - bool unsigned_payload, string& canonical_req, string& canonical_req_hash) +std::string get_v4_canonical_request_hash(struct req_state* const s, + const std::string& canonical_uri, + const std::string& canonical_qs, + const std::string& canonical_hdrs, + const std::string& signed_hdrs, + const std::string& request_payload, + const bool unsigned_payload) { string request_payload_hash; @@ -294,7 +309,8 @@ void rgw_create_s3_v4_canonical_request(struct req_state *s, const string& canon if (s->aws4_auth_streaming_mode) { request_payload_hash = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD"; } else { - rgw_hash_s3_string_sha256(request_payload.c_str(), request_payload.size(), request_payload_hash); + request_payload_hash = \ + hash_string_sha256(request_payload.c_str(), request_payload.size()); } } } @@ -303,23 +319,33 @@ void rgw_create_s3_v4_canonical_request(struct req_state *s, const string& canon ldout(s->cct, 10) << "payload request hash = " << request_payload_hash << dendl; - rgw_assemble_s3_v4_canonical_request(s->info.method, canonical_uri.c_str(), - canonical_qs.c_str(), canonical_hdrs.c_str(), signed_hdrs.c_str(), - request_payload_hash.c_str(), canonical_req); + std::string canonical_req = \ + assemble_v4_canonical_request(s->info.method, + canonical_uri.c_str(), + canonical_qs.c_str(), + canonical_hdrs.c_str(), + signed_hdrs.c_str(), + request_payload_hash.c_str()); - rgw_hash_s3_string_sha256(canonical_req.c_str(), canonical_req.size(), canonical_req_hash); + std::string canonical_req_hash = \ + hash_string_sha256(canonical_req.c_str(), canonical_req.size()); ldout(s->cct, 10) << "canonical request = " << canonical_req << dendl; ldout(s->cct, 10) << "canonical request hash = " << canonical_req_hash << dendl; + + return canonical_req_hash; } /* * assemble string to sign for signature version 4 */ -void rgw_assemble_s3_v4_string_to_sign(const char *algorithm, const char *request_date, - const char *credential_scope, const char *hashed_qr, string& dest_str) -{ - string dest; +static std::string rgw_assemble_s3_v4_string_to_sign( + const char* const algorithm, + const char* const request_date, + const char* const credential_scope, + const char* const hashed_qr +) { + std::string dest; if (algorithm) dest = algorithm; @@ -336,43 +362,45 @@ void rgw_assemble_s3_v4_string_to_sign(const char *algorithm, const char *reques if (hashed_qr) dest.append(hashed_qr); - dest_str = dest; + return dest; } /* * create string to sign for signature version 4 + * + * http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html */ -void rgw_create_s3_v4_string_to_sign(CephContext *cct, const string& algorithm, const string& request_date, - const string& credential_scope, const string& hashed_qr, - string& string_to_sign) { - - rgw_assemble_s3_v4_string_to_sign(algorithm.c_str(), request_date.c_str(), - credential_scope.c_str(), hashed_qr.c_str(), string_to_sign); - - ldout(cct, 10) << "string to sign = " << rgw::crypt_sanitize::log_content{string_to_sign.c_str()} << dendl; +std::string get_v4_string_to_sign(CephContext* const cct, + const std::string& algorithm, + const std::string& request_date, + const std::string& credential_scope, + const std::string& hashed_qr) +{ + const auto string_to_sign = \ + rgw_assemble_s3_v4_string_to_sign( + algorithm.c_str(), + request_date.c_str(), + credential_scope.c_str(), + hashed_qr.c_str()); + + ldout(cct, 10) << "string to sign = " + << rgw::crypt_sanitize::log_content{string_to_sign.c_str()} + << dendl; + return string_to_sign; } /* * calculate the AWS signature version 4 */ -int rgw_calculate_s3_v4_aws_signature(struct req_state *s, - const string& access_key_id, const string &date, const string& region, const string& service, - const string& string_to_sign, string& signature, const string &access_key_secret) { - - string secret_key = "AWS4"; - - if (access_key_secret.empty()) { - map::iterator iter = s->user->access_keys.find(access_key_id); - if (iter == s->user->access_keys.end()) { - ldout(s->cct, 10) << "ERROR: access key not encoded in user info" << dendl; - return -EPERM; - } - RGWAccessKey& k = iter->second; - secret_key.append(k.key); - } else { - secret_key.append(access_key_secret); - } - +std::string get_v4_signature(struct req_state* const s, + const std::string& access_key_id, + const std::string& date, + const std::string& region, + const std::string& service, + const std::string& string_to_sign, + const std::string& access_key_secret) +{ + std::string secret_key = "AWS4" + access_key_secret; char secret_k[secret_key.size() * MAX_UTF8_SZ]; size_t n = 0; @@ -422,6 +450,7 @@ int rgw_calculate_s3_v4_aws_signature(struct req_state *s, ldout(s->cct, 10) << "signing_k = " << string(aux) << dendl; + /* TODO(rzarzynski): remove any modification to req_state! */ s->aws4_auth->signing_key = aux; /* new signature */ @@ -433,9 +462,13 @@ int rgw_calculate_s3_v4_aws_signature(struct req_state *s, ldout(s->cct, 10) << "signature_k = " << string(aux) << dendl; - signature = string(aux); + std::string signature = string(aux); ldout(s->cct, 10) << "new signature = " << signature << dendl; - return 0; + return signature; } + +} /* namespace s3 */ +} /* namespace auth */ +} /* namespace rgw */ diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index b10a969f53cd..5c1f8b0481a9 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -155,18 +155,35 @@ int rgw_get_s3_header_digest(const string& auth_hdr, const string& key, string& dest); int rgw_get_s3_header_digest(const string& auth_hdr, const string& key, string& dest); -void rgw_hash_s3_string_sha256(const char *data, int len, string& dest); -void rgw_create_s3_v4_canonical_request(struct req_state *s, const string& canonical_uri, - const string& canonical_qs, const string& canonical_hdrs, - const string& signed_hdrs, const string& request_payload, - bool unsigned_payload, - string& canonical_req, string& canonical_req_hash); -void rgw_create_s3_v4_string_to_sign(CephContext *cct, const string& algorithm, - const string& request_date, const string& credential_scope, - const string& hashed_qr, string& string_to_sign); -int rgw_calculate_s3_v4_aws_signature(struct req_state *s, const string& access_key_id, - const string &date, const string& region, - const string& service, const string& string_to_sign, - string& signature, const std::string& access_key_secret=""); +namespace rgw { +namespace auth { +namespace s3 { + +std::string hash_string_sha256(const char* data, int len); + +std::string get_v4_canonical_request_hash(struct req_state* s, + const std::string& canonical_uri, + const std::string& canonical_qs, + const std::string& canonical_hdrs, + const std::string& signed_hdrs, + const std::string& request_payload, + bool unsigned_payload); + +std::string get_v4_string_to_sign(CephContext* cct, + const std::string& algorithm, + const std::string& request_date, + const std::string& credential_scope, + const std::string& hashed_qr); + +std::string get_v4_signature(struct req_state* s, + const std::string& access_key_id, + const std::string& date, + const std::string& region, + const std::string& service, + const std::string& string_to_sign, + const std::string& access_key_secret); +} /* namespace s3 */ +} /* namespace auth */ +} /* namespace rgw */ #endif diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 61de6afcd2f4..925717ce5b40 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -1202,11 +1202,10 @@ int RGWPutObj_ObjStore_S3::validate_aws4_single_chunk(char *chunk_str, /* string to sign */ - string hash_empty_str; - rgw_hash_s3_string_sha256("", 0, hash_empty_str); + const std::string hash_empty_str = rgw::auth::s3::hash_string_sha256("", 0); - string hash_chunk_data; - rgw_hash_s3_string_sha256(chunk_data_str, chunk_data_size, hash_chunk_data); + const std::string hash_chunk_data = \ + rgw::auth::s3::hash_string_sha256(chunk_data_str, chunk_data_size); string string_to_sign = "AWS4-HMAC-SHA256-PAYLOAD\n"; string_to_sign.append(s->aws4_auth->date + "\n"); @@ -1750,15 +1749,11 @@ int RGWPostObj_ObjStore_S3::get_policy() std::string encoded_policy_str(s->auth.s3_postobj_creds.encoded_policy.c_str(), s->auth.s3_postobj_creds.encoded_policy.length()); - std::string new_signature_str; - - int err = rgw_calculate_s3_v4_aws_signature(s, s3_access_key, - date_cs, region_cs, service_cs, - encoded_policy_str, new_signature_str, - s3_secret_key); - if (err) { - return err; - } + std::string new_signature_str = \ + rgw::auth::s3::get_v4_signature(s, s3_access_key, date_cs, + region_cs, service_cs, + encoded_policy_str, + s3_secret_key); ldout(s->cct, 10) << "----------------------------- Verifying signatures" << dendl; ldout(s->cct, 10) << "Signature = " << received_signature_str << dendl; @@ -3428,13 +3423,12 @@ int RGW_Auth_S3::authorize_v4_complete(RGWRados *store, struct req_state *s, con size_t pos; /* craft canonical request */ - - string canonical_req; - string canonical_req_hash; - - rgw_create_s3_v4_canonical_request(s, s->aws4_auth->canonical_uri, s->aws4_auth->canonical_qs, - s->aws4_auth->canonical_hdrs, s->aws4_auth->signed_hdrs, request_payload, unsigned_payload, - canonical_req, canonical_req_hash); + string canonical_req_hash = \ + rgw::auth::s3::get_v4_canonical_request_hash(s, s->aws4_auth->canonical_uri, + s->aws4_auth->canonical_qs, + s->aws4_auth->canonical_hdrs, + s->aws4_auth->signed_hdrs, + request_payload, unsigned_payload); /* Validate x-amz-sha256 */ @@ -3453,10 +3447,11 @@ int RGW_Auth_S3::authorize_v4_complete(RGWRados *store, struct req_state *s, con * http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html */ - string string_to_sign; - - rgw_create_s3_v4_string_to_sign(s->cct, "AWS4-HMAC-SHA256", s->aws4_auth->date, s->aws4_auth->credential_scope, - canonical_req_hash, string_to_sign); + std::string string_to_sign = \ + rgw::auth::s3::get_v4_string_to_sign(s->cct, "AWS4-HMAC-SHA256", + s->aws4_auth->date, + s->aws4_auth->credential_scope, + canonical_req_hash); /* * calculate the AWS signature @@ -3480,18 +3475,24 @@ int RGW_Auth_S3::authorize_v4_complete(RGWRados *store, struct req_state *s, con pos = service_cs.find("/"); service_cs = service_cs.substr(0, pos); - int err = rgw_calculate_s3_v4_aws_signature(s, s->aws4_auth->access_key_id, date_cs, - region_cs, service_cs, string_to_sign, s->aws4_auth->new_signature); + const auto iter = s->user->access_keys.find(s->aws4_auth->access_key_id); + if (iter == std::end(s->user->access_keys)) { + ldout(s->cct, 10) << "ERROR: access key not encoded in user info" << dendl; + return -EPERM; + } + const RGWAccessKey& k = iter->second; + + s->aws4_auth->new_signature = \ + rgw::auth::s3::get_v4_signature(s, s->aws4_auth->access_key_id, date_cs, + region_cs, service_cs, string_to_sign, + k.key); + ldout(s->cct, 10) << "----------------------------- Verifying signatures" << dendl; ldout(s->cct, 10) << "Signature = " << s->aws4_auth->signature << dendl; ldout(s->cct, 10) << "New Signature = " << s->aws4_auth->new_signature << dendl; ldout(s->cct, 10) << "-----------------------------" << dendl; - if (err) { - return err; - } - s->aws4_auth->seed_signature = s->aws4_auth->new_signature; return 0;