diff --git a/pkg/pki/sshkey.go b/pkg/pki/sshkey.go index 74b31b69bc5a0..a27879bf0cfea 100644 --- a/pkg/pki/sshkey.go +++ b/pkg/pki/sshkey.go @@ -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 @@ -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) diff --git a/pkg/pki/sshkey_test.go b/pkg/pki/sshkey_test.go index 21b4ea676e2ec..36c081c7229cb 100644 --- a/pkg/pki/sshkey_test.go +++ b/pkg/pki/sshkey_test.go @@ -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" @@ -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) {