Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(753)

Delta Between Two Patch Sets: ssh/keys.go

Issue 13272055: code review 13272055: go.crypto/ssh: fix certificate parsing/marshaling. (Closed)
Left Patch Set: diff -r c923f02daf74 https://code.google.com/p/go.crypto Created 10 years, 6 months ago
Right Patch Set: diff -r 2cd6b3b93cdb https://code.google.com/p/go.crypto Created 10 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « ssh/common.go ('k') | ssh/keys_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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
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
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
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
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 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b