LEFT | RIGHT |
1 package ssh | 1 package ssh |
2 | 2 |
3 import ( | 3 import ( |
4 "bytes" | 4 "bytes" |
5 "crypto" | |
6 "crypto/dsa" | 5 "crypto/dsa" |
| 6 "crypto/ecdsa" |
| 7 "crypto/elliptic" |
7 "crypto/rand" | 8 "crypto/rand" |
8 "crypto/rsa" | 9 "crypto/rsa" |
9 "encoding/base64" | 10 "encoding/base64" |
10 "reflect" | 11 "reflect" |
| 12 "strings" |
11 "testing" | 13 "testing" |
12 ) | 14 ) |
13 | 15 |
14 func TestRSAMarshal(t *testing.T) { | 16 var ecdsaKey Signer |
15 » k0 := &rsakey.PublicKey | 17 |
16 » k1 := NewRSAPublicKey(k0) | 18 func rawKey(pub PublicKey) interface{} { |
17 » k2, rest, ok := ParsePublicKey(MarshalPublicKey(k1)) | 19 » switch k := pub.(type) { |
18 » if !ok { | 20 » case *rsaPublicKey: |
19 » » t.Errorf("could not parse back Blob output") | 21 » » return (*rsa.PublicKey)(k) |
| 22 » case *dsaPublicKey: |
| 23 » » return (*dsa.PublicKey)(k) |
| 24 » case *ecdsaPublicKey: |
| 25 » » return (*ecdsa.PublicKey)(k) |
20 } | 26 } |
21 » if len(rest) > 0 { | 27 » panic("unknown key type") |
22 » » t.Errorf("trailing junk in RSA Blob() output") | 28 } |
23 » } | 29 |
24 » if !reflect.DeepEqual(k0, k2.RawKey().(*rsa.PublicKey)) { | 30 func TestKeyMarshalParse(t *testing.T) { |
25 » » t.Errorf("got %#v in roundtrip, want %#v", k2.RawKey(), k0) | 31 » keys := []Signer{rsaKey, dsaKey, ecdsaKey} |
| 32 » for _, priv := range keys { |
| 33 » » pub := priv.PublicKey() |
| 34 » » roundtrip, rest, ok := ParsePublicKey(MarshalPublicKey(pub)) |
| 35 » » if !ok { |
| 36 » » » t.Errorf("ParsePublicKey(%T) failed", pub) |
| 37 » » } |
| 38 |
| 39 » » if len(rest) > 0 { |
| 40 » » » t.Errorf("ParsePublicKey(%T): trailing junk", pub) |
| 41 » » } |
| 42 |
| 43 » » k1 := rawKey(pub) |
| 44 » » k2 := rawKey(roundtrip) |
| 45 |
| 46 » » if !reflect.DeepEqual(k1, k2) { |
| 47 » » » t.Errorf("got %#v in roundtrip, want %#v", k2, k1) |
| 48 » » } |
26 } | 49 } |
27 } | 50 } |
28 | 51 |
29 func TestRSAKeyVerify(t *testing.T) { | 52 func TestUnsupportedCurves(t *testing.T) { |
30 » pub := NewRSAPublicKey(&rsakey.PublicKey) | 53 » raw, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader) |
31 | |
32 » data := []byte("sign me") | |
33 » h := crypto.SHA1.New() | |
34 » h.Write(data) | |
35 » digest := h.Sum(nil) | |
36 | |
37 » sig, err := rsa.SignPKCS1v15(rand.Reader, rsakey, crypto.SHA1, digest) | |
38 if err != nil { | 54 if err != nil { |
39 » » t.Fatalf("SignPKCS1v15: %v", err) | 55 » » t.Fatalf("GenerateKey: %v", err) |
40 } | 56 } |
41 | 57 |
42 » if !pub.Verify(data, sig) { | 58 » if _, err = NewSignerFromKey(raw); err == nil || !strings.Contains(err.E
rror(), "only P256") { |
43 » » t.Errorf("publicKey.Verify failed") | 59 » » t.Fatalf("NewPrivateKey should not succeed with P224, got: %v",
err) |
| 60 » } |
| 61 |
| 62 » if _, err = NewPublicKey(&raw.PublicKey); err == nil || !strings.Contain
s(err.Error(), "only P256") { |
| 63 » » t.Fatalf("NewPublicKey should not succeed with P224, got: %v", e
rr) |
44 } | 64 } |
45 } | 65 } |
46 | 66 |
47 func TestDSAMarshal(t *testing.T) { | 67 func TestNewPublicKey(t *testing.T) { |
48 » k0 := &dsakey.PublicKey | 68 » keys := []Signer{rsaKey, dsaKey, ecdsaKey} |
49 » k1 := NewDSAPublicKey(k0) | 69 » for _, k := range keys { |
50 » k2, rest, ok := ParsePublicKey(MarshalPublicKey(k1)) | 70 » » raw := rawKey(k.PublicKey()) |
51 » if !ok { | 71 » » pub, err := NewPublicKey(raw) |
52 » » t.Errorf("could not parse back Blob output") | 72 » » if err != nil { |
53 » } | 73 » » » t.Errorf("NewPublicKey(%#v): %v", raw, err) |
54 » if len(rest) > 0 { | 74 » » } |
55 » » t.Errorf("trailing junk in DSA Blob() output") | 75 » » if !reflect.DeepEqual(k.PublicKey(), pub) { |
56 » } | 76 » » » t.Errorf("NewPublicKey(%#v) = %#v, want %#v", raw, pub,
k.PublicKey()) |
57 » if !reflect.DeepEqual(k0, k2.RawKey().(*dsa.PublicKey)) { | 77 » » } |
58 » » t.Errorf("got %#v in roundtrip, want %#v", k2.RawKey(), k0) | |
59 } | 78 } |
60 } | 79 } |
61 | 80 |
62 // TODO(hanwen): test for ECDSA marshal. | 81 func TestKeySignVerify(t *testing.T) { |
| 82 » keys := []Signer{rsaKey, dsaKey, ecdsaKey} |
| 83 » for _, priv := range keys { |
| 84 » » pub := priv.PublicKey() |
| 85 |
| 86 » » data := []byte("sign me") |
| 87 » » sig, err := priv.Sign(rand.Reader, data) |
| 88 » » if err != nil { |
| 89 » » » t.Fatalf("Sign(%T): %v", priv, err) |
| 90 » » } |
| 91 |
| 92 » » if !pub.Verify(data, sig) { |
| 93 » » » t.Errorf("publicKey.Verify(%T) failed", priv) |
| 94 » » } |
| 95 » } |
| 96 } |
| 97 |
| 98 func TestParseRSAPrivateKey(t *testing.T) { |
| 99 » key, err := ParsePrivateKey([]byte(testServerPrivateKey)) |
| 100 » if err != nil { |
| 101 » » t.Fatalf("ParsePrivateKey: %v", err) |
| 102 » } |
| 103 |
| 104 » rsa, ok := key.(*rsaPrivateKey) |
| 105 » if !ok { |
| 106 » » t.Fatalf("got %T, want *rsa.PrivateKey", rsa) |
| 107 » } |
| 108 |
| 109 » if err := rsa.Validate(); err != nil { |
| 110 » » t.Errorf("Validate: %v", err) |
| 111 » } |
| 112 } |
| 113 |
| 114 func TestParseECPrivateKey(t *testing.T) { |
| 115 » // Taken from the data in test/ . |
| 116 » pem := []byte(`-----BEGIN EC PRIVATE KEY----- |
| 117 MHcCAQEEINGWx0zo6fhJ/0EAfrPzVFyFC9s18lBt3cRoEDhS3ARooAoGCCqGSM49 |
| 118 AwEHoUQDQgAEi9Hdw6KvZcWxfg2IDhA7UkpDtzzt6ZqJXSsFdLd+Kx4S3Sx4cVO+ |
| 119 6/ZOXRnPmNAlLUqjShUsUBBngG0u2fqEqA== |
| 120 -----END EC PRIVATE KEY-----`) |
| 121 |
| 122 » key, err := ParsePrivateKey(pem) |
| 123 » if err != nil { |
| 124 » » t.Fatalf("ParsePrivateKey: %v", err) |
| 125 » } |
| 126 |
| 127 » ecKey, ok := key.(*ecdsaPrivateKey) |
| 128 » if !ok { |
| 129 » » t.Fatalf("got %T, want *ecdsaPrivateKey", ecKey) |
| 130 » } |
| 131 |
| 132 » if !validateECPublicKey(ecKey.Curve, ecKey.X, ecKey.Y) { |
| 133 » » t.Fatalf("public key does not validate.") |
| 134 » } |
| 135 } |
| 136 |
| 137 // ssh-keygen -t dsa -f /tmp/idsa.pem |
| 138 var dsaPEM = `-----BEGIN DSA PRIVATE KEY----- |
| 139 MIIBuwIBAAKBgQD6PDSEyXiI9jfNs97WuM46MSDCYlOqWw80ajN16AohtBncs1YB |
| 140 lHk//dQOvCYOsYaE+gNix2jtoRjwXhDsc25/IqQbU1ahb7mB8/rsaILRGIbA5WH3 |
| 141 EgFtJmXFovDz3if6F6TzvhFpHgJRmLYVR8cqsezL3hEZOvvs2iH7MorkxwIVAJHD |
| 142 nD82+lxh2fb4PMsIiaXudAsBAoGAQRf7Q/iaPRn43ZquUhd6WwvirqUj+tkIu6eV |
| 143 2nZWYmXLlqFQKEy4Tejl7Wkyzr2OSYvbXLzo7TNxLKoWor6ips0phYPPMyXld14r |
| 144 juhT24CrhOzuLMhDduMDi032wDIZG4Y+K7ElU8Oufn8Sj5Wge8r6ANmmVgmFfynr |
| 145 FhdYCngCgYEA3ucGJ93/Mx4q4eKRDxcWD3QzWyqpbRVRRV1Vmih9Ha/qC994nJFz |
| 146 DQIdjxDIT2Rk2AGzMqFEB68Zc3O+Wcsmz5eWWzEwFxaTwOGWTyDqsDRLm3fD+QYj |
| 147 nOwuxb0Kce+gWI8voWcqC9cyRm09jGzu2Ab3Bhtpg8JJ8L7gS3MRZK4CFEx4UAfY |
| 148 Fmsr0W6fHB9nhS4/UXM8 |
| 149 -----END DSA PRIVATE KEY-----` |
| 150 |
| 151 func TestParseDSA(t *testing.T) { |
| 152 » s, err := ParsePrivateKey([]byte(dsaPEM)) |
| 153 » if err != nil { |
| 154 » » t.Fatalf("ParsePrivateKey returned error: %s", err) |
| 155 » } |
| 156 |
| 157 » data := []byte("sign me") |
| 158 » sig, err := s.Sign(rand.Reader, data) |
| 159 » if err != nil { |
| 160 » » t.Fatalf("dsa.Sign: %v", err) |
| 161 » } |
| 162 |
| 163 » if !s.PublicKey().Verify(data, sig) { |
| 164 » » t.Error("Verify failed.") |
| 165 » } |
| 166 } |
63 | 167 |
64 func TestParseCert(t *testing.T) { | 168 func TestParseCert(t *testing.T) { |
65 // Cert generated by ssh-keygen 6.0p1 Debian-4. | 169 // Cert generated by ssh-keygen 6.0p1 Debian-4. |
66 // % ssh-keygen -s ca-key -I test user-key | 170 // % ssh-keygen -s ca-key -I test user-key |
67 b64data := "AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgb1srW/W3ZDjY
AO45xLYAwzHBDLsJ4Ux6ICFIkTjb1LEAAAADAQABAAAAYQCkoR51poH0wE8w72cqSB8Sszx+vAhzcMdC
O0wqHTj7UNENHWEXGrU0E0UQekD7U+yhkhtoyjbPOVIP7hNa6aRk/ezdh/iUnCIt4Jt1v3Z1h1P+hA4Q
uYFMHNB+rmjPwAcAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIA
AAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAA
AAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVz
ZXItcmMAAAAAAAAAAAAAAHcAAAAHc3NoLXJzYQAAAAMBAAEAAABhANFS2kaktpSGc+CcmEKPyw9mJC4n
ZKxHKTgLVZeaGbFZOvJTNzBspQHdy7Q1uKSfktxpgjZnksiu/tFF9ngyY2KFoc+U88ya95IZUycBGCUb
BQ8+bhDtw/icdDGQD5WnUwAAAG8AAAAHc3NoLXJzYQAAAGC8Y9Z2LQKhIhxf52773XaWrXdxP0t3GBVo
4A10vUWiYoAGepr6rQIoGGXFxT4B9Gp+nEBJjOwKDXPrAevow0T9ca8gZN+0ykbhSrXLE5Ao48rqr3zP
4O1/9P7e6gp0gw8=" | 171 b64data := "AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgb1srW/W3ZDjY
AO45xLYAwzHBDLsJ4Ux6ICFIkTjb1LEAAAADAQABAAAAYQCkoR51poH0wE8w72cqSB8Sszx+vAhzcMdC
O0wqHTj7UNENHWEXGrU0E0UQekD7U+yhkhtoyjbPOVIP7hNa6aRk/ezdh/iUnCIt4Jt1v3Z1h1P+hA4Q
uYFMHNB+rmjPwAcAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAAAAAAAAAAP//////////AAAAAAAAAIIA
AAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAA
AAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVz
ZXItcmMAAAAAAAAAAAAAAHcAAAAHc3NoLXJzYQAAAAMBAAEAAABhANFS2kaktpSGc+CcmEKPyw9mJC4n
ZKxHKTgLVZeaGbFZOvJTNzBspQHdy7Q1uKSfktxpgjZnksiu/tFF9ngyY2KFoc+U88ya95IZUycBGCUb
BQ8+bhDtw/icdDGQD5WnUwAAAG8AAAAHc3NoLXJzYQAAAGC8Y9Z2LQKhIhxf52773XaWrXdxP0t3GBVo
4A10vUWiYoAGepr6rQIoGGXFxT4B9Gp+nEBJjOwKDXPrAevow0T9ca8gZN+0ykbhSrXLE5Ao48rqr3zP
4O1/9P7e6gp0gw8=" |
68 | 172 |
69 data, err := base64.StdEncoding.DecodeString(b64data) | 173 data, err := base64.StdEncoding.DecodeString(b64data) |
70 if err != nil { | 174 if err != nil { |
71 t.Fatal("base64.StdEncoding.DecodeString: ", err) | 175 t.Fatal("base64.StdEncoding.DecodeString: ", err) |
72 } | 176 } |
73 key, rest, ok := ParsePublicKey(data) | 177 key, rest, ok := ParsePublicKey(data) |
74 if !ok { | 178 if !ok { |
75 t.Fatalf("could not parse certificate") | 179 t.Fatalf("could not parse certificate") |
76 } | 180 } |
77 if len(rest) > 0 { | 181 if len(rest) > 0 { |
78 » » t.Errorf("rest: got %#v, want empty", rest) | 182 » » t.Errorf("rest: got %q, want empty", rest) |
79 } | 183 } |
80 _, ok = key.(*OpenSSHCertV01) | 184 _, ok = key.(*OpenSSHCertV01) |
81 if !ok { | 185 if !ok { |
82 t.Fatalf("got %#v, want *OpenSSHCertV01", key) | 186 t.Fatalf("got %#v, want *OpenSSHCertV01", key) |
83 } | 187 } |
84 | 188 |
85 marshaled := MarshalPublicKey(key) | 189 marshaled := MarshalPublicKey(key) |
86 if !bytes.Equal(data, marshaled) { | 190 if !bytes.Equal(data, marshaled) { |
87 t.Errorf("marshaled certificate does not match original: got %q,
want %q", marshaled, data) | 191 t.Errorf("marshaled certificate does not match original: got %q,
want %q", marshaled, data) |
88 } | 192 } |
89 } | 193 } |
| 194 |
| 195 func init() { |
| 196 raw, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) |
| 197 ecdsaKey, _ = NewSignerFromKey(raw) |
| 198 } |
LEFT | RIGHT |