theupdateframework / go-tuf

Go implementation of The Update Framework (TUF)
https://theupdateframework.com
Apache License 2.0
618 stars 104 forks source link

Support AWS KMS signing #525

Open ChevronTango opened 1 year ago

ChevronTango commented 1 year ago

Right now the only way of signing your metadata files is by using a local key file. Many users would prefer to store sensitive keys in KMS. tools like 'tuftool' allow for specifying an AWS KMS id (eg. tuftool root sign --key aws-kms:///<my-kms-id>) and using that to sign the various role metadata files, allowing for a more safe environment. It would be great if the go CLI equally supported this functionality and use case.

ChevronTango commented 1 year ago

I was able to achieve this using a few tricks and I wanted to document it here in case others came looking for a solution. I still think a built in solution would be elegant.

Firstly I had to add the key to my root.json, and the easiest method I found for doing that was to use tuftool. I'll raise a new issue to cover off asking for an easier way to achieve this in the tuf-cli, but its just some json manipulation and resigning so shouldn't be too hard.

export TARGETS_TUF_KEY_ID=$(tuftool root add-key "staged/root.json" "aws-kms://$TARGETS_KMS_ID" --role targets)

After that I then was able to successfully sign the targets.json with a kms key using the following:

aws kms sign \
--key-id $TARGETS_KMS_ID \
--signing-algorithm RSASSA_PSS_SHA_256  \
--message-type RAW \
--message "$(tuf payload targets.json | base64 -w 0)" \
| jq -r '.Signature' | base64 -d -w 0 | xxd -p | tr -d \\n \
| jq -R --arg keyid "$TARGETS_TUF_KEY_ID" '[{"keyid": $keyid, "sig": .}]' > targets.json.signature

tuf add-signature --signature targets.json.signature targets.json

I suspect I could tidy this up a bit more but I was just happy to have a working kms signing solution.

for reference, my KMS key is RSA_4096 and SIGN_VERIFY and my root.json entry looks like the following:

...
"keys": {
    "<TARGETS_TUF_KEY_ID>": {
        "keytype": "rsa",
        "keytype": {"public": "-----BEGIN PUBLIC KEY-----\nxxxxxxxxxxxxxxxxxxxxxx\n-----END PUBLIC KEY-----\n"},
        "scheme": "rsassa-pss-sha256",
    }
}
...
udf2457 commented 1 year ago

I agree more should be done to improve support for offline storage of keys. From my perspective (#427), PKCS#11 support would be far more useful, that would mean you could integrate smartcards, yubikeys etc. I assume AWS KMS should be able to talk PKCS#11 too, or maybe they save that for AWS CloudHSM ?