~juju-qa/ubuntu/xenial/juju/2.0-rc2

« back to all changes in this revision

Viewing changes to src/golang.org/x/crypto/ssh/agent/client.go

  • Committer: Nicholas Skaggs
  • Date: 2016-09-30 14:39:30 UTC
  • mfrom: (1.8.1)
  • Revision ID: nicholas.skaggs@canonical.com-20160930143930-vwwhrefh6ftckccy
import upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
// Use of this source code is governed by a BSD-style
3
3
// license that can be found in the LICENSE file.
4
4
 
5
 
/*
6
 
  Package agent implements a client to an ssh-agent daemon.
7
 
 
8
 
References:
9
 
  [PROTOCOL.agent]:    http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.agent?rev=HEAD
10
 
*/
 
5
// Package agent implements the ssh-agent protocol, and provides both
 
6
// a client and a server. The client can talk to a standard ssh-agent
 
7
// that uses UNIX sockets, and one could implement an alternative
 
8
// ssh-agent process using the sample server.
 
9
//
 
10
// References:
 
11
//  [PROTOCOL.agent]:    http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.agent?rev=HEAD
11
12
package agent // import "golang.org/x/crypto/ssh/agent"
12
13
 
13
14
import (
24
25
        "math/big"
25
26
        "sync"
26
27
 
 
28
        "golang.org/x/crypto/ed25519"
27
29
        "golang.org/x/crypto/ssh"
28
30
)
29
31
 
75
77
 
76
78
// See [PROTOCOL.agent], section 3.
77
79
const (
78
 
        agentRequestV1Identities = 1
 
80
        agentRequestV1Identities   = 1
 
81
        agentRemoveAllV1Identities = 9
79
82
 
80
83
        // 3.2 Requests from client to agent for protocol 2 key operations
81
84
        agentAddIdentity         = 17
182
185
        return k.Blob
183
186
}
184
187
 
185
 
// Verify satisfies the ssh.PublicKey interface, but is not
186
 
// implemented for agent keys.
 
188
// Verify satisfies the ssh.PublicKey interface.
187
189
func (k *Key) Verify(data []byte, sig *ssh.Signature) error {
188
 
        return errors.New("agent: agent key does not know how to verify")
 
190
        pubKey, err := ssh.ParsePublicKey(k.Blob)
 
191
        if err != nil {
 
192
                return fmt.Errorf("agent: bad public key: %v", err)
 
193
        }
 
194
        return pubKey.Verify(data, sig)
189
195
}
190
196
 
191
197
type wireKey struct {
375
381
                msg = new(identitiesAnswerAgentMsg)
376
382
        case agentSignResponse:
377
383
                msg = new(signResponseAgentMsg)
 
384
        case agentV1IdentitiesAnswer:
 
385
                msg = new(agentV1IdentityMsg)
378
386
        default:
379
387
                return nil, fmt.Errorf("agent: unknown type tag %d", packet[0])
380
388
        }
385
393
}
386
394
 
387
395
type rsaKeyMsg struct {
388
 
        Type        string `sshtype:"17"`
 
396
        Type        string `sshtype:"17|25"`
389
397
        N           *big.Int
390
398
        E           *big.Int
391
399
        D           *big.Int
397
405
}
398
406
 
399
407
type dsaKeyMsg struct {
400
 
        Type        string `sshtype:"17"`
 
408
        Type        string `sshtype:"17|25"`
401
409
        P           *big.Int
402
410
        Q           *big.Int
403
411
        G           *big.Int
408
416
}
409
417
 
410
418
type ecdsaKeyMsg struct {
411
 
        Type        string `sshtype:"17"`
 
419
        Type        string `sshtype:"17|25"`
412
420
        Curve       string
413
421
        KeyBytes    []byte
414
422
        D           *big.Int
416
424
        Constraints []byte `ssh:"rest"`
417
425
}
418
426
 
 
427
type ed25519KeyMsg struct {
 
428
        Type        string `sshtype:"17|25"`
 
429
        Pub         []byte
 
430
        Priv        []byte
 
431
        Comments    string
 
432
        Constraints []byte `ssh:"rest"`
 
433
}
 
434
 
419
435
// Insert adds a private key to the agent.
420
436
func (c *client) insertKey(s interface{}, comment string, constraints []byte) error {
421
437
        var req []byte
457
473
                        Comments:    comment,
458
474
                        Constraints: constraints,
459
475
                })
 
476
        case *ed25519.PrivateKey:
 
477
                req = ssh.Marshal(ed25519KeyMsg{
 
478
                        Type:        ssh.KeyAlgoED25519,
 
479
                        Pub:         []byte(*k)[32:],
 
480
                        Priv:        []byte(*k),
 
481
                        Comments:    comment,
 
482
                        Constraints: constraints,
 
483
                })
460
484
        default:
461
485
                return fmt.Errorf("agent: unsupported key type %T", s)
462
486
        }
477
501
}
478
502
 
479
503
type rsaCertMsg struct {
480
 
        Type        string `sshtype:"17"`
 
504
        Type        string `sshtype:"17|25"`
481
505
        CertBytes   []byte
482
506
        D           *big.Int
483
507
        Iqmp        *big.Int // IQMP = Inverse Q Mod P
488
512
}
489
513
 
490
514
type dsaCertMsg struct {
491
 
        Type        string `sshtype:"17"`
 
515
        Type        string `sshtype:"17|25"`
492
516
        CertBytes   []byte
493
517
        X           *big.Int
494
518
        Comments    string
496
520
}
497
521
 
498
522
type ecdsaCertMsg struct {
499
 
        Type        string `sshtype:"17"`
 
523
        Type        string `sshtype:"17|25"`
500
524
        CertBytes   []byte
501
525
        D           *big.Int
502
526
        Comments    string
503
527
        Constraints []byte `ssh:"rest"`
504
528
}
505
529
 
506
 
// Insert adds a private key to the agent. If a certificate is given,
 
530
type ed25519CertMsg struct {
 
531
        Type        string `sshtype:"17|25"`
 
532
        CertBytes   []byte
 
533
        Pub         []byte
 
534
        Priv        []byte
 
535
        Comments    string
 
536
        Constraints []byte `ssh:"rest"`
 
537
}
 
538
 
 
539
// Add adds a private key to the agent. If a certificate is given,
507
540
// that certificate is added instead as public key.
508
541
func (c *client) Add(key AddedKey) error {
509
542
        var constraints []byte
547
580
                })
548
581
        case *dsa.PrivateKey:
549
582
                req = ssh.Marshal(dsaCertMsg{
550
 
                        Type:      cert.Type(),
551
 
                        CertBytes: cert.Marshal(),
552
 
                        X:         k.X,
553
 
                        Comments:  comment,
 
583
                        Type:        cert.Type(),
 
584
                        CertBytes:   cert.Marshal(),
 
585
                        X:           k.X,
 
586
                        Comments:    comment,
 
587
                        Constraints: constraints,
554
588
                })
555
589
        case *ecdsa.PrivateKey:
556
590
                req = ssh.Marshal(ecdsaCertMsg{
557
 
                        Type:      cert.Type(),
558
 
                        CertBytes: cert.Marshal(),
559
 
                        D:         k.D,
560
 
                        Comments:  comment,
 
591
                        Type:        cert.Type(),
 
592
                        CertBytes:   cert.Marshal(),
 
593
                        D:           k.D,
 
594
                        Comments:    comment,
 
595
                        Constraints: constraints,
 
596
                })
 
597
        case *ed25519.PrivateKey:
 
598
                req = ssh.Marshal(ed25519CertMsg{
 
599
                        Type:        cert.Type(),
 
600
                        CertBytes:   cert.Marshal(),
 
601
                        Pub:         []byte(*k)[32:],
 
602
                        Priv:        []byte(*k),
 
603
                        Comments:    comment,
 
604
                        Constraints: constraints,
561
605
                })
562
606
        default:
563
607
                return fmt.Errorf("agent: unsupported key type %T", s)