keys_test.go 20 KB

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