Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 

452 rader
9.9 KiB

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