Skip to content

Commit

Permalink
rgw: introduce string_to_sign_t abstraction to the AWS auth.
Browse files Browse the repository at this point in the history
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
  • Loading branch information
rzarzynski committed Jun 7, 2017
1 parent 73e78ae commit f3317f6
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 78 deletions.
2 changes: 1 addition & 1 deletion src/rgw/rgw_auth_keystone.cc
Expand Up @@ -416,7 +416,7 @@ EC2Engine::get_creds_info(const EC2Engine::token_envelope_t& token,
rgw::auth::Engine::result_t EC2Engine::authenticate(
const boost::string_view& access_key_id,
const boost::string_view& signature,
const std::string& string_to_sign,
const string_to_sign_t& string_to_sign,
const signature_factory_t&,
const completer_factory_t& completer_factory,
/* Passthorugh only! */
Expand Down
2 changes: 1 addition & 1 deletion src/rgw/rgw_auth_keystone.h
Expand Up @@ -93,7 +93,7 @@ class EC2Engine : public rgw::auth::s3::AWSEngine {
const boost::string_view& signature) const;
result_t authenticate(const boost::string_view& access_key_id,
const boost::string_view& signature,
const std::string& string_to_sign,
const string_to_sign_t& string_to_sign,
const signature_factory_t&,
const completer_factory_t& completer_factory,
const req_state* s) const override;
Expand Down
35 changes: 22 additions & 13 deletions src/rgw/rgw_auth_s3.cc
Expand Up @@ -676,11 +676,12 @@ get_v4_canon_req_hash(CephContext* cct,
*
* http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html
*/
std::string get_v4_string_to_sign(CephContext* const cct,
const boost::string_view& algorithm,
const boost::string_view& request_date,
const boost::string_view& credential_scope,
const sha256_digest_t& canonreq_hash)
AWSEngine::VersionAbstractor::string_to_sign_t
get_v4_string_to_sign(CephContext* const cct,
const boost::string_view& algorithm,
const boost::string_view& request_date,
const boost::string_view& credential_scope,
const sha256_digest_t& canonreq_hash)
{
const auto hexed_cr_hash = buf_to_hex(canonreq_hash);

Expand Down Expand Up @@ -750,9 +751,10 @@ transform_secret_key(const boost::string_view& secret_access_key)
/*
* calculate the SigningKey of AWS auth version 4
*/
sha256_digest_t get_v4_signing_key(CephContext* const cct,
const boost::string_view& credential_scope,
const boost::string_view& secret_access_key)
static sha256_digest_t
get_v4_signing_key(CephContext* const cct,
const boost::string_view& credential_scope,
const boost::string_view& secret_access_key)
{
boost::string_view date, region, service;
std::tie(date, region, service) = parse_cred_scope(credential_scope);
Expand All @@ -776,14 +778,21 @@ sha256_digest_t get_v4_signing_key(CephContext* const cct,

/*
* calculate the AWS signature version 4
*
* http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
*
* srv_signature_t is an alias over Ceph's basic_sstring. We're using
* it to keep everything within the stack boundaries instead of doing
* dynamic allocations.
*/
AWSEngine::VersionAbstractor::server_signature_t
get_v4_signature(CephContext* const cct,
const sha256_digest_t& signing_key,
const boost::string_view& string_to_sign)
get_v4_signature(const boost::string_view& credential_scope,
CephContext* const cct,
const boost::string_view& secret_key,
const AWSEngine::VersionAbstractor::string_to_sign_t& string_to_sign)
{
auto signing_key = get_v4_signing_key(cct, credential_scope, secret_key);

/* The server-side generated digest for comparison. */
const auto digest = calc_hmac_sha256(signing_key, string_to_sign);

Expand All @@ -802,7 +811,7 @@ get_v4_signature(CephContext* const cct,
AWSEngine::VersionAbstractor::server_signature_t
get_v2_signature(CephContext* const cct,
const std::string& secret_key,
const std::string& string_to_sign)
const AWSEngine::VersionAbstractor::string_to_sign_t& string_to_sign)
{
if (secret_key.empty()) {
throw -EINVAL;
Expand Down
25 changes: 11 additions & 14 deletions src/rgw/rgw_auth_s3.h
Expand Up @@ -412,26 +412,23 @@ get_v4_canon_req_hash(CephContext* cct,
const boost::string_view& signed_hdrs,
const boost::string_view& request_payload_hash);

std::string get_v4_string_to_sign(CephContext* cct,
const boost::string_view& algorithm,
const boost::string_view& request_date,
const boost::string_view& credential_scope,
const sha256_digest_t& canonreq_hash);

extern sha256_digest_t
get_v4_signing_key(CephContext* const cct,
const boost::string_view& credential_scope,
const boost::string_view& access_key_secret);
AWSEngine::VersionAbstractor::string_to_sign_t
get_v4_string_to_sign(CephContext* cct,
const boost::string_view& algorithm,
const boost::string_view& request_date,
const boost::string_view& credential_scope,
const sha256_digest_t& canonreq_hash);

extern AWSEngine::VersionAbstractor::server_signature_t
get_v4_signature(CephContext* cct,
const sha256_digest_t& signing_key,
const boost::string_view& string_to_sign);
get_v4_signature(const boost::string_view& credential_scope,
CephContext* const cct,
const boost::string_view& secret_key,
const AWSEngine::VersionAbstractor::string_to_sign_t& string_to_sign);

extern AWSEngine::VersionAbstractor::server_signature_t
get_v2_signature(CephContext*,
const std::string& secret_key,
const std::string& string_to_sign);
const AWSEngine::VersionAbstractor::string_to_sign_t& string_to_sign);

} /* namespace s3 */
} /* namespace auth */
Expand Down
53 changes: 30 additions & 23 deletions src/rgw/rgw_rest_s3.cc
Expand Up @@ -3565,25 +3565,6 @@ AWSGeneralAbstractor::get_auth_data(const req_state* const s) const
}
}

/* srv_signature_t is an alias over Ceph's basic_sstring. We're using
* it to keep everything within the stack boundaries instead of doing
* dynamic allocations. */
static inline AWSVerAbstractor::server_signature_t
v4_signature(const boost::string_view& credential_scope,

CephContext* const cct,
const boost::string_view& secret_key,
const boost::string_view& string_to_sign)
{
auto signing_key = \
rgw::auth::s3::get_v4_signing_key(cct, credential_scope, secret_key);

auto server_signature = \
rgw::auth::s3::get_v4_signature(cct, std::move(signing_key),
string_to_sign);
return server_signature;
}

std::tuple<AWSVerAbstractor::access_key_id_t,
AWSVerAbstractor::client_signature_t,
AWSVerAbstractor::string_to_sign_t,
Expand Down Expand Up @@ -3648,7 +3629,7 @@ AWSGeneralAbstractor::get_auth_data_v4(const req_state* const s,
credential_scope,
std::move(canonical_req_hash));

const auto sig_factory = std::bind(v4_signature,
const auto sig_factory = std::bind(rgw::auth::s3::get_v4_signature,
credential_scope,
std::placeholders::_1,
std::placeholders::_2,
Expand Down Expand Up @@ -3852,7 +3833,7 @@ AWSBrowserUploadAbstractor::get_auth_data_v4(const req_state* const s) const
const boost::string_view credential_scope = credential.substr(pos + 1);
dout(10) << "credential scope = " << credential_scope << dendl;

const auto sig_factory = std::bind(v4_signature,
const auto sig_factory = std::bind(rgw::auth::s3::get_v4_signature,
credential_scope,
std::placeholders::_1,
std::placeholders::_2,
Expand Down Expand Up @@ -3882,6 +3863,32 @@ AWSBrowserUploadAbstractor::get_auth_data(const req_state* const s) const
}
}


AWSEngine::result_t
AWSEngine::authenticate(const req_state* const s) const
{
boost::string_view access_key_id;
boost::string_view signature;
VersionAbstractor::string_to_sign_t string_to_sign;

VersionAbstractor::signature_factory_t signature_factory;
VersionAbstractor::completer_factory_t completer_factory;

/* Small reminder: an ver_abstractor is allowed to throw! */
std::tie(access_key_id,
signature,
string_to_sign,
signature_factory,
completer_factory) = ver_abstractor.get_auth_data(s);

if (access_key_id.empty() || signature.empty()) {
return result_t::deny(-EINVAL);
} else {
return authenticate(access_key_id, signature, string_to_sign,
signature_factory, completer_factory, s);
}
}

} /* namespace s3 */
} /* namespace auth */
} /* namespace rgw */
Expand Down Expand Up @@ -3939,7 +3946,7 @@ rgw::auth::Engine::result_t
rgw::auth::s3::LDAPEngine::authenticate(
const boost::string_view& access_key_id,
const boost::string_view& signature,
const std::string& string_to_sign,
const string_to_sign_t& string_to_sign,
const signature_factory_t&,
const completer_factory_t& completer_factory,
const req_state* const s) const
Expand Down Expand Up @@ -3983,7 +3990,7 @@ rgw::auth::Engine::result_t
rgw::auth::s3::LocalEngine::authenticate(
const boost::string_view& _access_key_id,
const boost::string_view& signature,
const std::string& string_to_sign,
const string_to_sign_t& string_to_sign,
const signature_factory_t& signature_factory,
const completer_factory_t& completer_factory,
const req_state* const s) const
Expand Down
34 changes: 8 additions & 26 deletions src/rgw/rgw_rest_s3.h
Expand Up @@ -9,6 +9,7 @@
#include <mutex>

#include <boost/utility/string_view.hpp>
#include <boost/container/static_vector.hpp>

#include "common/backport14.h"
#include "common/sstring.hh"
Expand Down Expand Up @@ -687,7 +688,7 @@ class AWSEngine : public rgw::auth::Engine {
using signature_factory_t = \
std::function<server_signature_t(CephContext* cct,
const std::string& secret_key,
const std::string& string_to_sign)>;
const string_to_sign_t& string_to_sign)>;

/* Return an instance of Completer for verifying the payload's fingerprint
* if necessary. Otherwise caller gets nullptr. Caller may provide secret
Expand All @@ -714,6 +715,7 @@ class AWSEngine : public rgw::auth::Engine {
}

using result_t = rgw::auth::Engine::result_t;
using string_to_sign_t = VersionAbstractor::string_to_sign_t;
using signature_factory_t = VersionAbstractor::signature_factory_t;
using completer_factory_t = VersionAbstractor::completer_factory_t;

Expand All @@ -722,36 +724,16 @@ class AWSEngine : public rgw::auth::Engine {
* Replace these thing with a simple, dedicated structure. */
virtual result_t authenticate(const boost::string_view& access_key_id,
const boost::string_view& signature,
const std::string& string_to_sign,
const string_to_sign_t& string_to_sign,
const signature_factory_t& signature_factory,
const completer_factory_t& completer_factory,
const req_state* s) const = 0;

public:
result_t authenticate(const req_state* const s) const final {
boost::string_view access_key_id;
boost::string_view signature;
std::string string_to_sign;

VersionAbstractor::signature_factory_t signature_factory;
VersionAbstractor::completer_factory_t completer_factory;

/* Small reminder: an ver_abstractor is allowed to throw! */
std::tie(access_key_id,
signature,
string_to_sign,
signature_factory,
completer_factory) = ver_abstractor.get_auth_data(s);

if (access_key_id.empty() || signature.empty()) {
return result_t::deny(-EINVAL);
} else {
return authenticate(access_key_id, signature, string_to_sign,
signature_factory, completer_factory, s);
}
}
result_t authenticate(const req_state* const s) const final;
};


class AWSGeneralAbstractor : public AWSEngine::VersionAbstractor {
CephContext* const cct;

Expand Down Expand Up @@ -833,7 +815,7 @@ class LDAPEngine : public AWSEngine {

result_t authenticate(const boost::string_view& access_key_id,
const boost::string_view& signature,
const std::string& string_to_sign,
const string_to_sign_t& string_to_sign,
const signature_factory_t&,
const completer_factory_t& completer_factory,
const req_state* s) const override;
Expand Down Expand Up @@ -862,7 +844,7 @@ class LocalEngine : public AWSEngine {

result_t authenticate(const boost::string_view& access_key_id,
const boost::string_view& signature,
const std::string& string_to_sign,
const string_to_sign_t& string_to_sign,
const signature_factory_t& signature_factory,
const completer_factory_t& completer_factory,
const req_state* s) const override;
Expand Down

0 comments on commit f3317f6

Please sign in to comment.