LEFT | RIGHT |
1 package ssh | 1 package ssh |
2 | 2 |
3 import ( | 3 import ( |
4 "bytes" | |
5 "crypto/dsa" | 4 "crypto/dsa" |
6 "crypto/ecdsa" | 5 "crypto/ecdsa" |
7 "crypto/elliptic" | 6 "crypto/elliptic" |
8 "crypto/rand" | 7 "crypto/rand" |
9 "crypto/rsa" | 8 "crypto/rsa" |
10 "io" | |
11 "reflect" | 9 "reflect" |
12 "strings" | 10 "strings" |
13 "testing" | 11 "testing" |
14 "time" | 12 "time" |
15 ) | 13 ) |
16 | 14 |
17 var ( | 15 var ( |
18 ecdsaKey Signer | 16 ecdsaKey Signer |
19 ecdsa384Key Signer | 17 ecdsa384Key Signer |
20 ecdsa521Key Signer | 18 ecdsa521Key Signer |
21 testCertKey Signer | 19 testCertKey Signer |
22 ) | 20 ) |
23 | 21 |
24 type testSigner struct { | 22 type testSigner struct { |
25 » priv Signer | 23 » Signer |
26 » pub PublicKey | 24 » pub PublicKey |
27 } | 25 } |
28 | 26 |
29 func (ts *testSigner) PublicKey() PublicKey { | 27 func (ts *testSigner) PublicKey() PublicKey { |
30 if ts.pub != nil { | 28 if ts.pub != nil { |
31 return ts.pub | 29 return ts.pub |
32 } | 30 } |
33 » return ts.priv.PublicKey() | 31 » return ts.Signer.PublicKey() |
34 } | 32 } |
35 | 33 |
36 func (ts *testSigner) Sign(rand io.Reader, data []byte) ([]byte, error) { | 34 func init() { |
37 » return ts.priv.Sign(rand, data) | 35 » raw256, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) |
| 36 » ecdsaKey, _ = NewSignerFromKey(raw256) |
| 37 |
| 38 » raw384, _ := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) |
| 39 » ecdsa384Key, _ = NewSignerFromKey(raw384) |
| 40 |
| 41 » raw521, _ := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) |
| 42 » ecdsa521Key, _ = NewSignerFromKey(raw521) |
| 43 |
| 44 » // Create a cert and sign it for use in tests. |
| 45 » testCert := &OpenSSHCertV01{ |
| 46 » » Nonce: []byte{}, // To pass reflect.DeepEqual after ma
rshal & parse, this must be non-nil |
| 47 » » Key: ecdsaKey.PublicKey(), |
| 48 » » ValidPrincipals: []string{"gopher1", "gopher2"}, // increases te
st coverage |
| 49 » » ValidAfter: time.Now().Truncate(time.Second), |
| 50 » » ValidBefore: time.Now().Truncate(time.Second).Add(time.Hour)
, |
| 51 » » Reserved: []byte{}, // To pass reflect.DeepEqual after ma
rshal & parse, this must be non-nil |
| 52 » » SignatureKey: rsaKey.PublicKey(), |
| 53 » } |
| 54 » sigBytes, _ := rsaKey.Sign(rand.Reader, testCert.BytesForSigning()) |
| 55 » testCert.Signature = &signature{ |
| 56 » » Format: testCert.SignatureKey.PublicKeyAlgo(), |
| 57 » » Blob: sigBytes, |
| 58 » } |
| 59 » testCertKey = &testSigner{ |
| 60 » » Signer: ecdsaKey, |
| 61 » » pub: testCert, |
| 62 » } |
38 } | 63 } |
39 | 64 |
40 func rawKey(pub PublicKey) interface{} { | 65 func rawKey(pub PublicKey) interface{} { |
41 switch k := pub.(type) { | 66 switch k := pub.(type) { |
42 case *rsaPublicKey: | 67 case *rsaPublicKey: |
43 return (*rsa.PublicKey)(k) | 68 return (*rsa.PublicKey)(k) |
44 case *dsaPublicKey: | 69 case *dsaPublicKey: |
45 return (*dsa.PublicKey)(k) | 70 return (*dsa.PublicKey)(k) |
46 case *ecdsaPublicKey: | 71 case *ecdsaPublicKey: |
47 return (*ecdsa.PublicKey)(k) | 72 return (*ecdsa.PublicKey)(k) |
48 case *OpenSSHCertV01: | 73 case *OpenSSHCertV01: |
49 return k | 74 return k |
50 } | 75 } |
51 panic("unknown key type") | 76 panic("unknown key type") |
52 } | 77 } |
53 | 78 |
54 func TestKeyMarshalParse(t *testing.T) { | 79 func TestKeyMarshalParse(t *testing.T) { |
55 keys := []Signer{rsaKey, dsaKey, ecdsaKey, ecdsa384Key, ecdsa521Key, tes
tCertKey} | 80 keys := []Signer{rsaKey, dsaKey, ecdsaKey, ecdsa384Key, ecdsa521Key, tes
tCertKey} |
56 for _, priv := range keys { | 81 for _, priv := range keys { |
57 pub := priv.PublicKey() | 82 pub := priv.PublicKey() |
58 roundtrip, rest, ok := ParsePublicKey(MarshalPublicKey(pub)) | 83 roundtrip, rest, ok := ParsePublicKey(MarshalPublicKey(pub)) |
59 if !ok { | 84 if !ok { |
60 t.Errorf("ParsePublicKey(%T) failed", pub) | 85 t.Errorf("ParsePublicKey(%T) failed", pub) |
61 } | 86 } |
62 | 87 |
63 if len(rest) > 0 { | 88 if len(rest) > 0 { |
64 t.Errorf("ParsePublicKey(%T): trailing junk", pub) | 89 t.Errorf("ParsePublicKey(%T): trailing junk", pub) |
65 } | 90 } |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 data := []byte("sign me") | 206 data := []byte("sign me") |
182 sig, err := s.Sign(rand.Reader, data) | 207 sig, err := s.Sign(rand.Reader, data) |
183 if err != nil { | 208 if err != nil { |
184 t.Fatalf("dsa.Sign: %v", err) | 209 t.Fatalf("dsa.Sign: %v", err) |
185 } | 210 } |
186 | 211 |
187 if !s.PublicKey().Verify(data, sig) { | 212 if !s.PublicKey().Verify(data, sig) { |
188 t.Error("Verify failed.") | 213 t.Error("Verify failed.") |
189 } | 214 } |
190 } | 215 } |
191 | |
192 // Cert generated by ssh-keygen 6.0p1 Debian-4. | |
193 // % ssh-keygen -s ca-key -I test user-key | |
194 var exampleSSHCert = `ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb
3BlbnNzaC5jb20AAAAgb1srW/W3ZDjYAO45xLYAwzHBDLsJ4Ux6ICFIkTjb1LEAAAADAQABAAAAYQCko
R51poH0wE8w72cqSB8Sszx+vAhzcMdCO0wqHTj7UNENHWEXGrU0E0UQekD7U+yhkhtoyjbPOVIP7hNa6
aRk/ezdh/iUnCIt4Jt1v3Z1h1P+hA4QuYFMHNB+rmjPwAcAAAAAAAAAAAAAAAEAAAAEdGVzdAAAAAAAA
AAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdwZXJta
XQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAKcGVyb
Wl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAHcAAAAHc3NoLXJzYQAAAAMBAAEAA
ABhANFS2kaktpSGc+CcmEKPyw9mJC4nZKxHKTgLVZeaGbFZOvJTNzBspQHdy7Q1uKSfktxpgjZnksiu/
tFF9ngyY2KFoc+U88ya95IZUycBGCUbBQ8+bhDtw/icdDGQD5WnUwAAAG8AAAAHc3NoLXJzYQAAAGC8Y
9Z2LQKhIhxf52773XaWrXdxP0t3GBVo4A10vUWiYoAGepr6rQIoGGXFxT4B9Gp+nEBJjOwKDXPrAevow
0T9ca8gZN+0ykbhSrXLE5Ao48rqr3zP4O1/9P7e6gp0gw8=` | |
195 | |
196 func TestParseCert(t *testing.T) { | |
197 authKeyBytes := []byte(exampleSSHCert) | |
198 | |
199 key, _, _, rest, ok := ParseAuthorizedKey(authKeyBytes) | |
200 if !ok { | |
201 t.Fatalf("could not parse certificate") | |
202 } | |
203 if len(rest) > 0 { | |
204 t.Errorf("rest: got %q, want empty", rest) | |
205 } | |
206 | |
207 if _, ok = key.(*OpenSSHCertV01); !ok { | |
208 t.Fatalf("got %#v, want *OpenSSHCertV01", key) | |
209 } | |
210 | |
211 marshaled := MarshalAuthorizedKey(key) | |
212 // Before comparison, remove the trailing newline that | |
213 // MarshalAuthorizedKey adds. | |
214 marshaled = marshaled[:len(marshaled)-1] | |
215 if !bytes.Equal(authKeyBytes, marshaled) { | |
216 t.Errorf("marshaled certificate does not match original: got %q,
want %q", marshaled, authKeyBytes) | |
217 } | |
218 } | |
219 | |
220 func TestVerifyCert(t *testing.T) { | |
221 key, _, _, _, _ := ParseAuthorizedKey([]byte(exampleSSHCert)) | |
222 validCert := key.(*OpenSSHCertV01) | |
223 if ok := verifyOpenSSHCertV01(validCert); !ok { | |
224 t.Error("Unable to validate certificate!") | |
225 } | |
226 | |
227 invalidCert := &OpenSSHCertV01{ | |
228 Key: rsaKey.PublicKey(), | |
229 SignatureKey: ecdsaKey.PublicKey(), | |
230 Signature: &signature{}, | |
231 } | |
232 if ok := verifyOpenSSHCertV01(invalidCert); ok { | |
233 t.Error("Invalid cert signature passed validation!") | |
234 } | |
235 } | |
236 | |
237 func init() { | |
238 raw256, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) | |
239 ecdsaKey, _ = NewSignerFromKey(raw256) | |
240 | |
241 raw384, _ := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) | |
242 ecdsa384Key, _ = NewSignerFromKey(raw384) | |
243 | |
244 raw521, _ := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) | |
245 ecdsa521Key, _ = NewSignerFromKey(raw521) | |
246 | |
247 // Create a cert and sign it for use in tests. | |
248 testCert := &OpenSSHCertV01{ | |
249 Nonce: []byte{}, | |
250 Key: ecdsaKey.PublicKey(), | |
251 ValidPrincipals: []string{"gopher1", "gopher2"}, // increases te
st coverage | |
252 ValidAfter: time.Now().Truncate(time.Second), | |
253 ValidBefore: time.Now().Truncate(time.Second).Add(time.Hour)
, | |
254 Reserved: []byte{}, | |
255 SignatureKey: rsaKey.PublicKey(), | |
256 } | |
257 sigBytes, _ := rsaKey.Sign(rand.Reader, testCert.BytesForSigning()) | |
258 testCert.Signature = &signature{ | |
259 Format: testCert.SignatureKey.PublicKeyAlgo(), | |
260 Blob: sigBytes, | |
261 } | |
262 testCertKey = &testSigner{ | |
263 priv: ecdsaKey, | |
264 pub: testCert, | |
265 } | |
266 } | |
LEFT | RIGHT |