-
Notifications
You must be signed in to change notification settings - Fork 60
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
Support ECDH for ECDSA keys #80
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for sending a PR :)
Keys implement an optional interface because it's what the standard library wants. The only prior art I could find for Diffie-Hellman was:
I think this package shouldn't establishing a key agreement interface. Maybe just export keyECDSA as concrete type that you can type switch on?
type ECPrivetKey struct {}
func (k *ECPrivateKey) Public() crypto.Public {}
func (k *ECPrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)
func (k *ECPrivateKey) KeyAgreement(peer *ecdsa.PublicKey) ([]byte, error)
Then using the API looks like:
priv, err := yk.PrivateKey(slot, pub, auth)
if err != nil {
// ...
}
ecPriv, ok := priv.(*piv.ECPrivateKey)
if !ok {
// ...
}
sharedKey, err := ecPriv.KeyAgreement(peer)
If there's ever an actual key agreement interface to satisfy in the future, then ECPrivateKey can implement that later.
Ooh I hadn't found the stdlib one. Of course it makes sense TLS would have one. I'll happily steal the The reason I exported an interface, not a concrete type, was that I was thinking there might be a non-ECDSA keytype that can do Diffie-Hellman on the yubikey. But yeah the interface is easy to add later, if and when. I can switch to a concrete type. |
Naming question: You used |
ECDSAPrivateKey works for me |
Pushed fixups for all feedback above. If you're happy with the end result, I'll rebase them together and take the draft flag off this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple comments, but other than that lgtm. Thanks for this!
piv/key.go
Outdated
@@ -667,24 +671,82 @@ func (yk *YubiKey) PrivateKey(slot Slot, public crypto.PublicKey, auth KeyAuth) | |||
} | |||
} | |||
|
|||
type keyECDSA struct { | |||
// ECDSAPrivateKey is used to access a ECDSA signing key. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: include user instructions to get a *ECDSAPrivateKey. Anyone reading the docs will probably appreciate that :)
// ECDSAPrivateKey is a crypto.PrivateKey implementation used to directly access ECDSA
// operations. Keys returned by PrivateKey() can be type casted to use these methods.
//
// priv, err := yk.PrivateKey(slot, pub, auth)
// if err != nil {
// // ...
// }
// ecdsaPriv, ok := priv.(*piv. ECDSAPrivateKey)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wrote proper examples for SharedKey, that should also demonstrate this, and the documentation for the type referring there.
Oh an please squash your commits :) I can merge after |
Squashed, all ready to go. (Branch |
Oops, sorry, I want to clean up one more nit in the example. |
Nope, nevermind, what I needed to do was refresh my godoc window to see that I had already fixed the nit. All good! |
Feedback on APIs would be most welcome.
Fixes #79