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 "encoding/base64" | |
11 "reflect" | 9 "reflect" |
12 "strings" | 10 "strings" |
13 "testing" | 11 "testing" |
| 12 "time" |
14 ) | 13 ) |
15 | 14 |
16 var ecdsaKey Signer | 15 var ( |
| 16 » ecdsaKey Signer |
| 17 » ecdsa384Key Signer |
| 18 » ecdsa521Key Signer |
| 19 » testCertKey Signer |
| 20 ) |
| 21 |
| 22 type testSigner struct { |
| 23 » Signer |
| 24 » pub PublicKey |
| 25 } |
| 26 |
| 27 func (ts *testSigner) PublicKey() PublicKey { |
| 28 » if ts.pub != nil { |
| 29 » » return ts.pub |
| 30 » } |
| 31 » return ts.Signer.PublicKey() |
| 32 } |
| 33 |
| 34 func init() { |
| 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 » } |
| 63 } |
17 | 64 |
18 func rawKey(pub PublicKey) interface{} { | 65 func rawKey(pub PublicKey) interface{} { |
19 switch k := pub.(type) { | 66 switch k := pub.(type) { |
20 case *rsaPublicKey: | 67 case *rsaPublicKey: |
21 return (*rsa.PublicKey)(k) | 68 return (*rsa.PublicKey)(k) |
22 case *dsaPublicKey: | 69 case *dsaPublicKey: |
23 return (*dsa.PublicKey)(k) | 70 return (*dsa.PublicKey)(k) |
24 case *ecdsaPublicKey: | 71 case *ecdsaPublicKey: |
25 return (*ecdsa.PublicKey)(k) | 72 return (*ecdsa.PublicKey)(k) |
| 73 case *OpenSSHCertV01: |
| 74 return k |
26 } | 75 } |
27 panic("unknown key type") | 76 panic("unknown key type") |
28 } | 77 } |
29 | 78 |
30 func TestKeyMarshalParse(t *testing.T) { | 79 func TestKeyMarshalParse(t *testing.T) { |
31 » keys := []Signer{rsaKey, dsaKey, ecdsaKey} | 80 » keys := []Signer{rsaKey, dsaKey, ecdsaKey, ecdsa384Key, ecdsa521Key, tes
tCertKey} |
32 for _, priv := range keys { | 81 for _, priv := range keys { |
33 pub := priv.PublicKey() | 82 pub := priv.PublicKey() |
34 roundtrip, rest, ok := ParsePublicKey(MarshalPublicKey(pub)) | 83 roundtrip, rest, ok := ParsePublicKey(MarshalPublicKey(pub)) |
35 if !ok { | 84 if !ok { |
36 t.Errorf("ParsePublicKey(%T) failed", pub) | 85 t.Errorf("ParsePublicKey(%T) failed", pub) |
37 } | 86 } |
38 | 87 |
39 if len(rest) > 0 { | 88 if len(rest) > 0 { |
40 t.Errorf("ParsePublicKey(%T): trailing junk", pub) | 89 t.Errorf("ParsePublicKey(%T): trailing junk", pub) |
41 } | 90 } |
(...skipping 30 matching lines...) Expand all Loading... |
72 if err != nil { | 121 if err != nil { |
73 t.Errorf("NewPublicKey(%#v): %v", raw, err) | 122 t.Errorf("NewPublicKey(%#v): %v", raw, err) |
74 } | 123 } |
75 if !reflect.DeepEqual(k.PublicKey(), pub) { | 124 if !reflect.DeepEqual(k.PublicKey(), pub) { |
76 t.Errorf("NewPublicKey(%#v) = %#v, want %#v", raw, pub,
k.PublicKey()) | 125 t.Errorf("NewPublicKey(%#v) = %#v, want %#v", raw, pub,
k.PublicKey()) |
77 } | 126 } |
78 } | 127 } |
79 } | 128 } |
80 | 129 |
81 func TestKeySignVerify(t *testing.T) { | 130 func TestKeySignVerify(t *testing.T) { |
82 » keys := []Signer{rsaKey, dsaKey, ecdsaKey} | 131 » keys := []Signer{rsaKey, dsaKey, ecdsaKey, testCertKey} |
83 for _, priv := range keys { | 132 for _, priv := range keys { |
84 pub := priv.PublicKey() | 133 pub := priv.PublicKey() |
85 | 134 |
86 data := []byte("sign me") | 135 data := []byte("sign me") |
87 sig, err := priv.Sign(rand.Reader, data) | 136 sig, err := priv.Sign(rand.Reader, data) |
88 if err != nil { | 137 if err != nil { |
89 t.Fatalf("Sign(%T): %v", priv, err) | 138 t.Fatalf("Sign(%T): %v", priv, err) |
90 } | 139 } |
91 | 140 |
92 if !pub.Verify(data, sig) { | 141 if !pub.Verify(data, sig) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 data := []byte("sign me") | 206 data := []byte("sign me") |
158 sig, err := s.Sign(rand.Reader, data) | 207 sig, err := s.Sign(rand.Reader, data) |
159 if err != nil { | 208 if err != nil { |
160 t.Fatalf("dsa.Sign: %v", err) | 209 t.Fatalf("dsa.Sign: %v", err) |
161 } | 210 } |
162 | 211 |
163 if !s.PublicKey().Verify(data, sig) { | 212 if !s.PublicKey().Verify(data, sig) { |
164 t.Error("Verify failed.") | 213 t.Error("Verify failed.") |
165 } | 214 } |
166 } | 215 } |
167 | |
168 func TestParseCert(t *testing.T) { | |
169 // Cert generated by ssh-keygen 6.0p1 Debian-4. | |
170 // % ssh-keygen -s ca-key -I test user-key | |
171 b64data := []byte("ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12
MDFAb3BlbnNzaC5jb20AAAAgb1srW/W3ZDjYAO45xLYAwzHBDLsJ4Ux6ICFIkTjb1LEAAAADAQABAAAA
YQCkoR51poH0wE8w72cqSB8Sszx+vAhzcMdCO0wqHTj7UNENHWEXGrU0E0UQekD7U+yhkhtoyjbPOVIP
7hNa6aRk/ezdh/iUnCIt4Jt1v3Z1h1P+hA4QuYFMHNB+rmjPwAcAAAAAAAAAAAAAAAEAAAAEdGVzdAAA
AAAAAAAAAAAAAP//////////AAAAAAAAAIIAAAAVcGVybWl0LVgxMS1mb3J3YXJkaW5nAAAAAAAAABdw
ZXJtaXQtYWdlbnQtZm9yd2FyZGluZwAAAAAAAAAWcGVybWl0LXBvcnQtZm9yd2FyZGluZwAAAAAAAAAK
cGVybWl0LXB0eQAAAAAAAAAOcGVybWl0LXVzZXItcmMAAAAAAAAAAAAAAHcAAAAHc3NoLXJzYQAAAAMB
AAEAAABhANFS2kaktpSGc+CcmEKPyw9mJC4nZKxHKTgLVZeaGbFZOvJTNzBspQHdy7Q1uKSfktxpgjZn
ksiu/tFF9ngyY2KFoc+U88ya95IZUycBGCUbBQ8+bhDtw/icdDGQD5WnUwAAAG8AAAAHc3NoLXJzYQAA
AGC8Y9Z2LQKhIhxf52773XaWrXdxP0t3GBVo4A10vUWiYoAGepr6rQIoGGXFxT4B9Gp+nEBJjOwKDXPr
Aevow0T9ca8gZN+0ykbhSrXLE5Ao48rqr3zP4O1/9P7e6gp0gw8=") | |
172 | |
173 key, _, _, rest, ok := ParseAuthorizedKey(b64data) | |
174 if !ok { | |
175 t.Fatalf("could not parse certificate") | |
176 } | |
177 if len(rest) > 0 { | |
178 t.Errorf("rest: got %q, want empty", rest) | |
179 } | |
180 | |
181 cert, ok := key.(*OpenSSHCertV01) | |
182 if !ok { | |
183 t.Fatalf("got %#v, want *OpenSSHCertV01", key) | |
184 } | |
185 | |
186 if ok = verifyOpenSSHCertV01(cert); !ok { | |
187 t.Error("Unable to validate certificate!") | |
188 } | |
189 | |
190 marshaled := MarshalAuthorizedKey(key) | |
191 if !bytes.Equal(b64data, marshaled) { | |
192 t.Errorf("marshaled certificate does not match original: got %q,
want %q", marshaled, b64data) | |
193 } | |
194 } | |
195 | |
196 func init() { | |
197 raw, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) | |
198 ecdsaKey, _ = NewSignerFromKey(raw) | |
199 } | |
LEFT | RIGHT |