github.com/psiphon-labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/common/crypto/ssh/keys_test.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ssh
     6  
     7  import (
     8  	"bytes"
     9  	"crypto/dsa"
    10  	"crypto/ecdsa"
    11  	"crypto/elliptic"
    12  	"crypto/rand"
    13  	"crypto/rsa"
    14  	"crypto/x509"
    15  	"encoding/base64"
    16  	"encoding/hex"
    17  	"encoding/pem"
    18  	"fmt"
    19  	"io"
    20  	"reflect"
    21  	"strings"
    22  	"testing"
    23  
    24  	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/crypto/ssh/testdata"
    25  	"golang.org/x/crypto/ed25519"
    26  )
    27  
    28  func rawKey(pub PublicKey) interface{} {
    29  	switch k := pub.(type) {
    30  	case *rsaPublicKey:
    31  		return (*rsa.PublicKey)(k)
    32  	case *dsaPublicKey:
    33  		return (*dsa.PublicKey)(k)
    34  	case *ecdsaPublicKey:
    35  		return (*ecdsa.PublicKey)(k)
    36  	case ed25519PublicKey:
    37  		return (ed25519.PublicKey)(k)
    38  	case *Certificate:
    39  		return k
    40  	}
    41  	panic("unknown key type")
    42  }
    43  
    44  func TestKeyMarshalParse(t *testing.T) {
    45  	for _, priv := range testSigners {
    46  		pub := priv.PublicKey()
    47  		roundtrip, err := ParsePublicKey(pub.Marshal())
    48  		if err != nil {
    49  			t.Errorf("ParsePublicKey(%T): %v", pub, err)
    50  		}
    51  
    52  		k1 := rawKey(pub)
    53  		k2 := rawKey(roundtrip)
    54  
    55  		if !reflect.DeepEqual(k1, k2) {
    56  			t.Errorf("got %#v in roundtrip, want %#v", k2, k1)
    57  		}
    58  	}
    59  }
    60  
    61  func TestUnsupportedCurves(t *testing.T) {
    62  	raw, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
    63  	if err != nil {
    64  		t.Fatalf("GenerateKey: %v", err)
    65  	}
    66  
    67  	if _, err = NewSignerFromKey(raw); err == nil || !strings.Contains(err.Error(), "only P-256") {
    68  		t.Fatalf("NewPrivateKey should not succeed with P-224, got: %v", err)
    69  	}
    70  
    71  	if _, err = NewPublicKey(&raw.PublicKey); err == nil || !strings.Contains(err.Error(), "only P-256") {
    72  		t.Fatalf("NewPublicKey should not succeed with P-224, got: %v", err)
    73  	}
    74  }
    75  
    76  func TestNewPublicKey(t *testing.T) {
    77  	for _, k := range testSigners {
    78  		raw := rawKey(k.PublicKey())
    79  		// Skip certificates, as NewPublicKey does not support them.
    80  		if _, ok := raw.(*Certificate); ok {
    81  			continue
    82  		}
    83  		pub, err := NewPublicKey(raw)
    84  		if err != nil {
    85  			t.Errorf("NewPublicKey(%#v): %v", raw, err)
    86  		}
    87  		if !reflect.DeepEqual(k.PublicKey(), pub) {
    88  			t.Errorf("NewPublicKey(%#v) = %#v, want %#v", raw, pub, k.PublicKey())
    89  		}
    90  	}
    91  }
    92  
    93  func TestKeySignVerify(t *testing.T) {
    94  	for _, priv := range testSigners {
    95  		pub := priv.PublicKey()
    96  
    97  		data := []byte("sign me")
    98  		sig, err := priv.Sign(rand.Reader, data)
    99  		if err != nil {
   100  			t.Fatalf("Sign(%T): %v", priv, err)
   101  		}
   102  
   103  		if err := pub.Verify(data, sig); err != nil {
   104  			t.Errorf("publicKey.Verify(%T): %v", priv, err)
   105  		}
   106  		sig.Blob[5]++
   107  		if err := pub.Verify(data, sig); err == nil {
   108  			t.Errorf("publicKey.Verify on broken sig did not fail")
   109  		}
   110  	}
   111  }
   112  
   113  func TestKeySignWithAlgorithmVerify(t *testing.T) {
   114  	for _, priv := range testSigners {
   115  		if algorithmSigner, ok := priv.(AlgorithmSigner); !ok {
   116  			t.Errorf("Signers constructed by ssh package should always implement the AlgorithmSigner interface: %T", priv)
   117  		} else {
   118  			pub := priv.PublicKey()
   119  			data := []byte("sign me")
   120  
   121  			signWithAlgTestCase := func(algorithm string, expectedAlg string) {
   122  				sig, err := algorithmSigner.SignWithAlgorithm(rand.Reader, data, algorithm)
   123  				if err != nil {
   124  					t.Fatalf("Sign(%T): %v", priv, err)
   125  				}
   126  				if sig.Format != expectedAlg {
   127  					t.Errorf("signature format did not match requested signature algorithm: %s != %s", sig.Format, expectedAlg)
   128  				}
   129  
   130  				if err := pub.Verify(data, sig); err != nil {
   131  					t.Errorf("publicKey.Verify(%T): %v", priv, err)
   132  				}
   133  				sig.Blob[5]++
   134  				if err := pub.Verify(data, sig); err == nil {
   135  					t.Errorf("publicKey.Verify on broken sig did not fail")
   136  				}
   137  			}
   138  
   139  			// Using the empty string as the algorithm name should result in the same signature format as the algorithm-free Sign method.
   140  			defaultSig, err := priv.Sign(rand.Reader, data)
   141  			if err != nil {
   142  				t.Fatalf("Sign(%T): %v", priv, err)
   143  			}
   144  			signWithAlgTestCase("", defaultSig.Format)
   145  
   146  			// RSA keys are the only ones which currently support more than one signing algorithm
   147  			if pub.Type() == KeyAlgoRSA {
   148  				for _, algorithm := range []string{SigAlgoRSA, SigAlgoRSASHA2256, SigAlgoRSASHA2512} {
   149  					signWithAlgTestCase(algorithm, algorithm)
   150  				}
   151  			}
   152  		}
   153  	}
   154  }
   155  
   156  func TestParseRSAPrivateKey(t *testing.T) {
   157  	key := testPrivateKeys["rsa"]
   158  
   159  	rsa, ok := key.(*rsa.PrivateKey)
   160  	if !ok {
   161  		t.Fatalf("got %T, want *rsa.PrivateKey", rsa)
   162  	}
   163  
   164  	if err := rsa.Validate(); err != nil {
   165  		t.Errorf("Validate: %v", err)
   166  	}
   167  }
   168  
   169  func TestParseECPrivateKey(t *testing.T) {
   170  	key := testPrivateKeys["ecdsa"]
   171  
   172  	ecKey, ok := key.(*ecdsa.PrivateKey)
   173  	if !ok {
   174  		t.Fatalf("got %T, want *ecdsa.PrivateKey", ecKey)
   175  	}
   176  
   177  	if !validateECPublicKey(ecKey.Curve, ecKey.X, ecKey.Y) {
   178  		t.Fatalf("public key does not validate.")
   179  	}
   180  }
   181  
   182  func TestParseEncryptedPrivateKeysWithPassphrase(t *testing.T) {
   183  	data := []byte("sign me")
   184  	for _, tt := range testdata.PEMEncryptedKeys {
   185  		t.Run(tt.Name, func(t *testing.T) {
   186  			_, err := ParsePrivateKeyWithPassphrase(tt.PEMBytes, []byte("incorrect"))
   187  			if err != x509.IncorrectPasswordError {
   188  				t.Errorf("got %v want IncorrectPasswordError", err)
   189  			}
   190  
   191  			s, err := ParsePrivateKeyWithPassphrase(tt.PEMBytes, []byte(tt.EncryptionKey))
   192  			if err != nil {
   193  				t.Fatalf("ParsePrivateKeyWithPassphrase returned error: %s", err)
   194  			}
   195  
   196  			sig, err := s.Sign(rand.Reader, data)
   197  			if err != nil {
   198  				t.Fatalf("Signer.Sign: %v", err)
   199  			}
   200  			if err := s.PublicKey().Verify(data, sig); err != nil {
   201  				t.Errorf("Verify failed: %v", err)
   202  			}
   203  
   204  			_, err = ParsePrivateKey(tt.PEMBytes)
   205  			if err == nil {
   206  				t.Fatalf("ParsePrivateKey succeeded, expected an error")
   207  			}
   208  
   209  			if err, ok := err.(*PassphraseMissingError); !ok {
   210  				t.Errorf("got error %q, want PassphraseMissingError", err)
   211  			} else if tt.IncludesPublicKey {
   212  				if err.PublicKey == nil {
   213  					t.Fatalf("expected PassphraseMissingError.PublicKey not to be nil")
   214  				}
   215  				got, want := err.PublicKey.Marshal(), s.PublicKey().Marshal()
   216  				if !bytes.Equal(got, want) {
   217  					t.Errorf("error field %q doesn't match signer public key %q", got, want)
   218  				}
   219  			}
   220  		})
   221  	}
   222  }
   223  
   224  func TestParseDSA(t *testing.T) {
   225  	// We actually exercise the ParsePrivateKey codepath here, as opposed to
   226  	// using the ParseRawPrivateKey+NewSignerFromKey path that testdata_test.go
   227  	// uses.
   228  	s, err := ParsePrivateKey(testdata.PEMBytes["dsa"])
   229  	if err != nil {
   230  		t.Fatalf("ParsePrivateKey returned error: %s", err)
   231  	}
   232  
   233  	data := []byte("sign me")
   234  	sig, err := s.Sign(rand.Reader, data)
   235  	if err != nil {
   236  		t.Fatalf("dsa.Sign: %v", err)
   237  	}
   238  
   239  	if err := s.PublicKey().Verify(data, sig); err != nil {
   240  		t.Errorf("Verify failed: %v", err)
   241  	}
   242  }
   243  
   244  // Tests for authorized_keys parsing.
   245  
   246  // getTestKey returns a public key, and its base64 encoding.
   247  func getTestKey() (PublicKey, string) {
   248  	k := testPublicKeys["rsa"]
   249  
   250  	b := &bytes.Buffer{}
   251  	e := base64.NewEncoder(base64.StdEncoding, b)
   252  	e.Write(k.Marshal())
   253  	e.Close()
   254  
   255  	return k, b.String()
   256  }
   257  
   258  func TestMarshalParsePublicKey(t *testing.T) {
   259  	pub, pubSerialized := getTestKey()
   260  	line := fmt.Sprintf("%s %s user@host", pub.Type(), pubSerialized)
   261  
   262  	authKeys := MarshalAuthorizedKey(pub)
   263  	actualFields := strings.Fields(string(authKeys))
   264  	if len(actualFields) == 0 {
   265  		t.Fatalf("failed authKeys: %v", authKeys)
   266  	}
   267  
   268  	// drop the comment
   269  	expectedFields := strings.Fields(line)[0:2]
   270  
   271  	if !reflect.DeepEqual(actualFields, expectedFields) {
   272  		t.Errorf("got %v, expected %v", actualFields, expectedFields)
   273  	}
   274  
   275  	actPub, _, _, _, err := ParseAuthorizedKey([]byte(line))
   276  	if err != nil {
   277  		t.Fatalf("cannot parse %v: %v", line, err)
   278  	}
   279  	if !reflect.DeepEqual(actPub, pub) {
   280  		t.Errorf("got %v, expected %v", actPub, pub)
   281  	}
   282  }
   283  
   284  type testAuthResult struct {
   285  	pubKey   PublicKey
   286  	options  []string
   287  	comments string
   288  	rest     string
   289  	ok       bool
   290  }
   291  
   292  func testAuthorizedKeys(t *testing.T, authKeys []byte, expected []testAuthResult) {
   293  	rest := authKeys
   294  	var values []testAuthResult
   295  	for len(rest) > 0 {
   296  		var r testAuthResult
   297  		var err error
   298  		r.pubKey, r.comments, r.options, rest, err = ParseAuthorizedKey(rest)
   299  		r.ok = (err == nil)
   300  		t.Log(err)
   301  		r.rest = string(rest)
   302  		values = append(values, r)
   303  	}
   304  
   305  	if !reflect.DeepEqual(values, expected) {
   306  		t.Errorf("got %#v, expected %#v", values, expected)
   307  	}
   308  }
   309  
   310  func TestAuthorizedKeyBasic(t *testing.T) {
   311  	pub, pubSerialized := getTestKey()
   312  	line := "ssh-rsa " + pubSerialized + " user@host"
   313  	testAuthorizedKeys(t, []byte(line),
   314  		[]testAuthResult{
   315  			{pub, nil, "user@host", "", true},
   316  		})
   317  }
   318  
   319  func TestAuth(t *testing.T) {
   320  	pub, pubSerialized := getTestKey()
   321  	authWithOptions := []string{
   322  		`# comments to ignore before any keys...`,
   323  		``,
   324  		`env="HOME=/home/root",no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host`,
   325  		`# comments to ignore, along with a blank line`,
   326  		``,
   327  		`env="HOME=/home/root2" ssh-rsa ` + pubSerialized + ` user2@host2`,
   328  		``,
   329  		`# more comments, plus a invalid entry`,
   330  		`ssh-rsa data-that-will-not-parse user@host3`,
   331  	}
   332  	for _, eol := range []string{"\n", "\r\n"} {
   333  		authOptions := strings.Join(authWithOptions, eol)
   334  		rest2 := strings.Join(authWithOptions[3:], eol)
   335  		rest3 := strings.Join(authWithOptions[6:], eol)
   336  		testAuthorizedKeys(t, []byte(authOptions), []testAuthResult{
   337  			{pub, []string{`env="HOME=/home/root"`, "no-port-forwarding"}, "user@host", rest2, true},
   338  			{pub, []string{`env="HOME=/home/root2"`}, "user2@host2", rest3, true},
   339  			{nil, nil, "", "", false},
   340  		})
   341  	}
   342  }
   343  
   344  func TestAuthWithQuotedSpaceInEnv(t *testing.T) {
   345  	pub, pubSerialized := getTestKey()
   346  	authWithQuotedSpaceInEnv := []byte(`env="HOME=/home/root dir",no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host`)
   347  	testAuthorizedKeys(t, []byte(authWithQuotedSpaceInEnv), []testAuthResult{
   348  		{pub, []string{`env="HOME=/home/root dir"`, "no-port-forwarding"}, "user@host", "", true},
   349  	})
   350  }
   351  
   352  func TestAuthWithQuotedCommaInEnv(t *testing.T) {
   353  	pub, pubSerialized := getTestKey()
   354  	authWithQuotedCommaInEnv := []byte(`env="HOME=/home/root,dir",no-port-forwarding ssh-rsa ` + pubSerialized + `   user@host`)
   355  	testAuthorizedKeys(t, []byte(authWithQuotedCommaInEnv), []testAuthResult{
   356  		{pub, []string{`env="HOME=/home/root,dir"`, "no-port-forwarding"}, "user@host", "", true},
   357  	})
   358  }
   359  
   360  func TestAuthWithQuotedQuoteInEnv(t *testing.T) {
   361  	pub, pubSerialized := getTestKey()
   362  	authWithQuotedQuoteInEnv := []byte(`env="HOME=/home/\"root dir",no-port-forwarding` + "\t" + `ssh-rsa` + "\t" + pubSerialized + `   user@host`)
   363  	authWithDoubleQuotedQuote := []byte(`no-port-forwarding,env="HOME=/home/ \"root dir\"" ssh-rsa ` + pubSerialized + "\t" + `user@host`)
   364  	testAuthorizedKeys(t, []byte(authWithQuotedQuoteInEnv), []testAuthResult{
   365  		{pub, []string{`env="HOME=/home/\"root dir"`, "no-port-forwarding"}, "user@host", "", true},
   366  	})
   367  
   368  	testAuthorizedKeys(t, []byte(authWithDoubleQuotedQuote), []testAuthResult{
   369  		{pub, []string{"no-port-forwarding", `env="HOME=/home/ \"root dir\""`}, "user@host", "", true},
   370  	})
   371  }
   372  
   373  func TestAuthWithInvalidSpace(t *testing.T) {
   374  	_, pubSerialized := getTestKey()
   375  	authWithInvalidSpace := []byte(`env="HOME=/home/root dir", no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host
   376  #more to follow but still no valid keys`)
   377  	testAuthorizedKeys(t, []byte(authWithInvalidSpace), []testAuthResult{
   378  		{nil, nil, "", "", false},
   379  	})
   380  }
   381  
   382  func TestAuthWithMissingQuote(t *testing.T) {
   383  	pub, pubSerialized := getTestKey()
   384  	authWithMissingQuote := []byte(`env="HOME=/home/root,no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host
   385  env="HOME=/home/root",shared-control ssh-rsa ` + pubSerialized + ` user@host`)
   386  
   387  	testAuthorizedKeys(t, []byte(authWithMissingQuote), []testAuthResult{
   388  		{pub, []string{`env="HOME=/home/root"`, `shared-control`}, "user@host", "", true},
   389  	})
   390  }
   391  
   392  func TestInvalidEntry(t *testing.T) {
   393  	authInvalid := []byte(`ssh-rsa`)
   394  	_, _, _, _, err := ParseAuthorizedKey(authInvalid)
   395  	if err == nil {
   396  		t.Errorf("got valid entry for %q", authInvalid)
   397  	}
   398  }
   399  
   400  var knownHostsParseTests = []struct {
   401  	input string
   402  	err   string
   403  
   404  	marker  string
   405  	comment string
   406  	hosts   []string
   407  	rest    string
   408  }{
   409  	{
   410  		"",
   411  		"EOF",
   412  
   413  		"", "", nil, "",
   414  	},
   415  	{
   416  		"# Just a comment",
   417  		"EOF",
   418  
   419  		"", "", nil, "",
   420  	},
   421  	{
   422  		"   \t   ",
   423  		"EOF",
   424  
   425  		"", "", nil, "",
   426  	},
   427  	{
   428  		"localhost ssh-rsa {RSAPUB}",
   429  		"",
   430  
   431  		"", "", []string{"localhost"}, "",
   432  	},
   433  	{
   434  		"localhost\tssh-rsa {RSAPUB}",
   435  		"",
   436  
   437  		"", "", []string{"localhost"}, "",
   438  	},
   439  	{
   440  		"localhost\tssh-rsa {RSAPUB}\tcomment comment",
   441  		"",
   442  
   443  		"", "comment comment", []string{"localhost"}, "",
   444  	},
   445  	{
   446  		"localhost\tssh-rsa {RSAPUB}\tcomment comment\n",
   447  		"",
   448  
   449  		"", "comment comment", []string{"localhost"}, "",
   450  	},
   451  	{
   452  		"localhost\tssh-rsa {RSAPUB}\tcomment comment\r\n",
   453  		"",
   454  
   455  		"", "comment comment", []string{"localhost"}, "",
   456  	},
   457  	{
   458  		"localhost\tssh-rsa {RSAPUB}\tcomment comment\r\nnext line",
   459  		"",
   460  
   461  		"", "comment comment", []string{"localhost"}, "next line",
   462  	},
   463  	{
   464  		"localhost,[host2:123]\tssh-rsa {RSAPUB}\tcomment comment",
   465  		"",
   466  
   467  		"", "comment comment", []string{"localhost", "[host2:123]"}, "",
   468  	},
   469  	{
   470  		"@marker \tlocalhost,[host2:123]\tssh-rsa {RSAPUB}",
   471  		"",
   472  
   473  		"marker", "", []string{"localhost", "[host2:123]"}, "",
   474  	},
   475  	{
   476  		"@marker \tlocalhost,[host2:123]\tssh-rsa aabbccdd",
   477  		"short read",
   478  
   479  		"", "", nil, "",
   480  	},
   481  }
   482  
   483  func TestKnownHostsParsing(t *testing.T) {
   484  	rsaPub, rsaPubSerialized := getTestKey()
   485  
   486  	for i, test := range knownHostsParseTests {
   487  		var expectedKey PublicKey
   488  		const rsaKeyToken = "{RSAPUB}"
   489  
   490  		input := test.input
   491  		if strings.Contains(input, rsaKeyToken) {
   492  			expectedKey = rsaPub
   493  			input = strings.Replace(test.input, rsaKeyToken, rsaPubSerialized, -1)
   494  		}
   495  
   496  		marker, hosts, pubKey, comment, rest, err := ParseKnownHosts([]byte(input))
   497  		if err != nil {
   498  			if len(test.err) == 0 {
   499  				t.Errorf("#%d: unexpectedly failed with %q", i, err)
   500  			} else if !strings.Contains(err.Error(), test.err) {
   501  				t.Errorf("#%d: expected error containing %q, but got %q", i, test.err, err)
   502  			}
   503  			continue
   504  		} else if len(test.err) != 0 {
   505  			t.Errorf("#%d: succeeded but expected error including %q", i, test.err)
   506  			continue
   507  		}
   508  
   509  		if !reflect.DeepEqual(expectedKey, pubKey) {
   510  			t.Errorf("#%d: expected key %#v, but got %#v", i, expectedKey, pubKey)
   511  		}
   512  
   513  		if marker != test.marker {
   514  			t.Errorf("#%d: expected marker %q, but got %q", i, test.marker, marker)
   515  		}
   516  
   517  		if comment != test.comment {
   518  			t.Errorf("#%d: expected comment %q, but got %q", i, test.comment, comment)
   519  		}
   520  
   521  		if !reflect.DeepEqual(test.hosts, hosts) {
   522  			t.Errorf("#%d: expected hosts %#v, but got %#v", i, test.hosts, hosts)
   523  		}
   524  
   525  		if rest := string(rest); rest != test.rest {
   526  			t.Errorf("#%d: expected remaining input to be %q, but got %q", i, test.rest, rest)
   527  		}
   528  	}
   529  }
   530  
   531  func TestFingerprintLegacyMD5(t *testing.T) {
   532  	pub, _ := getTestKey()
   533  	fingerprint := FingerprintLegacyMD5(pub)
   534  	want := "fb:61:6d:1a:e3:f0:95:45:3c:a0:79:be:4a:93:63:66" // ssh-keygen -lf -E md5 rsa
   535  	if fingerprint != want {
   536  		t.Errorf("got fingerprint %q want %q", fingerprint, want)
   537  	}
   538  }
   539  
   540  func TestFingerprintSHA256(t *testing.T) {
   541  	pub, _ := getTestKey()
   542  	fingerprint := FingerprintSHA256(pub)
   543  	want := "SHA256:Anr3LjZK8YVpjrxu79myrW9Hrb/wpcMNpVvTq/RcBm8" // ssh-keygen -lf rsa
   544  	if fingerprint != want {
   545  		t.Errorf("got fingerprint %q want %q", fingerprint, want)
   546  	}
   547  }
   548  
   549  func TestInvalidKeys(t *testing.T) {
   550  	keyTypes := []string{
   551  		"RSA PRIVATE KEY",
   552  		"PRIVATE KEY",
   553  		"EC PRIVATE KEY",
   554  		"DSA PRIVATE KEY",
   555  		"OPENSSH PRIVATE KEY",
   556  	}
   557  
   558  	for _, keyType := range keyTypes {
   559  		for _, dataLen := range []int{0, 1, 2, 5, 10, 20} {
   560  			data := make([]byte, dataLen)
   561  			if _, err := io.ReadFull(rand.Reader, data); err != nil {
   562  				t.Fatal(err)
   563  			}
   564  
   565  			var buf bytes.Buffer
   566  			pem.Encode(&buf, &pem.Block{
   567  				Type:  keyType,
   568  				Bytes: data,
   569  			})
   570  
   571  			// This test is just to ensure that the function
   572  			// doesn't panic so the return value is ignored.
   573  			ParseRawPrivateKey(buf.Bytes())
   574  		}
   575  	}
   576  }
   577  
   578  func TestSKKeys(t *testing.T) {
   579  	for _, d := range testdata.SKData {
   580  		pk, _, _, _, err := ParseAuthorizedKey(d.PubKey)
   581  		if err != nil {
   582  			t.Fatalf("parseAuthorizedKey returned error: %v", err)
   583  		}
   584  
   585  		sigBuf := make([]byte, hex.DecodedLen(len(d.HexSignature)))
   586  		if _, err := hex.Decode(sigBuf, d.HexSignature); err != nil {
   587  			t.Fatalf("hex.Decode() failed: %v", err)
   588  		}
   589  
   590  		dataBuf := make([]byte, hex.DecodedLen(len(d.HexData)))
   591  		if _, err := hex.Decode(dataBuf, d.HexData); err != nil {
   592  			t.Fatalf("hex.Decode() failed: %v", err)
   593  		}
   594  
   595  		sig, _, ok := parseSignature(sigBuf)
   596  		if !ok {
   597  			t.Fatalf("parseSignature(%v) failed", sigBuf)
   598  		}
   599  
   600  		// Test that good data and signature pass verification
   601  		if err := pk.Verify(dataBuf, sig); err != nil {
   602  			t.Errorf("%s: PublicKey.Verify(%v, %v) failed: %v", d.Name, dataBuf, sig, err)
   603  		}
   604  
   605  		// Invalid data being passed in
   606  		invalidData := []byte("INVALID DATA")
   607  		if err := pk.Verify(invalidData, sig); err == nil {
   608  			t.Errorf("%s with invalid data: PublicKey.Verify(%v, %v) passed unexpectedly", d.Name, invalidData, sig)
   609  		}
   610  
   611  		// Change byte in blob to corrup signature
   612  		sig.Blob[5] = byte('A')
   613  		// Corrupted data being passed in
   614  		if err := pk.Verify(dataBuf, sig); err == nil {
   615  			t.Errorf("%s with corrupted signature: PublicKey.Verify(%v, %v) passed unexpectedly", d.Name, dataBuf, sig)
   616  		}
   617  	}
   618  }