userver: userver/crypto/aws.hpp Source File
Loading...
Searching...
No Matches
aws.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/crypto/aws.hpp
4/// @brief AWS Signature Version 4 helpers
5/// @ingroup userver_universal
6
7#include <ctime>
8#include <string>
9#include <string_view>
10
11#include <userver/http/header_map.hpp>
12#include <userver/http/predefined_header.hpp>
13
14USERVER_NAMESPACE_BEGIN
15
16/// AWS Signature Version 4
17namespace crypto::aws {
18
19/// @see https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv-create-signed-request.html
20inline constexpr std::string_view kAws4HmacSha256 = "AWS4-HMAC-SHA256";
21inline constexpr std::string_view kAws4Request = "aws4_request";
22inline constexpr std::string_view kUnsignedPayload = "UNSIGNED-PAYLOAD";
23
24inline constexpr USERVER_NAMESPACE::http::headers::PredefinedHeader kAmzDate{"X-Amz-Date"};
25inline constexpr USERVER_NAMESPACE::http::headers::PredefinedHeader kAmzContentSha256{"X-Amz-Content-Sha256"};
26
27/// Inputs for header-based AWS Signature Version 4.
28///
29/// `Host` must already be present in the header map. `canonical_uri` and
30/// `canonical_query` are service-specific (see the SigV4 docs); they are not
31/// derived from the headers.
33 std::string_view http_method;
34 std::string_view canonical_uri;
35 std::string_view canonical_query{};
36 std::string_view payload{};
37 std::string_view access_key;
38 std::string_view secret_key;
39 std::string_view region;
40 std::string_view service;
41};
42
43/// Date and credential scope used to sign a request.
45 std::time_t now{};
46 std::string amz_date;
47 std::string date_stamp;
48 std::string credential_scope;
49};
50
51/// Adds `X-Amz-Date`, `X-Amz-Content-Sha256` and `Authorization` to @a headers.
52///
53/// @throws std::runtime_error if `Host` is missing or empty
54void SignRequestV4(USERVER_NAMESPACE::http::headers::HeaderMap& headers, const SignV4Request& request);
55
56/// Builds `YYYYMMDDThhmmssZ`, `YYYYMMDD` and `{date}/{region}/{service}/aws4_request`
57/// from the current time (`utils::datetime::Now`, mockable in tests).
58V4TimeScope MakeV4TimeScope(std::string_view region, std::string_view service);
59
60/// Canonical request string: method, URI, query, headers, signed headers, payload hash.
62 std::string_view http_method,
63 std::string_view canonical_uri,
64 std::string_view canonical_query,
65 std::string_view canonical_headers,
66 std::string_view signed_headers,
67 std::string_view payload_hash
68);
69
70/// `AWS4-HMAC-SHA256` string to sign for @a canonical_request.
71std::string MakeV4StringToSign(std::string_view canonical_request, const V4TimeScope& scope);
72
73/// HMAC-SHA256 signature of @a string_to_sign with the derived signing key.
74std::string MakeV4Signature(
75 std::string_view string_to_sign,
76 const V4TimeScope& scope,
77 std::string_view region,
78 std::string_view service,
79 std::string_view secret_key
80);
81
82} // namespace crypto::aws
83
84USERVER_NAMESPACE_END