ssh: add sk-ecdsa-sha2-nistp256 and sk-ed25519

This adds server-side support for the newly introduced OpenSSH
keytypes sk-ecdsa-sha2-nistp256@openssh.com and sk-ed25519@openssh.com
(including their corresponding certificates), which are backed
by U2F/FIDO2 tokens.

Change-Id: I53d5ed3d0457ae4758ee986055e187ee5787a2d1
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/208017
Reviewed-by: Han-Wen Nienhuys <hanwen@google.com>
Run-TryBot: Han-Wen Nienhuys <hanwen@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/ssh/keys_test.go b/ssh/keys_test.go
index 3847b3b..23a3566 100644
--- a/ssh/keys_test.go
+++ b/ssh/keys_test.go
@@ -13,6 +13,7 @@
 	"crypto/rsa"
 	"crypto/x509"
 	"encoding/base64"
+	"encoding/hex"
 	"encoding/pem"
 	"fmt"
 	"io"
@@ -572,3 +573,45 @@
 		}
 	}
 }
+
+func TestSKKeys(t *testing.T) {
+	for _, d := range testdata.SKData {
+		pk, _, _, _, err := ParseAuthorizedKey(d.PubKey)
+		if err != nil {
+			t.Fatalf("parseAuthorizedKey returned error: %v", err)
+		}
+
+		sigBuf := make([]byte, hex.DecodedLen(len(d.HexSignature)))
+		if _, err := hex.Decode(sigBuf, d.HexSignature); err != nil {
+			t.Fatalf("hex.Decode() failed: %v", err)
+		}
+
+		dataBuf := make([]byte, hex.DecodedLen(len(d.HexData)))
+		if _, err := hex.Decode(dataBuf, d.HexData); err != nil {
+			t.Fatalf("hex.Decode() failed: %v", err)
+		}
+
+		sig, _, ok := parseSignature(sigBuf)
+		if !ok {
+			t.Fatalf("parseSignature(%v) failed", sigBuf)
+		}
+
+		// Test that good data and signature pass verification
+		if err := pk.Verify(dataBuf, sig); err != nil {
+			t.Errorf("%s: PublicKey.Verify(%v, %v) failed: %v", d.Name, dataBuf, sig, err)
+		}
+
+		// Invalid data being passed in
+		invalidData := []byte("INVALID DATA")
+		if err := pk.Verify(invalidData, sig); err == nil {
+			t.Errorf("%s with invalid data: PublicKey.Verify(%v, %v) passed unexpectedly", d.Name, invalidData, sig)
+		}
+
+		// Change byte in blob to corrup signature
+		sig.Blob[5] = byte('A')
+		// Corrupted data being passed in
+		if err := pk.Verify(dataBuf, sig); err == nil {
+			t.Errorf("%s with corrupted signature: PublicKey.Verify(%v, %v) passed unexpectedly", d.Name, dataBuf, sig)
+		}
+	}
+}