[ARCH-332] KMS keystore support#1767
Conversation
✅ API Diff Results - No breaking changes |
| "github.com/ethereum/go-ethereum/crypto/secp256k1" | ||
| ) | ||
|
|
||
| // SPKI represents the SubjectPublicKeyInfo structure as defined in [RFC 5280] in ASN.1 format. |
There was a problem hiding this comment.
This is partially lifted from https://github.com/smartcontractkit/chainlink-deployments-framework/blob/main/chain/evm/provider/kms_signer.go, however with the following changes:
- Ethereum specific terminology removed. SEC1 is a format thats used in Ethereums and blockchains in general, but its not ethereum specific.
- Added SEC1->ASN1 conversion functions as well so we can just round trip test converting sig/pubkeys between the 2 formats.
Originally I was going to keep it internal, but if I export the helpers then I can remove the second impl in chainlink-deployments-framework.
| kmslib "github.com/aws/aws-sdk-go/service/kms" | ||
| ) | ||
|
|
||
| // Client is an interface that defines the methods for interacting with AWS KMS. We only expose |
There was a problem hiding this comment.
Similar to whats used in CLD, except I exposed another 2 functions to allow for the Reader interface to be implemented. I also dropped the region stuff, that can be specified in the AWS profile so seems simpler to just let people specify that there.
| KeyID string | ||
| } | ||
|
|
||
| func NewFakeKMSClient(keys []Key) (*FakeKMSClient, error) { |
There was a problem hiding this comment.
A fake seemed to fit well here instead of mocking/mockery
| Short: "CLI for managing keystore keys", | ||
| SilenceUsage: true, | ||
| } | ||
| cmd.PersistentFlags().String("file-path", "", "Overrides KEYSTORE_FILE_PATH environment variable") |
There was a problem hiding this comment.
On second thought I don't think these are worth the trouble just removing them (would have to add another one for KMS too).
| cmd.PersistentFlags().String("password", "", "Overrides KEYSTORE_PASSWORD environment variable. Not recommended as will leave shell traces.") | ||
|
|
||
| cmd.AddCommand(NewListCmd(), NewGetCmd(), NewCreateCmd(), NewDeleteCmd(), NewExportCmd(), NewImportCmd(), NewSetMetadataCmd(), NewSignCmd(), NewVerifyCmd(), NewEncryptCmd(), NewDecryptCmd()) | ||
| // Check if KMS profile is set - if so, hide commands that don't work with KMS |
There was a problem hiding this comment.
CLI can't be used to create KMS keys, so we hide admin intf
|
|
||
| // padTo32Bytes pads the given byte slice to 32 bytes by trimming leading zeros and prepending | ||
| // zeros. | ||
| func padTo32Bytes(buffer []byte) []byte { |
There was a problem hiding this comment.
sorry, what would this function do with make([]byte, 32) input? Will it 1. first trim each of the 32 bytes since they are zero, and 2. then readd each zero byte to the slice?
There was a problem hiding this comment.
yeah it would, I suppose it could be optimized for that specific case. But doesn't seem worth the trouble
| } | ||
|
|
||
| keys = append(keys, keystore.GetKeyResponse{ | ||
| KeyInfo: keystore.KeyInfo{ |
There was a problem hiding this comment.
Should newKeyInfo be used instead?
There was a problem hiding this comment.
its unexported right now from the main package, I think we could export it though and use it. Can do in the next PR (planning to add ed25519 support for KMS next)
| kmsProfile := os.Getenv("KEYSTORE_KMS_PROFILE") | ||
| if kmsProfile != "" { | ||
| client, err := kms.NewClient(kmsProfile) |
There was a problem hiding this comment.
Would this work with KMS already set in the environment variables? For example, does this work with aws-vault, which I know a lot of people use to have AWS tokens in the Apple Keychain.
There was a problem hiding this comment.
yes I believe so because the profile credentials are top of the priority stack. Haven't tested that, but I suspect the KMS pointer/config may need to iterate a bit as we try it out in different scenarios
It seems ed25519 is now also supported in KMS. Will add in a follow up.
Confirmed CLI works against real KMS in staging.