Left: | ||
Right: |
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. |
hanwen-google
2013/09/18 20:02:39
can you quote the command line?
jpsugar
2013/09/18 20:10:48
Done.
| |
170 // % ssh-keygen -s ca-key -I test user-key | |
66 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=" |
67 | 172 |
68 data, err := base64.StdEncoding.DecodeString(b64data) | 173 data, err := base64.StdEncoding.DecodeString(b64data) |
69 if err != nil { | 174 if err != nil { |
70 » » t.Fatal(err) | 175 » » t.Fatal("base64.StdEncoding.DecodeString: ", err) |
hanwen-google
2013/09/18 20:02:39
mention the failing function for context.
jpsugar
2013/09/18 20:10:48
Done.
| |
71 } | 176 } |
72 key, rest, ok := ParsePublicKey(data) | 177 key, rest, ok := ParsePublicKey(data) |
73 if !ok { | 178 if !ok { |
74 t.Fatalf("could not parse certificate") | 179 t.Fatalf("could not parse certificate") |
75 } | 180 } |
76 if len(rest) > 0 { | 181 if len(rest) > 0 { |
77 » » t.Errorf("rest: got %#v, want empty", rest) | 182 » » t.Errorf("rest: got %q, want empty", rest) |
78 } | 183 } |
79 » cert, ok := key.(*OpenSSHCertV01) | 184 » _, ok = key.(*OpenSSHCertV01) |
80 if !ok { | 185 if !ok { |
81 t.Fatalf("got %#v, want *OpenSSHCertV01", key) | 186 t.Fatalf("got %#v, want *OpenSSHCertV01", key) |
82 } | 187 } |
83 | 188 |
84 marshaled := MarshalPublicKey(key) | 189 marshaled := MarshalPublicKey(key) |
85 if !bytes.Equal(data, marshaled) { | 190 if !bytes.Equal(data, marshaled) { |
86 » » t.Errorf("marshaled certificate does not match original: got %#v , want %#v", marshaled, data) | 191 » » t.Errorf("marshaled certificate does not match original: got %q, want %q", marshaled, data) |
hanwen-google
2013/09/18 20:02:39
%#v will print
[]byte{0x1, 0x3, ... }
I'd use %q
jpsugar
2013/09/18 20:10:48
Done.
| |
87 } | 192 } |
88 } | 193 } |
194 | |
195 func init() { | |
196 raw, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) | |
197 ecdsaKey, _ = NewSignerFromKey(raw) | |
198 } | |
LEFT | RIGHT |