Alternative TLS implementation in Go
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

403 regels
12 KiB

  1. // Copyright 2010 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 tls
  5. import (
  6. "crypto"
  7. "crypto/elliptic"
  8. "crypto/md5"
  9. "crypto/rsa"
  10. "crypto/sha1"
  11. "errors"
  12. "io"
  13. "math/big"
  14. "golang_org/x/crypto/curve25519"
  15. )
  16. var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
  17. var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message")
  18. // rsaKeyAgreement implements the standard TLS key agreement where the client
  19. // encrypts the pre-master secret to the server's public key.
  20. type rsaKeyAgreement struct{}
  21. func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, sk crypto.PrivateKey, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
  22. return nil, nil
  23. }
  24. func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, sk crypto.PrivateKey, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
  25. if len(ckx.ciphertext) < 2 {
  26. return nil, errClientKeyExchange
  27. }
  28. ciphertext := ckx.ciphertext
  29. if version != VersionSSL30 {
  30. ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
  31. if ciphertextLen != len(ckx.ciphertext)-2 {
  32. return nil, errClientKeyExchange
  33. }
  34. ciphertext = ckx.ciphertext[2:]
  35. }
  36. priv, ok := sk.(crypto.Decrypter)
  37. if !ok {
  38. return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter")
  39. }
  40. // Perform constant time RSA PKCS#1 v1.5 decryption
  41. preMasterSecret, err := priv.Decrypt(config.rand(), ciphertext, &rsa.PKCS1v15DecryptOptions{SessionKeyLen: 48})
  42. if err != nil {
  43. return nil, err
  44. }
  45. // We don't check the version number in the premaster secret. For one,
  46. // by checking it, we would leak information about the validity of the
  47. // encrypted pre-master secret. Secondly, it provides only a small
  48. // benefit against a downgrade attack and some implementations send the
  49. // wrong version anyway. See the discussion at the end of section
  50. // 7.4.7.1 of RFC 4346.
  51. return preMasterSecret, nil
  52. }
  53. func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, pk crypto.PublicKey, skx *serverKeyExchangeMsg) error {
  54. return errors.New("tls: unexpected ServerKeyExchange")
  55. }
  56. func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, pk crypto.PublicKey) ([]byte, *clientKeyExchangeMsg, error) {
  57. preMasterSecret := make([]byte, 48)
  58. preMasterSecret[0] = byte(clientHello.vers >> 8)
  59. preMasterSecret[1] = byte(clientHello.vers)
  60. _, err := io.ReadFull(config.rand(), preMasterSecret[2:])
  61. if err != nil {
  62. return nil, nil, err
  63. }
  64. encrypted, err := rsa.EncryptPKCS1v15(config.rand(), pk.(*rsa.PublicKey), preMasterSecret)
  65. if err != nil {
  66. return nil, nil, err
  67. }
  68. ckx := new(clientKeyExchangeMsg)
  69. ckx.ciphertext = make([]byte, len(encrypted)+2)
  70. ckx.ciphertext[0] = byte(len(encrypted) >> 8)
  71. ckx.ciphertext[1] = byte(len(encrypted))
  72. copy(ckx.ciphertext[2:], encrypted)
  73. return preMasterSecret, ckx, nil
  74. }
  75. // sha1Hash calculates a SHA1 hash over the given byte slices.
  76. func sha1Hash(slices [][]byte) []byte {
  77. hsha1 := sha1.New()
  78. for _, slice := range slices {
  79. hsha1.Write(slice)
  80. }
  81. return hsha1.Sum(nil)
  82. }
  83. // md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the
  84. // concatenation of an MD5 and SHA1 hash.
  85. func md5SHA1Hash(slices [][]byte) []byte {
  86. md5sha1 := make([]byte, md5.Size+sha1.Size)
  87. hmd5 := md5.New()
  88. for _, slice := range slices {
  89. hmd5.Write(slice)
  90. }
  91. copy(md5sha1, hmd5.Sum(nil))
  92. copy(md5sha1[md5.Size:], sha1Hash(slices))
  93. return md5sha1
  94. }
  95. // hashForServerKeyExchange hashes the given slices and returns their digest
  96. // using the given hash function.
  97. func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint16, slices ...[]byte) ([]byte, error) {
  98. if version >= VersionTLS12 {
  99. h := hashFunc.New()
  100. for _, slice := range slices {
  101. h.Write(slice)
  102. }
  103. digest := h.Sum(nil)
  104. return digest, nil
  105. }
  106. if sigType == signatureECDSA {
  107. return sha1Hash(slices), nil
  108. }
  109. return md5SHA1Hash(slices), nil
  110. }
  111. func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
  112. switch id {
  113. case CurveP256:
  114. return elliptic.P256(), true
  115. case CurveP384:
  116. return elliptic.P384(), true
  117. case CurveP521:
  118. return elliptic.P521(), true
  119. default:
  120. return nil, false
  121. }
  122. }
  123. // ecdheKeyAgreement implements a TLS key agreement where the server
  124. // generates an ephemeral EC public/private key pair and signs it. The
  125. // pre-master secret is then calculated using ECDH. The signature may
  126. // either be ECDSA or RSA.
  127. type ecdheKeyAgreement struct {
  128. version uint16
  129. isRSA bool
  130. privateKey []byte
  131. curveid CurveID
  132. // publicKey is used to store the peer's public value when X25519 is
  133. // being used.
  134. publicKey []byte
  135. // x and y are used to store the peer's public value when one of the
  136. // NIST curves is being used.
  137. x, y *big.Int
  138. }
  139. func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, sk crypto.PrivateKey, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
  140. preferredCurves := config.curvePreferences()
  141. NextCandidate:
  142. for _, candidate := range preferredCurves {
  143. for _, c := range clientHello.supportedCurves {
  144. if candidate == c {
  145. ka.curveid = c
  146. break NextCandidate
  147. }
  148. }
  149. }
  150. if ka.curveid == 0 {
  151. return nil, errors.New("tls: no supported elliptic curves offered")
  152. }
  153. var ecdhePublic []byte
  154. if ka.curveid == X25519 {
  155. var scalar, public [32]byte
  156. if _, err := io.ReadFull(config.rand(), scalar[:]); err != nil {
  157. return nil, err
  158. }
  159. curve25519.ScalarBaseMult(&public, &scalar)
  160. ka.privateKey = scalar[:]
  161. ecdhePublic = public[:]
  162. } else {
  163. curve, ok := curveForCurveID(ka.curveid)
  164. if !ok {
  165. return nil, errors.New("tls: preferredCurves includes unsupported curve")
  166. }
  167. var x, y *big.Int
  168. var err error
  169. ka.privateKey, x, y, err = elliptic.GenerateKey(curve, config.rand())
  170. if err != nil {
  171. return nil, err
  172. }
  173. ecdhePublic = elliptic.Marshal(curve, x, y)
  174. }
  175. // http://tools.ietf.org/html/rfc4492#section-5.4
  176. serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic))
  177. serverECDHParams[0] = 3 // named curve
  178. serverECDHParams[1] = byte(ka.curveid >> 8)
  179. serverECDHParams[2] = byte(ka.curveid)
  180. serverECDHParams[3] = byte(len(ecdhePublic))
  181. copy(serverECDHParams[4:], ecdhePublic)
  182. priv, ok := sk.(crypto.Signer)
  183. if !ok {
  184. return nil, errors.New("tls: certificate private key does not implement crypto.Signer")
  185. }
  186. signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(priv.Public(), clientHello.supportedSignatureAlgorithms, supportedSignatureAlgorithms, ka.version)
  187. if err != nil {
  188. return nil, err
  189. }
  190. if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {
  191. return nil, errors.New("tls: certificate cannot be used with the selected cipher suite")
  192. }
  193. digest, err := hashForServerKeyExchange(sigType, hashFunc, ka.version, clientHello.random, hello.random, serverECDHParams)
  194. if err != nil {
  195. return nil, err
  196. }
  197. var sig []byte
  198. signOpts := crypto.SignerOpts(hashFunc)
  199. if sigType == signatureRSAPSS {
  200. signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: hashFunc}
  201. }
  202. sig, err = priv.Sign(config.rand(), digest, signOpts)
  203. if err != nil {
  204. return nil, errors.New("tls: failed to sign ECDHE parameters: " + err.Error())
  205. }
  206. skx := new(serverKeyExchangeMsg)
  207. sigAndHashLen := 0
  208. if ka.version >= VersionTLS12 {
  209. sigAndHashLen = 2
  210. }
  211. skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig))
  212. copy(skx.key, serverECDHParams)
  213. k := skx.key[len(serverECDHParams):]
  214. if ka.version >= VersionTLS12 {
  215. k[0] = byte(signatureAlgorithm >> 8)
  216. k[1] = byte(signatureAlgorithm)
  217. k = k[2:]
  218. }
  219. k[0] = byte(len(sig) >> 8)
  220. k[1] = byte(len(sig))
  221. copy(k[2:], sig)
  222. return skx, nil
  223. }
  224. func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, sk crypto.PrivateKey, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
  225. if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
  226. return nil, errClientKeyExchange
  227. }
  228. if ka.curveid == X25519 {
  229. if len(ckx.ciphertext) != 1+32 {
  230. return nil, errClientKeyExchange
  231. }
  232. var theirPublic, sharedKey, scalar [32]byte
  233. copy(theirPublic[:], ckx.ciphertext[1:])
  234. copy(scalar[:], ka.privateKey)
  235. curve25519.ScalarMult(&sharedKey, &scalar, &theirPublic)
  236. return sharedKey[:], nil
  237. }
  238. curve, ok := curveForCurveID(ka.curveid)
  239. if !ok {
  240. panic("internal error")
  241. }
  242. x, y := elliptic.Unmarshal(curve, ckx.ciphertext[1:]) // Unmarshal also checks whether the given point is on the curve
  243. if x == nil {
  244. return nil, errClientKeyExchange
  245. }
  246. x, _ = curve.ScalarMult(x, y, ka.privateKey)
  247. curveSize := (curve.Params().BitSize + 7) >> 3
  248. xBytes := x.Bytes()
  249. if len(xBytes) == curveSize {
  250. return xBytes, nil
  251. }
  252. preMasterSecret := make([]byte, curveSize)
  253. copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
  254. return preMasterSecret, nil
  255. }
  256. func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, pk crypto.PublicKey, skx *serverKeyExchangeMsg) error {
  257. if len(skx.key) < 4 {
  258. return errServerKeyExchange
  259. }
  260. if skx.key[0] != 3 { // named curve
  261. return errors.New("tls: server selected unsupported curve")
  262. }
  263. ka.curveid = CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
  264. publicLen := int(skx.key[3])
  265. if publicLen+4 > len(skx.key) {
  266. return errServerKeyExchange
  267. }
  268. serverECDHParams := skx.key[:4+publicLen]
  269. publicKey := serverECDHParams[4:]
  270. sig := skx.key[4+publicLen:]
  271. if len(sig) < 2 {
  272. return errServerKeyExchange
  273. }
  274. if ka.curveid == X25519 {
  275. if len(publicKey) != 32 {
  276. return errors.New("tls: bad X25519 public value")
  277. }
  278. ka.publicKey = publicKey
  279. } else {
  280. curve, ok := curveForCurveID(ka.curveid)
  281. if !ok {
  282. return errors.New("tls: server selected unsupported curve")
  283. }
  284. ka.x, ka.y = elliptic.Unmarshal(curve, publicKey) // Unmarshal also checks whether the given point is on the curve
  285. if ka.x == nil {
  286. return errServerKeyExchange
  287. }
  288. }
  289. var signatureAlgorithm SignatureScheme
  290. if ka.version >= VersionTLS12 {
  291. // handle SignatureAndHashAlgorithm
  292. signatureAlgorithm = SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1])
  293. sig = sig[2:]
  294. if len(sig) < 2 {
  295. return errServerKeyExchange
  296. }
  297. }
  298. _, sigType, hashFunc, err := pickSignatureAlgorithm(pk, []SignatureScheme{signatureAlgorithm}, clientHello.supportedSignatureAlgorithms, ka.version)
  299. if err != nil {
  300. return err
  301. }
  302. if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {
  303. return errServerKeyExchange
  304. }
  305. sigLen := int(sig[0])<<8 | int(sig[1])
  306. if sigLen+2 != len(sig) {
  307. return errServerKeyExchange
  308. }
  309. sig = sig[2:]
  310. digest, err := hashForServerKeyExchange(sigType, hashFunc, ka.version, clientHello.random, serverHello.random, serverECDHParams)
  311. if err != nil {
  312. return err
  313. }
  314. return verifyHandshakeSignature(sigType, pk, hashFunc, digest, sig)
  315. }
  316. func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, pk crypto.PublicKey) ([]byte, *clientKeyExchangeMsg, error) {
  317. if ka.curveid == 0 {
  318. return nil, nil, errors.New("tls: missing ServerKeyExchange message")
  319. }
  320. var serialized, preMasterSecret []byte
  321. if ka.curveid == X25519 {
  322. var ourPublic, theirPublic, sharedKey, scalar [32]byte
  323. if _, err := io.ReadFull(config.rand(), scalar[:]); err != nil {
  324. return nil, nil, err
  325. }
  326. copy(theirPublic[:], ka.publicKey)
  327. curve25519.ScalarBaseMult(&ourPublic, &scalar)
  328. curve25519.ScalarMult(&sharedKey, &scalar, &theirPublic)
  329. serialized = ourPublic[:]
  330. preMasterSecret = sharedKey[:]
  331. } else {
  332. curve, ok := curveForCurveID(ka.curveid)
  333. if !ok {
  334. panic("internal error")
  335. }
  336. priv, mx, my, err := elliptic.GenerateKey(curve, config.rand())
  337. if err != nil {
  338. return nil, nil, err
  339. }
  340. x, _ := curve.ScalarMult(ka.x, ka.y, priv)
  341. preMasterSecret = make([]byte, (curve.Params().BitSize+7)>>3)
  342. xBytes := x.Bytes()
  343. copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
  344. serialized = elliptic.Marshal(curve, mx, my)
  345. }
  346. ckx := new(clientKeyExchangeMsg)
  347. ckx.ciphertext = make([]byte, 1+len(serialized))
  348. ckx.ciphertext[0] = byte(len(serialized))
  349. copy(ckx.ciphertext[1:], serialized)
  350. return preMasterSecret, ckx, nil
  351. }