Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

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