1
#include "source/extensions/common/aws/signers/sigv4a_signer_impl.h"
2

            
3
#include "source/common/common/hex.h"
4
#include "source/common/crypto/utility.h"
5
#include "source/extensions/common/aws/signers/sigv4a_common.h"
6
#include "source/extensions/common/aws/utility.h"
7

            
8
namespace Envoy {
9
namespace Extensions {
10
namespace Common {
11
namespace Aws {
12

            
13
std::string SigV4ASignerImpl::createAuthorizationHeader(
14
    const absl::string_view access_key_id, const absl::string_view credential_scope,
15
    const std::map<std::string, std::string>& canonical_headers,
16
14
    absl::string_view signature) const {
17
14
  const auto signed_headers = Utility::joinCanonicalHeaderNames(canonical_headers);
18
14
  return fmt::format(SigV4ASignatureConstants::SigV4AAuthorizationHeaderFormat,
19
14
                     createAuthorizationCredential(access_key_id, credential_scope), signed_headers,
20
14
                     signature);
21
14
}
22

            
23
std::string SigV4ASignerImpl::createCredentialScope(
24
    const absl::string_view short_date,
25
95
    ABSL_ATTRIBUTE_UNUSED const absl::string_view override_region) const {
26
95
  return fmt::format(SigV4ASignatureConstants::SigV4ACredentialScopeFormat, short_date,
27
95
                     service_name_);
28
95
}
29

            
30
std::string SigV4ASignerImpl::createStringToSign(const absl::string_view canonical_request,
31
                                                 const absl::string_view long_date,
32
95
                                                 const absl::string_view credential_scope) const {
33
95
  auto& crypto_util = Envoy::Common::Crypto::UtilitySingleton::get();
34
95
  return fmt::format(
35
95
      SigV4ASignatureConstants::SigV4AStringToSignFormat, getAlgorithmString(), long_date,
36
95
      credential_scope,
37
95
      Hex::encode(crypto_util.getSha256Digest(Buffer::OwnedImpl(canonical_request))));
38
95
}
39

            
40
void SigV4ASignerImpl::addRegionHeader(Http::RequestHeaderMap& headers,
41
51
                                       const absl::string_view override_region) const {
42
51
  headers.setCopy(SigV4ASignatureHeaders::get().RegionSet,
43
51
                  override_region.empty() ? getRegion() : override_region);
44
51
}
45

            
46
void SigV4ASignerImpl::addRegionQueryParam(Envoy::Http::Utility::QueryParamsMulti& query_params,
47
44
                                           const absl::string_view override_region) const {
48
44
  query_params.add(SignatureQueryParameterValues::AmzRegionSet,
49
44
                   Utility::encodeQueryComponentPreservingPlus(
50
44
                       override_region.empty() ? getRegion() : override_region));
51
44
}
52

            
53
std::string SigV4ASignerImpl::createSignature(
54
    const absl::string_view access_key_id, const absl::string_view secret_access_key,
55
    ABSL_ATTRIBUTE_UNUSED const absl::string_view short_date,
56
    const absl::string_view string_to_sign,
57
95
    ABSL_ATTRIBUTE_UNUSED const absl::string_view override_region) const {
58

            
59
95
  auto& crypto_util = Envoy::Common::Crypto::UtilitySingleton::get();
60
95
  auto ec_key_or = key_derivation_ptr_->derivePrivateKey(access_key_id, secret_access_key);
61
95
  if (!ec_key_or.ok()) {
62
1
    ENVOY_LOG(debug, "SigV4A key derivation failed {}", ec_key_or.status().message());
63
1
    return invalid_signature_;
64
1
  }
65

            
66
94
  std::vector<uint8_t> signature(ECDSA_size(ec_key_or.value()));
67
94
  unsigned int signature_size;
68

            
69
  // Sign the SHA256 hash of our calculated string_to_sign
70
94
  auto hash = crypto_util.getSha256Digest(Buffer::OwnedImpl(string_to_sign));
71

            
72
94
  ECDSA_sign(0, hash.data(), hash.size(), signature.data(), &signature_size, ec_key_or.value());
73

            
74
94
  EC_KEY_free(ec_key_or.value());
75
94
  std::string encoded_signature(
76
94
      Hex::encode(std::vector<uint8_t>(signature.data(), signature.data() + signature_size)));
77

            
78
94
  return encoded_signature;
79
95
}
80

            
81
139
absl::string_view SigV4ASignerImpl::getAlgorithmString() const {
82
139
  return SigV4ASignatureConstants::SigV4AAlgorithm;
83
139
}
84

            
85
} // namespace Aws
86
} // namespace Common
87
} // namespace Extensions
88
} // namespace Envoy