OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package tls | 5 package tls |
6 | 6 |
7 import ( | 7 import ( |
8 "crypto/hmac" | 8 "crypto/hmac" |
9 "crypto/md5" | 9 "crypto/md5" |
10 "crypto/sha1" | 10 "crypto/sha1" |
(...skipping 26 matching lines...) Expand all Loading... |
37 } | 37 } |
38 copy(result[j:j+todo], b) | 38 copy(result[j:j+todo], b) |
39 j += todo | 39 j += todo |
40 | 40 |
41 h.Reset() | 41 h.Reset() |
42 h.Write(a) | 42 h.Write(a) |
43 a = h.Sum() | 43 a = h.Sum() |
44 } | 44 } |
45 } | 45 } |
46 | 46 |
47 // pRF11 implements the TLS 1.1 pseudo-random function, as defined in RFC 4346,
section 5. | 47 // pRF10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246,
section 5. |
48 func pRF11(result, secret, label, seed []byte) { | 48 func pRF10(result, secret, label, seed []byte) { |
49 hashSHA1 := sha1.New | 49 hashSHA1 := sha1.New |
50 hashMD5 := md5.New | 50 hashMD5 := md5.New |
51 | 51 |
52 labelAndSeed := make([]byte, len(label)+len(seed)) | 52 labelAndSeed := make([]byte, len(label)+len(seed)) |
53 copy(labelAndSeed, label) | 53 copy(labelAndSeed, label) |
54 copy(labelAndSeed[len(label):], seed) | 54 copy(labelAndSeed[len(label):], seed) |
55 | 55 |
56 s1, s2 := splitPreMasterSecret(secret) | 56 s1, s2 := splitPreMasterSecret(secret) |
57 pHash(result, s1, labelAndSeed, hashMD5) | 57 pHash(result, s1, labelAndSeed, hashMD5) |
58 result2 := make([]byte, len(result)) | 58 result2 := make([]byte, len(result)) |
59 pHash(result2, s2, labelAndSeed, hashSHA1) | 59 pHash(result2, s2, labelAndSeed, hashSHA1) |
60 | 60 |
61 for i, b := range result2 { | 61 for i, b := range result2 { |
62 result[i] ^= b | 62 result[i] ^= b |
63 } | 63 } |
64 } | 64 } |
65 | 65 |
66 const ( | 66 const ( |
67 tlsRandomLength = 32 // Length of a random nonce in TLS 1.1. | 67 tlsRandomLength = 32 // Length of a random nonce in TLS 1.1. |
68 masterSecretLength = 48 // Length of a master secret in TLS 1.1. | 68 masterSecretLength = 48 // Length of a master secret in TLS 1.1. |
69 finishedVerifyLength = 12 // Length of verify_data in a Finished message
. | 69 finishedVerifyLength = 12 // Length of verify_data in a Finished message
. |
70 ) | 70 ) |
71 | 71 |
72 var masterSecretLabel = []byte("master secret") | 72 var masterSecretLabel = []byte("master secret") |
73 var keyExpansionLabel = []byte("key expansion") | 73 var keyExpansionLabel = []byte("key expansion") |
74 var clientFinishedLabel = []byte("client finished") | 74 var clientFinishedLabel = []byte("client finished") |
75 var serverFinishedLabel = []byte("server finished") | 75 var serverFinishedLabel = []byte("server finished") |
76 | 76 |
77 // keysFromPreMasterSecret generates the connection keys from the pre master | 77 // keysFromPreMasterSecret generates the connection keys from the pre master |
78 // secret, given the lengths of the MAC and cipher keys, as defined in RFC | 78 // secret, given the lengths of the MAC key, cipher key and IV, as defined in |
79 // 4346, section 6.3. | 79 // RFC 2246, section 6.3. |
80 func keysFromPreMasterSecret11(preMasterSecret, clientRandom, serverRandom []byt
e, macLen, keyLen int) (masterSecret, clientMAC, serverMAC, clientKey, serverKey
[]byte) { | 80 func keysFromPreMasterSecret10(preMasterSecret, clientRandom, serverRandom []byt
e, macLen, keyLen, ivLen int) (masterSecret, clientMAC, serverMAC, clientKey, se
rverKey, clientIV, serverIV []byte) { |
81 var seed [tlsRandomLength * 2]byte | 81 var seed [tlsRandomLength * 2]byte |
82 copy(seed[0:len(clientRandom)], clientRandom) | 82 copy(seed[0:len(clientRandom)], clientRandom) |
83 copy(seed[len(clientRandom):], serverRandom) | 83 copy(seed[len(clientRandom):], serverRandom) |
84 masterSecret = make([]byte, masterSecretLength) | 84 masterSecret = make([]byte, masterSecretLength) |
85 » pRF11(masterSecret, preMasterSecret, masterSecretLabel, seed[0:]) | 85 » pRF10(masterSecret, preMasterSecret, masterSecretLabel, seed[0:]) |
86 | 86 |
87 copy(seed[0:len(clientRandom)], serverRandom) | 87 copy(seed[0:len(clientRandom)], serverRandom) |
88 copy(seed[len(serverRandom):], clientRandom) | 88 copy(seed[len(serverRandom):], clientRandom) |
89 | 89 |
90 » n := 2*macLen + 2*keyLen | 90 » n := 2*macLen + 2*keyLen + 2*ivLen |
91 keyMaterial := make([]byte, n) | 91 keyMaterial := make([]byte, n) |
92 » pRF11(keyMaterial, masterSecret, keyExpansionLabel, seed[0:]) | 92 » pRF10(keyMaterial, masterSecret, keyExpansionLabel, seed[0:]) |
93 » clientMAC = keyMaterial[0:macLen] | 93 » clientMAC = keyMaterial[:macLen] |
94 » serverMAC = keyMaterial[macLen : macLen*2] | 94 » keyMaterial = keyMaterial[macLen:] |
95 » clientKey = keyMaterial[macLen*2 : macLen*2+keyLen] | 95 » serverMAC = keyMaterial[:macLen] |
96 » serverKey = keyMaterial[macLen*2+keyLen:] | 96 » keyMaterial = keyMaterial[macLen:] |
| 97 » clientKey = keyMaterial[:keyLen] |
| 98 » keyMaterial = keyMaterial[keyLen:] |
| 99 » serverKey = keyMaterial[:keyLen] |
| 100 » keyMaterial = keyMaterial[keyLen:] |
| 101 » clientIV = keyMaterial[:ivLen] |
| 102 » keyMaterial = keyMaterial[ivLen:] |
| 103 » serverIV = keyMaterial[:ivLen] |
97 return | 104 return |
98 } | 105 } |
99 | 106 |
100 // A finishedHash calculates the hash of a set of handshake messages suitable | 107 // A finishedHash calculates the hash of a set of handshake messages suitable |
101 // for including in a Finished message. | 108 // for including in a Finished message. |
102 type finishedHash struct { | 109 type finishedHash struct { |
103 clientMD5 hash.Hash | 110 clientMD5 hash.Hash |
104 clientSHA1 hash.Hash | 111 clientSHA1 hash.Hash |
105 serverMD5 hash.Hash | 112 serverMD5 hash.Hash |
106 serverSHA1 hash.Hash | 113 serverSHA1 hash.Hash |
(...skipping 11 matching lines...) Expand all Loading... |
118 return len(msg), nil | 125 return len(msg), nil |
119 } | 126 } |
120 | 127 |
121 // finishedSum calculates the contents of the verify_data member of a Finished | 128 // finishedSum calculates the contents of the verify_data member of a Finished |
122 // message given the MD5 and SHA1 hashes of a set of handshake messages. | 129 // message given the MD5 and SHA1 hashes of a set of handshake messages. |
123 func finishedSum(md5, sha1, label, masterSecret []byte) []byte { | 130 func finishedSum(md5, sha1, label, masterSecret []byte) []byte { |
124 seed := make([]byte, len(md5)+len(sha1)) | 131 seed := make([]byte, len(md5)+len(sha1)) |
125 copy(seed, md5) | 132 copy(seed, md5) |
126 copy(seed[len(md5):], sha1) | 133 copy(seed[len(md5):], sha1) |
127 out := make([]byte, finishedVerifyLength) | 134 out := make([]byte, finishedVerifyLength) |
128 » pRF11(out, masterSecret, label, seed) | 135 » pRF10(out, masterSecret, label, seed) |
129 return out | 136 return out |
130 } | 137 } |
131 | 138 |
132 // clientSum returns the contents of the verify_data member of a client's | 139 // clientSum returns the contents of the verify_data member of a client's |
133 // Finished message. | 140 // Finished message. |
134 func (h finishedHash) clientSum(masterSecret []byte) []byte { | 141 func (h finishedHash) clientSum(masterSecret []byte) []byte { |
135 md5 := h.clientMD5.Sum() | 142 md5 := h.clientMD5.Sum() |
136 sha1 := h.clientSHA1.Sum() | 143 sha1 := h.clientSHA1.Sum() |
137 return finishedSum(md5, sha1, clientFinishedLabel, masterSecret) | 144 return finishedSum(md5, sha1, clientFinishedLabel, masterSecret) |
138 } | 145 } |
139 | 146 |
140 // serverSum returns the contents of the verify_data member of a server's | 147 // serverSum returns the contents of the verify_data member of a server's |
141 // Finished message. | 148 // Finished message. |
142 func (h finishedHash) serverSum(masterSecret []byte) []byte { | 149 func (h finishedHash) serverSum(masterSecret []byte) []byte { |
143 md5 := h.serverMD5.Sum() | 150 md5 := h.serverMD5.Sum() |
144 sha1 := h.serverSHA1.Sum() | 151 sha1 := h.serverSHA1.Sum() |
145 return finishedSum(md5, sha1, serverFinishedLabel, masterSecret) | 152 return finishedSum(md5, sha1, serverFinishedLabel, masterSecret) |
146 } | 153 } |
OLD | NEW |