server.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  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. package agent
  5. import (
  6. "crypto/dsa"
  7. "crypto/ecdsa"
  8. "crypto/elliptic"
  9. "crypto/rsa"
  10. "encoding/binary"
  11. "errors"
  12. "fmt"
  13. "io"
  14. "log"
  15. "math/big"
  16. "golang.org/x/crypto/ssh"
  17. )
  18. // Server wraps an Agent and uses it to implement the agent side of
  19. // the SSH-agent, wire protocol.
  20. type server struct {
  21. agent Agent
  22. }
  23. func (s *server) processRequestBytes(reqData []byte) []byte {
  24. rep, err := s.processRequest(reqData)
  25. if err != nil {
  26. if err != errLocked {
  27. // TODO(hanwen): provide better logging interface?
  28. log.Printf("agent %d: %v", reqData[0], err)
  29. }
  30. return []byte{agentFailure}
  31. }
  32. if err == nil && rep == nil {
  33. return []byte{agentSuccess}
  34. }
  35. return ssh.Marshal(rep)
  36. }
  37. func marshalKey(k *Key) []byte {
  38. var record struct {
  39. Blob []byte
  40. Comment string
  41. }
  42. record.Blob = k.Marshal()
  43. record.Comment = k.Comment
  44. return ssh.Marshal(&record)
  45. }
  46. // See [PROTOCOL.agent], section 2.5.1.
  47. const agentV1IdentitiesAnswer = 2
  48. type agentV1IdentityMsg struct {
  49. Numkeys uint32 `sshtype:"2"`
  50. }
  51. type agentRemoveIdentityMsg struct {
  52. KeyBlob []byte `sshtype:"18"`
  53. }
  54. type agentLockMsg struct {
  55. Passphrase []byte `sshtype:"22"`
  56. }
  57. type agentUnlockMsg struct {
  58. Passphrase []byte `sshtype:"23"`
  59. }
  60. func (s *server) processRequest(data []byte) (interface{}, error) {
  61. switch data[0] {
  62. case agentRequestV1Identities:
  63. return &agentV1IdentityMsg{0}, nil
  64. case agentRemoveAllV1Identities:
  65. return nil, nil
  66. case agentRemoveIdentity:
  67. var req agentRemoveIdentityMsg
  68. if err := ssh.Unmarshal(data, &req); err != nil {
  69. return nil, err
  70. }
  71. var wk wireKey
  72. if err := ssh.Unmarshal(req.KeyBlob, &wk); err != nil {
  73. return nil, err
  74. }
  75. return nil, s.agent.Remove(&Key{Format: wk.Format, Blob: req.KeyBlob})
  76. case agentRemoveAllIdentities:
  77. return nil, s.agent.RemoveAll()
  78. case agentLock:
  79. var req agentLockMsg
  80. if err := ssh.Unmarshal(data, &req); err != nil {
  81. return nil, err
  82. }
  83. return nil, s.agent.Lock(req.Passphrase)
  84. case agentUnlock:
  85. var req agentLockMsg
  86. if err := ssh.Unmarshal(data, &req); err != nil {
  87. return nil, err
  88. }
  89. return nil, s.agent.Unlock(req.Passphrase)
  90. case agentSignRequest:
  91. var req signRequestAgentMsg
  92. if err := ssh.Unmarshal(data, &req); err != nil {
  93. return nil, err
  94. }
  95. var wk wireKey
  96. if err := ssh.Unmarshal(req.KeyBlob, &wk); err != nil {
  97. return nil, err
  98. }
  99. k := &Key{
  100. Format: wk.Format,
  101. Blob: req.KeyBlob,
  102. }
  103. sig, err := s.agent.Sign(k, req.Data) // TODO(hanwen): flags.
  104. if err != nil {
  105. return nil, err
  106. }
  107. return &signResponseAgentMsg{SigBlob: ssh.Marshal(sig)}, nil
  108. case agentRequestIdentities:
  109. keys, err := s.agent.List()
  110. if err != nil {
  111. return nil, err
  112. }
  113. rep := identitiesAnswerAgentMsg{
  114. NumKeys: uint32(len(keys)),
  115. }
  116. for _, k := range keys {
  117. rep.Keys = append(rep.Keys, marshalKey(k)...)
  118. }
  119. return rep, nil
  120. case agentAddIdConstrained, agentAddIdentity:
  121. return nil, s.insertIdentity(data)
  122. }
  123. return nil, fmt.Errorf("unknown opcode %d", data[0])
  124. }
  125. func parseRSAKey(req []byte) (*AddedKey, error) {
  126. var k rsaKeyMsg
  127. if err := ssh.Unmarshal(req, &k); err != nil {
  128. return nil, err
  129. }
  130. if k.E.BitLen() > 30 {
  131. return nil, errors.New("agent: RSA public exponent too large")
  132. }
  133. priv := &rsa.PrivateKey{
  134. PublicKey: rsa.PublicKey{
  135. E: int(k.E.Int64()),
  136. N: k.N,
  137. },
  138. D: k.D,
  139. Primes: []*big.Int{k.P, k.Q},
  140. }
  141. priv.Precompute()
  142. return &AddedKey{PrivateKey: priv, Comment: k.Comments}, nil
  143. }
  144. func parseDSAKey(req []byte) (*AddedKey, error) {
  145. var k dsaKeyMsg
  146. if err := ssh.Unmarshal(req, &k); err != nil {
  147. return nil, err
  148. }
  149. priv := &dsa.PrivateKey{
  150. PublicKey: dsa.PublicKey{
  151. Parameters: dsa.Parameters{
  152. P: k.P,
  153. Q: k.Q,
  154. G: k.G,
  155. },
  156. Y: k.Y,
  157. },
  158. X: k.X,
  159. }
  160. return &AddedKey{PrivateKey: priv, Comment: k.Comments}, nil
  161. }
  162. func unmarshalECDSA(curveName string, keyBytes []byte, privScalar *big.Int) (priv *ecdsa.PrivateKey, err error) {
  163. priv = &ecdsa.PrivateKey{
  164. D: privScalar,
  165. }
  166. switch curveName {
  167. case "nistp256":
  168. priv.Curve = elliptic.P256()
  169. case "nistp384":
  170. priv.Curve = elliptic.P384()
  171. case "nistp521":
  172. priv.Curve = elliptic.P521()
  173. default:
  174. return nil, fmt.Errorf("agent: unknown curve %q", curveName)
  175. }
  176. priv.X, priv.Y = elliptic.Unmarshal(priv.Curve, keyBytes)
  177. if priv.X == nil || priv.Y == nil {
  178. return nil, errors.New("agent: point not on curve")
  179. }
  180. return priv, nil
  181. }
  182. func parseECDSAKey(req []byte) (*AddedKey, error) {
  183. var k ecdsaKeyMsg
  184. if err := ssh.Unmarshal(req, &k); err != nil {
  185. return nil, err
  186. }
  187. priv, err := unmarshalECDSA(k.Curve, k.KeyBytes, k.D)
  188. if err != nil {
  189. return nil, err
  190. }
  191. return &AddedKey{PrivateKey: &priv, Comment: k.Comments}, nil
  192. }
  193. func parseRSACert(req []byte) (*AddedKey, error) {
  194. var k rsaCertMsg
  195. if err := ssh.Unmarshal(req, &k); err != nil {
  196. return nil, err
  197. }
  198. pubKey, err := ssh.ParsePublicKey(k.CertBytes)
  199. if err != nil {
  200. return nil, err
  201. }
  202. cert, ok := pubKey.(*ssh.Certificate)
  203. if !ok {
  204. return nil, errors.New("agent: bad RSA certificate")
  205. }
  206. // An RSA publickey as marshaled by rsaPublicKey.Marshal() in keys.go
  207. var rsaPub struct {
  208. Name string
  209. E *big.Int
  210. N *big.Int
  211. }
  212. if err := ssh.Unmarshal(cert.Key.Marshal(), &rsaPub); err != nil {
  213. return nil, fmt.Errorf("agent: Unmarshal failed to parse public key: %v", err)
  214. }
  215. if rsaPub.E.BitLen() > 30 {
  216. return nil, errors.New("agent: RSA public exponent too large")
  217. }
  218. priv := rsa.PrivateKey{
  219. PublicKey: rsa.PublicKey{
  220. E: int(rsaPub.E.Int64()),
  221. N: rsaPub.N,
  222. },
  223. D: k.D,
  224. Primes: []*big.Int{k.Q, k.P},
  225. }
  226. priv.Precompute()
  227. return &AddedKey{PrivateKey: &priv, Certificate: cert, Comment: k.Comments}, nil
  228. }
  229. func parseDSACert(req []byte) (*AddedKey, error) {
  230. var k dsaCertMsg
  231. if err := ssh.Unmarshal(req, &k); err != nil {
  232. return nil, err
  233. }
  234. pubKey, err := ssh.ParsePublicKey(k.CertBytes)
  235. if err != nil {
  236. return nil, err
  237. }
  238. cert, ok := pubKey.(*ssh.Certificate)
  239. if !ok {
  240. return nil, errors.New("agent: bad DSA certificate")
  241. }
  242. // A DSA publickey as marshaled by dsaPublicKey.Marshal() in keys.go
  243. var w struct {
  244. Name string
  245. P, Q, G, Y *big.Int
  246. }
  247. if err := ssh.Unmarshal(cert.Key.Marshal(), &w); err != nil {
  248. return nil, fmt.Errorf("agent: Unmarshal failed to parse public key: %v", err)
  249. }
  250. priv := &dsa.PrivateKey{
  251. PublicKey: dsa.PublicKey{
  252. Parameters: dsa.Parameters{
  253. P: w.P,
  254. Q: w.Q,
  255. G: w.G,
  256. },
  257. Y: w.Y,
  258. },
  259. X: k.X,
  260. }
  261. return &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}, nil
  262. }
  263. func parseECDSACert(req []byte) (*AddedKey, error) {
  264. var k ecdsaCertMsg
  265. if err := ssh.Unmarshal(req, &k); err != nil {
  266. return nil, err
  267. }
  268. pubKey, err := ssh.ParsePublicKey(k.CertBytes)
  269. if err != nil {
  270. return nil, err
  271. }
  272. cert, ok := pubKey.(*ssh.Certificate)
  273. if !ok {
  274. return nil, errors.New("agent: bad ECDSA certificate")
  275. }
  276. // An ECDSA publickey as marshaled by ecdsaPublicKey.Marshal() in keys.go
  277. var ecdsaPub struct {
  278. Name string
  279. ID string
  280. Key []byte
  281. }
  282. if err := ssh.Unmarshal(cert.Key.Marshal(), &ecdsaPub); err != nil {
  283. return nil, err
  284. }
  285. priv, err := unmarshalECDSA(ecdsaPub.ID, ecdsaPub.Key, k.D)
  286. if err != nil {
  287. return nil, err
  288. }
  289. return &AddedKey{PrivateKey: priv, Certificate: cert, Comment: k.Comments}, nil
  290. }
  291. func (s *server) insertIdentity(req []byte) error {
  292. var record struct {
  293. Type string `sshtype:"17|25"`
  294. Rest []byte `ssh:"rest"`
  295. }
  296. if err := ssh.Unmarshal(req, &record); err != nil {
  297. return err
  298. }
  299. var addedKey *AddedKey
  300. var err error
  301. switch record.Type {
  302. case ssh.KeyAlgoRSA:
  303. addedKey, err = parseRSAKey(req)
  304. case ssh.KeyAlgoDSA:
  305. addedKey, err = parseDSAKey(req)
  306. case ssh.KeyAlgoECDSA256, ssh.KeyAlgoECDSA384, ssh.KeyAlgoECDSA521:
  307. addedKey, err = parseECDSACert(req)
  308. case ssh.CertAlgoRSAv01:
  309. addedKey, err = parseRSACert(req)
  310. case ssh.CertAlgoDSAv01:
  311. addedKey, err = parseDSACert(req)
  312. case ssh.CertAlgoECDSA256v01, ssh.CertAlgoECDSA384v01, ssh.CertAlgoECDSA521v01:
  313. addedKey, err = parseECDSACert(req)
  314. default:
  315. return fmt.Errorf("agent: not implemented: %q", record.Type)
  316. }
  317. if err != nil {
  318. return err
  319. }
  320. return s.agent.Add(*addedKey)
  321. }
  322. // ServeAgent serves the agent protocol on the given connection. It
  323. // returns when an I/O error occurs.
  324. func ServeAgent(agent Agent, c io.ReadWriter) error {
  325. s := &server{agent}
  326. var length [4]byte
  327. for {
  328. if _, err := io.ReadFull(c, length[:]); err != nil {
  329. return err
  330. }
  331. l := binary.BigEndian.Uint32(length[:])
  332. if l > maxAgentResponseBytes {
  333. // We also cap requests.
  334. return fmt.Errorf("agent: request too large: %d", l)
  335. }
  336. req := make([]byte, l)
  337. if _, err := io.ReadFull(c, req); err != nil {
  338. return err
  339. }
  340. repData := s.processRequestBytes(req)
  341. if len(repData) > maxAgentResponseBytes {
  342. return fmt.Errorf("agent: reply too large: %d bytes", len(repData))
  343. }
  344. binary.BigEndian.PutUint32(length[:], uint32(len(repData)))
  345. if _, err := c.Write(length[:]); err != nil {
  346. return err
  347. }
  348. if _, err := c.Write(repData); err != nil {
  349. return err
  350. }
  351. }
  352. }