Skip to content

Commit 349231f

Browse files
marainogopherbot
authored andcommitted
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 <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> Reviewed-by: Than McIntosh <[email protected]> Auto-Submit: Nicola Murino <[email protected]> Reviewed-by: Nicola Murino <[email protected]>
1 parent 44c9b0f commit 349231f

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

ssh/keys.go

+8
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,10 @@ func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error {
904904
return errors.New("ssh: signature did not verify")
905905
}
906906

907+
func (k *skECDSAPublicKey) CryptoPublicKey() crypto.PublicKey {
908+
return &k.PublicKey
909+
}
910+
907911
type skEd25519PublicKey struct {
908912
// application is a URL-like string, typically "ssh:" for SSH.
909913
// see openssh/PROTOCOL.u2f for details.
@@ -1000,6 +1004,10 @@ func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error {
10001004
return nil
10011005
}
10021006

1007+
func (k *skEd25519PublicKey) CryptoPublicKey() crypto.PublicKey {
1008+
return k.PublicKey
1009+
}
1010+
10031011
// NewSignerFromKey takes an *rsa.PrivateKey, *dsa.PrivateKey,
10041012
// *ecdsa.PrivateKey or any other crypto.Signer and returns a
10051013
// corresponding Signer instance. ECDSA keys must use P-256, P-384 or

ssh/keys_test.go

+46
Original file line numberDiff line numberDiff line change
@@ -726,3 +726,49 @@ func TestNewSignerWithAlgos(t *testing.T) {
726726
t.Error("signer with algos created with restricted algorithms")
727727
}
728728
}
729+
730+
func TestCryptoPublicKey(t *testing.T) {
731+
for _, priv := range testSigners {
732+
p1 := priv.PublicKey()
733+
key, ok := p1.(CryptoPublicKey)
734+
if !ok {
735+
continue
736+
}
737+
p2, err := NewPublicKey(key.CryptoPublicKey())
738+
if err != nil {
739+
t.Fatalf("NewPublicKey(CryptoPublicKey) failed for %s, got: %v", p1.Type(), err)
740+
}
741+
if !reflect.DeepEqual(p1, p2) {
742+
t.Errorf("got %#v in NewPublicKey, want %#v", p2, p1)
743+
}
744+
}
745+
for _, d := range testdata.SKData {
746+
p1, _, _, _, err := ParseAuthorizedKey(d.PubKey)
747+
if err != nil {
748+
t.Fatalf("parseAuthorizedKey returned error: %v", err)
749+
}
750+
k1, ok := p1.(CryptoPublicKey)
751+
if !ok {
752+
t.Fatalf("%T does not implement CryptoPublicKey", p1)
753+
}
754+
755+
var p2 PublicKey
756+
switch pub := k1.CryptoPublicKey().(type) {
757+
case *ecdsa.PublicKey:
758+
p2 = &skECDSAPublicKey{
759+
application: "ssh:",
760+
PublicKey: *pub,
761+
}
762+
case ed25519.PublicKey:
763+
p2 = &skEd25519PublicKey{
764+
application: "ssh:",
765+
PublicKey: pub,
766+
}
767+
default:
768+
t.Fatalf("unexpected type %T from CryptoPublicKey()", pub)
769+
}
770+
if !reflect.DeepEqual(p1, p2) {
771+
t.Errorf("got %#v, want %#v", p2, p1)
772+
}
773+
}
774+
}

0 commit comments

Comments
 (0)