common.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. // Copyright 2011 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"
  7. "fmt"
  8. "sync"
  9. _ "crypto/sha1"
  10. _ "crypto/sha256"
  11. _ "crypto/sha512"
  12. )
  13. // These are string constants in the SSH protocol.
  14. const (
  15. hostAlgoRSA = "ssh-rsa"
  16. hostAlgoDSA = "ssh-dss"
  17. compressionNone = "none"
  18. serviceUserAuth = "ssh-userauth"
  19. serviceSSH = "ssh-connection"
  20. )
  21. var supportedKexAlgos = []string{
  22. kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
  23. kexAlgoDH14SHA1, kexAlgoDH1SHA1,
  24. }
  25. var supportedHostKeyAlgos = []string{hostAlgoRSA}
  26. var supportedCompressions = []string{compressionNone}
  27. // hashFuncs keeps the mapping of supported algorithms to their respective
  28. // hashes needed for signature verification.
  29. var hashFuncs = map[string]crypto.Hash{
  30. KeyAlgoRSA: crypto.SHA1,
  31. KeyAlgoDSA: crypto.SHA1,
  32. KeyAlgoECDSA256: crypto.SHA256,
  33. KeyAlgoECDSA384: crypto.SHA384,
  34. KeyAlgoECDSA521: crypto.SHA512,
  35. CertAlgoRSAv01: crypto.SHA1,
  36. CertAlgoDSAv01: crypto.SHA1,
  37. CertAlgoECDSA256v01: crypto.SHA256,
  38. CertAlgoECDSA384v01: crypto.SHA384,
  39. CertAlgoECDSA521v01: crypto.SHA512,
  40. }
  41. // UnexpectedMessageError results when the SSH message that we received didn't
  42. // match what we wanted.
  43. type UnexpectedMessageError struct {
  44. expected, got uint8
  45. }
  46. func (u UnexpectedMessageError) Error() string {
  47. return fmt.Sprintf("ssh: unexpected message type %d (expected %d)", u.got, u.expected)
  48. }
  49. // ParseError results from a malformed SSH message.
  50. type ParseError struct {
  51. msgType uint8
  52. }
  53. func (p ParseError) Error() string {
  54. return fmt.Sprintf("ssh: parse error in message type %d", p.msgType)
  55. }
  56. func findCommonAlgorithm(clientAlgos []string, serverAlgos []string) (commonAlgo string, ok bool) {
  57. for _, clientAlgo := range clientAlgos {
  58. for _, serverAlgo := range serverAlgos {
  59. if clientAlgo == serverAlgo {
  60. return clientAlgo, true
  61. }
  62. }
  63. }
  64. return
  65. }
  66. func findCommonCipher(clientCiphers []string, serverCiphers []string) (commonCipher string, ok bool) {
  67. for _, clientCipher := range clientCiphers {
  68. for _, serverCipher := range serverCiphers {
  69. // reject the cipher if we have no cipherModes definition
  70. if clientCipher == serverCipher && cipherModes[clientCipher] != nil {
  71. return clientCipher, true
  72. }
  73. }
  74. }
  75. return
  76. }
  77. func findAgreedAlgorithms(transport *transport, clientKexInit, serverKexInit *kexInitMsg) (kexAlgo, hostKeyAlgo string, ok bool) {
  78. kexAlgo, ok = findCommonAlgorithm(clientKexInit.KexAlgos, serverKexInit.KexAlgos)
  79. if !ok {
  80. return
  81. }
  82. hostKeyAlgo, ok = findCommonAlgorithm(clientKexInit.ServerHostKeyAlgos, serverKexInit.ServerHostKeyAlgos)
  83. if !ok {
  84. return
  85. }
  86. transport.writer.cipherAlgo, ok = findCommonCipher(clientKexInit.CiphersClientServer, serverKexInit.CiphersClientServer)
  87. if !ok {
  88. return
  89. }
  90. transport.reader.cipherAlgo, ok = findCommonCipher(clientKexInit.CiphersServerClient, serverKexInit.CiphersServerClient)
  91. if !ok {
  92. return
  93. }
  94. transport.writer.macAlgo, ok = findCommonAlgorithm(clientKexInit.MACsClientServer, serverKexInit.MACsClientServer)
  95. if !ok {
  96. return
  97. }
  98. transport.reader.macAlgo, ok = findCommonAlgorithm(clientKexInit.MACsServerClient, serverKexInit.MACsServerClient)
  99. if !ok {
  100. return
  101. }
  102. transport.writer.compressionAlgo, ok = findCommonAlgorithm(clientKexInit.CompressionClientServer, serverKexInit.CompressionClientServer)
  103. if !ok {
  104. return
  105. }
  106. transport.reader.compressionAlgo, ok = findCommonAlgorithm(clientKexInit.CompressionServerClient, serverKexInit.CompressionServerClient)
  107. if !ok {
  108. return
  109. }
  110. ok = true
  111. return
  112. }
  113. // Cryptographic configuration common to both ServerConfig and ClientConfig.
  114. type CryptoConfig struct {
  115. // The allowed key exchanges algorithms. If unspecified then a
  116. // default set of algorithms is used.
  117. KeyExchanges []string
  118. // The allowed cipher algorithms. If unspecified then DefaultCipherOrder is
  119. // used.
  120. Ciphers []string
  121. // The allowed MAC algorithms. If unspecified then DefaultMACOrder is used.
  122. MACs []string
  123. }
  124. func (c *CryptoConfig) ciphers() []string {
  125. if c.Ciphers == nil {
  126. return DefaultCipherOrder
  127. }
  128. return c.Ciphers
  129. }
  130. func (c *CryptoConfig) kexes() []string {
  131. if c.KeyExchanges == nil {
  132. return defaultKeyExchangeOrder
  133. }
  134. return c.KeyExchanges
  135. }
  136. func (c *CryptoConfig) macs() []string {
  137. if c.MACs == nil {
  138. return DefaultMACOrder
  139. }
  140. return c.MACs
  141. }
  142. // serialize a signed slice according to RFC 4254 6.6. The name should
  143. // be a key type name, rather than a cert type name.
  144. func serializeSignature(name string, sig []byte) []byte {
  145. length := stringLength(len(name))
  146. length += stringLength(len(sig))
  147. ret := make([]byte, length)
  148. r := marshalString(ret, []byte(name))
  149. r = marshalString(r, sig)
  150. return ret
  151. }
  152. // MarshalPublicKey serializes a supported key or certificate for use
  153. // by the SSH wire protocol. It can be used for comparison with the
  154. // pubkey argument of ServerConfig's PublicKeyCallback as well as for
  155. // generating an authorized_keys or host_keys file.
  156. func MarshalPublicKey(key PublicKey) []byte {
  157. // See also RFC 4253 6.6.
  158. algoname := key.PrivateKeyAlgo()
  159. blob := key.Marshal()
  160. length := stringLength(len(algoname))
  161. length += len(blob)
  162. ret := make([]byte, length)
  163. r := marshalString(ret, []byte(algoname))
  164. copy(r, blob)
  165. return ret
  166. }
  167. // pubAlgoToPrivAlgo returns the private key algorithm format name that
  168. // corresponds to a given public key algorithm format name. For most
  169. // public keys, the private key algorithm name is the same. For some
  170. // situations, such as openssh certificates, the private key algorithm and
  171. // public key algorithm names differ. This accounts for those situations.
  172. func pubAlgoToPrivAlgo(pubAlgo string) string {
  173. switch pubAlgo {
  174. case CertAlgoRSAv01:
  175. return KeyAlgoRSA
  176. case CertAlgoDSAv01:
  177. return KeyAlgoDSA
  178. case CertAlgoECDSA256v01:
  179. return KeyAlgoECDSA256
  180. case CertAlgoECDSA384v01:
  181. return KeyAlgoECDSA384
  182. case CertAlgoECDSA521v01:
  183. return KeyAlgoECDSA521
  184. }
  185. return pubAlgo
  186. }
  187. // buildDataSignedForAuth returns the data that is signed in order to prove
  188. // posession of a private key. See RFC 4252, section 7.
  189. func buildDataSignedForAuth(sessionId []byte, req userAuthRequestMsg, algo, pubKey []byte) []byte {
  190. user := []byte(req.User)
  191. service := []byte(req.Service)
  192. method := []byte(req.Method)
  193. length := stringLength(len(sessionId))
  194. length += 1
  195. length += stringLength(len(user))
  196. length += stringLength(len(service))
  197. length += stringLength(len(method))
  198. length += 1
  199. length += stringLength(len(algo))
  200. length += stringLength(len(pubKey))
  201. ret := make([]byte, length)
  202. r := marshalString(ret, sessionId)
  203. r[0] = msgUserAuthRequest
  204. r = r[1:]
  205. r = marshalString(r, user)
  206. r = marshalString(r, service)
  207. r = marshalString(r, method)
  208. r[0] = 1
  209. r = r[1:]
  210. r = marshalString(r, algo)
  211. r = marshalString(r, pubKey)
  212. return ret
  213. }
  214. // safeString sanitises s according to RFC 4251, section 9.2.
  215. // All control characters except tab, carriage return and newline are
  216. // replaced by 0x20.
  217. func safeString(s string) string {
  218. out := []byte(s)
  219. for i, c := range out {
  220. if c < 0x20 && c != 0xd && c != 0xa && c != 0x9 {
  221. out[i] = 0x20
  222. }
  223. }
  224. return string(out)
  225. }
  226. func appendU16(buf []byte, n uint16) []byte {
  227. return append(buf, byte(n>>8), byte(n))
  228. }
  229. func appendU32(buf []byte, n uint32) []byte {
  230. return append(buf, byte(n>>24), byte(n>>16), byte(n>>8), byte(n))
  231. }
  232. func appendInt(buf []byte, n int) []byte {
  233. return appendU32(buf, uint32(n))
  234. }
  235. func appendString(buf []byte, s string) []byte {
  236. buf = appendU32(buf, uint32(len(s)))
  237. buf = append(buf, s...)
  238. return buf
  239. }
  240. func appendBool(buf []byte, b bool) []byte {
  241. if b {
  242. buf = append(buf, 1)
  243. } else {
  244. buf = append(buf, 0)
  245. }
  246. return buf
  247. }
  248. // newCond is a helper to hide the fact that there is no usable zero
  249. // value for sync.Cond.
  250. func newCond() *sync.Cond { return sync.NewCond(new(sync.Mutex)) }
  251. // window represents the buffer available to clients
  252. // wishing to write to a channel.
  253. type window struct {
  254. *sync.Cond
  255. win uint32 // RFC 4254 5.2 says the window size can grow to 2^32-1
  256. }
  257. // add adds win to the amount of window available
  258. // for consumers.
  259. func (w *window) add(win uint32) bool {
  260. // a zero sized window adjust is a noop.
  261. if win == 0 {
  262. return true
  263. }
  264. w.L.Lock()
  265. if w.win+win < win {
  266. w.L.Unlock()
  267. return false
  268. }
  269. w.win += win
  270. // It is unusual that multiple goroutines would be attempting to reserve
  271. // window space, but not guaranteed. Use broadcast to notify all waiters
  272. // that additional window is available.
  273. w.Broadcast()
  274. w.L.Unlock()
  275. return true
  276. }
  277. // reserve reserves win from the available window capacity.
  278. // If no capacity remains, reserve will block. reserve may
  279. // return less than requested.
  280. func (w *window) reserve(win uint32) uint32 {
  281. w.L.Lock()
  282. for w.win == 0 {
  283. w.Wait()
  284. }
  285. if w.win < win {
  286. win = w.win
  287. }
  288. w.win -= win
  289. w.L.Unlock()
  290. return win
  291. }