summaryrefslogtreecommitdiff
path: root/Utilities/cmcurl/lib/http_aws_sigv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/http_aws_sigv4.c')
-rw-r--r--Utilities/cmcurl/lib/http_aws_sigv4.c74
1 files changed, 57 insertions, 17 deletions
diff --git a/Utilities/cmcurl/lib/http_aws_sigv4.c b/Utilities/cmcurl/lib/http_aws_sigv4.c
index 440eb385f8..8c6d1c9dc8 100644
--- a/Utilities/cmcurl/lib/http_aws_sigv4.c
+++ b/Utilities/cmcurl/lib/http_aws_sigv4.c
@@ -32,8 +32,6 @@
#include "http_aws_sigv4.h"
#include "curl_sha256.h"
#include "transfer.h"
-
-#include "strcase.h"
#include "parsedate.h"
#include "sendf.h"
@@ -118,7 +116,7 @@ static void trim_headers(struct curl_slist *head)
}
}
-/* maximum lenth for the aws sivg4 parts */
+/* maximum length for the aws sivg4 parts */
#define MAX_SIGV4_LEN 64
#define MAX_SIGV4_LEN_TXT "64"
@@ -268,6 +266,40 @@ fail:
return ret;
}
+#define CONTENT_SHA256_KEY_LEN (MAX_SIGV4_LEN + sizeof("X--Content-Sha256"))
+
+/* try to parse a payload hash from the content-sha256 header */
+static char *parse_content_sha_hdr(struct Curl_easy *data,
+ const char *provider1,
+ size_t *value_len)
+{
+ char key[CONTENT_SHA256_KEY_LEN];
+ size_t key_len;
+ char *value;
+ size_t len;
+
+ key_len = msnprintf(key, sizeof(key), "x-%s-content-sha256", provider1);
+
+ value = Curl_checkheaders(data, key, key_len);
+ if(!value)
+ return NULL;
+
+ value = strchr(value, ':');
+ if(!value)
+ return NULL;
+ ++value;
+
+ while(*value && ISBLANK(*value))
+ ++value;
+
+ len = strlen(value);
+ while(len > 0 && ISBLANK(value[len-1]))
+ --len;
+
+ *value_len = len;
+ return value;
+}
+
CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
{
CURLcode ret = CURLE_OUT_OF_MEMORY;
@@ -286,6 +318,8 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
struct dynbuf canonical_headers;
struct dynbuf signed_headers;
char *date_header = NULL;
+ char *payload_hash = NULL;
+ size_t payload_hash_len = 0;
const char *post_data = data->set.postfields;
size_t post_data_len = 0;
unsigned char sha_hash[32];
@@ -308,7 +342,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
return CURLE_OK;
}
- /* we init thoses buffers here, so goto fail will free initialized dynbuf */
+ /* we init those buffers here, so goto fail will free initialized dynbuf */
Curl_dyn_init(&canonical_headers, CURL_MAX_HTTP_HEADER);
Curl_dyn_init(&signed_headers, CURL_MAX_HTTP_HEADER);
@@ -403,17 +437,23 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
memcpy(date, timestamp, sizeof(date));
date[sizeof(date) - 1] = 0;
- if(post_data) {
- if(data->set.postfieldsize < 0)
- post_data_len = strlen(post_data);
- else
- post_data_len = (size_t)data->set.postfieldsize;
- }
- if(Curl_sha256it(sha_hash, (const unsigned char *) post_data,
- post_data_len))
- goto fail;
+ payload_hash = parse_content_sha_hdr(data, provider1, &payload_hash_len);
- sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex));
+ if(!payload_hash) {
+ if(post_data) {
+ if(data->set.postfieldsize < 0)
+ post_data_len = strlen(post_data);
+ else
+ post_data_len = (size_t)data->set.postfieldsize;
+ }
+ if(Curl_sha256it(sha_hash, (const unsigned char *) post_data,
+ post_data_len))
+ goto fail;
+
+ sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex));
+ payload_hash = sha_hex;
+ payload_hash_len = strlen(sha_hex);
+ }
{
Curl_HttpReq httpreq;
@@ -427,13 +467,13 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
"%s\n" /* CanonicalQueryString */
"%s\n" /* CanonicalHeaders */
"%s\n" /* SignedHeaders */
- "%s", /* HashedRequestPayload in hex */
+ "%.*s", /* HashedRequestPayload in hex */
method,
data->state.up.path,
data->state.up.query ? data->state.up.query : "",
Curl_dyn_ptr(&canonical_headers),
Curl_dyn_ptr(&signed_headers),
- sha_hex);
+ (int)payload_hash_len, payload_hash);
if(!canonical_request)
goto fail;
}
@@ -460,7 +500,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy)
/*
* Google allows using RSA key instead of HMAC, so this code might change
- * in the future. For now we ony support HMAC.
+ * in the future. For now we only support HMAC.
*/
str_to_sign = curl_maprintf("%s4-HMAC-SHA256\n" /* Algorithm */
"%s\n" /* RequestDateTime */