Skip to content

Commit

Permalink
Merge pull request #13304 from aclevername/ed25519
Browse files Browse the repository at this point in the history
Add support for ed25519 keys in AWS
  • Loading branch information
k8s-ci-robot committed Mar 2, 2022
2 parents cb1a3a1 + 191f54f commit f87f53a
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 32 deletions.
44 changes: 18 additions & 26 deletions pkg/pki/sshkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,19 @@ func ComputeAWSKeyFingerprint(publicKey string) (string, error) {
return "", err
}

der, err := toDER(sshPublicKey)
if err != nil {
return "", fmt.Errorf("error computing fingerprint for SSH public key: %v", err)
switch fmt.Sprintf("%T", sshPublicKey) {
case "*ssh.rsaPublicKey":
der, err := rsaToDER(sshPublicKey)
if err != nil {
return "", fmt.Errorf("error computing fingerprint for SSH public key: %v", err)
}
h := md5.Sum(der)
return colonSeparatedHex(h[:]), nil
case "ssh.ed25519PublicKey":
return ssh.FingerprintSHA256(sshPublicKey), nil
}
h := md5.Sum(der)

return colonSeparatedHex(h[:]), nil
return "", fmt.Errorf("unexpected type of SSH key (%T); AWS can only import RSA and ed25519 keys", sshPublicKey)
}

// ComputeOpenSSHKeyFingerprint computes the OpenSSH fingerprint of the SSH public key
Expand All @@ -93,30 +99,16 @@ func ComputeOpenSSHKeyFingerprint(publicKey string) (string, error) {
return colonSeparatedHex(h[:]), nil
}

// toDER gets the DER encoding of the SSH public key
// rsaToDER gets the DER encoding of the SSH public key
// Annoyingly, the ssh code wraps the actual crypto keys, so we have to use reflection tricks
func toDER(pubkey ssh.PublicKey) ([]byte, error) {
pubkeyValue := reflect.ValueOf(pubkey)
typeName := fmt.Sprintf("%T", pubkey)

func rsaToDER(pubkey ssh.PublicKey) ([]byte, error) {
var cryptoKey crypto.PublicKey
switch typeName {
case "*ssh.rsaPublicKey":
var rsaPublicKey *rsa.PublicKey
targetType := reflect.ValueOf(rsaPublicKey).Type()
rsaPublicKey = pubkeyValue.Convert(targetType).Interface().(*rsa.PublicKey)
cryptoKey = rsaPublicKey

// case "*dsaPublicKey":
// var dsaPublicKey *dsa.PublicKey
// targetType := reflect.ValueOf(dsaPublicKey).Type()
// dsaPublicKey = pubkeyValue.Convert(targetType).Interface().(*dsa.PublicKey)
// cryptoKey = dsaPublicKey

default:
return nil, fmt.Errorf("unexpected type of SSH key (%q); AWS can only import RSA keys", typeName)
}
var rsaPublicKey *rsa.PublicKey

pubkeyValue := reflect.ValueOf(pubkey)
targetType := reflect.ValueOf(rsaPublicKey).Type()
rsaPublicKey = pubkeyValue.Convert(targetType).Interface().(*rsa.PublicKey)
cryptoKey = rsaPublicKey
der, err := x509.MarshalPKIXPublicKey(cryptoKey)
if err != nil {
return nil, fmt.Errorf("error marshaling SSH public key: %v", err)
Expand Down
12 changes: 6 additions & 6 deletions pkg/pki/sshkey_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ func Test_AWSFingerprint_RsaKeyEncrypted(t *testing.T) {
checkAWSFingerprintEqual(t, key, "c9:c5:05:5e:ea:54:fc:a4:7c:7c:75:5c:d2:71:5e:40")
}

func Test_AWSFingerprint_Ed25519Key(t *testing.T) {
key := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBoB6Gtu8zPAPO1yF4OwysWUD8ZSEQYzMpOT0YvF9qJV user@example"
checkAWSFingerprintEqual(t, key, "SHA256:HvE7+gmH78VS53+iPuRDh/gKjVo26OzYU/qOnJWAgyk")
}

func Test_AWSFingerprint_TrickyWhitespace(t *testing.T) {
// No name, \r instead of whitespace
key := "ssh-rsa\rAAAAB3NzaC1yc2EAAAADAQABAAABAQCySdqIU+FhCWl3BNrAvPaOe5VfL2aCARUWwy91ZP+T7LBwFa9lhdttfjp/VX1D1/PVwntn2EhN079m8c2kfdmiZ/iCHqrLyIGSd+BOiCz0lT47znvANSfxYjLUuKrWWWeaXqerJkOsAD4PHchRLbZGPdbfoBKwtb/WT4GMRQmb9vmiaZYjsfdPPM9KkWI9ECoWFGjGehA8D+iYIPR711kRacb1xdYmnjHqxAZHFsb5L8wDWIeAyhy49cBD+lbzTiioq2xWLorXuFmXh6Do89PgzvHeyCLY6816f/kCX6wIFts8A2eaEHFL4rAOsuh6qHmSxGCR9peSyuRW8DxV725x\r"
Expand All @@ -62,12 +67,7 @@ func Test_AWSFingerprint_TrickyWhitespace(t *testing.T) {

func Test_AWSFingerprint_DsaKey(t *testing.T) {
key := "ssh-dss AAAAB3NzaC1kc3MAAACBAIcCTu3vi9rNjsnhCrHeII7jSN6/FmnIdy09pQAsMAGGvCS9HBOteCKbIyYQQ0+Gi76Oui7cJ2VQojdxOxeZPoSP+QYnA+CVYhnowVVLeRA9VBQG3ZLInoXaqe3nR4/OXhY75GmYShBBPTQ+/fWGX9ltoXfygSc4KjhBNudvj75VAAAAFQDiw8A4MhY0aHSX/mtpa7XV8+iS6wAAAIAXyQaxM/dk0o1vBV3H0V0lGhog3mF7EJPdw7jagYvXQP1tAhzNofxZVhXHr4wGfiTQv9j5plDqQzCI/15a6DRyo9zI+zdPTR41W3dGrk56O2/Qxsz3/vNip5OwpOJ88yMmBX9m36gg0WrOXcZDgErhvZWRt5cXa9QjVg/KpxYLPAAAAIB8e5M82IiRLi+k1k4LsELKArQGzVkPgynESfnEXX0TKGiR7PJvBNGaKnPJtJ0Rrc38w/hLTeklroJt9Rdey/NI9b6tc+ur2pmJdnYppnNCm03WszU4oFD/7KIqR84Hf0fMbWd1hRvznpZhngZ505KNsL+ck0+Tlq6Hdhe2baXJcA== justin@machine"
checkAWSFingerprintError(t, key, "AWS can only import RSA keys")
}

func Test_AWSFingerprint_Ed25519Key(t *testing.T) {
key := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFpyraYd4rUFftiEKzUO4wKFAgTkXxuJcRZwVcsuZJ8G justin@machine"
checkAWSFingerprintError(t, key, "AWS can only import RSA keys")
checkAWSFingerprintError(t, key, "AWS can only import RSA and ed25519 keys")
}

func checkOpenSSHFingerprintEqual(t *testing.T, publicKey string, fingerprint string) {
Expand Down

0 comments on commit f87f53a

Please sign in to comment.