keys.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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 ssh
  5. import (
  6. "crypto/dsa"
  7. "crypto/rsa"
  8. "math/big"
  9. )
  10. // parsePubKey parses a public key according to RFC 4253, section 6.6.
  11. func parsePubKey(in []byte) (out interface{}, rest []byte, ok bool) {
  12. algo, in, ok := parseString(in)
  13. if !ok {
  14. return
  15. }
  16. switch string(algo) {
  17. case hostAlgoRSA:
  18. return parseRSA(in)
  19. case hostAlgoDSA:
  20. return parseDSA(in)
  21. case hostAlgoRSACertV01, hostAlgoDSACertV01:
  22. return parseOpenSSHCertV01(in, string(algo))
  23. }
  24. panic("ssh: unknown public key type")
  25. }
  26. // parseRSA parses an RSA key according to RFC 4253, section 6.6.
  27. func parseRSA(in []byte) (out *rsa.PublicKey, rest []byte, ok bool) {
  28. key := new(rsa.PublicKey)
  29. bigE, in, ok := parseInt(in)
  30. if !ok || bigE.BitLen() > 24 {
  31. return
  32. }
  33. e := bigE.Int64()
  34. if e < 3 || e&1 == 0 {
  35. ok = false
  36. return
  37. }
  38. key.E = int(e)
  39. if key.N, in, ok = parseInt(in); !ok {
  40. return
  41. }
  42. ok = true
  43. return key, in, ok
  44. }
  45. // parseDSA parses an DSA key according to RFC 4253, section 6.6.
  46. func parseDSA(in []byte) (out *dsa.PublicKey, rest []byte, ok bool) {
  47. key := new(dsa.PublicKey)
  48. if key.P, in, ok = parseInt(in); !ok {
  49. return
  50. }
  51. if key.Q, in, ok = parseInt(in); !ok {
  52. return
  53. }
  54. if key.G, in, ok = parseInt(in); !ok {
  55. return
  56. }
  57. if key.Y, in, ok = parseInt(in); !ok {
  58. return
  59. }
  60. ok = true
  61. return key, in, ok
  62. }
  63. // marshalPrivRSA serializes an RSA private key according to RFC 4253, section 6.6.
  64. func marshalPrivRSA(priv *rsa.PrivateKey) []byte {
  65. e := new(big.Int).SetInt64(int64(priv.E))
  66. length := stringLength(len(hostAlgoRSA))
  67. length += intLength(e)
  68. length += intLength(priv.N)
  69. ret := make([]byte, length)
  70. r := marshalString(ret, []byte(hostAlgoRSA))
  71. r = marshalInt(r, e)
  72. r = marshalInt(r, priv.N)
  73. return ret
  74. }
  75. // marshalPubRSA serializes an RSA public key according to RFC 4253, section 6.6.
  76. func marshalPubRSA(key *rsa.PublicKey) []byte {
  77. e := new(big.Int).SetInt64(int64(key.E))
  78. length := intLength(e)
  79. length += intLength(key.N)
  80. ret := make([]byte, length)
  81. r := marshalInt(ret, e)
  82. r = marshalInt(r, key.N)
  83. return ret
  84. }
  85. // marshalPubDSA serializes an DSA public key according to RFC 4253, section 6.6.
  86. func marshalPubDSA(key *dsa.PublicKey) []byte {
  87. length := intLength(key.P)
  88. length += intLength(key.Q)
  89. length += intLength(key.G)
  90. length += intLength(key.Y)
  91. ret := make([]byte, length)
  92. r := marshalInt(ret, key.P)
  93. r = marshalInt(r, key.Q)
  94. r = marshalInt(r, key.G)
  95. marshalInt(r, key.Y)
  96. return ret
  97. }