update packaging
[platform/core/system/edge-orchestration.git] / vendor / github.com / miekg / dns / vendor / golang.org / x / crypto / ssh / agent / server.go
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package agent
6
7 import (
8         "crypto/dsa"
9         "crypto/ecdsa"
10         "crypto/elliptic"
11         "crypto/rsa"
12         "encoding/binary"
13         "errors"
14         "fmt"
15         "io"
16         "log"
17         "math/big"
18
19         "golang.org/x/crypto/ed25519"
20         "golang.org/x/crypto/ssh"
21 )
22
23 // Server wraps an Agent and uses it to implement the agent side of
24 // the SSH-agent, wire protocol.
25 type server struct {
26         agent Agent
27 }
28
29 func (s *server) processRequestBytes(reqData []byte) []byte {
30         rep, err := s.processRequest(reqData)
31         if err != nil {
32                 if err != errLocked {
33                         // TODO(hanwen): provide better logging interface?
34                         log.Printf("agent %d: %v", reqData[0], err)
35                 }
36                 return []byte{agentFailure}
37         }
38
39         if err == nil && rep == nil {
40                 return []byte{agentSuccess}
41         }
42
43         return ssh.Marshal(rep)
44 }
45
46 func marshalKey(k *Key) []byte {
47         var record struct {
48                 Blob    []byte
49                 Comment string
50         }
51         record.Blob = k.Marshal()
52         record.Comment = k.Comment
53
54         return ssh.Marshal(&record)
55 }
56
57 // See [PROTOCOL.agent], section 2.5.1.
58 const agentV1IdentitiesAnswer = 2
59
60 type agentV1IdentityMsg struct {
61         Numkeys uint32 `sshtype:"2"`
62 }
63
64 type agentRemoveIdentityMsg struct {
65         KeyBlob []byte `sshtype:"18"`
66 }
67
68 type agentLockMsg struct {
69         Passphrase []byte `sshtype:"22"`
70 }
71
72 type agentUnlockMsg struct {
73         Passphrase []byte `sshtype:"23"`
74 }
75
76 func (s *server) processRequest(data []byte) (interface{}, error) {
77         switch data[0] {
78         case agentRequestV1Identities:
79                 return &agentV1IdentityMsg{0}, nil
80
81         case agentRemoveAllV1Identities:
82                 return nil, nil
83
84         case agentRemoveIdentity:
85                 var req agentRemoveIdentityMsg
86                 if err := ssh.Unmarshal(data, &req); err != nil {
87                         return nil, err
88                 }
89
90                 var wk wireKey
91                 if err := ssh.Unmarshal(req.KeyBlob, &wk); err != nil {
92                         return nil, err
93                 }
94
95                 return nil, s.agent.Remove(&Key{Format: wk.Format, Blob: req.KeyBlob})
96
97         case agentRemoveAllIdentities:
98                 return nil, s.agent.RemoveAll()
99
100         case agentLock:
101                 var req agentLockMsg
102                 if err := ssh.Unmarshal(data, &req); err != nil {
103                         return nil, err
104                 }
105
106                 return nil, s.agent.Lock(req.Passphrase)
107
108         case agentUnlock:
109                 var req agentUnlockMsg
110                 if err := ssh.Unmarshal(data, &req); err != nil {
111                         return nil, err
112                 }
113                 return nil, s.agent.Unlock(req.Passphrase)
114
115         case agentSignRequest:
116                 var req signRequestAgentMsg
117                 if err := ssh.Unmarshal(data, &req); err != nil {
118                         return nil, err
119                 }
120
121                 var wk wireKey
122                 if err := ssh.Unmarshal(req.KeyBlob, &wk); err != nil {
123                         return nil, err
124                 }
125
126                 k := &Key{
127                         Format: wk.Format,
128                         Blob:   req.KeyBlob,
129                 }
130
131                 sig, err := s.agent.Sign(k, req.Data) //  TODO(hanwen): flags.
132                 if err != nil {
133                         return nil, err
134                 }
135                 return &signResponseAgentMsg{SigBlob: ssh.Marshal(sig)}, nil
136
137         case agentRequestIdentities:
138                 keys, err := s.agent.List()
139                 if err != nil {
140                         return nil, err
141                 }
142
143                 rep := identitiesAnswerAgentMsg{
144                         NumKeys: uint32(len(keys)),
145                 }
146                 for _, k := range keys {
147                         rep.Keys = append(rep.Keys, marshalKey(k)...)
148                 }
149                 return rep, nil
150
151         case agentAddIDConstrained, agentAddIdentity:
152                 return nil, s.insertIdentity(data)
153         }
154
155         return nil, fmt.Errorf("unknown opcode %d", data[0])
156 }
157
158 func parseConstraints(constraints []byte) (lifetimeSecs uint32, confirmBeforeUse bool, extensions []ConstraintExtension, err error) {
159         for len(constraints) != 0 {
160                 switch constraints[0] {
161                 case agentConstrainLifetime:
162                         lifetimeSecs = binary.BigEndian.Uint32(constraints[1:5])
163                         constraints = constraints[5:]
164                 case agentConstrainConfirm:
165                         confirmBeforeUse = true
166                         constraints = constraints[1:]
167                 case agentConstrainExtension:
168                         var msg constrainExtensionAgentMsg
169                         if err = ssh.Unmarshal(constraints, &msg); err != nil {
170                                 return 0, false, nil, err
171                         }
172                         extensions = append(extensions, ConstraintExtension{
173                                 ExtensionName:    msg.ExtensionName,
174                                 ExtensionDetails: msg.ExtensionDetails,
175                         })
176                         constraints = msg.Rest
177                 default:
178                         return 0, false, nil, fmt.Errorf("unknown constraint type: %d", constraints[0])
179                 }
180         }
181         return
182 }
183
184 func setConstraints(key *AddedKey, constraintBytes []byte) error {
185         lifetimeSecs, confirmBeforeUse, constraintExtensions, err := parseConstraints(constraintBytes)
186         if err != nil {
187                 return err
188         }
189
190         key.LifetimeSecs = lifetimeSecs
191         key.ConfirmBeforeUse = confirmBeforeUse
192         key.ConstraintExtensions = constraintExtensions
193         return nil
194 }
195
196 func parseRSAKey(req []byte) (*AddedKey, error) {
197         var k rsaKeyMsg
198         if err := ssh.Unmarshal(req, &k); err != nil {
199                 return nil, err
200         }
201         if k.E.BitLen() > 30 {
202                 return nil, errors.New("agent: RSA public exponent too large")
203         }
204         priv := &rsa.PrivateKey{
205                 PublicKey: rsa.PublicKey{
206                         E: int(k.E.Int64()),
207                         N: k.N,
208                 },
209                 D:      k.D,
210                 Primes: []*big.Int{k.P, k.Q},
211         }
212         priv.Precompute()
213
214         addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
215         if err := setConstraints(addedKey, k.Constraints); err != nil {
216                 return nil, err
217         }
218         return addedKey, nil
219 }
220
221 func parseEd25519Key(req []byte) (*AddedKey, error) {
222         var k ed25519KeyMsg
223         if err := ssh.Unmarshal(req, &k); err != nil {
224                 return nil, err
225         }
226         priv := ed25519.PrivateKey(k.Priv)
227
228         addedKey := &AddedKey{PrivateKey: &priv, Comment: k.Comments}
229         if err := setConstraints(addedKey, k.Constraints); err != nil {
230                 return nil, err
231         }
232         return addedKey, nil
233 }
234
235 func parseDSAKey(req []byte) (*AddedKey, error) {
236         var k dsaKeyMsg
237         if err := ssh.Unmarshal(req, &k); err != nil {
238                 return nil, err
239         }
240         priv := &dsa.PrivateKey{
241                 PublicKey: dsa.PublicKey{
242                         Parameters: dsa.Parameters{
243                                 P: k.P,
244                                 Q: k.Q,
245                                 G: k.G,
246                         },
247                         Y: k.Y,
248                 },
249                 X: k.X,
250         }
251
252         addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
253         if err := setConstraints(addedKey, k.Constraints); err != nil {
254                 return nil, err
255         }
256         return addedKey, nil
257 }
258
259 func unmarshalECDSA(curveName string, keyBytes []byte, privScalar *big.Int) (priv *ecdsa.PrivateKey, err error) {
260         priv = &ecdsa.PrivateKey{
261                 D: privScalar,
262         }
263
264         switch curveName {
265         case "nistp256":
266                 priv.Curve = elliptic.P256()
267         case "nistp384":
268                 priv.Curve = elliptic.P384()
269         case "nistp521":
270                 priv.Curve = elliptic.P521()
271         default:
272                 return nil, fmt.Errorf("agent: unknown curve %q", curveName)
273         }
274
275         priv.X, priv.Y = elliptic.Unmarshal(priv.Curve, keyBytes)
276         if priv.X == nil || priv.Y == nil {
277                 return nil, errors.New("agent: point not on curve")
278         }
279
280         return priv, nil
281 }
282
283 func parseEd25519Cert(req []byte) (*AddedKey, error) {
284         var k ed25519CertMsg
285         if err := ssh.Unmarshal(req, &k); err != nil {
286                 return nil, err
287         }
288         pubKey, err := ssh.ParsePublicKey(k.CertBytes)
289         if err != nil {
290                 return nil, err
291         }
292         priv := ed25519.PrivateKey(k.Priv)
293         cert, ok := pubKey.(*ssh.Certificate)
294         if !ok {
295                 return nil, errors.New("agent: bad ED25519 certificate")
296         }
297
298         addedKey := &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}
299         if err := setConstraints(addedKey, k.Constraints); err != nil {
300                 return nil, err
301         }
302         return addedKey, nil
303 }
304
305 func parseECDSAKey(req []byte) (*AddedKey, error) {
306         var k ecdsaKeyMsg
307         if err := ssh.Unmarshal(req, &k); err != nil {
308                 return nil, err
309         }
310
311         priv, err := unmarshalECDSA(k.Curve, k.KeyBytes, k.D)
312         if err != nil {
313                 return nil, err
314         }
315
316         addedKey := &AddedKey{PrivateKey: priv, Comment: k.Comments}
317         if err := setConstraints(addedKey, k.Constraints); err != nil {
318                 return nil, err
319         }
320         return addedKey, nil
321 }
322
323 func parseRSACert(req []byte) (*AddedKey, error) {
324         var k rsaCertMsg
325         if err := ssh.Unmarshal(req, &k); err != nil {
326                 return nil, err
327         }
328
329         pubKey, err := ssh.ParsePublicKey(k.CertBytes)
330         if err != nil {
331                 return nil, err
332         }
333
334         cert, ok := pubKey.(*ssh.Certificate)
335         if !ok {
336                 return nil, errors.New("agent: bad RSA certificate")
337         }
338
339         // An RSA publickey as marshaled by rsaPublicKey.Marshal() in keys.go
340         var rsaPub struct {
341                 Name string
342                 E    *big.Int
343                 N    *big.Int
344         }
345         if err := ssh.Unmarshal(cert.Key.Marshal(), &rsaPub); err != nil {
346                 return nil, fmt.Errorf("agent: Unmarshal failed to parse public key: %v", err)
347         }
348
349         if rsaPub.E.BitLen() > 30 {
350                 return nil, errors.New("agent: RSA public exponent too large")
351         }
352
353         priv := rsa.PrivateKey{
354                 PublicKey: rsa.PublicKey{
355                         E: int(rsaPub.E.Int64()),
356                         N: rsaPub.N,
357                 },
358                 D:      k.D,
359                 Primes: []*big.Int{k.Q, k.P},
360         }
361         priv.Precompute()
362
363         addedKey := &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}
364         if err := setConstraints(addedKey, k.Constraints); err != nil {
365                 return nil, err
366         }
367         return addedKey, nil
368 }
369
370 func parseDSACert(req []byte) (*AddedKey, error) {
371         var k dsaCertMsg
372         if err := ssh.Unmarshal(req, &k); err != nil {
373                 return nil, err
374         }
375         pubKey, err := ssh.ParsePublicKey(k.CertBytes)
376         if err != nil {
377                 return nil, err
378         }
379         cert, ok := pubKey.(*ssh.Certificate)
380         if !ok {
381                 return nil, errors.New("agent: bad DSA certificate")
382         }
383
384         // A DSA publickey as marshaled by dsaPublicKey.Marshal() in keys.go
385         var w struct {
386                 Name       string
387                 P, Q, G, Y *big.Int
388         }
389         if err := ssh.Unmarshal(cert.Key.Marshal(), &w); err != nil {
390                 return nil, fmt.Errorf("agent: Unmarshal failed to parse public key: %v", err)
391         }
392
393         priv := &dsa.PrivateKey{
394                 PublicKey: dsa.PublicKey{
395                         Parameters: dsa.Parameters{
396                                 P: w.P,
397                                 Q: w.Q,
398                                 G: w.G,
399                         },
400                         Y: w.Y,
401                 },
402                 X: k.X,
403         }
404
405         addedKey := &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}
406         if err := setConstraints(addedKey, k.Constraints); err != nil {
407                 return nil, err
408         }
409         return addedKey, nil
410 }
411
412 func parseECDSACert(req []byte) (*AddedKey, error) {
413         var k ecdsaCertMsg
414         if err := ssh.Unmarshal(req, &k); err != nil {
415                 return nil, err
416         }
417
418         pubKey, err := ssh.ParsePublicKey(k.CertBytes)
419         if err != nil {
420                 return nil, err
421         }
422         cert, ok := pubKey.(*ssh.Certificate)
423         if !ok {
424                 return nil, errors.New("agent: bad ECDSA certificate")
425         }
426
427         // An ECDSA publickey as marshaled by ecdsaPublicKey.Marshal() in keys.go
428         var ecdsaPub struct {
429                 Name string
430                 ID   string
431                 Key  []byte
432         }
433         if err := ssh.Unmarshal(cert.Key.Marshal(), &ecdsaPub); err != nil {
434                 return nil, err
435         }
436
437         priv, err := unmarshalECDSA(ecdsaPub.ID, ecdsaPub.Key, k.D)
438         if err != nil {
439                 return nil, err
440         }
441
442         addedKey := &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}
443         if err := setConstraints(addedKey, k.Constraints); err != nil {
444                 return nil, err
445         }
446         return addedKey, nil
447 }
448
449 func (s *server) insertIdentity(req []byte) error {
450         var record struct {
451                 Type string `sshtype:"17|25"`
452                 Rest []byte `ssh:"rest"`
453         }
454
455         if err := ssh.Unmarshal(req, &record); err != nil {
456                 return err
457         }
458
459         var addedKey *AddedKey
460         var err error
461
462         switch record.Type {
463         case ssh.KeyAlgoRSA:
464                 addedKey, err = parseRSAKey(req)
465         case ssh.KeyAlgoDSA:
466                 addedKey, err = parseDSAKey(req)
467         case ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521:
468                 addedKey, err = parseECDSAKey(req)
469         case ssh.KeyAlgoED25519:
470                 addedKey, err = parseEd25519Key(req)
471         case ssh.CertAlgoRSAv01:
472                 addedKey, err = parseRSACert(req)
473         case ssh.CertAlgoDSAv01:
474                 addedKey, err = parseDSACert(req)
475         case ssh.CertAlgoECDSA256v01, ssh.CertAlgoECDSA384v01, ssh.CertAlgoECDSA521v01:
476                 addedKey, err = parseECDSACert(req)
477         case ssh.CertAlgoED25519v01:
478                 addedKey, err = parseEd25519Cert(req)
479         default:
480                 return fmt.Errorf("agent: not implemented: %q", record.Type)
481         }
482
483         if err != nil {
484                 return err
485         }
486         return s.agent.Add(*addedKey)
487 }
488
489 // ServeAgent serves the agent protocol on the given connection. It
490 // returns when an I/O error occurs.
491 func ServeAgent(agent Agent, c io.ReadWriter) error {
492         s := &server{agent}
493
494         var length [4]byte
495         for {
496                 if _, err := io.ReadFull(c, length[:]); err != nil {
497                         return err
498                 }
499                 l := binary.BigEndian.Uint32(length[:])
500                 if l > maxAgentResponseBytes {
501                         // We also cap requests.
502                         return fmt.Errorf("agent: request too large: %d", l)
503                 }
504
505                 req := make([]byte, l)
506                 if _, err := io.ReadFull(c, req); err != nil {
507                         return err
508                 }
509
510                 repData := s.processRequestBytes(req)
511                 if len(repData) > maxAgentResponseBytes {
512                         return fmt.Errorf("agent: reply too large: %d bytes", len(repData))
513                 }
514
515                 binary.BigEndian.PutUint32(length[:], uint32(len(repData)))
516                 if _, err := c.Write(length[:]); err != nil {
517                         return err
518                 }
519                 if _, err := c.Write(repData); err != nil {
520                         return err
521                 }
522         }
523 }