Line data Source code
1 : #pragma once 2 : 3 : #include <utility> 4 : 5 : #include "source/common/common/logger.h" 6 : #include "source/common/common/matchers.h" 7 : #include "source/common/common/utility.h" 8 : #include "source/common/http/headers.h" 9 : #include "source/common/singleton/const_singleton.h" 10 : #include "source/extensions/common/aws/credentials_provider.h" 11 : #include "source/extensions/common/aws/signer.h" 12 : 13 : namespace Envoy { 14 : namespace Extensions { 15 : namespace Common { 16 : namespace Aws { 17 : 18 : class SignatureHeaderValues { 19 : public: 20 : const Http::LowerCaseString ContentSha256{"x-amz-content-sha256"}; 21 : const Http::LowerCaseString Date{"x-amz-date"}; 22 : const Http::LowerCaseString SecurityToken{"x-amz-security-token"}; 23 : }; 24 : 25 : using SignatureHeaders = ConstSingleton<SignatureHeaderValues>; 26 : 27 : class SignatureConstantValues { 28 : public: 29 : const std::string Aws4Request{"aws4_request"}; 30 : const std::string HashedEmptyString{ 31 : "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"}; 32 : 33 : const std::string LongDateFormat{"%Y%m%dT%H%M00Z"}; 34 : const std::string ShortDateFormat{"%Y%m%d"}; 35 : const std::string UnsignedPayload{"UNSIGNED-PAYLOAD"}; 36 : }; 37 : 38 : using SignatureConstants = ConstSingleton<SignatureConstantValues>; 39 : 40 : using AwsSigningHeaderExclusionVector = std::vector<envoy::type::matcher::v3::StringMatcher>; 41 : 42 : /** 43 : * Implementation of the Signature V4 signing process. 44 : * See https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html 45 : */ 46 : class SignerBaseImpl : public Signer, public Logger::Loggable<Logger::Id::aws> { 47 : public: 48 : SignerBaseImpl(absl::string_view service_name, absl::string_view region, 49 : const CredentialsProviderSharedPtr& credentials_provider, TimeSource& time_source, 50 : const AwsSigningHeaderExclusionVector& matcher_config) 51 : : service_name_(service_name), region_(region), credentials_provider_(credentials_provider), 52 : time_source_(time_source), long_date_formatter_(SignatureConstants::get().LongDateFormat), 53 6 : short_date_formatter_(SignatureConstants::get().ShortDateFormat) { 54 6 : for (const auto& matcher : matcher_config) { 55 0 : excluded_header_matchers_.emplace_back( 56 0 : std::make_unique<Matchers::StringMatcherImpl<envoy::type::matcher::v3::StringMatcher>>( 57 0 : matcher)); 58 0 : } 59 6 : } 60 : 61 : void sign(Http::RequestMessage& message, bool sign_body = false, 62 : const absl::string_view override_region = "") override; 63 : void sign(Http::RequestHeaderMap& headers, const std::string& content_hash, 64 : const absl::string_view override_region = "") override; 65 : void signEmptyPayload(Http::RequestHeaderMap& headers, 66 : const absl::string_view override_region = "") override; 67 : void signUnsignedPayload(Http::RequestHeaderMap& headers, 68 : const absl::string_view override_region = "") override; 69 : 70 : protected: 71 : std::string getRegion() const; 72 : 73 : std::string createContentHash(Http::RequestMessage& message, bool sign_body) const; 74 : 75 : virtual void addRegionHeader(Http::RequestHeaderMap& headers, 76 : const absl::string_view override_region) const; 77 : 78 : virtual std::string createCredentialScope(const absl::string_view short_date, 79 : const absl::string_view override_region) const PURE; 80 : 81 : virtual std::string createStringToSign(const absl::string_view canonical_request, 82 : const absl::string_view long_date, 83 : const absl::string_view credential_scope) const PURE; 84 : 85 : virtual std::string createSignature(const absl::string_view access_key_id, 86 : const absl::string_view secret_access_key, 87 : const absl::string_view short_date, 88 : const absl::string_view string_to_sign, 89 : const absl::string_view override_region) const PURE; 90 : 91 : virtual std::string 92 : createAuthorizationHeader(const absl::string_view access_key_id, 93 : const absl::string_view credential_scope, 94 : const std::map<std::string, std::string>& canonical_headers, 95 : const absl::string_view signature) const PURE; 96 : 97 6 : std::vector<Matchers::StringMatcherPtr> defaultMatchers() const { 98 6 : std::vector<Matchers::StringMatcherPtr> matcher_ptrs{}; 99 18 : for (const auto& header : default_excluded_headers_) { 100 18 : envoy::type::matcher::v3::StringMatcher m; 101 18 : m.set_exact(header); 102 18 : matcher_ptrs.emplace_back( 103 18 : std::make_unique<Matchers::StringMatcherImpl<envoy::type::matcher::v3::StringMatcher>>( 104 18 : m)); 105 18 : } 106 6 : return matcher_ptrs; 107 6 : } 108 : 109 : const std::string service_name_; 110 : const std::string region_; 111 : const std::vector<std::string> default_excluded_headers_ = { 112 : Http::Headers::get().ForwardedFor.get(), Http::Headers::get().ForwardedProto.get(), 113 : "x-amzn-trace-id"}; 114 : std::vector<Matchers::StringMatcherPtr> excluded_header_matchers_ = defaultMatchers(); 115 : CredentialsProviderSharedPtr credentials_provider_; 116 : TimeSource& time_source_; 117 : DateFormatter long_date_formatter_; 118 : DateFormatter short_date_formatter_; 119 : const std::string blank_str_; 120 : }; 121 : 122 : } // namespace Aws 123 : } // namespace Common 124 : } // namespace Extensions 125 : } // namespace Envoy