LEFT | RIGHT |
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package ssh | 5 package ssh |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "crypto" | 9 "crypto" |
10 "crypto/dsa" | 10 "crypto/dsa" |
11 "crypto/ecdsa" | 11 "crypto/ecdsa" |
12 "crypto/elliptic" | 12 "crypto/elliptic" |
13 "crypto/rsa" | 13 "crypto/rsa" |
| 14 "crypto/x509" |
| 15 "encoding/asn1" |
14 "encoding/base64" | 16 "encoding/base64" |
| 17 "encoding/pem" |
| 18 "errors" |
| 19 "fmt" |
| 20 "io" |
15 "math/big" | 21 "math/big" |
16 ) | 22 ) |
17 | 23 |
18 // These constants represent the algorithm names for key types supported by this | 24 // These constants represent the algorithm names for key types supported by this |
19 // package. | 25 // package. |
20 const ( | 26 const ( |
21 KeyAlgoRSA = "ssh-rsa" | 27 KeyAlgoRSA = "ssh-rsa" |
22 KeyAlgoDSA = "ssh-dss" | 28 KeyAlgoDSA = "ssh-dss" |
23 KeyAlgoECDSA256 = "ecdsa-sha2-nistp256" | 29 KeyAlgoECDSA256 = "ecdsa-sha2-nistp256" |
24 KeyAlgoECDSA384 = "ecdsa-sha2-nistp384" | 30 KeyAlgoECDSA384 = "ecdsa-sha2-nistp384" |
(...skipping 12 matching lines...) Expand all Loading... |
37 return parseECDSA(in) | 43 return parseECDSA(in) |
38 case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA3
84v01, CertAlgoECDSA521v01: | 44 case CertAlgoRSAv01, CertAlgoDSAv01, CertAlgoECDSA256v01, CertAlgoECDSA3
84v01, CertAlgoECDSA521v01: |
39 return parseOpenSSHCertV01(in, algo) | 45 return parseOpenSSHCertV01(in, algo) |
40 } | 46 } |
41 return nil, nil, false | 47 return nil, nil, false |
42 } | 48 } |
43 | 49 |
44 // parseAuthorizedKey parses a public key in OpenSSH authorized_keys format | 50 // parseAuthorizedKey parses a public key in OpenSSH authorized_keys format |
45 // (see sshd(8) manual page) once the options and key type fields have been | 51 // (see sshd(8) manual page) once the options and key type fields have been |
46 // removed. | 52 // removed. |
47 func parseAuthorizedKey(in []byte) (out interface{}, comment string, ok bool) { | 53 func parseAuthorizedKey(in []byte) (out PublicKey, comment string, ok bool) { |
48 in = bytes.TrimSpace(in) | 54 in = bytes.TrimSpace(in) |
49 | 55 |
50 i := bytes.IndexAny(in, " \t") | 56 i := bytes.IndexAny(in, " \t") |
51 if i == -1 { | 57 if i == -1 { |
52 i = len(in) | 58 i = len(in) |
53 } | 59 } |
54 base64Key := in[:i] | 60 base64Key := in[:i] |
55 | 61 |
56 key := make([]byte, base64.StdEncoding.DecodedLen(len(base64Key))) | 62 key := make([]byte, base64.StdEncoding.DecodedLen(len(base64Key))) |
57 n, err := base64.StdEncoding.Decode(key, base64Key) | 63 n, err := base64.StdEncoding.Decode(key, base64Key) |
58 if err != nil { | 64 if err != nil { |
59 return | 65 return |
60 } | 66 } |
61 key = key[:n] | 67 key = key[:n] |
62 out, _, ok = ParsePublicKey(key) | 68 out, _, ok = ParsePublicKey(key) |
63 if !ok { | 69 if !ok { |
64 return nil, "", false | 70 return nil, "", false |
65 } | 71 } |
66 comment = string(bytes.TrimSpace(in[i:])) | 72 comment = string(bytes.TrimSpace(in[i:])) |
67 return | 73 return |
68 } | 74 } |
69 | 75 |
70 // ParseAuthorizedKeys parses a public key from an authorized_keys | 76 // ParseAuthorizedKeys parses a public key from an authorized_keys |
71 // file used in OpenSSH according to the sshd(8) manual page. | 77 // file used in OpenSSH according to the sshd(8) manual page. |
72 func ParseAuthorizedKey(in []byte) (out interface{}, comment string, options []s
tring, rest []byte, ok bool) { | 78 func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []str
ing, rest []byte, ok bool) { |
73 for len(in) > 0 { | 79 for len(in) > 0 { |
74 end := bytes.IndexByte(in, '\n') | 80 end := bytes.IndexByte(in, '\n') |
75 if end != -1 { | 81 if end != -1 { |
76 rest = in[end+1:] | 82 rest = in[end+1:] |
77 in = in[:end] | 83 in = in[:end] |
78 } else { | 84 } else { |
79 rest = nil | 85 rest = nil |
80 } | 86 } |
81 | 87 |
82 end = bytes.IndexByte(in, '\r') | 88 end = bytes.IndexByte(in, '\r') |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 PublicKeyAlgo() string | 209 PublicKeyAlgo() string |
204 | 210 |
205 // Marshal returns the serialized key data in SSH wire format, | 211 // Marshal returns the serialized key data in SSH wire format, |
206 // without the name prefix. Callers should typically use | 212 // without the name prefix. Callers should typically use |
207 // MarshalPublicKey(). | 213 // MarshalPublicKey(). |
208 Marshal() []byte | 214 Marshal() []byte |
209 | 215 |
210 // Verify that sig is a signature on the given data using this | 216 // Verify that sig is a signature on the given data using this |
211 // key. This function will hash the data appropriately first. | 217 // key. This function will hash the data appropriately first. |
212 Verify(data []byte, sigBlob []byte) bool | 218 Verify(data []byte, sigBlob []byte) bool |
213 | 219 } |
214 » // RawKey returns the underlying object, eg. *rsa.PublicKey. | 220 |
215 » RawKey() interface{} | 221 // A Signer is can create signatures that verify against a public key. |
216 } | 222 type Signer interface { |
217 | 223 » // PublicKey returns an associated PublicKey instance. |
218 // TODO(hanwen): define PrivateKey too. | 224 » PublicKey() PublicKey |
| 225 |
| 226 » // Sign returns raw signature for the given data. This method |
| 227 » // will apply the hash specified for the keytype to the data. |
| 228 » Sign(rand io.Reader, data []byte) ([]byte, error) |
| 229 } |
219 | 230 |
220 type rsaPublicKey rsa.PublicKey | 231 type rsaPublicKey rsa.PublicKey |
221 | 232 |
222 func (r *rsaPublicKey) PrivateKeyAlgo() string { | 233 func (r *rsaPublicKey) PrivateKeyAlgo() string { |
223 return "ssh-rsa" | 234 return "ssh-rsa" |
224 } | 235 } |
225 | 236 |
226 func (r *rsaPublicKey) PublicKeyAlgo() string { | 237 func (r *rsaPublicKey) PublicKeyAlgo() string { |
227 » return "ssh-rsa" | 238 » return r.PrivateKeyAlgo() |
228 } | |
229 | |
230 func (r *rsaPublicKey) RawKey() interface{} { | |
231 » return (*rsa.PublicKey)(r) | |
232 } | 239 } |
233 | 240 |
234 // parseRSA parses an RSA key according to RFC 4253, section 6.6. | 241 // parseRSA parses an RSA key according to RFC 4253, section 6.6. |
235 func parseRSA(in []byte) (out PublicKey, rest []byte, ok bool) { | 242 func parseRSA(in []byte) (out PublicKey, rest []byte, ok bool) { |
236 key := new(rsa.PublicKey) | 243 key := new(rsa.PublicKey) |
237 | 244 |
238 bigE, in, ok := parseInt(in) | 245 bigE, in, ok := parseInt(in) |
239 if !ok || bigE.BitLen() > 24 { | 246 if !ok || bigE.BitLen() > 24 { |
240 return | 247 return |
241 } | 248 } |
242 e := bigE.Int64() | 249 e := bigE.Int64() |
243 if e < 3 || e&1 == 0 { | 250 if e < 3 || e&1 == 0 { |
244 ok = false | 251 ok = false |
245 return | 252 return |
246 } | 253 } |
247 key.E = int(e) | 254 key.E = int(e) |
248 | 255 |
249 if key.N, in, ok = parseInt(in); !ok { | 256 if key.N, in, ok = parseInt(in); !ok { |
250 return | 257 return |
251 } | 258 } |
252 | 259 |
253 ok = true | 260 ok = true |
254 » return NewRSAPublicKey(key), in, ok | 261 » return (*rsaPublicKey)(key), in, ok |
255 } | 262 } |
256 | 263 |
257 func (r *rsaPublicKey) Marshal() []byte { | 264 func (r *rsaPublicKey) Marshal() []byte { |
258 // See RFC 4253, section 6.6. | 265 // See RFC 4253, section 6.6. |
259 e := new(big.Int).SetInt64(int64(r.E)) | 266 e := new(big.Int).SetInt64(int64(r.E)) |
260 length := intLength(e) | 267 length := intLength(e) |
261 length += intLength(r.N) | 268 length += intLength(r.N) |
262 | 269 |
263 ret := make([]byte, length) | 270 ret := make([]byte, length) |
264 rest := marshalInt(ret, e) | 271 rest := marshalInt(ret, e) |
265 marshalInt(rest, r.N) | 272 marshalInt(rest, r.N) |
266 | 273 |
267 return ret | 274 return ret |
268 } | 275 } |
269 | 276 |
270 func (r *rsaPublicKey) Verify(data []byte, sig []byte) bool { | 277 func (r *rsaPublicKey) Verify(data []byte, sig []byte) bool { |
271 h := crypto.SHA1.New() | 278 h := crypto.SHA1.New() |
272 h.Write(data) | 279 h.Write(data) |
273 digest := h.Sum(nil) | 280 digest := h.Sum(nil) |
274 return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), crypto.SHA1, digest, sig)
== nil | 281 return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), crypto.SHA1, digest, sig)
== nil |
275 } | 282 } |
276 | 283 |
277 func NewRSAPublicKey(k *rsa.PublicKey) PublicKey { | 284 type rsaPrivateKey struct { |
278 » return (*rsaPublicKey)(k) | 285 » *rsa.PrivateKey |
| 286 } |
| 287 |
| 288 func (r *rsaPrivateKey) PublicKey() PublicKey { |
| 289 » return (*rsaPublicKey)(&r.PrivateKey.PublicKey) |
| 290 } |
| 291 |
| 292 func (r *rsaPrivateKey) Sign(rand io.Reader, data []byte) ([]byte, error) { |
| 293 » h := crypto.SHA1.New() |
| 294 » h.Write(data) |
| 295 » digest := h.Sum(nil) |
| 296 » return rsa.SignPKCS1v15(rand, r.PrivateKey, crypto.SHA1, digest) |
279 } | 297 } |
280 | 298 |
281 type dsaPublicKey dsa.PublicKey | 299 type dsaPublicKey dsa.PublicKey |
282 | 300 |
283 func (r *dsaPublicKey) PrivateKeyAlgo() string { | 301 func (r *dsaPublicKey) PrivateKeyAlgo() string { |
284 return "ssh-dss" | 302 return "ssh-dss" |
285 } | 303 } |
| 304 |
286 func (r *dsaPublicKey) PublicKeyAlgo() string { | 305 func (r *dsaPublicKey) PublicKeyAlgo() string { |
287 » return "ssh-dss" | 306 » return r.PrivateKeyAlgo() |
288 } | |
289 func (r *dsaPublicKey) RawKey() interface{} { | |
290 » return (*dsa.PublicKey)(r) | |
291 } | 307 } |
292 | 308 |
293 // parseDSA parses an DSA key according to RFC 4253, section 6.6. | 309 // parseDSA parses an DSA key according to RFC 4253, section 6.6. |
294 func parseDSA(in []byte) (out PublicKey, rest []byte, ok bool) { | 310 func parseDSA(in []byte) (out PublicKey, rest []byte, ok bool) { |
295 key := new(dsa.PublicKey) | 311 key := new(dsa.PublicKey) |
296 | 312 |
297 if key.P, in, ok = parseInt(in); !ok { | 313 if key.P, in, ok = parseInt(in); !ok { |
298 return | 314 return |
299 } | 315 } |
300 | 316 |
301 if key.Q, in, ok = parseInt(in); !ok { | 317 if key.Q, in, ok = parseInt(in); !ok { |
302 return | 318 return |
303 } | 319 } |
304 | 320 |
305 if key.G, in, ok = parseInt(in); !ok { | 321 if key.G, in, ok = parseInt(in); !ok { |
306 return | 322 return |
307 } | 323 } |
308 | 324 |
309 if key.Y, in, ok = parseInt(in); !ok { | 325 if key.Y, in, ok = parseInt(in); !ok { |
310 return | 326 return |
311 } | 327 } |
312 | 328 |
313 ok = true | 329 ok = true |
314 » return NewDSAPublicKey(key), in, ok | 330 » return (*dsaPublicKey)(key), in, ok |
315 } | 331 } |
316 | 332 |
317 func (r *dsaPublicKey) Marshal() []byte { | 333 func (r *dsaPublicKey) Marshal() []byte { |
318 // See RFC 4253, section 6.6. | 334 // See RFC 4253, section 6.6. |
319 length := intLength(r.P) | 335 length := intLength(r.P) |
320 length += intLength(r.Q) | 336 length += intLength(r.Q) |
321 length += intLength(r.G) | 337 length += intLength(r.G) |
322 length += intLength(r.Y) | 338 length += intLength(r.Y) |
323 | 339 |
324 ret := make([]byte, length) | 340 ret := make([]byte, length) |
(...skipping 16 matching lines...) Expand all Loading... |
341 // padding, unsigned, and in network byte order). | 357 // padding, unsigned, and in network byte order). |
342 // For DSS purposes, sig.Blob should be exactly 40 bytes in length. | 358 // For DSS purposes, sig.Blob should be exactly 40 bytes in length. |
343 if len(sigBlob) != 40 { | 359 if len(sigBlob) != 40 { |
344 return false | 360 return false |
345 } | 361 } |
346 r := new(big.Int).SetBytes(sigBlob[:20]) | 362 r := new(big.Int).SetBytes(sigBlob[:20]) |
347 s := new(big.Int).SetBytes(sigBlob[20:]) | 363 s := new(big.Int).SetBytes(sigBlob[20:]) |
348 return dsa.Verify((*dsa.PublicKey)(k), digest, r, s) | 364 return dsa.Verify((*dsa.PublicKey)(k), digest, r, s) |
349 } | 365 } |
350 | 366 |
351 func NewDSAPublicKey(k *dsa.PublicKey) PublicKey { | 367 type dsaPrivateKey struct { |
352 » return (*dsaPublicKey)(k) | 368 » *dsa.PrivateKey |
| 369 } |
| 370 |
| 371 func (k *dsaPrivateKey) PublicKey() PublicKey { |
| 372 » return (*dsaPublicKey)(&k.PrivateKey.PublicKey) |
| 373 } |
| 374 |
| 375 func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) ([]byte, error) { |
| 376 » h := crypto.SHA1.New() |
| 377 » h.Write(data) |
| 378 » digest := h.Sum(nil) |
| 379 » r, s, err := dsa.Sign(rand, k.PrivateKey, digest) |
| 380 » if err != nil { |
| 381 » » return nil, err |
| 382 » } |
| 383 |
| 384 » sig := make([]byte, 40) |
| 385 » copy(sig[:20], r.Bytes()) |
| 386 » copy(sig[20:], s.Bytes()) |
| 387 » return sig, nil |
353 } | 388 } |
354 | 389 |
355 type ecdsaPublicKey ecdsa.PublicKey | 390 type ecdsaPublicKey ecdsa.PublicKey |
356 | 391 |
357 func NewECDSAPublicKey(k *ecdsa.PublicKey) PublicKey { | |
358 return (*ecdsaPublicKey)(k) | |
359 } | |
360 func (r *ecdsaPublicKey) RawKey() interface{} { | |
361 return (*ecdsa.PublicKey)(r) | |
362 } | |
363 | |
364 func (key *ecdsaPublicKey) PrivateKeyAlgo() string { | 392 func (key *ecdsaPublicKey) PrivateKeyAlgo() string { |
365 » return "ecdh-sha2-" + key.nistID() | 393 » return "ecdsa-sha2-" + key.nistID() |
366 } | 394 } |
367 | 395 |
368 func (key *ecdsaPublicKey) nistID() string { | 396 func (key *ecdsaPublicKey) nistID() string { |
369 switch key.Params().BitSize { | 397 switch key.Params().BitSize { |
370 case 256: | 398 case 256: |
371 return "nistp256" | 399 return "nistp256" |
372 case 384: | 400 case 384: |
373 return "nistp384" | 401 return "nistp384" |
374 case 521: | 402 case 521: |
375 return "nistp521" | 403 return "nistp521" |
376 } | 404 } |
377 panic("ssh: unsupported ecdsa key size") | 405 panic("ssh: unsupported ecdsa key size") |
378 } | 406 } |
379 | 407 |
380 // RFC 5656, section 6.2.1 (for ECDSA). | 408 func supportedEllipticCurve(curve elliptic.Curve) bool { |
381 func (key *ecdsaPublicKey) hash() crypto.Hash { | 409 » return (curve == elliptic.P256() || curve == elliptic.P384() || curve ==
elliptic.P521()) |
382 » switch key.Params().BitSize { | 410 } |
383 » case 256: | 411 |
| 412 // ecHash returns the hash to match the given elliptic curve, see RFC |
| 413 // 5656, section 6.2.1 |
| 414 func ecHash(curve elliptic.Curve) crypto.Hash { |
| 415 » bitSize := curve.Params().BitSize |
| 416 » switch { |
| 417 » case bitSize <= 256: |
384 return crypto.SHA256 | 418 return crypto.SHA256 |
385 » case 384: | 419 » case bitSize <= 384: |
386 return crypto.SHA384 | 420 return crypto.SHA384 |
387 » case 521: | 421 » } |
388 » » return crypto.SHA512 | 422 » return crypto.SHA512 |
389 » } | |
390 » panic("ssh: unsupported ecdsa key size") | |
391 } | 423 } |
392 | 424 |
393 func (key *ecdsaPublicKey) PublicKeyAlgo() string { | 425 func (key *ecdsaPublicKey) PublicKeyAlgo() string { |
394 » switch key.Params().BitSize { | 426 » return key.PrivateKeyAlgo() |
395 » case 256: | |
396 » » return KeyAlgoECDSA256 | |
397 » case 384: | |
398 » » return KeyAlgoECDSA384 | |
399 » case 521: | |
400 » » return KeyAlgoECDSA521 | |
401 » } | |
402 » panic("ssh: unsupported ecdsa key size") | |
403 } | 427 } |
404 | 428 |
405 // parseECDSA parses an ECDSA key according to RFC 5656, section 3.1. | 429 // parseECDSA parses an ECDSA key according to RFC 5656, section 3.1. |
406 func parseECDSA(in []byte) (out PublicKey, rest []byte, ok bool) { | 430 func parseECDSA(in []byte) (out PublicKey, rest []byte, ok bool) { |
407 var identifier []byte | 431 var identifier []byte |
408 if identifier, in, ok = parseString(in); !ok { | 432 if identifier, in, ok = parseString(in); !ok { |
409 return | 433 return |
410 } | 434 } |
411 | 435 |
412 key := new(ecdsa.PublicKey) | 436 key := new(ecdsa.PublicKey) |
(...skipping 13 matching lines...) Expand all Loading... |
426 var keyBytes []byte | 450 var keyBytes []byte |
427 if keyBytes, in, ok = parseString(in); !ok { | 451 if keyBytes, in, ok = parseString(in); !ok { |
428 return | 452 return |
429 } | 453 } |
430 | 454 |
431 key.X, key.Y = elliptic.Unmarshal(key.Curve, keyBytes) | 455 key.X, key.Y = elliptic.Unmarshal(key.Curve, keyBytes) |
432 if key.X == nil || key.Y == nil { | 456 if key.X == nil || key.Y == nil { |
433 ok = false | 457 ok = false |
434 return | 458 return |
435 } | 459 } |
436 » return NewECDSAPublicKey(key), in, ok | 460 » return (*ecdsaPublicKey)(key), in, ok |
437 } | 461 } |
438 | 462 |
439 func (key *ecdsaPublicKey) Marshal() []byte { | 463 func (key *ecdsaPublicKey) Marshal() []byte { |
440 // See RFC 5656, section 3.1. | 464 // See RFC 5656, section 3.1. |
441 keyBytes := elliptic.Marshal(key.Curve, key.X, key.Y) | 465 keyBytes := elliptic.Marshal(key.Curve, key.X, key.Y) |
442 | 466 |
443 ID := key.nistID() | 467 ID := key.nistID() |
444 length := stringLength(len(ID)) | 468 length := stringLength(len(ID)) |
445 length += stringLength(len(keyBytes)) | 469 length += stringLength(len(keyBytes)) |
446 | 470 |
447 ret := make([]byte, length) | 471 ret := make([]byte, length) |
448 r := marshalString(ret, []byte(ID)) | 472 r := marshalString(ret, []byte(ID)) |
449 r = marshalString(r, keyBytes) | 473 r = marshalString(r, keyBytes) |
450 return ret | 474 return ret |
451 } | 475 } |
452 | 476 |
453 func (key *ecdsaPublicKey) Verify(data []byte, sigBlob []byte) bool { | 477 func (key *ecdsaPublicKey) Verify(data []byte, sigBlob []byte) bool { |
454 » h := key.hash().New() | 478 » h := ecHash(key.Curve).New() |
455 h.Write(data) | 479 h.Write(data) |
456 digest := h.Sum(nil) | 480 digest := h.Sum(nil) |
457 | 481 |
458 // Per RFC 5656, section 3.1.2, | 482 // Per RFC 5656, section 3.1.2, |
459 // The ecdsa_signature_blob value has the following specific encoding: | 483 // The ecdsa_signature_blob value has the following specific encoding: |
460 // mpint r | 484 // mpint r |
461 // mpint s | 485 // mpint s |
462 r, rest, ok := parseInt(sigBlob) | 486 r, rest, ok := parseInt(sigBlob) |
463 if !ok { | 487 if !ok { |
464 return false | 488 return false |
465 } | 489 } |
466 s, rest, ok := parseInt(rest) | 490 s, rest, ok := parseInt(rest) |
467 if !ok || len(rest) > 0 { | 491 if !ok || len(rest) > 0 { |
468 return false | 492 return false |
469 } | 493 } |
470 return ecdsa.Verify((*ecdsa.PublicKey)(key), digest, r, s) | 494 return ecdsa.Verify((*ecdsa.PublicKey)(key), digest, r, s) |
471 } | 495 } |
| 496 |
| 497 type ecdsaPrivateKey struct { |
| 498 *ecdsa.PrivateKey |
| 499 } |
| 500 |
| 501 func (k *ecdsaPrivateKey) PublicKey() PublicKey { |
| 502 return (*ecdsaPublicKey)(&k.PrivateKey.PublicKey) |
| 503 } |
| 504 |
| 505 func (k *ecdsaPrivateKey) Sign(rand io.Reader, data []byte) ([]byte, error) { |
| 506 h := ecHash(k.PrivateKey.PublicKey.Curve).New() |
| 507 h.Write(data) |
| 508 digest := h.Sum(nil) |
| 509 r, s, err := ecdsa.Sign(rand, k.PrivateKey, digest) |
| 510 if err != nil { |
| 511 return nil, err |
| 512 } |
| 513 |
| 514 sig := make([]byte, intLength(r)+intLength(s)) |
| 515 rest := marshalInt(sig, r) |
| 516 marshalInt(rest, s) |
| 517 return sig, nil |
| 518 } |
| 519 |
| 520 // NewPrivateKey takes a pointer to rsa, dsa or ecdsa PrivateKey |
| 521 // returns a corresponding Signer instance. EC keys should use P256, |
| 522 // P384 or P521. |
| 523 func NewSignerFromKey(k interface{}) (Signer, error) { |
| 524 var sshKey Signer |
| 525 switch t := k.(type) { |
| 526 case *rsa.PrivateKey: |
| 527 sshKey = &rsaPrivateKey{t} |
| 528 case *dsa.PrivateKey: |
| 529 sshKey = &dsaPrivateKey{t} |
| 530 case *ecdsa.PrivateKey: |
| 531 if !supportedEllipticCurve(t.Curve) { |
| 532 return nil, errors.New("ssh: only P256, P384 and P521 EC
keys are supported.") |
| 533 } |
| 534 |
| 535 sshKey = &ecdsaPrivateKey{t} |
| 536 default: |
| 537 return nil, fmt.Errorf("ssh: unsupported key type %T", k) |
| 538 } |
| 539 return sshKey, nil |
| 540 } |
| 541 |
| 542 // NewPublicKey takes a pointer to rsa, dsa or ecdsa PublicKey |
| 543 // and returns a corresponding ssh PublicKey instance. EC keys should use P256,
P384 or P521. |
| 544 func NewPublicKey(k interface{}) (PublicKey, error) { |
| 545 var sshKey PublicKey |
| 546 switch t := k.(type) { |
| 547 case *rsa.PublicKey: |
| 548 sshKey = (*rsaPublicKey)(t) |
| 549 case *ecdsa.PublicKey: |
| 550 if !supportedEllipticCurve(t.Curve) { |
| 551 return nil, errors.New("ssh: only P256, P384 and P521 EC
keys are supported.") |
| 552 } |
| 553 sshKey = (*ecdsaPublicKey)(t) |
| 554 case *dsa.PublicKey: |
| 555 sshKey = (*dsaPublicKey)(t) |
| 556 default: |
| 557 return nil, fmt.Errorf("ssh: unsupported key type %T", k) |
| 558 } |
| 559 return sshKey, nil |
| 560 } |
| 561 |
| 562 // ParsePublicKey parses a PEM encoded private key. It supports |
| 563 // PKCS#1, RSA, DSA and ECDSA private keys. |
| 564 func ParsePrivateKey(pemBytes []byte) (Signer, error) { |
| 565 block, _ := pem.Decode(pemBytes) |
| 566 if block == nil { |
| 567 return nil, errors.New("ssh: no key found") |
| 568 } |
| 569 |
| 570 var rawkey interface{} |
| 571 switch block.Type { |
| 572 case "RSA PRIVATE KEY": |
| 573 rsa, err := x509.ParsePKCS1PrivateKey(block.Bytes) |
| 574 if err != nil { |
| 575 return nil, err |
| 576 } |
| 577 rawkey = rsa |
| 578 case "EC PRIVATE KEY": |
| 579 ec, err := x509.ParseECPrivateKey(block.Bytes) |
| 580 if err != nil { |
| 581 return nil, err |
| 582 } |
| 583 rawkey = ec |
| 584 case "DSA PRIVATE KEY": |
| 585 ec, err := parseDSAPrivate(block.Bytes) |
| 586 if err != nil { |
| 587 return nil, err |
| 588 } |
| 589 rawkey = ec |
| 590 default: |
| 591 return nil, fmt.Errorf("ssh: unsupported key type %q", block.Typ
e) |
| 592 } |
| 593 |
| 594 return NewSignerFromKey(rawkey) |
| 595 } |
| 596 |
| 597 // parseDSAPrivate parses a DSA key in ASN.1 DER encoding, as |
| 598 // documented in the OpenSSL DSA manpage. |
| 599 // TODO(hanwen): move this in to crypto/x509 after the Go 1.2 freeze. |
| 600 func parseDSAPrivate(p []byte) (*dsa.PrivateKey, error) { |
| 601 k := struct { |
| 602 Version int |
| 603 P *big.Int |
| 604 Q *big.Int |
| 605 G *big.Int |
| 606 Priv *big.Int |
| 607 Pub *big.Int |
| 608 }{} |
| 609 rest, err := asn1.Unmarshal(p, &k) |
| 610 if err != nil { |
| 611 return nil, errors.New("ssh: failed to parse DSA key: " + err.Er
ror()) |
| 612 } |
| 613 if len(rest) > 0 { |
| 614 return nil, errors.New("ssh: garbage after DSA key") |
| 615 } |
| 616 |
| 617 return &dsa.PrivateKey{ |
| 618 PublicKey: dsa.PublicKey{ |
| 619 Parameters: dsa.Parameters{ |
| 620 P: k.P, |
| 621 Q: k.Q, |
| 622 G: k.G, |
| 623 }, |
| 624 Y: k.Priv, |
| 625 }, |
| 626 X: k.Pub, |
| 627 }, nil |
| 628 } |
LEFT | RIGHT |