Skip to content

Commit

Permalink
ssh: implement CryptoPublicKey on sk keys
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
maraino authored and gopherbot committed May 29, 2024
1 parent 44c9b0f commit 349231f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
8 changes: 8 additions & 0 deletions ssh/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
46 changes: 46 additions & 0 deletions ssh/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}

0 comments on commit 349231f

Please sign in to comment.