in source/aws_signing.c [1476:1566]
static int s_build_canonical_payload(struct aws_signing_state_aws *state) {
const struct aws_signable *signable = state->signable;
struct aws_allocator *allocator = state->allocator;
struct aws_byte_buf *payload_hash_buffer = &state->payload_hash;
AWS_ASSERT(payload_hash_buffer->len == 0);
struct aws_byte_buf body_buffer;
AWS_ZERO_STRUCT(body_buffer);
struct aws_byte_buf digest_buffer;
AWS_ZERO_STRUCT(digest_buffer);
struct aws_hash *hash = NULL;
int result = AWS_OP_ERR;
if (state->config.signed_body_value.len == 0) {
/* No value provided by user, so we must calculate it */
hash = aws_sha256_new(allocator);
if (hash == NULL) {
return AWS_OP_ERR;
}
if (aws_byte_buf_init(&body_buffer, allocator, BODY_READ_BUFFER_SIZE) ||
aws_byte_buf_init(&digest_buffer, allocator, AWS_SHA256_LEN)) {
goto on_cleanup;
}
struct aws_input_stream *payload_stream = NULL;
if (aws_signable_get_payload_stream(signable, &payload_stream)) {
goto on_cleanup;
}
if (payload_stream != NULL) {
if (aws_input_stream_seek(payload_stream, 0, AWS_SSB_BEGIN)) {
goto on_cleanup;
}
struct aws_stream_status payload_status;
AWS_ZERO_STRUCT(payload_status);
while (!payload_status.is_end_of_stream) {
/* reset the temporary body buffer; we can calculate the hash in window chunks */
body_buffer.len = 0;
if (aws_input_stream_read(payload_stream, &body_buffer)) {
goto on_cleanup;
}
if (body_buffer.len > 0) {
struct aws_byte_cursor body_cursor = aws_byte_cursor_from_buf(&body_buffer);
aws_hash_update(hash, &body_cursor);
}
if (aws_input_stream_get_status(payload_stream, &payload_status)) {
goto on_cleanup;
}
}
/* reset the input stream for sending */
if (aws_input_stream_seek(payload_stream, 0, AWS_SSB_BEGIN)) {
goto on_cleanup;
}
}
if (aws_hash_finalize(hash, &digest_buffer, 0)) {
goto on_cleanup;
}
struct aws_byte_cursor digest_cursor = aws_byte_cursor_from_buf(&digest_buffer);
if (aws_hex_encode_append_dynamic(&digest_cursor, payload_hash_buffer)) {
goto on_cleanup;
}
} else {
/* Use value provided in config */
if (aws_byte_buf_append_dynamic(payload_hash_buffer, &state->config.signed_body_value)) {
goto on_cleanup;
}
}
result = AWS_OP_SUCCESS;
on_cleanup:
aws_byte_buf_clean_up(&digest_buffer);
aws_byte_buf_clean_up(&body_buffer);
if (hash) {
aws_hash_destroy(hash);
}
return result;
}