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.

crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 lat temu
crypto/tls: decouple handshake signatures from the handshake hash. Prior to TLS 1.2, the handshake had a pleasing property that one could incrementally hash it and, from that, get the needed hashes for both the CertificateVerify and Finished messages. TLS 1.2 introduced negotiation for the signature and hash and it became possible for the handshake hash to be, say, SHA-384, but for the CertificateVerify to sign the handshake with SHA-1. The problem is that one doesn't know in advance which hashes will be needed and thus the handshake needs to be buffered. Go ignored this, always kept a single handshake hash, and any signatures over the handshake had to use that hash. However, there are a set of servers that inspect the client's offered signature hash functions and will abort the handshake if one of the server's certificates is signed with a hash function outside of that set. https://robertsspaceindustries.com/ is an example of such a server. Clearly not a lot of thought happened when that server code was written, but its out there and we have to deal with it. This change decouples the handshake hash from the CertificateVerify hash. This lays the groundwork for advertising support for SHA-384 but doesn't actually make that change in the interests of reviewability. Updating the advertised hash functions will cause changes in many of the testdata/ files and some errors might get lost in the noise. This change only needs to update four testdata/ files: one because a SHA-384-based handshake is now being signed with SHA-256 and the others because the TLS 1.2 CertificateRequest message now includes SHA-1. This change also has the effect of adding support for client-certificates in SSLv3 servers. However, SSLv3 is now disabled by default so this should be moot. It would be possible to avoid much of this change and just support SHA-384 for the ServerKeyExchange as the SKX only signs over the nonces and SKX params (a design mistake in TLS). However, that would leave Go in the odd situation where it advertised support for SHA-384, but would only use the handshake hash when signing client certificates. I fear that'll just cause problems in the future. Much of this code was written by davidben@ for the purposes of testing BoringSSL. Partly addresses #9757 Change-Id: I5137a472b6076812af387a5a69fc62c7373cd485 Reviewed-on: https://go-review.googlesource.com/9415 Run-TryBot: Adam Langley <agl@golang.org> Reviewed-by: Adam Langley <agl@golang.org>
9 lat temu
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  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. }