ssh: implement CryptoPublicKey on sk keys

This commit implements the CryptoPublicKey interface for the
skECDSAPublicKey and skEd25519PublicKey types.

Fixes golang/go#62518

Change-Id: I2b8ac89196fbb3614bf5c675127bed23f1cf6b26
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/526875
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Auto-Submit: Nicola Murino <nicola.murino@gmail.com>
Reviewed-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
Mariano Cano
2024-05-29 18:20:30 +00:00
committed by Gopher Robot
parent 44c9b0ff9e
commit 349231f7e4
2 changed files with 54 additions and 0 deletions
+8
View File
@@ -904,6 +904,10 @@ func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error {
return errors.New("ssh: signature did not verify")
}
func (k *skECDSAPublicKey) CryptoPublicKey() crypto.PublicKey {
return &k.PublicKey
}
type skEd25519PublicKey struct {
// application is a URL-like string, typically "ssh:" for SSH.
// see openssh/PROTOCOL.u2f for details.
@@ -1000,6 +1004,10 @@ func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error {
return nil
}
func (k *skEd25519PublicKey) CryptoPublicKey() crypto.PublicKey {
return k.PublicKey
}
// NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,
// *ecdsa.PrivateKey or any other crypto.Signer and returns a
// corresponding Signer instance. ECDSA keys must use P-256, P-384 or
+46
View File
@@ -726,3 +726,49 @@ func TestNewSignerWithAlgos(t *testing.T) {
t.Error("signer with algos created with restricted algorithms")
}
}
func TestCryptoPublicKey(t *testing.T) {
for _, priv := range testSigners {
p1 := priv.PublicKey()
key, ok := p1.(CryptoPublicKey)
if !ok {
continue
}
p2, err := NewPublicKey(key.CryptoPublicKey())
if err != nil {
t.Fatalf("NewPublicKey(CryptoPublicKey) failed for %s, got: %v", p1.Type(), err)
}
if !reflect.DeepEqual(p1, p2) {
t.Errorf("got %#v in NewPublicKey, want %#v", p2, p1)
}
}
for _, d := range testdata.SKData {
p1, _, _, _, err := ParseAuthorizedKey(d.PubKey)
if err != nil {
t.Fatalf("parseAuthorizedKey returned error: %v", err)
}
k1, ok := p1.(CryptoPublicKey)
if !ok {
t.Fatalf("%T does not implement CryptoPublicKey", p1)
}
var p2 PublicKey
switch pub := k1.CryptoPublicKey().(type) {
case *ecdsa.PublicKey:
p2 = &skECDSAPublicKey{
application: "ssh:",
PublicKey: *pub,
}
case ed25519.PublicKey:
p2 = &skEd25519PublicKey{
application: "ssh:",
PublicKey: pub,
}
default:
t.Fatalf("unexpected type %T from CryptoPublicKey()", pub)
}
if !reflect.DeepEqual(p1, p2) {
t.Errorf("got %#v, want %#v", p2, p1)
}
}
}