1
#pragma once
2
#include "envoy/type/matcher/v3/string.pb.h"
3

            
4
#include "source/common/common/logger.h"
5
#include "source/common/common/utility.h"
6
#include "source/common/singleton/const_singleton.h"
7
#include "source/extensions/common/aws/credentials_provider.h"
8
#include "source/extensions/common/aws/signer.h"
9

            
10
namespace Envoy {
11
namespace Extensions {
12
namespace Common {
13
namespace Aws {
14

            
15
class IAMRolesAnywhereSignatureHeaderValues {
16
public:
17
  const Http::LowerCaseString ContentSha256{"x-amz-content-sha256"};
18
  const Http::LowerCaseString Date{"x-amz-date"};
19
  const Http::LowerCaseString X509{"x-amz-x509"};
20
  const Http::LowerCaseString X509Chain{"x-amz-x509-chain"};
21
};
22

            
23
using IAMRolesAnywhereSignatureHeaders = ConstSingleton<IAMRolesAnywhereSignatureHeaderValues>;
24

            
25
class IAMRolesAnywhereSignatureConstants {
26
public:
27
  static constexpr absl::string_view HashedEmptyString =
28
      "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
29

            
30
  static constexpr absl::string_view LongDateFormat = "%Y%m%dT%H%M%SZ";
31
  static constexpr absl::string_view ShortDateFormat = "%Y%m%d";
32
  static constexpr absl::string_view UnsignedPayload = "UNSIGNED-PAYLOAD";
33
  static constexpr absl::string_view AuthorizationCredentialFormat = "{}/{}";
34
  static constexpr uint16_t DefaultExpiration = 900;
35
};
36

            
37
using AwsSigningHeaderMatcherVector = std::vector<envoy::type::matcher::v3::StringMatcher>;
38

            
39
/**
40
 * Implementation of the Signature V4 signing process using X509 certificates.
41
 * See https://docs.aws.amazon.com/rolesanywhere/latest/userguide/authentication-sign-process.html
42
 */
43
class IAMRolesAnywhereSignerBaseImpl : public Signer, public Logger::Loggable<Logger::Id::aws> {
44
public:
45
  IAMRolesAnywhereSignerBaseImpl(absl::string_view service_name, absl::string_view region,
46
                                 const X509CredentialsProviderSharedPtr& credentials_provider,
47
                                 TimeSource& timesource)
48

            
49
27
      : service_name_(service_name), region_(region),
50
27
        x509_credentials_provider_(credentials_provider), time_source_(timesource),
51
27
        long_date_formatter_(std::string(IAMRolesAnywhereSignatureConstants::LongDateFormat)),
52
27
        short_date_formatter_(std::string(IAMRolesAnywhereSignatureConstants::ShortDateFormat)) {}
53

            
54
  absl::Status sign(Http::RequestMessage& message, bool sign_body = false,
55
                    const absl::string_view override_region = "") override;
56
  absl::Status signEmptyPayload(Http::RequestHeaderMap& headers,
57
                                const absl::string_view override_region = "") override;
58
  absl::Status signUnsignedPayload(Http::RequestHeaderMap& headers,
59
                                   const absl::string_view override_region = "") override;
60
  absl::Status sign(Http::RequestHeaderMap& headers, const std::string& content_hash,
61
                    const absl::string_view override_region = "") override;
62
  bool addCallbackIfCredentialsPending(CredentialsPendingCallback&& cb) override;
63

            
64
protected:
65
  std::string createContentHash(Http::RequestMessage& message, bool sign_body) const;
66

            
67
  virtual std::string createCredentialScope(const absl::string_view short_date,
68
                                            const absl::string_view override_region) const PURE;
69

            
70
  virtual std::string createStringToSign(const X509Credentials& x509_credentials,
71
                                         const absl::string_view canonical_request,
72
                                         const absl::string_view long_date,
73
                                         const absl::string_view credential_scope) const PURE;
74

            
75
  virtual absl::StatusOr<std::string>
76
  createSignature(const X509Credentials& x509_credentials,
77
                  const absl::string_view string_to_sign) const PURE;
78

            
79
  virtual std::string
80
  createAuthorizationHeader(const X509Credentials& x509_credentials,
81
                            const absl::string_view credential_scope,
82
                            const std::map<std::string, std::string>& canonical_headers,
83
                            const absl::string_view signature) const PURE;
84

            
85
  std::string createAuthorizationCredential(const X509Credentials& x509_credentials,
86
                                            absl::string_view credential_scope) const;
87

            
88
  void addRequiredHeaders(Http::RequestHeaderMap& headers, const std::string long_date);
89

            
90
  void addRequiredCertHeaders(Http::RequestHeaderMap& headers,
91
                              const X509Credentials& x509_credentials);
92

            
93
  const std::string service_name_;
94
  const std::string region_;
95
  CredentialsProviderChainSharedPtr credentials_provider_chain_;
96
  X509CredentialsProviderSharedPtr x509_credentials_provider_;
97
  TimeSource& time_source_;
98
  DateFormatter long_date_formatter_;
99
  DateFormatter short_date_formatter_;
100
};
101

            
102
} // namespace Aws
103
} // namespace Common
104
} // namespace Extensions
105
} // namespace Envoy