Skip to content

Commit 8d9d8bb

Browse files
Signing fixes
Co-authored-by: Nate Prewitt <[email protected]>
1 parent 80b891a commit 8d9d8bb

File tree

3 files changed

+39
-13
lines changed

3 files changed

+39
-13
lines changed

codegen/core/src/main/java/software/amazon/smithy/python/codegen/ClientGenerator.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,6 @@ await sleep(retry_token.retry_delay)
570570

571571
writer.pushState(new SignRequestSection());
572572
if (context.applicationProtocol().isHttpProtocol() && supportsAuth) {
573-
writer.addStdlibImport("binascii", "hexlify");
574573
writer.addStdlibImport("re");
575574
writer.write("""
576575
# Step 7i: sign the request
@@ -591,12 +590,12 @@ await sleep(retry_token.retry_delay)
591590
logger.debug("Signed HTTP request: %s", context.transport_request)
592591
593592
# TODO - Move this to separate resolution/population function
594-
fields = context._transport_request.fields
593+
fields = context.transport_request.fields
595594
auth_value = fields["Authorization"].as_string() # type: ignore
596595
signature = re.split("Signature=", auth_value)[-1] # type: ignore
597-
context._properties["signature"] = hexlify(signature.encode('utf-8')) # type: ignore
598-
context._properties["identity"] = identity
599-
context._properties["signer_properties"] = auth_option.signer_properties
596+
context.properties["signature"] = signature.encode('utf-8')
597+
context.properties["identity"] = identity
598+
context.properties["signer_properties"] = auth_option.signer_properties
600599
""");
601600
}
602601
writer.popState();

codegen/core/src/main/java/software/amazon/smithy/python/codegen/integrations/RestJsonProtocolGenerator.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.List;
88
import java.util.Set;
99
import software.amazon.smithy.aws.traits.protocols.RestJson1Trait;
10+
import software.amazon.smithy.model.knowledge.EventStreamIndex;
1011
import software.amazon.smithy.model.knowledge.HttpBinding;
1112
import software.amazon.smithy.model.node.ArrayNode;
1213
import software.amazon.smithy.model.node.ObjectNode;
@@ -156,6 +157,21 @@ protected void serializeDocumentBody(
156157
writer.popState();
157158
}
158159

160+
@Override
161+
protected void writeDefaultHeaders(GenerationContext context, PythonWriter writer, OperationShape operation) {
162+
var eventStreamIndex = EventStreamIndex.of(context.model());
163+
if (eventStreamIndex.getInputInfo(operation).isPresent()) {
164+
writer.addImport("smithy_http", "Field");
165+
writer.write(
166+
"Field(name=\"Content-Type\", values=[$S]),",
167+
"application/vnd.amazon.eventstream");
168+
writer.write(
169+
"Field(name=\"X-Amz-Content-SHA256\", values=[$S]),",
170+
"STREAMING-AWS4-HMAC-SHA256-EVENTS");
171+
}
172+
}
173+
174+
159175
@Override
160176
protected void serializePayloadBody(
161177
GenerationContext context,

packages/aws-sdk-signers/src/aws_sdk_signers/signers.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,12 @@ async def _format_canonical_payload(
744744
request: AWSRequest,
745745
signing_properties: SigV4SigningProperties,
746746
) -> str:
747+
if (
748+
"X-Amz-Content-SHA256" in request.fields
749+
and len(request.fields["X-Amz-Content-SHA256"].values) == 1
750+
):
751+
return request.fields["X-Amz-Content-SHA256"].values[0]
752+
747753
payload_hash = await self._compute_payload_hash(
748754
request=request, signing_properties=signing_properties
749755
)
@@ -819,23 +825,26 @@ async def sign_event(
819825
new_signing_properties = SigV4SigningProperties( # type: ignore
820826
**self._signing_properties
821827
)
828+
# TODO: If date is in properties, parse a datetime from it.
829+
date_obj = datetime.datetime.now(datetime.UTC)
822830
if "date" not in new_signing_properties:
823-
date_obj = datetime.datetime.now(datetime.UTC)
824831
new_signing_properties["date"] = date_obj.strftime(
825832
SIGV4_TIMESTAMP_FORMAT
826833
)
827834

828835
timestamp = new_signing_properties["date"]
829-
headers: dict[str, str | bytes] = {":date": timestamp}
836+
headers: dict[str, str | bytes] = {":date": date_obj}
830837
encoder = event_encoder_cls()
831-
encoder.encode_headers(event_message.headers)
838+
encoder.encode_headers(headers)
832839
encoded_headers = encoder.get_result()
833840

841+
payload = event_message.encode()
842+
834843
string_to_sign = await self._event_string_to_sign(
835844
timestamp=timestamp,
836845
scope=self._scope(new_signing_properties),
837846
encoded_headers=encoded_headers,
838-
payload=event_message.payload,
847+
payload=payload,
839848
prior_signature=self._prior_signature,
840849
)
841850
event_signature = await self._sign_event(
@@ -844,10 +853,12 @@ async def sign_event(
844853
signing_properties=new_signing_properties,
845854
)
846855
headers[":chunk-signature"] = event_signature
847-
event_message.headers.update(headers) # type: ignore
856+
857+
event_message.headers = headers
858+
event_message.payload = payload
848859

849860
# set new prior signature before releasing the lock
850-
self._prior_signature = event_signature
861+
self._prior_signature = hexlify(event_signature)
851862

852863
return event_message
853864

@@ -861,10 +872,10 @@ async def _event_string_to_sign(
861872
prior_signature: bytes,
862873
) -> str:
863874
return (
864-
"AWS-HMAC-SHA256-PAYLOAD\n"
875+
"AWS4-HMAC-SHA256-PAYLOAD\n"
865876
f"{timestamp}\n"
866877
f"{scope}\n"
867-
f"{hexlify(prior_signature).decode('utf-8')}\n"
878+
f"{prior_signature.decode('utf-8')}\n"
868879
f"{sha256(encoded_headers).hexdigest()}\n"
869880
f"{sha256(payload).hexdigest()}"
870881
)

0 commit comments

Comments
 (0)