AWS FreeRTOS code signing and cross accounts OTA Jobs

0

Hello!

Is there a way one can easily retrieve the code signing signature of a binary that has been successfully signed by AWS Code Signer with a Code Signing Profile for AWS FreeRTOS? So essentially I have a signed binary and its corresponding AWS Code Signing JobId, is it possible to retrieve its code signing signature (without unpacking the binary manually that is)?

Here's some info on why I am asking this. In this specific case, my Ci/Cd pipeline executes from a dedicated AWS service account that signs newly built firmwares once, amongst other things. These signed firmwares are then deployed to target AWS workload accounts. OTA Jobs need to be created in these target accounts from these same signed firmware, passed around cross-accounts. Since the original CodeSigning Jobs are not visible to these target accounts, one alternative is to treat signed firmwares as custom signing jobs when creating OTA Jobs, hence the original code signing signature is then needed as input.

Cheers, Will.

4 Answers
1
Accepted Answer

Hi Will.

Is there a way one can easily retrieve the code signing signature of a binary that has been successfully signed by AWS Code Signer with a Code Signing Profile for AWS FreeRTOS?

The output from from the signing operation isn't a binary. It's a JSON file, with the signature and and the original binary held as base64 encoded strings. Like this:

{"rawPayloadSize":123456,"signature":"foobar","signatureAlgorithm":"SHA256withECDSA","payload":"yadayada"}

So the unpack is pretty trivial.

OTA Jobs need to be created in these target accounts from these same signed firmware, passed around cross-accounts.

CreateOTAUpdate can be called without doing the signing again. However, there's a trick. The file stream it creates is of the original raw binary file, not the JSON object output by the code signing. When CreateOTAUpdate performs the code signing, it saves the output (the JSON) to the /SignedImages folder of the bucket. And it overwrites the object key again with the original raw binary. So both the raw binary, and the signed JSON, are denoted by the same object key. They're just different object versions. You'll need the raw binary in your deployment accounts as well, to make the CreateOTAUpdate call. (Or you could extract the binary from the JSON of course.)

Enter image description here

Since the original CodeSigning Jobs are not visible to these target accounts, one alternative is to treat signed firmwares as custom signing jobs when creating OTA Jobs, hence the original code signing signature is then needed as input.

Nice. If you're happy to get it from the JSON.

CreateOTAUpdate is really a convenience API that calls StartSigningJob, CreateStream and CreateJob. You can call these directly instead. So it may make sense to do the signing in your CI/CD account, and do only CreateStream and CreateJob in your deployment accounts. More information here: https://github.com/aws-samples/aws-iot-create-ota-update-deconstructed

profile pictureAWS
EXPERT
Greg_B
answered 18 days ago
  • Champion Greg!

    I wrongly assumed that the output of Code Signer was a signed binary, had I been more curious I would have found everything I needed right there :-). Perfect. Thanks for the tip also, in this specific scenario a better approach is to directly build the OTA job with CreateStream + CreateJob, I am already signing the binary with StartSigningJob independently after all.

    Cheers, Will.

0

Hey Will,

The signature used by OTA is included in the OTA Job document. You can view it in the console by clicking on the "job document" tab after selecting your OTA job.

From the aws cli, you can get the contents of this job document: aws iot get-job-document --job-id <job id here> and process this to get the signature in the sig-sha256-ecdsa or similar field depending on the signature type.

You might find this sample useful: https://github.com/aws-samples/aws-iot-create-ota-update-deconstructed

Thanks much,

Paul

AWS
answered 19 days ago
profile picture
EXPERT
reviewed 19 days ago
0

Hi Paul,

Precisely! To create an OTA Job in the first place, either the Code Signing JobId, or signature (for custom signed binary) is needed, neither of which can be accessed in the target workload accounts in which the OTA Jobs are to be created. The reason for this is because signing takes place in a separate AWS service account where ci/cd and AWS Code Signer are executed.

A hacky approach might indeed be to create a fake OTA Job in the originating AWS service account to reveal the signature, and then delete the OTA Job immediately. The signed binary and signature could then be passed on cross-account to the target AWS workload accounts, in which the OTA jobs need to be created. Essentially, my approach is to avoid releasing potentially divergent binaries by re-signing in each target workload account, best practice of moving the same unmodified artefact through deployment stages.

Cheers, Will.

answered 19 days ago
0

Hello Will,

I see your point and the issue you are facing.

my approach is to avoid releasing potentially divergent binaries by re-signing in each target workload account

I am trying to understand why would the binaries be divergent if you are using same algorithm and same source binary to be signed and are signing it using the same cert?

Regardless, if you have the code signing algorithm and the certificate with which to sign the binary, you can generate the signed binary yourself without having to rely on the IoT Jobs to sign the image for you. You can then pass around the image and the binary to the deployment stages. Would this approach work?

Thanks, Aniruddha

answered 18 days ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions