Alternative TLS implementation in Go
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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