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.
 
 
 
 
 
 

292 rivejä
8.2 KiB

  1. // Copyright 2009 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/hmac"
  8. "crypto/md5"
  9. "crypto/sha1"
  10. "crypto/sha256"
  11. "hash"
  12. )
  13. // Split a premaster secret in two as specified in RFC 4346, section 5.
  14. func splitPreMasterSecret(secret []byte) (s1, s2 []byte) {
  15. s1 = secret[0 : (len(secret)+1)/2]
  16. s2 = secret[len(secret)/2:]
  17. return
  18. }
  19. // pHash implements the P_hash function, as defined in RFC 4346, section 5.
  20. func pHash(result, secret, seed []byte, hash func() hash.Hash) {
  21. h := hmac.New(hash, secret)
  22. h.Write(seed)
  23. a := h.Sum(nil)
  24. j := 0
  25. for j < len(result) {
  26. h.Reset()
  27. h.Write(a)
  28. h.Write(seed)
  29. b := h.Sum(nil)
  30. todo := len(b)
  31. if j+todo > len(result) {
  32. todo = len(result) - j
  33. }
  34. copy(result[j:j+todo], b)
  35. j += todo
  36. h.Reset()
  37. h.Write(a)
  38. a = h.Sum(nil)
  39. }
  40. }
  41. // prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, section 5.
  42. func prf10(result, secret, label, seed []byte) {
  43. hashSHA1 := sha1.New
  44. hashMD5 := md5.New
  45. labelAndSeed := make([]byte, len(label)+len(seed))
  46. copy(labelAndSeed, label)
  47. copy(labelAndSeed[len(label):], seed)
  48. s1, s2 := splitPreMasterSecret(secret)
  49. pHash(result, s1, labelAndSeed, hashMD5)
  50. result2 := make([]byte, len(result))
  51. pHash(result2, s2, labelAndSeed, hashSHA1)
  52. for i, b := range result2 {
  53. result[i] ^= b
  54. }
  55. }
  56. // prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, section 5.
  57. func prf12(result, secret, label, seed []byte) {
  58. labelAndSeed := make([]byte, len(label)+len(seed))
  59. copy(labelAndSeed, label)
  60. copy(labelAndSeed[len(label):], seed)
  61. pHash(result, secret, labelAndSeed, sha256.New)
  62. }
  63. // prf30 implements the SSL 3.0 pseudo-random function, as defined in
  64. // www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 6.
  65. func prf30(result, secret, label, seed []byte) {
  66. hashSHA1 := sha1.New()
  67. hashMD5 := md5.New()
  68. done := 0
  69. i := 0
  70. // RFC5246 section 6.3 says that the largest PRF output needed is 128
  71. // bytes. Since no more ciphersuites will be added to SSLv3, this will
  72. // remain true. Each iteration gives us 16 bytes so 10 iterations will
  73. // be sufficient.
  74. var b [11]byte
  75. for done < len(result) {
  76. for j := 0; j <= i; j++ {
  77. b[j] = 'A' + byte(i)
  78. }
  79. hashSHA1.Reset()
  80. hashSHA1.Write(b[:i+1])
  81. hashSHA1.Write(secret)
  82. hashSHA1.Write(seed)
  83. digest := hashSHA1.Sum(nil)
  84. hashMD5.Reset()
  85. hashMD5.Write(secret)
  86. hashMD5.Write(digest)
  87. done += copy(result[done:], hashMD5.Sum(nil))
  88. i++
  89. }
  90. }
  91. const (
  92. tlsRandomLength = 32 // Length of a random nonce in TLS 1.1.
  93. masterSecretLength = 48 // Length of a master secret in TLS 1.1.
  94. finishedVerifyLength = 12 // Length of verify_data in a Finished message.
  95. )
  96. var masterSecretLabel = []byte("master secret")
  97. var keyExpansionLabel = []byte("key expansion")
  98. var clientFinishedLabel = []byte("client finished")
  99. var serverFinishedLabel = []byte("server finished")
  100. func prfForVersion(version uint16) func(result, secret, label, seed []byte) {
  101. switch version {
  102. case VersionSSL30:
  103. return prf30
  104. case VersionTLS10, VersionTLS11:
  105. return prf10
  106. case VersionTLS12:
  107. return prf12
  108. default:
  109. panic("unknown version")
  110. }
  111. }
  112. // masterFromPreMasterSecret generates the master secret from the pre-master
  113. // secret. See http://tools.ietf.org/html/rfc5246#section-8.1
  114. func masterFromPreMasterSecret(version uint16, preMasterSecret, clientRandom, serverRandom []byte) []byte {
  115. var seed [tlsRandomLength * 2]byte
  116. copy(seed[0:len(clientRandom)], clientRandom)
  117. copy(seed[len(clientRandom):], serverRandom)
  118. masterSecret := make([]byte, masterSecretLength)
  119. prfForVersion(version)(masterSecret, preMasterSecret, masterSecretLabel, seed[0:])
  120. return masterSecret
  121. }
  122. // keysFromMasterSecret generates the connection keys from the master
  123. // secret, given the lengths of the MAC key, cipher key and IV, as defined in
  124. // RFC 2246, section 6.3.
  125. func keysFromMasterSecret(version uint16, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {
  126. var seed [tlsRandomLength * 2]byte
  127. copy(seed[0:len(clientRandom)], serverRandom)
  128. copy(seed[len(serverRandom):], clientRandom)
  129. n := 2*macLen + 2*keyLen + 2*ivLen
  130. keyMaterial := make([]byte, n)
  131. prfForVersion(version)(keyMaterial, masterSecret, keyExpansionLabel, seed[0:])
  132. clientMAC = keyMaterial[:macLen]
  133. keyMaterial = keyMaterial[macLen:]
  134. serverMAC = keyMaterial[:macLen]
  135. keyMaterial = keyMaterial[macLen:]
  136. clientKey = keyMaterial[:keyLen]
  137. keyMaterial = keyMaterial[keyLen:]
  138. serverKey = keyMaterial[:keyLen]
  139. keyMaterial = keyMaterial[keyLen:]
  140. clientIV = keyMaterial[:ivLen]
  141. keyMaterial = keyMaterial[ivLen:]
  142. serverIV = keyMaterial[:ivLen]
  143. return
  144. }
  145. func newFinishedHash(version uint16) finishedHash {
  146. if version >= VersionTLS12 {
  147. return finishedHash{sha256.New(), sha256.New(), nil, nil, version}
  148. }
  149. return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), version}
  150. }
  151. // A finishedHash calculates the hash of a set of handshake messages suitable
  152. // for including in a Finished message.
  153. type finishedHash struct {
  154. client hash.Hash
  155. server hash.Hash
  156. // Prior to TLS 1.2, an additional MD5 hash is required.
  157. clientMD5 hash.Hash
  158. serverMD5 hash.Hash
  159. version uint16
  160. }
  161. func (h finishedHash) Write(msg []byte) (n int, err error) {
  162. h.client.Write(msg)
  163. h.server.Write(msg)
  164. if h.version < VersionTLS12 {
  165. h.clientMD5.Write(msg)
  166. h.serverMD5.Write(msg)
  167. }
  168. return len(msg), nil
  169. }
  170. // finishedSum30 calculates the contents of the verify_data member of a SSLv3
  171. // Finished message given the MD5 and SHA1 hashes of a set of handshake
  172. // messages.
  173. func finishedSum30(md5, sha1 hash.Hash, masterSecret []byte, magic [4]byte) []byte {
  174. md5.Write(magic[:])
  175. md5.Write(masterSecret)
  176. md5.Write(ssl30Pad1[:])
  177. md5Digest := md5.Sum(nil)
  178. md5.Reset()
  179. md5.Write(masterSecret)
  180. md5.Write(ssl30Pad2[:])
  181. md5.Write(md5Digest)
  182. md5Digest = md5.Sum(nil)
  183. sha1.Write(magic[:])
  184. sha1.Write(masterSecret)
  185. sha1.Write(ssl30Pad1[:40])
  186. sha1Digest := sha1.Sum(nil)
  187. sha1.Reset()
  188. sha1.Write(masterSecret)
  189. sha1.Write(ssl30Pad2[:40])
  190. sha1.Write(sha1Digest)
  191. sha1Digest = sha1.Sum(nil)
  192. ret := make([]byte, len(md5Digest)+len(sha1Digest))
  193. copy(ret, md5Digest)
  194. copy(ret[len(md5Digest):], sha1Digest)
  195. return ret
  196. }
  197. var ssl3ClientFinishedMagic = [4]byte{0x43, 0x4c, 0x4e, 0x54}
  198. var ssl3ServerFinishedMagic = [4]byte{0x53, 0x52, 0x56, 0x52}
  199. // clientSum returns the contents of the verify_data member of a client's
  200. // Finished message.
  201. func (h finishedHash) clientSum(masterSecret []byte) []byte {
  202. if h.version == VersionSSL30 {
  203. return finishedSum30(h.clientMD5, h.client, masterSecret, ssl3ClientFinishedMagic)
  204. }
  205. out := make([]byte, finishedVerifyLength)
  206. if h.version >= VersionTLS12 {
  207. seed := h.client.Sum(nil)
  208. prf12(out, masterSecret, clientFinishedLabel, seed)
  209. } else {
  210. seed := make([]byte, 0, md5.Size+sha1.Size)
  211. seed = h.clientMD5.Sum(seed)
  212. seed = h.client.Sum(seed)
  213. prf10(out, masterSecret, clientFinishedLabel, seed)
  214. }
  215. return out
  216. }
  217. // serverSum returns the contents of the verify_data member of a server's
  218. // Finished message.
  219. func (h finishedHash) serverSum(masterSecret []byte) []byte {
  220. if h.version == VersionSSL30 {
  221. return finishedSum30(h.serverMD5, h.server, masterSecret, ssl3ServerFinishedMagic)
  222. }
  223. out := make([]byte, finishedVerifyLength)
  224. if h.version >= VersionTLS12 {
  225. seed := h.server.Sum(nil)
  226. prf12(out, masterSecret, serverFinishedLabel, seed)
  227. } else {
  228. seed := make([]byte, 0, md5.Size+sha1.Size)
  229. seed = h.serverMD5.Sum(seed)
  230. seed = h.server.Sum(seed)
  231. prf10(out, masterSecret, serverFinishedLabel, seed)
  232. }
  233. return out
  234. }
  235. // hashForClientCertificate returns a digest, hash function, and TLS 1.2 hash
  236. // id suitable for signing by a TLS client certificate.
  237. func (h finishedHash) hashForClientCertificate(sigType uint8) ([]byte, crypto.Hash, uint8) {
  238. if h.version >= VersionTLS12 {
  239. digest := h.server.Sum(nil)
  240. return digest, crypto.SHA256, hashSHA256
  241. }
  242. if sigType == signatureECDSA {
  243. digest := h.server.Sum(nil)
  244. return digest, crypto.SHA1, hashSHA1
  245. }
  246. digest := make([]byte, 0, 36)
  247. digest = h.serverMD5.Sum(digest)
  248. digest = h.server.Sum(digest)
  249. return digest, crypto.MD5SHA1, 0 /* not specified in TLS 1.2. */
  250. }