Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor keys to allow more key types and add RSA key verifier #148

Merged
merged 18 commits into from
Oct 6, 2021

Conversation

asraa
Copy link
Contributor

@asraa asraa commented Sep 1, 2021

Local tests passes, still working on interop tests and double-checking for clean-up/small changes

This change makes it more friendly to add new keytypes:

  • There are now two data types, data.Key and data.PrivateKey representing the json data for public and private keys
  • There are two interfaces Signer and Verifier in the keys package that define conversions between the data formats and methods that are needed by the other modules
  • There is a map KeyMap that registers a key type with the Signer/Verifier implementation. You don't need both to register in the key map (e.g. go-tuf only verifies ecdsa, does not support signing)

Ah, another pain point: maybe there should be a file moving refactor so that the library code is in pkg/. these a keys/ package also conflicts with the keys/ folder that go-tuf creates for storing keys....

asraa added 3 commits August 30, 2021 12:46
Signed-off-by: Asra Ali <[email protected]>
Signed-off-by: Asra Ali <[email protected]>
Signed-off-by: Asra Ali <[email protected]>
@coveralls
Copy link

coveralls commented Sep 1, 2021

Pull Request Test Coverage Report for Build 1221983175

  • 108 of 188 (57.45%) changed or added relevant lines in 7 files are covered.
  • 171 unchanged lines in 3 files lost coverage.
  • Overall coverage decreased (-0.3%) to 69.178%

Changes Missing Coverage Covered Lines Changed/Added Lines %
local_store.go 19 20 95.0%
verify/db.go 9 11 81.82%
repo.go 9 12 75.0%
pkg/keys/keys.go 6 20 30.0%
pkg/keys/ed25519.go 57 80 71.25%
pkg/keys/ecdsa.go 3 40 7.5%
Files with Coverage Reduction New Missed Lines %
verify/verify.go 1 71.08%
client/delegations.go 8 78.67%
repo.go 162 72.1%
Totals Coverage Status
Change from base Build 1175464948: -0.3%
Covered Lines: 1809
Relevant Lines: 2615

💛 - Coveralls

client/client_test.go Outdated Show resolved Hide resolved
local_store.go Outdated Show resolved Hide resolved
verify/verifiers.go Outdated Show resolved Hide resolved
Signed-off-by: Asra Ali <[email protected]>
@asraa
Copy link
Contributor Author

asraa commented Sep 2, 2021

addressed some comments

Signed-off-by: Asra Ali <[email protected]>
@asraa asraa changed the title WIP Refactor keys to make key additions friendly Refactor keys to make key additions friendly Sep 3, 2021
Copy link

@d-niu d-niu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I really like the generalized approach to key types and separating the interfaces for signing/verification accordingly.

My biggest question is around the structure of the Signer interface + implementing a signer struct for each key. Right now, it's not very flexible for generating signatures (or verifications) in a kms.

Ideally, I would like to use as much of the same code to create keys with go's crypto package and any type of external key gen system. Right now, I'm thinking that creating keys, signing, verifying, and getting public keys should all be interface methods of kms. I'm not too sure what the best approach is here, but I think making the Signer and Verifier more abstract or even changing how we store things in the Key Map would work.

Here's the general structure of what I was thinking for key management systems. Though I have to admit, I wasn't really writing this with the current way keys are generating in memory in mind :/

Copy link
Member

@trishankatdatadog trishankatdatadog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I am ok with this. I understand @d-niu's concerns about extending this API to abstract away things like where the signing operation is actually being done, but I think this can be fixed later.

Can you finish moving the files for keys under keys/ to pkg?

keys/ed25519.go Outdated Show resolved Hide resolved
keys/keys.go Outdated Show resolved Hide resolved
@asraa
Copy link
Contributor Author

asraa commented Sep 7, 2021

Right now, I'm thinking that creating keys, signing, verifying, and getting public keys should all be interface methods of kms. I'm not too sure what the best approach is here, but I think making the Signer and Verifier more abstract or even changing how we store things in the Key Map would work.

Hm I think Signer and Verify should be separate (although they can be the same object in the case of a KMS client). Looking at your code, the part that probably won't fit is the crypto.Signer operation, since I don't think KMS easily supports crypto.Signer interface without a lot of finagling. Do you know what the Sign parameters should look like?

Edit: Wanna chat about the way things are stored in the Key Map? The Key Map is just meant to translate "type name" to an "empty type implementation". UnmarshalKey is meant to take the public key data from the JSON (probably including key resource ID) and try to instantiate the kms client. A method (NOT in the interface), like GenerateHashiVaultKey would look like the func HVClient(keyResourceID string) (KMSClient, error) you have. Does that make sense?

Signed-off-by: Asra Ali <[email protected]>
Signed-off-by: Asra Ali <[email protected]>
@asraa
Copy link
Contributor Author

asraa commented Sep 7, 2021

OK simplified the interface even more.

@asraa
Copy link
Contributor Author

asraa commented Sep 7, 2021

I might be missing something, but why can't GetVerifier() be a method of the key?

GetVerifier as a method data.Key? because it would introduce a circular dependency. (data.Key shouldn't know about the key implementations)

Edit: If you were looking at that test -- the purpose of GetVerifier is to take the JSON data.Key found in metadata and translate that to a verifier. I was testing basically testing marshalling to JSON and GetVerifier'ing back. So you create a key and sign and marshal as the repo builder, and then GetVerifier and verify as the client.

Copy link
Member

@trishankatdatadog trishankatdatadog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to unblock this for now, we can refine API if need be later

@trishankatdatadog
Copy link
Member

Oh, one more thing: we need RSA support, no?

@asraa
Copy link
Contributor Author

asraa commented Sep 7, 2021

Sounds good, we'll need to work how KMS signers will deal with crypto.Signer. (Probably we'll just define the Sign(...) method in the interface). Sigstore has a massive workaround for it, but we should keep it simple.

@asraa
Copy link
Contributor Author

asraa commented Sep 7, 2021

Oh, one more thing: we need RSA support, no?

I have a local follow-up PR!

@trishankatdatadog
Copy link
Member

trishankatdatadog commented Sep 7, 2021

Who else should we have review approve this? @hosseinsia @joshuagl @mnm678? Should not both be DD

@d-niu
Copy link

d-niu commented Sep 7, 2021

Edit: Wanna chat about the way things are stored in the Key Map? The Key Map is just meant to translate "type name" to an "empty type implementation". UnmarshalKey is meant to take the public key data from the JSON (probably including key resource ID) and try to instantiate the kms client. A method (NOT in the interface), like GenerateHashiVaultKey would look like the func HVClient(keyResourceID string) (KMSClient, error) you have. Does that make sense?

So, generating different types of keys, signing, and verifying in kms should not necessarily be under a separate kms interface. Instead, the connection to a kms client like hashicorp vault should be generated when you use a key from the key map and realize that it has some other attributes during UnmarshalKey, for instance.

@asraa
Copy link
Contributor Author

asraa commented Sep 7, 2021

Instead, the connection to a kms client like hashicorp vault should be generated when you use a key from the key map and realize that it has some other attributes during UnmarshalKey, for instance.

Maybe the constructors held in the map should have an Context or Params object?

@d-niu
Copy link

d-niu commented Sep 7, 2021

Maybe the constructors held in the map should have an Context or Params object?

For sure. Would context/params just hold something to indicate whether its locally generated or in a kms though? We probably won't store kms access tokens or paths in these params.

@asraa
Copy link
Contributor Author

asraa commented Sep 22, 2021

Added RSA key implementation.

@asraa asraa changed the title Refactor keys to make key additions friendly Refactor keys to allow more key types and add RSA key verifier Sep 22, 2021
Copy link
Contributor

@hosseinsia hosseinsia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job! Started reviewing. Some minor comments so far.

pkg/keys/ed25519.go Outdated Show resolved Hide resolved
local_store.go Outdated Show resolved Hide resolved
local_store.go Outdated Show resolved Hide resolved
local_store.go Outdated Show resolved Hide resolved
Signed-off-by: Asra Ali <[email protected]>
Signed-off-by: Asra Ali <[email protected]>
pkg/keys/ed25519.go Outdated Show resolved Hide resolved
pkg/keys/ed25519.go Outdated Show resolved Hide resolved
pkg/keys/ed25519.go Outdated Show resolved Hide resolved
repo.go Outdated Show resolved Hide resolved
data/types.go Show resolved Hide resolved
local_store.go Show resolved Hide resolved
local_store.go Outdated Show resolved Hide resolved
pkg/keys/rsa_test.go Outdated Show resolved Hide resolved
pkg/keys/rsa_test.go Outdated Show resolved Hide resolved
repo.go Outdated Show resolved Hide resolved
repo.go Outdated Show resolved Hide resolved
repo_test.go Outdated Show resolved Hide resolved
pkg/keys/keys.go Outdated Show resolved Hide resolved
repo_test.go Outdated Show resolved Hide resolved
pkg/keys/rsa_test.go Outdated Show resolved Hide resolved
verify/db.go Outdated Show resolved Hide resolved
verify/db.go Outdated Show resolved Hide resolved
verify/db.go Outdated Show resolved Hide resolved
verify/db.go Outdated Show resolved Hide resolved
verify/db.go Outdated Show resolved Hide resolved
pkg/keys/keys.go Show resolved Hide resolved
pkg/keys/keys.go Outdated Show resolved Hide resolved
pkg/keys/keys.go Outdated Show resolved Hide resolved
Signed-off-by: Asra Ali <[email protected]>
repo.go Outdated Show resolved Hide resolved
data/types.go Show resolved Hide resolved
data/types.go Outdated Show resolved Hide resolved
Signed-off-by: Asra Ali <[email protected]>
Signed-off-by: Asra Ali <[email protected]>
@hosseinsia
Copy link
Contributor

Fantastic work!
LGTM!

Copy link
Contributor

@hosseinsia hosseinsia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@trishankatdatadog
Copy link
Member

Thank you both very much, @asraa and @hosseinsia!

I would strongly encourage @joshuagl to review and approve to ensure there is no collusion 🙂

Copy link
Member

@trishankatdatadog trishankatdatadog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving in order to unblock. Great work, Asra! 🎉

@trishankatdatadog trishankatdatadog merged commit 1dc15a8 into theupdateframework:master Oct 6, 2021
@tamird
Copy link
Contributor

tamird commented Oct 8, 2021

This PR added a dependency on github.com/pkg/errors. I've sent #166 to replace the dependency with standard library functions.

mnm678 pushed a commit to mnm678/go-tuf that referenced this pull request Oct 21, 2021
…dateframework#148)

* wip

Signed-off-by: Asra Ali <[email protected]>

* update for testing

Signed-off-by: Asra Ali <[email protected]>

* working

Signed-off-by: Asra Ali <[email protected]>

* address comments

Signed-off-by: Asra Ali <[email protected]>

* factor to helper

Signed-off-by: Asra Ali <[email protected]>

* simplify key interface

Signed-off-by: Asra Ali <[email protected]>

* move into pkg/

Signed-off-by: Asra Ali <[email protected]>

* update impls

Signed-off-by: Asra Ali <[email protected]>

* remove empty block

Signed-off-by: Asra Ali <[email protected]>

* joshua suggestions

Signed-off-by: Asra Ali <[email protected]>

* add rsa key

Signed-off-by: Asra Ali <[email protected]>

* address comments

Signed-off-by: Asra Ali <[email protected]>

* update method name

Signed-off-by: Asra Ali <[email protected]>

* address preliminary comments

Signed-off-by: Asra Ali <[email protected]>

* address comments

Signed-off-by: Asra Ali <[email protected]>

* address comments

Signed-off-by: Asra Ali <[email protected]>

* add panic

Signed-off-by: Asra Ali <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants