]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: rework interfaces of AWSv4 helper primitives.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Thu, 13 Apr 2017 02:38:28 +0000 (04:38 +0200)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Wed, 7 Jun 2017 10:43:14 +0000 (12:43 +0200)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_auth_s3.cc
src/rgw/rgw_auth_s3.h
src/rgw/rgw_rest_s3.cc

index 56ce96b33354fbdefe6748253f8303caacdc64cb..785d2ce560f87c6e08f37eb98cf4b684f4074fad 100644 (file)
@@ -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<string, RGWAccessKey>::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 */
index b10a969f53cd83f5be45bec9be5f5063ddde6b13..5c1f8b0481a9823c8b48a23e05be6c6d53329c45 100644 (file)
@@ -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
index 61de6afcd2f449399f0650c3c1f89fd8edfbbf96..925717ce5b405264290be988b49cd9bf3ff7534f 100644 (file)
@@ -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;