1
2
3
4
5 package ssh
6
7 import (
8 "bytes"
9 "crypto/dsa"
10 "crypto/ecdsa"
11 "crypto/ed25519"
12 "crypto/elliptic"
13 "crypto/rand"
14 "crypto/rsa"
15 "crypto/x509"
16 "encoding/base64"
17 "encoding/hex"
18 "encoding/pem"
19 "errors"
20 "fmt"
21 "io"
22 "reflect"
23 "strings"
24 "testing"
25
26 "golang.org/x/crypto/ssh/testdata"
27 )
28
29 func rawKey(pub PublicKey) interface{} {
30 switch k := pub.(type) {
31 case *rsaPublicKey:
32 return (*rsa.PublicKey)(k)
33 case *dsaPublicKey:
34 return (*dsa.PublicKey)(k)
35 case *ecdsaPublicKey:
36 return (*ecdsa.PublicKey)(k)
37 case ed25519PublicKey:
38 return (ed25519.PublicKey)(k)
39 case *Certificate:
40 return k
41 }
42 panic("unknown key type")
43 }
44
45 func TestKeyMarshalParse(t *testing.T) {
46 for _, priv := range testSigners {
47 pub := priv.PublicKey()
48 roundtrip, err := ParsePublicKey(pub.Marshal())
49 if err != nil {
50 t.Errorf("ParsePublicKey(%T): %v", pub, err)
51 }
52
53 k1 := rawKey(pub)
54 k2 := rawKey(roundtrip)
55
56 if !reflect.DeepEqual(k1, k2) {
57 t.Errorf("got %#v in roundtrip, want %#v", k2, k1)
58 }
59 }
60 }
61
62 func TestUnsupportedCurves(t *testing.T) {
63 raw, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
64 if err != nil {
65 t.Fatalf("GenerateKey: %v", err)
66 }
67
68 if _, err = NewSignerFromKey(raw); err == nil || !strings.Contains(err.Error(), "only P-256") {
69 t.Fatalf("NewPrivateKey should not succeed with P-224, got: %v", err)
70 }
71
72 if _, err = NewPublicKey(&raw.PublicKey); err == nil || !strings.Contains(err.Error(), "only P-256") {
73 t.Fatalf("NewPublicKey should not succeed with P-224, got: %v", err)
74 }
75 }
76
77 func TestNewPublicKey(t *testing.T) {
78 for _, k := range testSigners {
79 raw := rawKey(k.PublicKey())
80
81 if _, ok := raw.(*Certificate); ok {
82 continue
83 }
84 pub, err := NewPublicKey(raw)
85 if err != nil {
86 t.Errorf("NewPublicKey(%#v): %v", raw, err)
87 }
88 if !reflect.DeepEqual(k.PublicKey(), pub) {
89 t.Errorf("NewPublicKey(%#v) = %#v, want %#v", raw, pub, k.PublicKey())
90 }
91 }
92 }
93
94 func TestKeySignVerify(t *testing.T) {
95 for _, priv := range testSigners {
96 pub := priv.PublicKey()
97
98 data := []byte("sign me")
99 sig, err := priv.Sign(rand.Reader, data)
100 if err != nil {
101 t.Fatalf("Sign(%T): %v", priv, err)
102 }
103
104 if err := pub.Verify(data, sig); err != nil {
105 t.Errorf("publicKey.Verify(%T): %v", priv, err)
106 }
107 sig.Blob[5]++
108 if err := pub.Verify(data, sig); err == nil {
109 t.Errorf("publicKey.Verify on broken sig did not fail")
110 }
111 }
112 }
113
114 func TestKeySignWithAlgorithmVerify(t *testing.T) {
115 for k, priv := range testSigners {
116 if algorithmSigner, ok := priv.(MultiAlgorithmSigner); !ok {
117 t.Errorf("Signers %q constructed by ssh package should always implement the MultiAlgorithmSigner interface: %T", k, priv)
118 } else {
119 pub := priv.PublicKey()
120 data := []byte("sign me")
121
122 signWithAlgTestCase := func(algorithm string, expectedAlg string) {
123 sig, err := algorithmSigner.SignWithAlgorithm(rand.Reader, data, algorithm)
124 if err != nil {
125 t.Fatalf("Sign(%T): %v", priv, err)
126 }
127 if sig.Format != expectedAlg {
128 t.Errorf("signature format did not match requested signature algorithm: %s != %s", sig.Format, expectedAlg)
129 }
130
131 if err := pub.Verify(data, sig); err != nil {
132 t.Errorf("publicKey.Verify(%T): %v", priv, err)
133 }
134 sig.Blob[5]++
135 if err := pub.Verify(data, sig); err == nil {
136 t.Errorf("publicKey.Verify on broken sig did not fail")
137 }
138 }
139
140
141 defaultSig, err := priv.Sign(rand.Reader, data)
142 if err != nil {
143 t.Fatalf("Sign(%T): %v", priv, err)
144 }
145 signWithAlgTestCase("", defaultSig.Format)
146
147
148 if pub.Type() == KeyAlgoRSA {
149 for _, algorithm := range []string{KeyAlgoRSA, KeyAlgoRSASHA256, KeyAlgoRSASHA512} {
150 signWithAlgTestCase(algorithm, algorithm)
151 }
152 }
153 }
154 }
155 }
156
157 func TestKeySignWithShortSignature(t *testing.T) {
158 signer := testSigners["rsa"].(AlgorithmSigner)
159 pub := signer.PublicKey()
160
161
162 tests := []struct {
163 algorithm string
164 data []byte
165 }{
166 {
167 algorithm: KeyAlgoRSA,
168 data: []byte("sign me92"),
169 },
170 {
171 algorithm: KeyAlgoRSASHA256,
172 data: []byte("sign me294"),
173 },
174 {
175 algorithm: KeyAlgoRSASHA512,
176 data: []byte("sign me60"),
177 },
178 }
179
180 for _, tt := range tests {
181 sig, err := signer.SignWithAlgorithm(rand.Reader, tt.data, tt.algorithm)
182 if err != nil {
183 t.Fatalf("Sign(%T): %v", signer, err)
184 }
185 if sig.Blob[0] != 0 {
186 t.Errorf("%s: Expected signature with a leading 0", tt.algorithm)
187 }
188 sig.Blob = sig.Blob[1:]
189 if err := pub.Verify(tt.data, sig); err != nil {
190 t.Errorf("publicKey.Verify(%s): %v", tt.algorithm, err)
191 }
192 }
193 }
194
195 func TestParseRSAPrivateKey(t *testing.T) {
196 key := testPrivateKeys["rsa"]
197
198 rsa, ok := key.(*rsa.PrivateKey)
199 if !ok {
200 t.Fatalf("got %T, want *rsa.PrivateKey", rsa)
201 }
202
203 if err := rsa.Validate(); err != nil {
204 t.Errorf("Validate: %v", err)
205 }
206 }
207
208 func TestParseECPrivateKey(t *testing.T) {
209 key := testPrivateKeys["ecdsa"]
210
211 ecKey, ok := key.(*ecdsa.PrivateKey)
212 if !ok {
213 t.Fatalf("got %T, want *ecdsa.PrivateKey", ecKey)
214 }
215
216 if !validateECPublicKey(ecKey.Curve, ecKey.X, ecKey.Y) {
217 t.Fatalf("public key does not validate.")
218 }
219 }
220
221 func TestParseEncryptedPrivateKeysWithPassphrase(t *testing.T) {
222 data := []byte("sign me")
223 for _, tt := range testdata.PEMEncryptedKeys {
224 t.Run(tt.Name, func(t *testing.T) {
225 _, err := ParsePrivateKeyWithPassphrase(tt.PEMBytes, []byte("incorrect"))
226 if err != x509.IncorrectPasswordError {
227 t.Errorf("got %v want IncorrectPasswordError", err)
228 }
229
230 s, err := ParsePrivateKeyWithPassphrase(tt.PEMBytes, []byte(tt.EncryptionKey))
231 if err != nil {
232 t.Fatalf("ParsePrivateKeyWithPassphrase returned error: %s", err)
233 }
234
235 sig, err := s.Sign(rand.Reader, data)
236 if err != nil {
237 t.Fatalf("Signer.Sign: %v", err)
238 }
239 if err := s.PublicKey().Verify(data, sig); err != nil {
240 t.Errorf("Verify failed: %v", err)
241 }
242
243 _, err = ParsePrivateKey(tt.PEMBytes)
244 if err == nil {
245 t.Fatalf("ParsePrivateKey succeeded, expected an error")
246 }
247
248 if err, ok := err.(*PassphraseMissingError); !ok {
249 t.Errorf("got error %q, want PassphraseMissingError", err)
250 } else if tt.IncludesPublicKey {
251 if err.PublicKey == nil {
252 t.Fatalf("expected PassphraseMissingError.PublicKey not to be nil")
253 }
254 got, want := err.PublicKey.Marshal(), s.PublicKey().Marshal()
255 if !bytes.Equal(got, want) {
256 t.Errorf("error field %q doesn't match signer public key %q", got, want)
257 }
258 }
259 })
260 }
261 }
262
263 func TestParseEncryptedPrivateKeysWithIncorrectPassphrase(t *testing.T) {
264 pem := testdata.PEMEncryptedKeys[0].PEMBytes
265 for i := 0; i < 4096; i++ {
266 _, err := ParseRawPrivateKeyWithPassphrase(pem, []byte(fmt.Sprintf("%d", i)))
267 if !errors.Is(err, x509.IncorrectPasswordError) {
268 t.Fatalf("expected error: %v, got: %v", x509.IncorrectPasswordError, err)
269 }
270 }
271 }
272
273 func TestParseDSA(t *testing.T) {
274
275
276
277 s, err := ParsePrivateKey(testdata.PEMBytes["dsa"])
278 if err != nil {
279 t.Fatalf("ParsePrivateKey returned error: %s", err)
280 }
281
282 data := []byte("sign me")
283 sig, err := s.Sign(rand.Reader, data)
284 if err != nil {
285 t.Fatalf("dsa.Sign: %v", err)
286 }
287
288 if err := s.PublicKey().Verify(data, sig); err != nil {
289 t.Errorf("Verify failed: %v", err)
290 }
291 }
292
293
294
295
296 func getTestKey() (PublicKey, string) {
297 k := testPublicKeys["rsa"]
298
299 b := &bytes.Buffer{}
300 e := base64.NewEncoder(base64.StdEncoding, b)
301 e.Write(k.Marshal())
302 e.Close()
303
304 return k, b.String()
305 }
306
307 func TestMarshalParsePublicKey(t *testing.T) {
308 pub, pubSerialized := getTestKey()
309 line := fmt.Sprintf("%s %s user@host", pub.Type(), pubSerialized)
310
311 authKeys := MarshalAuthorizedKey(pub)
312 actualFields := strings.Fields(string(authKeys))
313 if len(actualFields) == 0 {
314 t.Fatalf("failed authKeys: %v", authKeys)
315 }
316
317
318 expectedFields := strings.Fields(line)[0:2]
319
320 if !reflect.DeepEqual(actualFields, expectedFields) {
321 t.Errorf("got %v, expected %v", actualFields, expectedFields)
322 }
323
324 actPub, _, _, _, err := ParseAuthorizedKey([]byte(line))
325 if err != nil {
326 t.Fatalf("cannot parse %v: %v", line, err)
327 }
328 if !reflect.DeepEqual(actPub, pub) {
329 t.Errorf("got %v, expected %v", actPub, pub)
330 }
331 }
332
333 func TestMarshalPrivateKey(t *testing.T) {
334 tests := []struct {
335 name string
336 }{
337 {"rsa-openssh-format"},
338 {"ed25519"},
339 {"p256-openssh-format"},
340 {"p384-openssh-format"},
341 {"p521-openssh-format"},
342 }
343 for _, tt := range tests {
344 t.Run(tt.name, func(t *testing.T) {
345 expected, ok := testPrivateKeys[tt.name]
346 if !ok {
347 t.Fatalf("cannot find key %s", tt.name)
348 }
349
350 block, err := MarshalPrivateKey(expected, "test@golang.org")
351 if err != nil {
352 t.Fatalf("cannot marshal %s: %v", tt.name, err)
353 }
354
355 key, err := ParseRawPrivateKey(pem.EncodeToMemory(block))
356 if err != nil {
357 t.Fatalf("cannot parse %s: %v", tt.name, err)
358 }
359
360 if !reflect.DeepEqual(expected, key) {
361 t.Errorf("unexpected marshaled key %s", tt.name)
362 }
363 })
364 }
365 }
366
367 func TestMarshalPrivateKeyWithPassphrase(t *testing.T) {
368 tests := []struct {
369 name string
370 }{
371 {"rsa-openssh-format"},
372 {"ed25519"},
373 {"p256-openssh-format"},
374 {"p384-openssh-format"},
375 {"p521-openssh-format"},
376 }
377 for _, tt := range tests {
378 t.Run(tt.name, func(t *testing.T) {
379 expected, ok := testPrivateKeys[tt.name]
380 if !ok {
381 t.Fatalf("cannot find key %s", tt.name)
382 }
383
384 block, err := MarshalPrivateKeyWithPassphrase(expected, "test@golang.org", []byte("test-passphrase"))
385 if err != nil {
386 t.Fatalf("cannot marshal %s: %v", tt.name, err)
387 }
388
389 key, err := ParseRawPrivateKeyWithPassphrase(pem.EncodeToMemory(block), []byte("test-passphrase"))
390 if err != nil {
391 t.Fatalf("cannot parse %s: %v", tt.name, err)
392 }
393
394 if !reflect.DeepEqual(expected, key) {
395 t.Errorf("unexpected marshaled key %s", tt.name)
396 }
397 })
398 }
399 }
400
401 type testAuthResult struct {
402 pubKey PublicKey
403 options []string
404 comments string
405 rest string
406 ok bool
407 }
408
409 func testAuthorizedKeys(t *testing.T, authKeys []byte, expected []testAuthResult) {
410 rest := authKeys
411 var values []testAuthResult
412 for len(rest) > 0 {
413 var r testAuthResult
414 var err error
415 r.pubKey, r.comments, r.options, rest, err = ParseAuthorizedKey(rest)
416 r.ok = (err == nil)
417 t.Log(err)
418 r.rest = string(rest)
419 values = append(values, r)
420 }
421
422 if !reflect.DeepEqual(values, expected) {
423 t.Errorf("got %#v, expected %#v", values, expected)
424 }
425 }
426
427 func TestAuthorizedKeyBasic(t *testing.T) {
428 pub, pubSerialized := getTestKey()
429 line := "ssh-rsa " + pubSerialized + " user@host"
430 testAuthorizedKeys(t, []byte(line),
431 []testAuthResult{
432 {pub, nil, "user@host", "", true},
433 })
434 }
435
436 func TestAuth(t *testing.T) {
437 pub, pubSerialized := getTestKey()
438 authWithOptions := []string{
439 `# comments to ignore before any keys...`,
440 ``,
441 `env="HOME=/home/root",no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host`,
442 `# comments to ignore, along with a blank line`,
443 ``,
444 `env="HOME=/home/root2" ssh-rsa ` + pubSerialized + ` user2@host2`,
445 ``,
446 `# more comments, plus a invalid entry`,
447 `ssh-rsa data-that-will-not-parse user@host3`,
448 }
449 for _, eol := range []string{"\n", "\r\n"} {
450 authOptions := strings.Join(authWithOptions, eol)
451 rest2 := strings.Join(authWithOptions[3:], eol)
452 rest3 := strings.Join(authWithOptions[6:], eol)
453 testAuthorizedKeys(t, []byte(authOptions), []testAuthResult{
454 {pub, []string{`env="HOME=/home/root"`, "no-port-forwarding"}, "user@host", rest2, true},
455 {pub, []string{`env="HOME=/home/root2"`}, "user2@host2", rest3, true},
456 {nil, nil, "", "", false},
457 })
458 }
459 }
460
461 func TestAuthWithQuotedSpaceInEnv(t *testing.T) {
462 pub, pubSerialized := getTestKey()
463 authWithQuotedSpaceInEnv := []byte(`env="HOME=/home/root dir",no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host`)
464 testAuthorizedKeys(t, []byte(authWithQuotedSpaceInEnv), []testAuthResult{
465 {pub, []string{`env="HOME=/home/root dir"`, "no-port-forwarding"}, "user@host", "", true},
466 })
467 }
468
469 func TestAuthWithQuotedCommaInEnv(t *testing.T) {
470 pub, pubSerialized := getTestKey()
471 authWithQuotedCommaInEnv := []byte(`env="HOME=/home/root,dir",no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host`)
472 testAuthorizedKeys(t, []byte(authWithQuotedCommaInEnv), []testAuthResult{
473 {pub, []string{`env="HOME=/home/root,dir"`, "no-port-forwarding"}, "user@host", "", true},
474 })
475 }
476
477 func TestAuthWithQuotedQuoteInEnv(t *testing.T) {
478 pub, pubSerialized := getTestKey()
479 authWithQuotedQuoteInEnv := []byte(`env="HOME=/home/\"root dir",no-port-forwarding` + "\t" + `ssh-rsa` + "\t" + pubSerialized + ` user@host`)
480 authWithDoubleQuotedQuote := []byte(`no-port-forwarding,env="HOME=/home/ \"root dir\"" ssh-rsa ` + pubSerialized + "\t" + `user@host`)
481 testAuthorizedKeys(t, []byte(authWithQuotedQuoteInEnv), []testAuthResult{
482 {pub, []string{`env="HOME=/home/\"root dir"`, "no-port-forwarding"}, "user@host", "", true},
483 })
484
485 testAuthorizedKeys(t, []byte(authWithDoubleQuotedQuote), []testAuthResult{
486 {pub, []string{"no-port-forwarding", `env="HOME=/home/ \"root dir\""`}, "user@host", "", true},
487 })
488 }
489
490 func TestAuthWithInvalidSpace(t *testing.T) {
491 _, pubSerialized := getTestKey()
492 authWithInvalidSpace := []byte(`env="HOME=/home/root dir", no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host
493 #more to follow but still no valid keys`)
494 testAuthorizedKeys(t, []byte(authWithInvalidSpace), []testAuthResult{
495 {nil, nil, "", "", false},
496 })
497 }
498
499 func TestAuthWithMissingQuote(t *testing.T) {
500 pub, pubSerialized := getTestKey()
501 authWithMissingQuote := []byte(`env="HOME=/home/root,no-port-forwarding ssh-rsa ` + pubSerialized + ` user@host
502 env="HOME=/home/root",shared-control ssh-rsa ` + pubSerialized + ` user@host`)
503
504 testAuthorizedKeys(t, []byte(authWithMissingQuote), []testAuthResult{
505 {pub, []string{`env="HOME=/home/root"`, `shared-control`}, "user@host", "", true},
506 })
507 }
508
509 func TestInvalidEntry(t *testing.T) {
510 authInvalid := []byte(`ssh-rsa`)
511 _, _, _, _, err := ParseAuthorizedKey(authInvalid)
512 if err == nil {
513 t.Errorf("got valid entry for %q", authInvalid)
514 }
515 }
516
517 var knownHostsParseTests = []struct {
518 input string
519 err string
520
521 marker string
522 comment string
523 hosts []string
524 rest string
525 }{
526 {
527 "",
528 "EOF",
529
530 "", "", nil, "",
531 },
532 {
533 "# Just a comment",
534 "EOF",
535
536 "", "", nil, "",
537 },
538 {
539 " \t ",
540 "EOF",
541
542 "", "", nil, "",
543 },
544 {
545 "localhost ssh-rsa {RSAPUB}",
546 "",
547
548 "", "", []string{"localhost"}, "",
549 },
550 {
551 "localhost\tssh-rsa {RSAPUB}",
552 "",
553
554 "", "", []string{"localhost"}, "",
555 },
556 {
557 "localhost\tssh-rsa {RSAPUB}\tcomment comment",
558 "",
559
560 "", "comment comment", []string{"localhost"}, "",
561 },
562 {
563 "localhost\tssh-rsa {RSAPUB}\tcomment comment\n",
564 "",
565
566 "", "comment comment", []string{"localhost"}, "",
567 },
568 {
569 "localhost\tssh-rsa {RSAPUB}\tcomment comment\r\n",
570 "",
571
572 "", "comment comment", []string{"localhost"}, "",
573 },
574 {
575 "localhost\tssh-rsa {RSAPUB}\tcomment comment\r\nnext line",
576 "",
577
578 "", "comment comment", []string{"localhost"}, "next line",
579 },
580 {
581 "localhost,[host2:123]\tssh-rsa {RSAPUB}\tcomment comment",
582 "",
583
584 "", "comment comment", []string{"localhost", "[host2:123]"}, "",
585 },
586 {
587 "@marker \tlocalhost,[host2:123]\tssh-rsa {RSAPUB}",
588 "",
589
590 "marker", "", []string{"localhost", "[host2:123]"}, "",
591 },
592 {
593 "@marker \tlocalhost,[host2:123]\tssh-rsa aabbccdd",
594 "short read",
595
596 "", "", nil, "",
597 },
598 }
599
600 func TestKnownHostsParsing(t *testing.T) {
601 rsaPub, rsaPubSerialized := getTestKey()
602
603 for i, test := range knownHostsParseTests {
604 var expectedKey PublicKey
605 const rsaKeyToken = "{RSAPUB}"
606
607 input := test.input
608 if strings.Contains(input, rsaKeyToken) {
609 expectedKey = rsaPub
610 input = strings.Replace(test.input, rsaKeyToken, rsaPubSerialized, -1)
611 }
612
613 marker, hosts, pubKey, comment, rest, err := ParseKnownHosts([]byte(input))
614 if err != nil {
615 if len(test.err) == 0 {
616 t.Errorf("#%d: unexpectedly failed with %q", i, err)
617 } else if !strings.Contains(err.Error(), test.err) {
618 t.Errorf("#%d: expected error containing %q, but got %q", i, test.err, err)
619 }
620 continue
621 } else if len(test.err) != 0 {
622 t.Errorf("#%d: succeeded but expected error including %q", i, test.err)
623 continue
624 }
625
626 if !reflect.DeepEqual(expectedKey, pubKey) {
627 t.Errorf("#%d: expected key %#v, but got %#v", i, expectedKey, pubKey)
628 }
629
630 if marker != test.marker {
631 t.Errorf("#%d: expected marker %q, but got %q", i, test.marker, marker)
632 }
633
634 if comment != test.comment {
635 t.Errorf("#%d: expected comment %q, but got %q", i, test.comment, comment)
636 }
637
638 if !reflect.DeepEqual(test.hosts, hosts) {
639 t.Errorf("#%d: expected hosts %#v, but got %#v", i, test.hosts, hosts)
640 }
641
642 if rest := string(rest); rest != test.rest {
643 t.Errorf("#%d: expected remaining input to be %q, but got %q", i, test.rest, rest)
644 }
645 }
646 }
647
648 func TestFingerprintLegacyMD5(t *testing.T) {
649 pub, _ := getTestKey()
650 fingerprint := FingerprintLegacyMD5(pub)
651 want := "b7:ef:d3:d5:89:29:52:96:9f:df:47:41:4d:15:37:f4"
652 if fingerprint != want {
653 t.Errorf("got fingerprint %q want %q", fingerprint, want)
654 }
655 }
656
657 func TestFingerprintSHA256(t *testing.T) {
658 pub, _ := getTestKey()
659 fingerprint := FingerprintSHA256(pub)
660 want := "SHA256:fi5+D7UmDZDE9Q2sAVvvlpcQSIakN4DERdINgXd2AnE"
661 if fingerprint != want {
662 t.Errorf("got fingerprint %q want %q", fingerprint, want)
663 }
664 }
665
666 func TestInvalidKeys(t *testing.T) {
667 keyTypes := []string{
668 "RSA PRIVATE KEY",
669 "PRIVATE KEY",
670 "EC PRIVATE KEY",
671 "DSA PRIVATE KEY",
672 "OPENSSH PRIVATE KEY",
673 }
674
675 for _, keyType := range keyTypes {
676 for _, dataLen := range []int{0, 1, 2, 5, 10, 20} {
677 data := make([]byte, dataLen)
678 if _, err := io.ReadFull(rand.Reader, data); err != nil {
679 t.Fatal(err)
680 }
681
682 var buf bytes.Buffer
683 pem.Encode(&buf, &pem.Block{
684 Type: keyType,
685 Bytes: data,
686 })
687
688
689
690 ParseRawPrivateKey(buf.Bytes())
691 }
692 }
693 }
694
695 func TestSKKeys(t *testing.T) {
696 for _, d := range testdata.SKData {
697 pk, _, _, _, err := ParseAuthorizedKey(d.PubKey)
698 if err != nil {
699 t.Fatalf("parseAuthorizedKey returned error: %v", err)
700 }
701
702 sigBuf := make([]byte, hex.DecodedLen(len(d.HexSignature)))
703 if _, err := hex.Decode(sigBuf, d.HexSignature); err != nil {
704 t.Fatalf("hex.Decode() failed: %v", err)
705 }
706
707 dataBuf := make([]byte, hex.DecodedLen(len(d.HexData)))
708 if _, err := hex.Decode(dataBuf, d.HexData); err != nil {
709 t.Fatalf("hex.Decode() failed: %v", err)
710 }
711
712 sig, _, ok := parseSignature(sigBuf)
713 if !ok {
714 t.Fatalf("parseSignature(%v) failed", sigBuf)
715 }
716
717
718 if err := pk.Verify(dataBuf, sig); err != nil {
719 t.Errorf("%s: PublicKey.Verify(%v, %v) failed: %v", d.Name, dataBuf, sig, err)
720 }
721
722
723 invalidData := []byte("INVALID DATA")
724 if err := pk.Verify(invalidData, sig); err == nil {
725 t.Errorf("%s with invalid data: PublicKey.Verify(%v, %v) passed unexpectedly", d.Name, invalidData, sig)
726 }
727
728
729 sig.Blob[5] = byte('A')
730
731 if err := pk.Verify(dataBuf, sig); err == nil {
732 t.Errorf("%s with corrupted signature: PublicKey.Verify(%v, %v) passed unexpectedly", d.Name, dataBuf, sig)
733 }
734 }
735 }
736
737 func TestNewSignerWithAlgos(t *testing.T) {
738 algorithSigner, ok := testSigners["rsa"].(AlgorithmSigner)
739 if !ok {
740 t.Fatal("rsa test signer does not implement the AlgorithmSigner interface")
741 }
742 _, err := NewSignerWithAlgorithms(algorithSigner, nil)
743 if err == nil {
744 t.Error("signer with algos created with no algorithms")
745 }
746
747 _, err = NewSignerWithAlgorithms(algorithSigner, []string{KeyAlgoED25519})
748 if err == nil {
749 t.Error("signer with algos created with invalid algorithms")
750 }
751
752 _, err = NewSignerWithAlgorithms(algorithSigner, []string{CertAlgoRSASHA256v01})
753 if err == nil {
754 t.Error("signer with algos created with certificate algorithms")
755 }
756
757 mas, err := NewSignerWithAlgorithms(algorithSigner, []string{KeyAlgoRSASHA256, KeyAlgoRSASHA512})
758 if err != nil {
759 t.Errorf("unable to create signer with valid algorithms: %v", err)
760 }
761
762 _, err = NewSignerWithAlgorithms(mas, []string{KeyAlgoRSA})
763 if err == nil {
764 t.Error("signer with algos created with restricted algorithms")
765 }
766 }
767
768 func TestCryptoPublicKey(t *testing.T) {
769 for _, priv := range testSigners {
770 p1 := priv.PublicKey()
771 key, ok := p1.(CryptoPublicKey)
772 if !ok {
773 continue
774 }
775 p2, err := NewPublicKey(key.CryptoPublicKey())
776 if err != nil {
777 t.Fatalf("NewPublicKey(CryptoPublicKey) failed for %s, got: %v", p1.Type(), err)
778 }
779 if !reflect.DeepEqual(p1, p2) {
780 t.Errorf("got %#v in NewPublicKey, want %#v", p2, p1)
781 }
782 }
783 for _, d := range testdata.SKData {
784 p1, _, _, _, err := ParseAuthorizedKey(d.PubKey)
785 if err != nil {
786 t.Fatalf("parseAuthorizedKey returned error: %v", err)
787 }
788 k1, ok := p1.(CryptoPublicKey)
789 if !ok {
790 t.Fatalf("%T does not implement CryptoPublicKey", p1)
791 }
792
793 var p2 PublicKey
794 switch pub := k1.CryptoPublicKey().(type) {
795 case *ecdsa.PublicKey:
796 p2 = &skECDSAPublicKey{
797 application: "ssh:",
798 PublicKey: *pub,
799 }
800 case ed25519.PublicKey:
801 p2 = &skEd25519PublicKey{
802 application: "ssh:",
803 PublicKey: pub,
804 }
805 default:
806 t.Fatalf("unexpected type %T from CryptoPublicKey()", pub)
807 }
808 if !reflect.DeepEqual(p1, p2) {
809 t.Errorf("got %#v, want %#v", p2, p1)
810 }
811 }
812 }
813
View as plain text