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

Delta Between Two Patch Sets: ssh/keys.go

Issue 13338044: code review 13338044: go.crypto/ssh: introduce PrivateKey method. (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 c923f02daf74 https://code.google.com/p/go.crypto Created 10 years, 6 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/example_test.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"
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 PublicKeyAlgo() string 207 PublicKeyAlgo() string
208 208
209 // Marshal returns the serialized key data in SSH wire format, 209 // Marshal returns the serialized key data in SSH wire format,
210 // without the name prefix. Callers should typically use 210 // without the name prefix. Callers should typically use
211 // MarshalPublicKey(). 211 // MarshalPublicKey().
212 Marshal() []byte 212 Marshal() []byte
213 213
214 // Verify that sig is a signature on the given data using this 214 // Verify that sig is a signature on the given data using this
215 // key. This function will hash the data appropriately first. 215 // key. This function will hash the data appropriately first.
216 Verify(data []byte, sigBlob []byte) bool 216 Verify(data []byte, sigBlob []byte) bool
217 217 }
218 » // RawKey returns the underlying object, eg. *rsa.PublicKey. 218
219 » RawKey() interface{} 219 // A Signer is can create signatures that verify against a public key.
220 } 220 type Signer interface {
221
222 // PrivateKey is an abstraction of different types of private keys.
223 type PrivateKey interface {
224 // PublicKey returns an associated PublicKey instance. 221 // PublicKey returns an associated PublicKey instance.
225 PublicKey() PublicKey 222 PublicKey() PublicKey
226 223
227 » // RawKey returns the underlying object, eg. *rsa.PrivateKey. 224 » // Sign returns raw signature for the given data. This method
228 » RawKey() interface{} 225 » // will apply the hash specified for the keytype to the data.
229
230 » // Sign returns raw signature data for the given data.
231 Sign(rand io.Reader, data []byte) ([]byte, error) 226 Sign(rand io.Reader, data []byte) ([]byte, error)
jmp 2013/09/18 04:07:51 I like the new interface. I have had this thought
232 } 227 }
228
229 type rsaPublicKey rsa.PublicKey
233 230
234 func (r *rsaPublicKey) PrivateKeyAlgo() string { 231 func (r *rsaPublicKey) PrivateKeyAlgo() string {
235 return "ssh-rsa" 232 return "ssh-rsa"
236 } 233 }
237 234
238 func (r *rsaPublicKey) PublicKeyAlgo() string { 235 func (r *rsaPublicKey) PublicKeyAlgo() string {
239 » return "ssh-rsa" 236 » return r.PrivateKeyAlgo()
240 }
241
242 func (r *rsaPublicKey) RawKey() interface{} {
243 » return (*rsa.PublicKey)(r)
244 } 237 }
245 238
246 // parseRSA parses an RSA key according to RFC 4253, section 6.6. 239 // parseRSA parses an RSA key according to RFC 4253, section 6.6.
247 func parseRSA(in []byte) (out PublicKey, rest []byte, ok bool) { 240 func parseRSA(in []byte) (out PublicKey, rest []byte, ok bool) {
248 key := new(rsa.PublicKey) 241 key := new(rsa.PublicKey)
249 242
250 bigE, in, ok := parseInt(in) 243 bigE, in, ok := parseInt(in)
251 if !ok || bigE.BitLen() > 24 { 244 if !ok || bigE.BitLen() > 24 {
252 return 245 return
253 } 246 }
254 e := bigE.Int64() 247 e := bigE.Int64()
255 if e < 3 || e&1 == 0 { 248 if e < 3 || e&1 == 0 {
256 ok = false 249 ok = false
257 return 250 return
258 } 251 }
259 key.E = int(e) 252 key.E = int(e)
260 253
261 if key.N, in, ok = parseInt(in); !ok { 254 if key.N, in, ok = parseInt(in); !ok {
262 return 255 return
263 } 256 }
264 257
265 ok = true 258 ok = true
266 » return NewRSAPublicKey(key), in, ok 259 » return (*rsaPublicKey)(key), in, ok
267 } 260 }
268 261
269 func (r *rsaPublicKey) Marshal() []byte { 262 func (r *rsaPublicKey) Marshal() []byte {
270 // See RFC 4253, section 6.6. 263 // See RFC 4253, section 6.6.
271 e := new(big.Int).SetInt64(int64(r.E)) 264 e := new(big.Int).SetInt64(int64(r.E))
272 length := intLength(e) 265 length := intLength(e)
273 length += intLength(r.N) 266 length += intLength(r.N)
274 267
275 ret := make([]byte, length) 268 ret := make([]byte, length)
276 rest := marshalInt(ret, e) 269 rest := marshalInt(ret, e)
277 marshalInt(rest, r.N) 270 marshalInt(rest, r.N)
278 271
279 return ret 272 return ret
280 } 273 }
281 274
282 func (r *rsaPublicKey) Verify(data []byte, sig []byte) bool { 275 func (r *rsaPublicKey) Verify(data []byte, sig []byte) bool {
283 h := crypto.SHA1.New() 276 h := crypto.SHA1.New()
284 h.Write(data) 277 h.Write(data)
285 digest := h.Sum(nil) 278 digest := h.Sum(nil)
286 return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), crypto.SHA1, digest, sig) == nil 279 return rsa.VerifyPKCS1v15((*rsa.PublicKey)(r), crypto.SHA1, digest, sig) == nil
287 } 280 }
288 281
289 func NewRSAPublicKey(k *rsa.PublicKey) PublicKey {
290 return (*rsaPublicKey)(k)
291 }
292
293 type rsaPublicKey rsa.PublicKey
294
295 type rsaPrivateKey struct { 282 type rsaPrivateKey struct {
296 *rsa.PrivateKey 283 *rsa.PrivateKey
297 } 284 }
298 285
299 func (r *rsaPrivateKey) PublicKey() PublicKey { 286 func (r *rsaPrivateKey) PublicKey() PublicKey {
300 return (*rsaPublicKey)(&r.PrivateKey.PublicKey) 287 return (*rsaPublicKey)(&r.PrivateKey.PublicKey)
301 }
302
303 func (r *rsaPrivateKey) RawKey() interface{} {
304 return r.PrivateKey
305 } 288 }
306 289
307 func (r *rsaPrivateKey) Sign(rand io.Reader, data []byte) ([]byte, error) { 290 func (r *rsaPrivateKey) Sign(rand io.Reader, data []byte) ([]byte, error) {
308 h := crypto.SHA1.New() 291 h := crypto.SHA1.New()
309 h.Write(data) 292 h.Write(data)
310 digest := h.Sum(nil) 293 digest := h.Sum(nil)
311 return rsa.SignPKCS1v15(rand, r.PrivateKey, crypto.SHA1, digest) 294 return rsa.SignPKCS1v15(rand, r.PrivateKey, crypto.SHA1, digest)
312 } 295 }
313 296
314 type dsaPublicKey dsa.PublicKey 297 type dsaPublicKey dsa.PublicKey
315 298
316 func (r *dsaPublicKey) PrivateKeyAlgo() string { 299 func (r *dsaPublicKey) PrivateKeyAlgo() string {
317 return "ssh-dss" 300 return "ssh-dss"
318 } 301 }
302
319 func (r *dsaPublicKey) PublicKeyAlgo() string { 303 func (r *dsaPublicKey) PublicKeyAlgo() string {
320 » return "ssh-dss" 304 » return r.PrivateKeyAlgo()
321 }
322 func (r *dsaPublicKey) RawKey() interface{} {
323 » return (*dsa.PublicKey)(r)
324 } 305 }
325 306
326 // parseDSA parses an DSA key according to RFC 4253, section 6.6. 307 // parseDSA parses an DSA key according to RFC 4253, section 6.6.
327 func parseDSA(in []byte) (out PublicKey, rest []byte, ok bool) { 308 func parseDSA(in []byte) (out PublicKey, rest []byte, ok bool) {
328 key := new(dsa.PublicKey) 309 key := new(dsa.PublicKey)
329 310
330 if key.P, in, ok = parseInt(in); !ok { 311 if key.P, in, ok = parseInt(in); !ok {
331 return 312 return
332 } 313 }
333 314
334 if key.Q, in, ok = parseInt(in); !ok { 315 if key.Q, in, ok = parseInt(in); !ok {
335 return 316 return
336 } 317 }
337 318
338 if key.G, in, ok = parseInt(in); !ok { 319 if key.G, in, ok = parseInt(in); !ok {
339 return 320 return
340 } 321 }
341 322
342 if key.Y, in, ok = parseInt(in); !ok { 323 if key.Y, in, ok = parseInt(in); !ok {
343 return 324 return
344 } 325 }
345 326
346 ok = true 327 ok = true
347 » return NewDSAPublicKey(key), in, ok 328 » return (*dsaPublicKey)(key), in, ok
348 } 329 }
349 330
350 func (r *dsaPublicKey) Marshal() []byte { 331 func (r *dsaPublicKey) Marshal() []byte {
351 // See RFC 4253, section 6.6. 332 // See RFC 4253, section 6.6.
352 length := intLength(r.P) 333 length := intLength(r.P)
353 length += intLength(r.Q) 334 length += intLength(r.Q)
354 length += intLength(r.G) 335 length += intLength(r.G)
355 length += intLength(r.Y) 336 length += intLength(r.Y)
356 337
357 ret := make([]byte, length) 338 ret := make([]byte, length)
(...skipping 16 matching lines...) Expand all
374 // padding, unsigned, and in network byte order). 355 // padding, unsigned, and in network byte order).
375 // For DSS purposes, sig.Blob should be exactly 40 bytes in length. 356 // For DSS purposes, sig.Blob should be exactly 40 bytes in length.
376 if len(sigBlob) != 40 { 357 if len(sigBlob) != 40 {
377 return false 358 return false
378 } 359 }
379 r := new(big.Int).SetBytes(sigBlob[:20]) 360 r := new(big.Int).SetBytes(sigBlob[:20])
380 s := new(big.Int).SetBytes(sigBlob[20:]) 361 s := new(big.Int).SetBytes(sigBlob[20:])
381 return dsa.Verify((*dsa.PublicKey)(k), digest, r, s) 362 return dsa.Verify((*dsa.PublicKey)(k), digest, r, s)
382 } 363 }
383 364
384 func NewDSAPublicKey(k *dsa.PublicKey) PublicKey {
385 return (*dsaPublicKey)(k)
386 }
387
388 type dsaPrivateKey struct { 365 type dsaPrivateKey struct {
389 *dsa.PrivateKey 366 *dsa.PrivateKey
390 } 367 }
391 368
392 func (k *dsaPrivateKey) PublicKey() PublicKey { 369 func (k *dsaPrivateKey) PublicKey() PublicKey {
393 return (*dsaPublicKey)(&k.PrivateKey.PublicKey) 370 return (*dsaPublicKey)(&k.PrivateKey.PublicKey)
394 }
395
396 func (k *dsaPrivateKey) RawKey() interface{} {
397 return k.PrivateKey
398 } 371 }
399 372
400 func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) ([]byte, error) { 373 func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) ([]byte, error) {
401 h := crypto.SHA1.New() 374 h := crypto.SHA1.New()
402 h.Write(data) 375 h.Write(data)
403 digest := h.Sum(nil) 376 digest := h.Sum(nil)
404 r, s, err := dsa.Sign(rand, k.PrivateKey, digest) 377 r, s, err := dsa.Sign(rand, k.PrivateKey, digest)
405 if err != nil { 378 if err != nil {
406 return nil, err 379 return nil, err
407 } 380 }
408 381
409 sig := make([]byte, 40) 382 sig := make([]byte, 40)
410 copy(sig[:20], r.Bytes()) 383 copy(sig[:20], r.Bytes())
411 copy(sig[20:], s.Bytes()) 384 copy(sig[20:], s.Bytes())
412 return sig, nil 385 return sig, nil
413 } 386 }
414 387
415 type ecdsaPublicKey ecdsa.PublicKey 388 type ecdsaPublicKey ecdsa.PublicKey
416
417 func NewECDSAPublicKey(k *ecdsa.PublicKey) PublicKey {
418 return (*ecdsaPublicKey)(k)
419 }
420 func (r *ecdsaPublicKey) RawKey() interface{} {
421 return (*ecdsa.PublicKey)(r)
422 }
423 389
424 func (key *ecdsaPublicKey) PrivateKeyAlgo() string { 390 func (key *ecdsaPublicKey) PrivateKeyAlgo() string {
425 return "ecdsa-sha2-" + key.nistID() 391 return "ecdsa-sha2-" + key.nistID()
426 } 392 }
427 393
428 func (key *ecdsaPublicKey) nistID() string { 394 func (key *ecdsaPublicKey) nistID() string {
429 switch key.Params().BitSize { 395 switch key.Params().BitSize {
430 case 256: 396 case 256:
431 return "nistp256" 397 return "nistp256"
432 case 384: 398 case 384:
433 return "nistp384" 399 return "nistp384"
434 case 521: 400 case 521:
435 return "nistp521" 401 return "nistp521"
436 } 402 }
437 panic("ssh: unsupported ecdsa key size") 403 panic("ssh: unsupported ecdsa key size")
404 }
405
406 func supportedEllipticCurve(curve elliptic.Curve) bool {
407 return (curve == elliptic.P256() || curve == elliptic.P384() || curve == elliptic.P521())
438 } 408 }
439 409
440 // ecHash returns the hash to match the given elliptic curve, see RFC 410 // ecHash returns the hash to match the given elliptic curve, see RFC
441 // 5656, section 6.2.1 411 // 5656, section 6.2.1
442 func ecHash(curve elliptic.Curve) crypto.Hash { 412 func ecHash(curve elliptic.Curve) crypto.Hash {
443 bitSize := curve.Params().BitSize 413 bitSize := curve.Params().BitSize
444 switch { 414 switch {
445 case bitSize <= 256: 415 case bitSize <= 256:
446 return crypto.SHA256 416 return crypto.SHA256
447 case bitSize <= 384: 417 case bitSize <= 384:
448 return crypto.SHA384 418 return crypto.SHA384
449 } 419 }
450 return crypto.SHA512 420 return crypto.SHA512
451 } 421 }
452 422
453 func (key *ecdsaPublicKey) PublicKeyAlgo() string { 423 func (key *ecdsaPublicKey) PublicKeyAlgo() string {
454 » switch key.Params().BitSize { 424 » return key.PrivateKeyAlgo()
455 » case 256:
456 » » return KeyAlgoECDSA256
457 » case 384:
458 » » return KeyAlgoECDSA384
459 » case 521:
460 » » return KeyAlgoECDSA521
461 » }
462 » panic("ssh: unsupported ecdsa key size")
463 } 425 }
464 426
465 // parseECDSA parses an ECDSA key according to RFC 5656, section 3.1. 427 // parseECDSA parses an ECDSA key according to RFC 5656, section 3.1.
466 func parseECDSA(in []byte) (out PublicKey, rest []byte, ok bool) { 428 func parseECDSA(in []byte) (out PublicKey, rest []byte, ok bool) {
467 var identifier []byte 429 var identifier []byte
468 if identifier, in, ok = parseString(in); !ok { 430 if identifier, in, ok = parseString(in); !ok {
469 return 431 return
470 } 432 }
471 433
472 key := new(ecdsa.PublicKey) 434 key := new(ecdsa.PublicKey)
(...skipping 13 matching lines...) Expand all
486 var keyBytes []byte 448 var keyBytes []byte
487 if keyBytes, in, ok = parseString(in); !ok { 449 if keyBytes, in, ok = parseString(in); !ok {
488 return 450 return
489 } 451 }
490 452
491 key.X, key.Y = elliptic.Unmarshal(key.Curve, keyBytes) 453 key.X, key.Y = elliptic.Unmarshal(key.Curve, keyBytes)
492 if key.X == nil || key.Y == nil { 454 if key.X == nil || key.Y == nil {
493 ok = false 455 ok = false
494 return 456 return
495 } 457 }
496 » return NewECDSAPublicKey(key), in, ok 458 » return (*ecdsaPublicKey)(key), in, ok
497 } 459 }
498 460
499 func (key *ecdsaPublicKey) Marshal() []byte { 461 func (key *ecdsaPublicKey) Marshal() []byte {
500 // See RFC 5656, section 3.1. 462 // See RFC 5656, section 3.1.
501 keyBytes := elliptic.Marshal(key.Curve, key.X, key.Y) 463 keyBytes := elliptic.Marshal(key.Curve, key.X, key.Y)
502 464
503 ID := key.nistID() 465 ID := key.nistID()
504 length := stringLength(len(ID)) 466 length := stringLength(len(ID))
505 length += stringLength(len(keyBytes)) 467 length += stringLength(len(keyBytes))
506 468
(...skipping 24 matching lines...) Expand all
531 } 493 }
532 494
533 type ecdsaPrivateKey struct { 495 type ecdsaPrivateKey struct {
534 *ecdsa.PrivateKey 496 *ecdsa.PrivateKey
535 } 497 }
536 498
537 func (k *ecdsaPrivateKey) PublicKey() PublicKey { 499 func (k *ecdsaPrivateKey) PublicKey() PublicKey {
538 return (*ecdsaPublicKey)(&k.PrivateKey.PublicKey) 500 return (*ecdsaPublicKey)(&k.PrivateKey.PublicKey)
539 } 501 }
540 502
541 func (k *ecdsaPrivateKey) RawKey() interface{} {
542 return k.PrivateKey
543 }
544
545 func (k *ecdsaPrivateKey) Sign(rand io.Reader, data []byte) ([]byte, error) { 503 func (k *ecdsaPrivateKey) Sign(rand io.Reader, data []byte) ([]byte, error) {
546 h := ecHash(k.PrivateKey.PublicKey.Curve).New() 504 h := ecHash(k.PrivateKey.PublicKey.Curve).New()
547 h.Write(data) 505 h.Write(data)
548 digest := h.Sum(nil) 506 digest := h.Sum(nil)
549 r, s, err := ecdsa.Sign(rand, k.PrivateKey, digest) 507 r, s, err := ecdsa.Sign(rand, k.PrivateKey, digest)
550 if err != nil { 508 if err != nil {
551 return nil, err 509 return nil, err
552 } 510 }
553 511
554 sig := make([]byte, intLength(r)+intLength(s)) 512 sig := make([]byte, intLength(r)+intLength(s))
555 rest := marshalInt(sig, r) 513 rest := marshalInt(sig, r)
556 marshalInt(rest, s) 514 marshalInt(rest, s)
557 return sig, nil 515 return sig, nil
558 } 516 }
559 517
560 // NewPrivateKey takes a pointer to rsa, dsa or ecdsa PrivateKey 518 // NewPrivateKey takes a pointer to rsa, dsa or ecdsa PrivateKey
561 // returns a corresponding ssh PrivateKey instance. 519 // returns a corresponding Signer instance. EC keys should use P256,
562 func NewPrivateKey(k interface{}) (PrivateKey, error) { 520 // P384 or P521.
521 func NewSignerFromKey(k interface{}) (Signer, error) {
522 » var sshKey Signer
563 switch t := k.(type) { 523 switch t := k.(type) {
564 case *rsa.PrivateKey: 524 case *rsa.PrivateKey:
565 » » return &rsaPrivateKey{t}, nil 525 » » sshKey = &rsaPrivateKey{t}
566 case *dsa.PrivateKey: 526 case *dsa.PrivateKey:
567 » » return &dsaPrivateKey{t}, nil 527 » » sshKey = &dsaPrivateKey{t}
568 case *ecdsa.PrivateKey: 528 case *ecdsa.PrivateKey:
569 » » return &ecdsaPrivateKey{t}, nil 529 » » if !supportedEllipticCurve(t.Curve) {
570 » } 530 » » » return nil, errors.New("ssh: only P256, P384 and P521 EC keys are supported.")
571 » return nil, fmt.Errorf("unsupport key type %T", k) 531 » » }
532
533 » » sshKey = &ecdsaPrivateKey{t}
534 » default:
535 » » return nil, fmt.Errorf("ssh: unsupported key type %T", k)
536 » }
537 » return sshKey, nil
538 }
539
540 // NewPublicKey takes a pointer to rsa, dsa or ecdsa PublicKey
541 // and returns a corresponding ssh PublicKey instance. EC keys should use P256, P384 or P521.
542 func NewPublicKey(k interface{}) (PublicKey, error) {
543 » var sshKey PublicKey
544 » switch t := k.(type) {
545 » case *rsa.PublicKey:
546 » » sshKey = (*rsaPublicKey)(t)
547 » case *ecdsa.PublicKey:
548 » » if !supportedEllipticCurve(t.Curve) {
549 » » » return nil, errors.New("ssh: only P256, P384 and P521 EC keys are supported.")
550 » » }
551 » » sshKey = (*ecdsaPublicKey)(t)
552 » case *dsa.PublicKey:
553 » » sshKey = (*dsaPublicKey)(t)
554 » default:
555 » » return nil, fmt.Errorf("ssh: unsupported key type %T", k)
556 » }
557 » return sshKey, nil
572 } 558 }
573 559
574 // ParsePublicKey parses a PEM encoded private key. Currently, only 560 // ParsePublicKey parses a PEM encoded private key. Currently, only
575 // PKCS#1, RSA private keys are supported. 561 // PKCS#1, RSA and ECDSA private keys are supported.
576 func ParsePrivateKey(pemBytes []byte) (PrivateKey, error) { 562 func ParsePrivateKey(pemBytes []byte) (Signer, error) {
577 block, _ := pem.Decode(pemBytes) 563 block, _ := pem.Decode(pemBytes)
578 if block == nil { 564 if block == nil {
579 return nil, errors.New("ssh: no key found") 565 return nil, errors.New("ssh: no key found")
580 } 566 }
581 567
582 var rawkey interface{} 568 var rawkey interface{}
583 switch block.Type { 569 switch block.Type {
584 case "RSA PRIVATE KEY": 570 case "RSA PRIVATE KEY":
585 rsa, err := x509.ParsePKCS1PrivateKey(block.Bytes) 571 rsa, err := x509.ParsePKCS1PrivateKey(block.Bytes)
586 if err != nil { 572 if err != nil {
587 return nil, err 573 return nil, err
588 } 574 }
589 rawkey = rsa 575 rawkey = rsa
590 » // TODO(hanwen): find doc for format and implement PEM parsing 576 » case "EC PRIVATE KEY":
jmp 2013/09/18 04:07:51 For ECDSA, this will already do what you want http
591 » // for (EC)DSA keys. 577 » » ec, err := x509.ParseECPrivateKey(block.Bytes)
578 » » if err != nil {
579 » » » return nil, err
580 » » }
581 » » rawkey = ec
582
583 » » // TODO(hanwen): find doc for format and implement PEM parsing
584 » » // for DSA keys.
592 default: 585 default:
593 » » return nil, fmt.Errorf("ssh: ParsePrivateKey does not support ke y type %q", 586 » » return nil, fmt.Errorf("ssh: unsupported key type %q", block.Typ e)
594 » » » block.Type) 587 » }
595 » } 588
596 589 » return NewSignerFromKey(rawkey)
597 » return NewPrivateKey(rawkey) 590 }
598 }
LEFTRIGHT

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