OLD | NEW |
1 /* | 1 /* |
2 * Key Derivation that doesn't use PKCS11 | 2 * Key Derivation that doesn't use PKCS11 |
3 * | 3 * |
4 * This Source Code Form is subject to the terms of the Mozilla Public | 4 * This Source Code Form is subject to the terms of the Mozilla Public |
5 * License, v. 2.0. If a copy of the MPL was not distributed with this | 5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
7 | 7 |
8 #include "ssl.h" » /* prereq to sslimpl.h */ | 8 #include "ssl.h" /* prereq to sslimpl.h */ |
9 #include "certt.h"» /* prereq to sslimpl.h */ | 9 #include "certt.h" /* prereq to sslimpl.h */ |
10 #include "keythi.h"» /* prereq to sslimpl.h */ | 10 #include "keythi.h" /* prereq to sslimpl.h */ |
11 #include "sslimpl.h" | 11 #include "sslimpl.h" |
12 #ifndef NO_PKCS11_BYPASS | 12 #ifndef NO_PKCS11_BYPASS |
13 #include "blapi.h" | 13 #include "blapi.h" |
14 #endif | 14 #endif |
15 | 15 |
16 #include "keyhi.h" | 16 #include "keyhi.h" |
17 #include "pk11func.h" | 17 #include "pk11func.h" |
18 #include "secasn1.h" | 18 #include "secasn1.h" |
19 #include "cert.h" | 19 #include "cert.h" |
20 #include "secmodt.h" | 20 #include "secmodt.h" |
21 | 21 |
22 #include "sslproto.h" | 22 #include "sslproto.h" |
23 #include "sslerr.h" | 23 #include "sslerr.h" |
24 | 24 |
25 #ifndef NO_PKCS11_BYPASS | 25 #ifndef NO_PKCS11_BYPASS |
26 /* make this a macro! */ | 26 /* make this a macro! */ |
27 #ifdef NOT_A_MACRO | 27 #ifdef NOT_A_MACRO |
28 static void | 28 static void |
29 buildSSLKey(unsigned char * keyBlock, unsigned int keyLen, SECItem * result, | 29 buildSSLKey(unsigned char *keyBlock, unsigned int keyLen, SECItem *result, |
30 const char * label) | 30 const char *label) |
31 { | 31 { |
32 result->type = siBuffer; | 32 result->type = siBuffer; |
33 result->data = keyBlock; | 33 result->data = keyBlock; |
34 result->len = keyLen; | 34 result->len = keyLen; |
35 PRINT_BUF(100, (NULL, label, keyBlock, keyLen)); | 35 PRINT_BUF(100, (NULL, label, keyBlock, keyLen)); |
36 } | 36 } |
37 #else | 37 #else |
38 #define buildSSLKey(keyBlock, keyLen, result, label) \ | 38 #define buildSSLKey(keyBlock, keyLen, result, label) \ |
39 { \ | 39 { \ |
40 (result)->type = siBuffer; \ | 40 (result)->type = siBuffer; \ |
41 (result)->data = keyBlock; \ | 41 (result)->data = keyBlock; \ |
42 (result)->len = keyLen; \ | 42 (result)->len = keyLen; \ |
43 PRINT_BUF(100, (NULL, label, keyBlock, keyLen)); \ | 43 PRINT_BUF(100, (NULL, label, keyBlock, keyLen)); \ |
44 } | 44 } |
45 #endif | 45 #endif |
46 | 46 |
47 /* | 47 /* |
48 * SSL Key generation given pre master secret | 48 * SSL Key generation given pre master secret |
49 */ | 49 */ |
50 #ifndef NUM_MIXERS | 50 #ifndef NUM_MIXERS |
51 #define NUM_MIXERS 9 | 51 #define NUM_MIXERS 9 |
52 #endif | 52 #endif |
53 static const char * const mixers[NUM_MIXERS] = { | 53 static const char *const mixers[NUM_MIXERS] = { |
54 "A", | 54 "A", |
55 "BB", | 55 "BB", |
56 "CCC", | 56 "CCC", |
57 "DDDD", | 57 "DDDD", |
58 "EEEEE", | 58 "EEEEE", |
59 "FFFFFF", | 59 "FFFFFF", |
60 "GGGGGGG", | 60 "GGGGGGG", |
61 "HHHHHHHH", | 61 "HHHHHHHH", |
62 "IIIIIIIII" | 62 "IIIIIIIII" |
63 }; | 63 }; |
64 | 64 |
65 | |
66 SECStatus | 65 SECStatus |
67 ssl3_KeyAndMacDeriveBypass( | 66 ssl3_KeyAndMacDeriveBypass( |
68 ssl3CipherSpec * pwSpec, | 67 ssl3CipherSpec *pwSpec, |
69 const unsigned char * cr, | 68 const unsigned char *cr, |
70 const unsigned char * sr, | 69 const unsigned char *sr, |
71 PRBool isTLS, | 70 PRBool isTLS, |
72 PRBool isExport) | 71 PRBool isExport) |
73 { | 72 { |
74 const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def; | 73 const ssl3BulkCipherDef *cipher_def = pwSpec->cipher_def; |
75 unsigned char * key_block = pwSpec->key_block; | 74 unsigned char *key_block = pwSpec->key_block; |
76 unsigned char * key_block2 = NULL; | 75 unsigned char *key_block2 = NULL; |
77 unsigned int block_bytes = 0; | 76 unsigned int block_bytes = 0; |
78 unsigned int block_needed = 0; | 77 unsigned int block_needed = 0; |
79 unsigned int i; | 78 unsigned int i; |
80 unsigned int keySize; /* actual size of cipher keys */ | 79 unsigned int keySize; /* actual size of cipher keys */ |
81 unsigned int effKeySize;»» /* effective size of cipher keys */ | 80 unsigned int effKeySize; /* effective size of cipher keys */ |
82 unsigned int macSize;» » /* size of MAC secret */ | 81 unsigned int macSize; /* size of MAC secret */ |
83 unsigned int IVSize;» » /* size of IV */ | 82 unsigned int IVSize; /* size of IV */ |
84 PRBool explicitIV = PR_FALSE; | 83 PRBool explicitIV = PR_FALSE; |
85 SECStatus rv = SECFailure; | 84 SECStatus rv = SECFailure; |
86 SECStatus status = SECSuccess; | 85 SECStatus status = SECSuccess; |
87 PRBool isFIPS = PR_FALSE; | 86 PRBool isFIPS = PR_FALSE; |
88 PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2; | 87 PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2; |
89 | 88 |
90 SECItem srcr; | 89 SECItem srcr; |
91 SECItem crsr; | 90 SECItem crsr; |
92 | 91 |
93 unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; | 92 unsigned char srcrdata[SSL3_RANDOM_LENGTH * 2]; |
94 unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; | 93 unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; |
95 PRUint64 md5buf[22]; | 94 PRUint64 md5buf[22]; |
96 PRUint64 shabuf[40]; | 95 PRUint64 shabuf[40]; |
97 | 96 |
98 #define md5Ctx ((MD5Context *)md5buf) | 97 #define md5Ctx ((MD5Context *)md5buf) |
99 #define shaCtx ((SHA1Context *)shabuf) | 98 #define shaCtx ((SHA1Context *)shabuf) |
100 | 99 |
101 static const SECItem zed = { siBuffer, NULL, 0 }; | 100 static const SECItem zed = { siBuffer, NULL, 0 }; |
102 | 101 |
103 if (pwSpec->msItem.data == NULL || | 102 if (pwSpec->msItem.data == NULL || |
104 pwSpec->msItem.len != SSL3_MASTER_SECRET_LENGTH) { | 103 pwSpec->msItem.len != SSL3_MASTER_SECRET_LENGTH) { |
105 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 104 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
106 » return rv; | 105 return rv; |
107 } | 106 } |
108 | 107 |
109 PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, | 108 PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, |
110 pwSpec->msItem.len)); | 109 pwSpec->msItem.len)); |
111 | 110 |
112 /* figure out how much is needed */ | 111 /* figure out how much is needed */ |
113 macSize = pwSpec->mac_size; | 112 macSize = pwSpec->mac_size; |
114 keySize = cipher_def->key_size; | 113 keySize = cipher_def->key_size; |
115 effKeySize = cipher_def->secret_key_size; | 114 effKeySize = cipher_def->secret_key_size; |
116 IVSize = cipher_def->iv_size; | 115 IVSize = cipher_def->iv_size; |
117 if (keySize == 0) { | 116 if (keySize == 0) { |
118 » effKeySize = IVSize = 0; /* only MACing */ | 117 effKeySize = IVSize = 0; /* only MACing */ |
119 } | 118 } |
120 if (cipher_def->type == type_block && | 119 if (cipher_def->type == type_block && |
121 » pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { | 120 pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { |
122 » /* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */ | 121 /* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */ |
123 » explicitIV = PR_TRUE; | 122 explicitIV = PR_TRUE; |
124 } | 123 } |
125 block_needed = | 124 block_needed = |
126 » 2 * (macSize + effKeySize + ((!isExport && !explicitIV) * IVSize)); | 125 2 * (macSize + effKeySize + ((!isExport && !explicitIV) * IVSize)); |
127 | 126 |
128 /* | 127 /* |
129 * clear out our returned keys so we can recover on failure | 128 * clear out our returned keys so we can recover on failure |
130 */ | 129 */ |
131 pwSpec->client.write_key_item = zed; | 130 pwSpec->client.write_key_item = zed; |
132 pwSpec->client.write_mac_key_item = zed; | 131 pwSpec->client.write_mac_key_item = zed; |
133 pwSpec->server.write_key_item = zed; | 132 pwSpec->server.write_key_item = zed; |
134 pwSpec->server.write_mac_key_item = zed; | 133 pwSpec->server.write_mac_key_item = zed; |
135 | 134 |
136 /* initialize the server random, client random block */ | 135 /* initialize the server random, client random block */ |
137 srcr.type = siBuffer; | 136 srcr.type = siBuffer; |
138 srcr.data = srcrdata; | 137 srcr.data = srcrdata; |
139 srcr.len = sizeof srcrdata; | 138 srcr.len = sizeof srcrdata; |
140 PORT_Memcpy(srcrdata, sr, SSL3_RANDOM_LENGTH); | 139 PORT_Memcpy(srcrdata, sr, SSL3_RANDOM_LENGTH); |
141 PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, cr, SSL3_RANDOM_LENGTH); | 140 PORT_Memcpy(srcrdata + SSL3_RANDOM_LENGTH, cr, SSL3_RANDOM_LENGTH); |
142 | 141 |
143 /* initialize the client random, server random block */ | 142 /* initialize the client random, server random block */ |
144 crsr.type = siBuffer; | 143 crsr.type = siBuffer; |
145 crsr.data = crsrdata; | 144 crsr.data = crsrdata; |
146 crsr.len = sizeof crsrdata; | 145 crsr.len = sizeof crsrdata; |
147 PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH); | 146 PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH); |
148 PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); | 147 PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); |
149 PRINT_BUF(100, (NULL, "Key & MAC CRSR", crsr.data, crsr.len)); | 148 PRINT_BUF(100, (NULL, "Key & MAC CRSR", crsr.data, crsr.len)); |
150 | 149 |
151 /* | 150 /* |
152 * generate the key material: | 151 * generate the key material: |
153 */ | 152 */ |
154 if (isTLS) { | 153 if (isTLS) { |
155 » SECItem keyblk; | 154 SECItem keyblk; |
156 | 155 |
157 » keyblk.type = siBuffer; | 156 keyblk.type = siBuffer; |
158 » keyblk.data = key_block; | 157 keyblk.data = key_block; |
159 » keyblk.len = block_needed; | 158 keyblk.len = block_needed; |
160 | 159 |
161 » if (isTLS12) { | 160 if (isTLS12) { |
162 » status = TLS_P_hash(HASH_AlgSHA256, &pwSpec->msItem, | 161 status = TLS_P_hash(HASH_AlgSHA256, &pwSpec->msItem, |
163 » » » » "key expansion", &srcr, &keyblk, isFIPS); | 162 "key expansion", &srcr, &keyblk, isFIPS); |
164 » } else { | 163 } else { |
165 » status = TLS_PRF(&pwSpec->msItem, "key expansion", &srcr, &keyblk, | 164 status = TLS_PRF(&pwSpec->msItem, "key expansion", &srcr, &keyblk, |
166 » » » isFIPS); | 165 isFIPS); |
167 » } | 166 } |
168 » if (status != SECSuccess) { | 167 if (status != SECSuccess) { |
169 » goto key_and_mac_derive_fail; | 168 goto key_and_mac_derive_fail; |
170 » } | 169 } |
171 » block_bytes = keyblk.len; | 170 block_bytes = keyblk.len; |
172 } else { | 171 } else { |
173 » /* key_block = | 172 /* key_block = |
174 » * MD5(master_secret + SHA('A' + master_secret + | 173 * MD5(master_secret + SHA('A' + master_secret + |
175 » * ServerHello.random + ClientHello.random)) + | 174 * ServerHello.random + ClientHello.random)) + |
176 » * MD5(master_secret + SHA('BB' + master_secret + | 175 * MD5(master_secret + SHA('BB' + master_secret + |
177 » * ServerHello.random + ClientHello.random)) + | 176 * ServerHello.random + ClientHello.random)) + |
178 » * MD5(master_secret + SHA('CCC' + master_secret + | 177 * MD5(master_secret + SHA('CCC' + master_secret + |
179 » * ServerHello.random + ClientHello.random)) + | 178 * ServerHello.random + ClientHello.random)) + |
180 » * [...]; | 179 * [...]; |
181 » */ | 180 */ |
182 » unsigned int made = 0; | 181 unsigned int made = 0; |
183 » for (i = 0; made < block_needed && i < NUM_MIXERS; ++i) { | 182 for (i = 0; made < block_needed && i < NUM_MIXERS; ++i) { |
184 » unsigned int outLen; | 183 unsigned int outLen; |
185 » unsigned char sha_out[SHA1_LENGTH]; | 184 unsigned char sha_out[SHA1_LENGTH]; |
186 | 185 |
187 » SHA1_Begin(shaCtx); | 186 SHA1_Begin(shaCtx); |
188 » SHA1_Update(shaCtx, (unsigned char*)(mixers[i]), i+1); | 187 SHA1_Update(shaCtx, (unsigned char *)(mixers[i]), i + 1); |
189 » SHA1_Update(shaCtx, pwSpec->msItem.data, pwSpec->msItem.len); | 188 SHA1_Update(shaCtx, pwSpec->msItem.data, pwSpec->msItem.len); |
190 » SHA1_Update(shaCtx, srcr.data, srcr.len); | 189 SHA1_Update(shaCtx, srcr.data, srcr.len); |
191 » SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH); | 190 SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH); |
192 » PORT_Assert(outLen == SHA1_LENGTH); | 191 PORT_Assert(outLen == SHA1_LENGTH); |
193 | 192 |
194 » MD5_Begin(md5Ctx); | 193 MD5_Begin(md5Ctx); |
195 » MD5_Update(md5Ctx, pwSpec->msItem.data, pwSpec->msItem.len); | 194 MD5_Update(md5Ctx, pwSpec->msItem.data, pwSpec->msItem.len); |
196 » MD5_Update(md5Ctx, sha_out, outLen); | 195 MD5_Update(md5Ctx, sha_out, outLen); |
197 » MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH); | 196 MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH); |
198 » PORT_Assert(outLen == MD5_LENGTH); | 197 PORT_Assert(outLen == MD5_LENGTH); |
199 » made += MD5_LENGTH; | 198 made += MD5_LENGTH; |
200 » } | 199 } |
201 » block_bytes = made; | 200 block_bytes = made; |
202 } | 201 } |
203 PORT_Assert(block_bytes >= block_needed); | 202 PORT_Assert(block_bytes >= block_needed); |
204 PORT_Assert(block_bytes <= sizeof pwSpec->key_block); | 203 PORT_Assert(block_bytes <= sizeof pwSpec->key_block); |
205 PRINT_BUF(100, (NULL, "key block", key_block, block_bytes)); | 204 PRINT_BUF(100, (NULL, "key block", key_block, block_bytes)); |
206 | 205 |
207 /* | 206 /* |
208 * Put the key material where it goes. | 207 * Put the key material where it goes. |
209 */ | 208 */ |
210 key_block2 = key_block + block_bytes; | 209 key_block2 = key_block + block_bytes; |
211 i = 0;» » » /* now shows how much consumed */ | 210 i = 0; /* now shows how much consumed */ |
212 | 211 |
213 /* | 212 /* |
214 * The key_block is partitioned as follows: | 213 * The key_block is partitioned as follows: |
215 * client_write_MAC_secret[CipherSpec.hash_size] | 214 * client_write_MAC_secret[CipherSpec.hash_size] |
216 */ | 215 */ |
217 buildSSLKey(&key_block[i],macSize, &pwSpec->client.write_mac_key_item, \ | 216 buildSSLKey(&key_block[i], macSize, &pwSpec->client.write_mac_key_item, |
218 "Client Write MAC Secret"); | 217 "Client Write MAC Secret"); |
219 i += macSize; | 218 i += macSize; |
220 | 219 |
221 /* | 220 /* |
222 * server_write_MAC_secret[CipherSpec.hash_size] | 221 * server_write_MAC_secret[CipherSpec.hash_size] |
223 */ | 222 */ |
224 buildSSLKey(&key_block[i],macSize, &pwSpec->server.write_mac_key_item, \ | 223 buildSSLKey(&key_block[i], macSize, &pwSpec->server.write_mac_key_item, |
225 "Server Write MAC Secret"); | 224 "Server Write MAC Secret"); |
226 i += macSize; | 225 i += macSize; |
227 | 226 |
228 if (!keySize) { | 227 if (!keySize) { |
229 » /* only MACing */ | 228 /* only MACing */ |
230 » buildSSLKey(NULL, 0, &pwSpec->client.write_key_item, \ | 229 buildSSLKey(NULL, 0, &pwSpec->client.write_key_item, |
231 » "Client Write Key (MAC only)"); | 230 "Client Write Key (MAC only)"); |
232 » buildSSLKey(NULL, 0, &pwSpec->server.write_key_item, \ | 231 buildSSLKey(NULL, 0, &pwSpec->server.write_key_item, |
233 » "Server Write Key (MAC only)"); | 232 "Server Write Key (MAC only)"); |
234 » buildSSLKey(NULL, 0, &pwSpec->client.write_iv_item, \ | 233 buildSSLKey(NULL, 0, &pwSpec->client.write_iv_item, |
235 » "Client Write IV (MAC only)"); | 234 "Client Write IV (MAC only)"); |
236 » buildSSLKey(NULL, 0, &pwSpec->server.write_iv_item, \ | 235 buildSSLKey(NULL, 0, &pwSpec->server.write_iv_item, |
237 » "Server Write IV (MAC only)"); | 236 "Server Write IV (MAC only)"); |
238 } else if (!isExport) { | 237 } else if (!isExport) { |
239 » /* | 238 /* |
240 » ** Generate Domestic write keys and IVs. | 239 ** Generate Domestic write keys and IVs. |
241 » ** client_write_key[CipherSpec.key_material] | 240 ** client_write_key[CipherSpec.key_material] |
242 » */ | 241 */ |
243 » buildSSLKey(&key_block[i], keySize, &pwSpec->client.write_key_item, \ | 242 buildSSLKey(&key_block[i], keySize, &pwSpec->client.write_key_item, |
244 » "Domestic Client Write Key"); | 243 "Domestic Client Write Key"); |
245 » i += keySize; | 244 i += keySize; |
246 | 245 |
247 » /* | 246 /* |
248 » ** server_write_key[CipherSpec.key_material] | 247 ** server_write_key[CipherSpec.key_material] |
249 » */ | 248 */ |
250 » buildSSLKey(&key_block[i], keySize, &pwSpec->server.write_key_item, \ | 249 buildSSLKey(&key_block[i], keySize, &pwSpec->server.write_key_item, |
251 » "Domestic Server Write Key"); | 250 "Domestic Server Write Key"); |
252 » i += keySize; | 251 i += keySize; |
253 | 252 |
254 » if (IVSize > 0) { | 253 if (IVSize > 0) { |
255 » if (explicitIV) { | 254 if (explicitIV) { |
256 » » static unsigned char zero_block[32]; | 255 static unsigned char zero_block[32]; |
257 » » PORT_Assert(IVSize <= sizeof zero_block); | 256 PORT_Assert(IVSize <= sizeof zero_block); |
258 » » buildSSLKey(&zero_block[0], IVSize, \ | 257 buildSSLKey(&zero_block[0], IVSize, |
259 » » » &pwSpec->client.write_iv_item, \ | 258 &pwSpec->client.write_iv_item, |
260 » » » "Domestic Client Write IV"); | 259 "Domestic Client Write IV"); |
261 » » buildSSLKey(&zero_block[0], IVSize, \ | 260 buildSSLKey(&zero_block[0], IVSize, |
262 » » » &pwSpec->server.write_iv_item, \ | 261 &pwSpec->server.write_iv_item, |
263 » » » "Domestic Server Write IV"); | 262 "Domestic Server Write IV"); |
264 » } else { | 263 } else { |
265 » » /* | 264 /* |
266 » » ** client_write_IV[CipherSpec.IV_size] | 265 ** client_write_IV[CipherSpec.IV_size] |
267 » » */ | 266 */ |
268 » » buildSSLKey(&key_block[i], IVSize, \ | 267 buildSSLKey(&key_block[i], IVSize, |
269 » » » &pwSpec->client.write_iv_item, \ | 268 &pwSpec->client.write_iv_item, |
270 » » » "Domestic Client Write IV"); | 269 "Domestic Client Write IV"); |
271 » » i += IVSize; | 270 i += IVSize; |
272 | 271 |
273 » » /* | 272 /* |
274 » » ** server_write_IV[CipherSpec.IV_size] | 273 ** server_write_IV[CipherSpec.IV_size] |
275 » » */ | 274 */ |
276 » » buildSSLKey(&key_block[i], IVSize, \ | 275 buildSSLKey(&key_block[i], IVSize, |
277 » » » &pwSpec->server.write_iv_item, \ | 276 &pwSpec->server.write_iv_item, |
278 » » » "Domestic Server Write IV"); | 277 "Domestic Server Write IV"); |
279 » » i += IVSize; | 278 i += IVSize; |
280 » } | 279 } |
281 » } | 280 } |
282 » PORT_Assert(i <= block_bytes); | 281 PORT_Assert(i <= block_bytes); |
283 } else if (!isTLS) { | 282 } else if (!isTLS) { |
284 » /* | 283 /* |
285 » ** Generate SSL3 Export write keys and IVs. | 284 ** Generate SSL3 Export write keys and IVs. |
286 » */ | 285 */ |
287 » unsigned int outLen; | 286 unsigned int outLen; |
288 | 287 |
289 » /* | 288 /* |
290 » ** client_write_key[CipherSpec.key_material] | 289 ** client_write_key[CipherSpec.key_material] |
291 » ** final_client_write_key = MD5(client_write_key + | 290 ** final_client_write_key = MD5(client_write_key + |
292 » ** ClientHello.random + ServerHello.random); | 291 ** ClientHello.random + ServerHello.random); |
293 » */ | 292 */ |
294 » MD5_Begin(md5Ctx); | 293 MD5_Begin(md5Ctx); |
295 » MD5_Update(md5Ctx, &key_block[i], effKeySize); | 294 MD5_Update(md5Ctx, &key_block[i], effKeySize); |
296 » MD5_Update(md5Ctx, crsr.data, crsr.len); | 295 MD5_Update(md5Ctx, crsr.data, crsr.len); |
297 » MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); | 296 MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); |
298 » i += effKeySize; | 297 i += effKeySize; |
299 » buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item, \ | 298 buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item, |
300 » "SSL3 Export Client Write Key"); | 299 "SSL3 Export Client Write Key"); |
301 » key_block2 += keySize; | 300 key_block2 += keySize; |
302 | 301 |
303 » /* | 302 /* |
304 » ** server_write_key[CipherSpec.key_material] | 303 ** server_write_key[CipherSpec.key_material] |
305 » ** final_server_write_key = MD5(server_write_key + | 304 ** final_server_write_key = MD5(server_write_key + |
306 » ** ServerHello.random + ClientHello.random); | 305 ** ServerHello.random + ClientHello.random); |
307 » */ | 306 */ |
308 » MD5_Begin(md5Ctx); | 307 MD5_Begin(md5Ctx); |
309 » MD5_Update(md5Ctx, &key_block[i], effKeySize); | 308 MD5_Update(md5Ctx, &key_block[i], effKeySize); |
310 » MD5_Update(md5Ctx, srcr.data, srcr.len); | 309 MD5_Update(md5Ctx, srcr.data, srcr.len); |
311 » MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); | 310 MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); |
312 » i += effKeySize; | 311 i += effKeySize; |
313 » buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item, \ | 312 buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item, |
314 » "SSL3 Export Server Write Key"); | 313 "SSL3 Export Server Write Key"); |
315 » key_block2 += keySize; | 314 key_block2 += keySize; |
316 » PORT_Assert(i <= block_bytes); | 315 PORT_Assert(i <= block_bytes); |
317 | 316 |
318 » if (IVSize) { | 317 if (IVSize) { |
319 » /* | 318 /* |
320 » ** client_write_IV = | 319 ** client_write_IV = |
321 » **» MD5(ClientHello.random + ServerHello.random); | 320 ** MD5(ClientHello.random + ServerHello.random); |
322 » */ | 321 */ |
323 » MD5_Begin(md5Ctx); | 322 MD5_Begin(md5Ctx); |
324 » MD5_Update(md5Ctx, crsr.data, crsr.len); | 323 MD5_Update(md5Ctx, crsr.data, crsr.len); |
325 » MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); | 324 MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); |
326 » buildSSLKey(key_block2, IVSize, &pwSpec->client.write_iv_item, \ | 325 buildSSLKey(key_block2, IVSize, &pwSpec->client.write_iv_item, |
327 » "SSL3 Export Client Write IV"); | 326 "SSL3 Export Client Write IV"); |
328 » key_block2 += IVSize; | 327 key_block2 += IVSize; |
329 | 328 |
330 » /* | 329 /* |
331 » ** server_write_IV = | 330 ** server_write_IV = |
332 » **» MD5(ServerHello.random + ClientHello.random); | 331 ** MD5(ServerHello.random + ClientHello.random); |
333 » */ | 332 */ |
334 » MD5_Begin(md5Ctx); | 333 MD5_Begin(md5Ctx); |
335 » MD5_Update(md5Ctx, srcr.data, srcr.len); | 334 MD5_Update(md5Ctx, srcr.data, srcr.len); |
336 » MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); | 335 MD5_End(md5Ctx, key_block2, &outLen, MD5_LENGTH); |
337 » buildSSLKey(key_block2, IVSize, &pwSpec->server.write_iv_item, \ | 336 buildSSLKey(key_block2, IVSize, &pwSpec->server.write_iv_item, |
338 » "SSL3 Export Server Write IV"); | 337 "SSL3 Export Server Write IV"); |
339 » key_block2 += IVSize; | 338 key_block2 += IVSize; |
340 » } | 339 } |
341 | 340 |
342 » PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block); | 341 PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block); |
343 } else { | 342 } else { |
344 » /* | 343 /* |
345 » ** Generate TLS Export write keys and IVs. | 344 ** Generate TLS Export write keys and IVs. |
346 » */ | 345 */ |
347 » SECItem secret ; | 346 SECItem secret; |
348 » SECItem keyblk ; | 347 SECItem keyblk; |
349 | 348 |
350 » secret.type = siBuffer; | 349 secret.type = siBuffer; |
351 » keyblk.type = siBuffer; | 350 keyblk.type = siBuffer; |
352 » /* | 351 /* |
353 » ** client_write_key[CipherSpec.key_material] | 352 ** client_write_key[CipherSpec.key_material] |
354 » ** final_client_write_key = PRF(client_write_key, | 353 ** final_client_write_key = PRF(client_write_key, |
355 » ** "client write key", | 354 ** "client write key", |
356 » ** client_random + server_random); | 355 ** client_random + server_random); |
357 » */ | 356 */ |
358 » secret.data = &key_block[i]; | 357 secret.data = &key_block[i]; |
359 » secret.len = effKeySize; | 358 secret.len = effKeySize; |
360 » i += effKeySize; | 359 i += effKeySize; |
361 » keyblk.data = key_block2; | 360 keyblk.data = key_block2; |
362 » keyblk.len = keySize; | 361 keyblk.len = keySize; |
363 » status = TLS_PRF(&secret, "client write key", &crsr, &keyblk, isFIPS); | 362 status = TLS_PRF(&secret, "client write key", &crsr, &keyblk, isFIPS); |
364 » if (status != SECSuccess) { | 363 if (status != SECSuccess) { |
365 » goto key_and_mac_derive_fail; | 364 goto key_and_mac_derive_fail; |
366 » } | 365 } |
367 » buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item, \ | 366 buildSSLKey(key_block2, keySize, &pwSpec->client.write_key_item, |
368 » "TLS Export Client Write Key"); | 367 "TLS Export Client Write Key"); |
369 » key_block2 += keySize; | 368 key_block2 += keySize; |
370 | 369 |
371 » /* | 370 /* |
372 » ** server_write_key[CipherSpec.key_material] | 371 ** server_write_key[CipherSpec.key_material] |
373 » ** final_server_write_key = PRF(server_write_key, | 372 ** final_server_write_key = PRF(server_write_key, |
374 » ** "server write key", | 373 ** "server write key", |
375 » ** client_random + server_random); | 374 ** client_random + server_random); |
376 » */ | 375 */ |
377 » secret.data = &key_block[i]; | 376 secret.data = &key_block[i]; |
378 » secret.len = effKeySize; | 377 secret.len = effKeySize; |
379 » i += effKeySize; | 378 i += effKeySize; |
380 » keyblk.data = key_block2; | 379 keyblk.data = key_block2; |
381 » keyblk.len = keySize; | 380 keyblk.len = keySize; |
382 » status = TLS_PRF(&secret, "server write key", &crsr, &keyblk, isFIPS); | 381 status = TLS_PRF(&secret, "server write key", &crsr, &keyblk, isFIPS); |
383 » if (status != SECSuccess) { | 382 if (status != SECSuccess) { |
384 » goto key_and_mac_derive_fail; | 383 goto key_and_mac_derive_fail; |
385 » } | 384 } |
386 » buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item, \ | 385 buildSSLKey(key_block2, keySize, &pwSpec->server.write_key_item, |
387 » "TLS Export Server Write Key"); | 386 "TLS Export Server Write Key"); |
388 » key_block2 += keySize; | 387 key_block2 += keySize; |
389 | 388 |
390 » /* | 389 /* |
391 » ** iv_block = PRF("", "IV block", client_random + server_random); | 390 ** iv_block = PRF("", "IV block", client_random + server_random); |
392 » ** client_write_IV[SecurityParameters.IV_size] | 391 ** client_write_IV[SecurityParameters.IV_size] |
393 » ** server_write_IV[SecurityParameters.IV_size] | 392 ** server_write_IV[SecurityParameters.IV_size] |
394 » */ | 393 */ |
395 » if (IVSize) { | 394 if (IVSize) { |
396 » secret.data = NULL; | 395 secret.data = NULL; |
397 » secret.len = 0; | 396 secret.len = 0; |
398 » keyblk.data = key_block2; | 397 keyblk.data = key_block2; |
399 » keyblk.len = 2 * IVSize; | 398 keyblk.len = 2 * IVSize; |
400 » status = TLS_PRF(&secret, "IV block", &crsr, &keyblk, isFIPS); | 399 status = TLS_PRF(&secret, "IV block", &crsr, &keyblk, isFIPS); |
401 » if (status != SECSuccess) { | 400 if (status != SECSuccess) { |
402 » » goto key_and_mac_derive_fail; | 401 goto key_and_mac_derive_fail; |
403 » } | 402 } |
404 » buildSSLKey(key_block2, IVSize, \ | 403 buildSSLKey(key_block2, IVSize, |
405 » &pwSpec->client.write_iv_item, \ | 404 &pwSpec->client.write_iv_item, |
406 » » » "TLS Export Client Write IV"); | 405 "TLS Export Client Write IV"); |
407 » buildSSLKey(key_block2 + IVSize, IVSize, \ | 406 buildSSLKey(key_block2 + IVSize, IVSize, |
408 » &pwSpec->server.write_iv_item, \ | 407 &pwSpec->server.write_iv_item, |
409 » » » "TLS Export Server Write IV"); | 408 "TLS Export Server Write IV"); |
410 » key_block2 += 2 * IVSize; | 409 key_block2 += 2 * IVSize; |
411 » } | 410 } |
412 » PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block); | 411 PORT_Assert(key_block2 - key_block <= sizeof pwSpec->key_block); |
413 } | 412 } |
414 rv = SECSuccess; | 413 rv = SECSuccess; |
415 | 414 |
416 key_and_mac_derive_fail: | 415 key_and_mac_derive_fail: |
417 | 416 |
418 MD5_DestroyContext(md5Ctx, PR_FALSE); | 417 MD5_DestroyContext(md5Ctx, PR_FALSE); |
419 SHA1_DestroyContext(shaCtx, PR_FALSE); | 418 SHA1_DestroyContext(shaCtx, PR_FALSE); |
420 | 419 |
421 if (rv != SECSuccess) { | 420 if (rv != SECSuccess) { |
422 » PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); | 421 PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); |
423 } | 422 } |
424 | 423 |
425 return rv; | 424 return rv; |
426 } | 425 } |
427 | 426 |
428 | |
429 /* derive the Master Secret from the PMS */ | 427 /* derive the Master Secret from the PMS */ |
430 /* Presently, this is only done wtih RSA PMS, and only on the server side, | 428 /* Presently, this is only done wtih RSA PMS, and only on the server side, |
431 * so isRSA is always true. | 429 * so isRSA is always true. |
432 */ | 430 */ |
433 SECStatus | 431 SECStatus |
434 ssl3_MasterSecretDeriveBypass( | 432 ssl3_MasterSecretDeriveBypass( |
435 ssl3CipherSpec * pwSpec, | 433 ssl3CipherSpec *pwSpec, |
436 const unsigned char * cr, | 434 const unsigned char *cr, |
437 const unsigned char * sr, | 435 const unsigned char *sr, |
438 const SECItem * pms, | 436 const SECItem *pms, |
439 PRBool isTLS, | 437 PRBool isTLS, |
440 PRBool isRSA) | 438 PRBool isRSA) |
441 { | 439 { |
442 unsigned char * key_block = pwSpec->key_block; | 440 unsigned char *key_block = pwSpec->key_block; |
443 SECStatus rv = SECSuccess; | 441 SECStatus rv = SECSuccess; |
444 PRBool isFIPS = PR_FALSE; | 442 PRBool isFIPS = PR_FALSE; |
445 PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2; | 443 PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2; |
446 | 444 |
447 SECItem crsr; | 445 SECItem crsr; |
448 | 446 |
449 unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; | 447 unsigned char crsrdata[SSL3_RANDOM_LENGTH * 2]; |
450 PRUint64 md5buf[22]; | 448 PRUint64 md5buf[22]; |
451 PRUint64 shabuf[40]; | 449 PRUint64 shabuf[40]; |
452 | 450 |
453 #define md5Ctx ((MD5Context *)md5buf) | 451 #define md5Ctx ((MD5Context *)md5buf) |
454 #define shaCtx ((SHA1Context *)shabuf) | 452 #define shaCtx ((SHA1Context *)shabuf) |
455 | 453 |
456 /* first do the consistancy checks */ | 454 /* first do the consistancy checks */ |
457 if (isRSA) { | 455 if (isRSA) { |
458 » PORT_Assert(pms->len == SSL3_RSA_PMS_LENGTH); | 456 PORT_Assert(pms->len == SSL3_RSA_PMS_LENGTH); |
459 » if (pms->len != SSL3_RSA_PMS_LENGTH) { | 457 if (pms->len != SSL3_RSA_PMS_LENGTH) { |
460 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 458 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
461 » return SECFailure; | 459 return SECFailure; |
462 » } | 460 } |
463 » /* caller must test PMS version for rollback */ | 461 /* caller must test PMS version for rollback */ |
464 } | 462 } |
465 | 463 |
466 /* initialize the client random, server random block */ | 464 /* initialize the client random, server random block */ |
467 crsr.type = siBuffer; | 465 crsr.type = siBuffer; |
468 crsr.data = crsrdata; | 466 crsr.data = crsrdata; |
469 crsr.len = sizeof crsrdata; | 467 crsr.len = sizeof crsrdata; |
470 PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH); | 468 PORT_Memcpy(crsrdata, cr, SSL3_RANDOM_LENGTH); |
471 PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); | 469 PORT_Memcpy(crsrdata + SSL3_RANDOM_LENGTH, sr, SSL3_RANDOM_LENGTH); |
472 PRINT_BUF(100, (NULL, "Master Secret CRSR", crsr.data, crsr.len)); | 470 PRINT_BUF(100, (NULL, "Master Secret CRSR", crsr.data, crsr.len)); |
473 | 471 |
474 /* finally do the key gen */ | 472 /* finally do the key gen */ |
475 if (isTLS) { | 473 if (isTLS) { |
476 » SECItem master = { siBuffer, NULL, 0 }; | 474 SECItem master = { siBuffer, NULL, 0 }; |
477 | 475 |
478 » master.data = key_block; | 476 master.data = key_block; |
479 » master.len = SSL3_MASTER_SECRET_LENGTH; | 477 master.len = SSL3_MASTER_SECRET_LENGTH; |
480 | 478 |
481 » if (isTLS12) { | 479 if (isTLS12) { |
482 » rv = TLS_P_hash(HASH_AlgSHA256, pms, "master secret", &crsr, | 480 rv = TLS_P_hash(HASH_AlgSHA256, pms, "master secret", &crsr, |
483 » » » &master, isFIPS); | 481 &master, isFIPS); |
484 » } else { | 482 } else { |
485 » rv = TLS_PRF(pms, "master secret", &crsr, &master, isFIPS); | 483 rv = TLS_PRF(pms, "master secret", &crsr, &master, isFIPS); |
486 » } | 484 } |
487 » if (rv != SECSuccess) { | 485 if (rv != SECSuccess) { |
488 » PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); | 486 PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE); |
489 » } | 487 } |
490 } else { | 488 } else { |
491 » int i; | 489 int i; |
492 » unsigned int made = 0; | 490 unsigned int made = 0; |
493 » for (i = 0; i < 3; i++) { | 491 for (i = 0; i < 3; i++) { |
494 » unsigned int outLen; | 492 unsigned int outLen; |
495 » unsigned char sha_out[SHA1_LENGTH]; | 493 unsigned char sha_out[SHA1_LENGTH]; |
496 | 494 |
497 » SHA1_Begin(shaCtx); | 495 SHA1_Begin(shaCtx); |
498 » SHA1_Update(shaCtx, (unsigned char*) mixers[i], i+1); | 496 SHA1_Update(shaCtx, (unsigned char *)mixers[i], i + 1); |
499 » SHA1_Update(shaCtx, pms->data, pms->len); | 497 SHA1_Update(shaCtx, pms->data, pms->len); |
500 » SHA1_Update(shaCtx, crsr.data, crsr.len); | 498 SHA1_Update(shaCtx, crsr.data, crsr.len); |
501 » SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH); | 499 SHA1_End(shaCtx, sha_out, &outLen, SHA1_LENGTH); |
502 » PORT_Assert(outLen == SHA1_LENGTH); | 500 PORT_Assert(outLen == SHA1_LENGTH); |
503 | 501 |
504 » MD5_Begin(md5Ctx); | 502 MD5_Begin(md5Ctx); |
505 » MD5_Update(md5Ctx, pms->data, pms->len); | 503 MD5_Update(md5Ctx, pms->data, pms->len); |
506 » MD5_Update(md5Ctx, sha_out, outLen); | 504 MD5_Update(md5Ctx, sha_out, outLen); |
507 » MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH); | 505 MD5_End(md5Ctx, key_block + made, &outLen, MD5_LENGTH); |
508 » PORT_Assert(outLen == MD5_LENGTH); | 506 PORT_Assert(outLen == MD5_LENGTH); |
509 » made += outLen; | 507 made += outLen; |
510 » } | 508 } |
511 } | 509 } |
512 | 510 |
513 /* store the results */ | 511 /* store the results */ |
514 PORT_Memcpy(pwSpec->raw_master_secret, key_block, | 512 PORT_Memcpy(pwSpec->raw_master_secret, key_block, |
515 » » SSL3_MASTER_SECRET_LENGTH); | 513 SSL3_MASTER_SECRET_LENGTH); |
516 pwSpec->msItem.data = pwSpec->raw_master_secret; | 514 pwSpec->msItem.data = pwSpec->raw_master_secret; |
517 pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH; | 515 pwSpec->msItem.len = SSL3_MASTER_SECRET_LENGTH; |
518 PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, | 516 PRINT_BUF(100, (NULL, "Master Secret", pwSpec->msItem.data, |
519 pwSpec->msItem.len)); | 517 pwSpec->msItem.len)); |
520 | 518 |
521 return rv; | 519 return rv; |
522 } | 520 } |
523 | 521 |
524 static SECStatus | 522 static SECStatus |
525 ssl_canExtractMS(PK11SymKey *pms, PRBool isTLS, PRBool isDH, PRBool *pcbp) | 523 ssl_canExtractMS(PK11SymKey *pms, PRBool isTLS, PRBool isDH, PRBool *pcbp) |
526 { SECStatus» rv; | 524 { |
527 PK11SymKey * ms = NULL; | 525 SECStatus rv; |
528 SECItem params = {siBuffer, NULL, 0}; | 526 PK11SymKey *ms = NULL; |
| 527 SECItem params = { siBuffer, NULL, 0 }; |
529 CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params; | 528 CK_SSL3_MASTER_KEY_DERIVE_PARAMS master_params; |
530 unsigned char rand[SSL3_RANDOM_LENGTH]; | 529 unsigned char rand[SSL3_RANDOM_LENGTH]; |
531 CK_VERSION pms_version; | 530 CK_VERSION pms_version; |
532 CK_MECHANISM_TYPE master_derive; | 531 CK_MECHANISM_TYPE master_derive; |
533 CK_MECHANISM_TYPE key_derive; | 532 CK_MECHANISM_TYPE key_derive; |
534 CK_FLAGS keyFlags; | 533 CK_FLAGS keyFlags; |
535 | 534 |
536 if (pms == NULL) | 535 if (pms == NULL) |
537 » return(SECFailure); | 536 return (SECFailure); |
538 | 537 |
539 PORT_Memset(rand, 0, SSL3_RANDOM_LENGTH); | 538 PORT_Memset(rand, 0, SSL3_RANDOM_LENGTH); |
540 | 539 |
541 if (isTLS) { | 540 if (isTLS) { |
542 » if(isDH) master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH; | 541 if (isDH) |
543 » else master_derive = CKM_TLS_MASTER_KEY_DERIVE; | 542 master_derive = CKM_TLS_MASTER_KEY_DERIVE_DH; |
544 » key_derive = CKM_TLS_KEY_AND_MAC_DERIVE; | 543 else |
545 » keyFlags = CKF_SIGN | CKF_VERIFY; | 544 master_derive = CKM_TLS_MASTER_KEY_DERIVE; |
| 545 key_derive = CKM_TLS_KEY_AND_MAC_DERIVE; |
| 546 keyFlags = CKF_SIGN | CKF_VERIFY; |
546 } else { | 547 } else { |
547 » if (isDH) master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH; | 548 if (isDH) |
548 » else master_derive = CKM_SSL3_MASTER_KEY_DERIVE; | 549 master_derive = CKM_SSL3_MASTER_KEY_DERIVE_DH; |
549 » key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE; | 550 else |
550 » keyFlags = 0; | 551 master_derive = CKM_SSL3_MASTER_KEY_DERIVE; |
| 552 key_derive = CKM_SSL3_KEY_AND_MAC_DERIVE; |
| 553 keyFlags = 0; |
551 } | 554 } |
552 | 555 |
553 master_params.pVersion = &pms_version; | 556 master_params.pVersion = &pms_version; |
554 master_params.RandomInfo.pClientRandom = rand; | 557 master_params.RandomInfo.pClientRandom = rand; |
555 master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH; | 558 master_params.RandomInfo.ulClientRandomLen = SSL3_RANDOM_LENGTH; |
556 master_params.RandomInfo.pServerRandom = rand; | 559 master_params.RandomInfo.pServerRandom = rand; |
557 master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH; | 560 master_params.RandomInfo.ulServerRandomLen = SSL3_RANDOM_LENGTH; |
558 | 561 |
559 params.data = (unsigned char *) &master_params; | 562 params.data = (unsigned char *)&master_params; |
560 params.len = sizeof master_params; | 563 params.len = sizeof master_params; |
561 | 564 |
562 ms = PK11_DeriveWithFlags(pms, master_derive, ¶ms, key_derive, | 565 ms = PK11_DeriveWithFlags(pms, master_derive, ¶ms, key_derive, |
563 » » » CKA_DERIVE, 0, keyFlags); | 566 CKA_DERIVE, 0, keyFlags); |
564 if (ms == NULL) | 567 if (ms == NULL) |
565 » return(SECFailure); | 568 return (SECFailure); |
566 | 569 |
567 rv = PK11_ExtractKeyValue(ms); | 570 rv = PK11_ExtractKeyValue(ms); |
568 *pcbp = (rv == SECSuccess); | 571 *pcbp = (rv == SECSuccess); |
569 PK11_FreeSymKey(ms); | 572 PK11_FreeSymKey(ms); |
570 | |
571 return(rv); | |
572 | 573 |
| 574 return (rv); |
573 } | 575 } |
574 #endif /* !NO_PKCS11_BYPASS */ | 576 #endif /* !NO_PKCS11_BYPASS */ |
575 | 577 |
576 /* Check the key exchange algorithm for each cipher in the list to see if | 578 /* Check the key exchange algorithm for each cipher in the list to see if |
577 * a master secret key can be extracted. If the KEA will use keys from the | 579 * a master secret key can be extracted. If the KEA will use keys from the |
578 * specified cert make sure the extract operation is attempted from the slot | 580 * specified cert make sure the extract operation is attempted from the slot |
579 * where the private key resides. | 581 * where the private key resides. |
580 * If MS can be extracted for all ciphers, (*pcanbypass) is set to TRUE and | 582 * If MS can be extracted for all ciphers, (*pcanbypass) is set to TRUE and |
581 * SECSuccess is returned. In all other cases but one (*pcanbypass) is | 583 * SECSuccess is returned. In all other cases but one (*pcanbypass) is |
582 * set to FALSE and SECFailure is returned. | 584 * set to FALSE and SECFailure is returned. |
583 * In that last case Derive() has been called successfully but the MS is null, | 585 * In that last case Derive() has been called successfully but the MS is null, |
584 * CanBypass sets (*pcanbypass) to FALSE and returns SECSuccess indicating the | 586 * CanBypass sets (*pcanbypass) to FALSE and returns SECSuccess indicating the |
585 * arguments were all valid but the slot cannot be bypassed. | 587 * arguments were all valid but the slot cannot be bypassed. |
586 */ | 588 */ |
587 | 589 |
588 /* XXX Add SSL_CBP_TLS1_1 and test it in protocolmask when setting isTLS. */ | 590 /* XXX Add SSL_CBP_TLS1_1 and test it in protocolmask when setting isTLS. */ |
589 | 591 |
590 SECStatus | 592 SECStatus |
591 SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey, | 593 SSL_CanBypass(CERTCertificate *cert, SECKEYPrivateKey *srvPrivkey, |
592 » PRUint32 protocolmask, PRUint16 *ciphersuites, int nsuites, | 594 PRUint32 protocolmask, PRUint16 *ciphersuites, int nsuites, |
593 PRBool *pcanbypass, void *pwArg) | 595 PRBool *pcanbypass, void *pwArg) |
594 { | 596 { |
595 #ifdef NO_PKCS11_BYPASS | 597 #ifdef NO_PKCS11_BYPASS |
596 if (!pcanbypass) { | 598 if (!pcanbypass) { |
597 PORT_SetError(SEC_ERROR_INVALID_ARGS); | 599 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
598 return SECFailure; | 600 return SECFailure; |
599 } | 601 } |
600 *pcanbypass = PR_FALSE; | 602 *pcanbypass = PR_FALSE; |
601 return SECSuccess; | 603 return SECSuccess; |
602 #else | 604 #else |
603 SECStatus» rv; | 605 SECStatus rv; |
604 int»» i; | 606 int i; |
605 PRUint16» suite; | 607 PRUint16 suite; |
606 PK11SymKey * pms = NULL; | 608 PK11SymKey *pms = NULL; |
607 SECKEYPublicKey * srvPubkey = NULL; | 609 SECKEYPublicKey *srvPubkey = NULL; |
608 KeyType» privKeytype; | 610 KeyType privKeytype; |
609 PK11SlotInfo * slot = NULL; | 611 PK11SlotInfo *slot = NULL; |
610 SECItem param; | 612 SECItem param; |
611 CK_VERSION » version; | 613 CK_VERSION version; |
612 CK_MECHANISM_TYPE mechanism_array[2]; | 614 CK_MECHANISM_TYPE mechanism_array[2]; |
613 SECItem enc_pms = {siBuffer, NULL, 0}; | 615 SECItem enc_pms = { siBuffer, NULL, 0 }; |
614 PRBool» isTLS = PR_FALSE; | 616 PRBool isTLS = PR_FALSE; |
615 SSLCipherSuiteInfo csdef; | 617 SSLCipherSuiteInfo csdef; |
616 PRBool» testrsa = PR_FALSE; | 618 PRBool testrsa = PR_FALSE; |
617 PRBool» testrsa_export = PR_FALSE; | 619 PRBool testrsa_export = PR_FALSE; |
618 PRBool» testecdh = PR_FALSE; | 620 PRBool testecdh = PR_FALSE; |
619 PRBool» testecdhe = PR_FALSE; | 621 PRBool testecdhe = PR_FALSE; |
620 #ifndef NSS_DISABLE_ECC | 622 #ifndef NSS_DISABLE_ECC |
621 SECKEYECParams ecParams = { siBuffer, NULL, 0 }; | 623 SECKEYECParams ecParams = { siBuffer, NULL, 0 }; |
622 #endif | 624 #endif |
623 | 625 |
624 if (!cert || !srvPrivkey || !ciphersuites || !pcanbypass) { | 626 if (!cert || !srvPrivkey || !ciphersuites || !pcanbypass) { |
625 » PORT_SetError(SEC_ERROR_INVALID_ARGS); | 627 PORT_SetError(SEC_ERROR_INVALID_ARGS); |
626 return SECFailure; | 628 return SECFailure; |
627 } | 629 } |
628 | 630 |
629 srvPubkey = CERT_ExtractPublicKey(cert); | 631 srvPubkey = CERT_ExtractPublicKey(cert); |
630 if (!srvPubkey) | 632 if (!srvPubkey) |
631 return SECFailure; | 633 return SECFailure; |
632 » | 634 |
633 *pcanbypass = PR_TRUE; | 635 *pcanbypass = PR_TRUE; |
634 rv = SECFailure; | 636 rv = SECFailure; |
635 | 637 |
636 /* determine which KEAs to test */ | 638 /* determine which KEAs to test */ |
637 /* 0 (TLS_NULL_WITH_NULL_NULL) is used as a list terminator because | 639 /* 0 (TLS_NULL_WITH_NULL_NULL) is used as a list terminator because |
638 * SSL3 and TLS specs forbid negotiating that cipher suite number. | 640 * SSL3 and TLS specs forbid negotiating that cipher suite number. |
639 */ | 641 */ |
640 for (i=0; i < nsuites && (suite = *ciphersuites++) != 0; i++) { | 642 for (i = 0; i < nsuites && (suite = *ciphersuites++) != 0; i++) { |
641 » /* skip SSL2 cipher suites and ones NSS doesn't support */ | 643 /* skip SSL2 cipher suites and ones NSS doesn't support */ |
642 » if (SSL_GetCipherSuiteInfo(suite, &csdef, sizeof(csdef)) != SECSuccess | 644 if (SSL_GetCipherSuiteInfo(suite, &csdef, sizeof(csdef)) != SECSuccess |
| |
643 » || SSL_IS_SSL2_CIPHER(suite) ) | 645 SSL_IS_SSL2_CIPHER(suite)) |
644 » continue; | 646 continue; |
645 » switch (csdef.keaType) { | 647 switch (csdef.keaType) { |
646 » case ssl_kea_rsa: | 648 case ssl_kea_rsa: |
647 » switch (csdef.cipherSuite) { | 649 switch (csdef.cipherSuite) { |
648 » case TLS_RSA_EXPORT1024_WITH_RC4_56_SHA: | 650 case TLS_RSA_EXPORT1024_WITH_RC4_56_SHA: |
649 » case TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA: | 651 case TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA: |
650 » case TLS_RSA_EXPORT_WITH_RC4_40_MD5: | 652 case TLS_RSA_EXPORT_WITH_RC4_40_MD5: |
651 » case TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5: | 653 case TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5: |
652 » » testrsa_export = PR_TRUE; | 654 testrsa_export = PR_TRUE; |
653 » } | 655 } |
654 » if (!testrsa_export) | 656 if (!testrsa_export) |
655 » » testrsa = PR_TRUE; | 657 testrsa = PR_TRUE; |
656 » break; | 658 break; |
657 » case ssl_kea_ecdh: | 659 case ssl_kea_ecdh: |
658 » if (strcmp(csdef.keaTypeName, "ECDHE") == 0) /* ephemeral? */ | 660 if (strcmp(csdef.keaTypeName, "ECDHE") == 0) /* ephemeral? */ |
659 » » testecdhe = PR_TRUE; | 661 testecdhe = PR_TRUE; |
660 » else | 662 else |
661 » » testecdh = PR_TRUE; | 663 testecdh = PR_TRUE; |
662 » break; | 664 break; |
663 » case ssl_kea_dh: | 665 case ssl_kea_dh: |
664 » /* this is actually DHE */ | 666 /* this is actually DHE */ |
665 » default: | 667 default: |
666 » continue; | 668 continue; |
667 » } | 669 } |
668 } | 670 } |
669 | 671 |
670 /* For each protocol try to derive and extract an MS. | 672 /* For each protocol try to derive and extract an MS. |
671 * Failure of function any function except MS extract means | 673 * Failure of function any function except MS extract means |
672 * continue with the next cipher test. Stop testing when the list is | 674 * continue with the next cipher test. Stop testing when the list is |
673 * exhausted or when the first MS extract--not derive--fails. | 675 * exhausted or when the first MS extract--not derive--fails. |
674 */ | 676 */ |
675 privKeytype = SECKEY_GetPrivateKeyType(srvPrivkey); | 677 privKeytype = SECKEY_GetPrivateKeyType(srvPrivkey); |
676 protocolmask &= SSL_CBP_SSL3|SSL_CBP_TLS1_0; | 678 protocolmask &= SSL_CBP_SSL3 | SSL_CBP_TLS1_0; |
677 while (protocolmask) { | 679 while (protocolmask) { |
678 » if (protocolmask & SSL_CBP_SSL3) { | 680 if (protocolmask & SSL_CBP_SSL3) { |
679 » isTLS = PR_FALSE; | 681 isTLS = PR_FALSE; |
680 » protocolmask ^= SSL_CBP_SSL3; | 682 protocolmask ^= SSL_CBP_SSL3; |
681 » } else { | 683 } else { |
682 » isTLS = PR_TRUE; | 684 isTLS = PR_TRUE; |
683 » protocolmask ^= SSL_CBP_TLS1_0; | 685 protocolmask ^= SSL_CBP_TLS1_0; |
684 » } | 686 } |
685 | 687 |
686 » if (privKeytype == rsaKey && testrsa_export) { | 688 if (privKeytype == rsaKey && testrsa_export) { |
687 » if (PK11_GetPrivateModulusLen(srvPrivkey) > EXPORT_RSA_KEY_LENGTH) { | 689 if (PK11_GetPrivateModulusLen(srvPrivkey) > EXPORT_RSA_KEY_LENGTH) { |
688 » » *pcanbypass = PR_FALSE; | 690 *pcanbypass = PR_FALSE; |
689 » » rv = SECSuccess; | 691 rv = SECSuccess; |
690 » » break; | 692 break; |
691 » } else | 693 } else |
692 » » testrsa = PR_TRUE; | 694 testrsa = PR_TRUE; |
693 » } | 695 } |
694 » for (; privKeytype == rsaKey && testrsa; ) { | 696 for (; privKeytype == rsaKey && testrsa;) { |
695 » /* TLS_RSA */ | 697 /* TLS_RSA */ |
696 » unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH]; | 698 unsigned char rsaPmsBuf[SSL3_RSA_PMS_LENGTH]; |
697 » unsigned int outLen = 0; | 699 unsigned int outLen = 0; |
698 » CK_MECHANISM_TYPE target; | 700 CK_MECHANISM_TYPE target; |
699 » SECStatus» irv; | 701 SECStatus irv; |
700 » | 702 |
701 » mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN; | 703 mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN; |
702 » mechanism_array[1] = CKM_RSA_PKCS; | 704 mechanism_array[1] = CKM_RSA_PKCS; |
703 | 705 |
704 » slot = PK11_GetBestSlotMultiple(mechanism_array, 2, pwArg); | 706 slot = PK11_GetBestSlotMultiple(mechanism_array, 2, pwArg); |
705 » if (slot == NULL) { | 707 if (slot == NULL) { |
706 » » PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND); | 708 PORT_SetError(SSL_ERROR_TOKEN_SLOT_NOT_FOUND); |
707 » » break; | 709 break; |
708 » } | 710 } |
709 | 711 |
710 » /* Generate the pre-master secret ... (client side) */ | 712 /* Generate the pre-master secret ... (client side) */ |
711 » version.major = 3 /*MSB(clientHelloVersion)*/; | 713 version.major = 3 /*MSB(clientHelloVersion)*/; |
712 » version.minor = 0 /*LSB(clientHelloVersion)*/; | 714 version.minor = 0 /*LSB(clientHelloVersion)*/; |
713 » param.data = (unsigned char *)&version; | 715 param.data = (unsigned char *)&version; |
714 » param.len = sizeof version; | 716 param.len = sizeof version; |
715 » pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, ¶m, 0, pwAr
g); | 717 pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, ¶m, 0, pwAr
g); |
716 » PK11_FreeSlot(slot); | 718 PK11_FreeSlot(slot); |
717 » if (!pms) | 719 if (!pms) |
718 » » break; | 720 break; |
719 » /* now wrap it */ | 721 /* now wrap it */ |
720 » enc_pms.len = SECKEY_PublicKeyStrength(srvPubkey); | 722 enc_pms.len = SECKEY_PublicKeyStrength(srvPubkey); |
721 » enc_pms.data = (unsigned char*)PORT_Alloc(enc_pms.len); | 723 enc_pms.data = (unsigned char *)PORT_Alloc(enc_pms.len); |
722 » if (enc_pms.data == NULL) { | 724 if (enc_pms.data == NULL) { |
723 » PORT_SetError(PR_OUT_OF_MEMORY_ERROR); | 725 PORT_SetError(PR_OUT_OF_MEMORY_ERROR); |
724 » break; | 726 break; |
725 » } | 727 } |
726 » irv = PK11_PubWrapSymKey(CKM_RSA_PKCS, srvPubkey, pms, &enc_pms); | 728 irv = PK11_PubWrapSymKey(CKM_RSA_PKCS, srvPubkey, pms, &enc_pms); |
727 » if (irv != SECSuccess) | 729 if (irv != SECSuccess) |
728 » » break; | 730 break; |
729 » PK11_FreeSymKey(pms); | 731 PK11_FreeSymKey(pms); |
730 » pms = NULL; | 732 pms = NULL; |
731 » /* now do the server side--check the triple bypass first */ | 733 /* now do the server side--check the triple bypass first */ |
732 » rv = PK11_PrivDecryptPKCS1(srvPrivkey, rsaPmsBuf, &outLen, | 734 rv = PK11_PrivDecryptPKCS1(srvPrivkey, rsaPmsBuf, &outLen, |
733 » » » » sizeof rsaPmsBuf, | 735 sizeof rsaPmsBuf, |
734 » » » » (unsigned char *)enc_pms.data, | 736 (unsigned char *)enc_pms.data, |
735 » » » » enc_pms.len); | 737 enc_pms.len); |
736 » /* if decrypt worked we're done with the RSA test */ | 738 /* if decrypt worked we're done with the RSA test */ |
737 » if (rv == SECSuccess) { | 739 if (rv == SECSuccess) { |
738 » » *pcanbypass = PR_TRUE; | 740 *pcanbypass = PR_TRUE; |
739 » » break; | 741 break; |
740 » } | 742 } |
741 » /* check for fallback to double bypass */ | 743 /* check for fallback to double bypass */ |
742 » target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE | 744 target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE |
743 » » » : CKM_SSL3_MASTER_KEY_DERIVE; | 745 : CKM_SSL3_MASTER_KEY_DERIVE; |
744 » pms = PK11_PubUnwrapSymKey(srvPrivkey, &enc_pms, | 746 pms = PK11_PubUnwrapSymKey(srvPrivkey, &enc_pms, |
745 » » » » target, CKA_DERIVE, 0); | 747 target, CKA_DERIVE, 0); |
746 » rv = ssl_canExtractMS(pms, isTLS, PR_FALSE, pcanbypass); | 748 rv = ssl_canExtractMS(pms, isTLS, PR_FALSE, pcanbypass); |
747 » if (rv == SECSuccess && *pcanbypass == PR_FALSE) | 749 if (rv == SECSuccess && *pcanbypass == PR_FALSE) |
748 » » goto done; | 750 goto done; |
749 » break; | 751 break; |
750 » } | 752 } |
751 | 753 |
752 » /* Check for NULL to avoid double free. | 754 /* Check for NULL to avoid double free. |
753 » * SECItem_FreeItem sets data NULL in secitem.c#265 | 755 * SECItem_FreeItem sets data NULL in secitem.c#265 |
754 » */ | 756 */ |
755 » if (enc_pms.data != NULL) { | 757 if (enc_pms.data != NULL) { |
756 » SECITEM_FreeItem(&enc_pms, PR_FALSE); | 758 SECITEM_FreeItem(&enc_pms, PR_FALSE); |
757 } | 759 } |
758 #ifndef NSS_DISABLE_ECC | 760 #ifndef NSS_DISABLE_ECC |
759 » for (; (privKeytype == ecKey && ( testecdh || testecdhe)) || | 761 for (; (privKeytype == ecKey && (testecdh || testecdhe)) || |
760 » (privKeytype == rsaKey && testecdhe); ) { | 762 (privKeytype == rsaKey && testecdhe);) { |
761 » CK_MECHANISM_TYPE target; | 763 CK_MECHANISM_TYPE target; |
762 » SECKEYPublicKey *keapub = NULL; | 764 SECKEYPublicKey *keapub = NULL; |
763 » SECKEYPrivateKey *keapriv; | 765 SECKEYPrivateKey *keapriv; |
764 » SECKEYPublicKey *cpub = NULL; /* client's ephemeral ECDH keys */ | 766 SECKEYPublicKey *cpub = NULL; /* client's ephemeral ECDH keys */ |
765 » SECKEYPrivateKey *cpriv = NULL; | 767 SECKEYPrivateKey *cpriv = NULL; |
766 » SECKEYECParams *pecParams = NULL; | 768 SECKEYECParams *pecParams = NULL; |
767 | 769 |
768 » if (privKeytype == ecKey && testecdhe) { | 770 if (privKeytype == ecKey && testecdhe) { |
769 » » /* TLS_ECDHE_ECDSA */ | 771 /* TLS_ECDHE_ECDSA */ |
770 » » pecParams = &srvPubkey->u.ec.DEREncodedParams; | 772 pecParams = &srvPubkey->u.ec.DEREncodedParams; |
771 » } else if (privKeytype == rsaKey && testecdhe) { | 773 } else if (privKeytype == rsaKey && testecdhe) { |
772 » » /* TLS_ECDHE_RSA */ | 774 /* TLS_ECDHE_RSA */ |
773 » » ECName ec_curve; | 775 ECName ec_curve; |
774 » » int» » serverKeyStrengthInBits; | 776 int serverKeyStrengthInBits; |
775 » » int» » signatureKeyStrength; | 777 int signatureKeyStrength; |
776 » » int» » requiredECCbits; | 778 int requiredECCbits; |
777 | 779 |
778 » » /* find a curve of equivalent strength to the RSA key's */ | 780 /* find a curve of equivalent strength to the RSA key's */ |
779 » » requiredECCbits = PK11_GetPrivateModulusLen(srvPrivkey); | 781 requiredECCbits = PK11_GetPrivateModulusLen(srvPrivkey); |
780 » » if (requiredECCbits < 0) | 782 if (requiredECCbits < 0) |
781 » » break; | 783 break; |
782 » » requiredECCbits *= BPB; | 784 requiredECCbits *= BPB; |
783 » » serverKeyStrengthInBits = srvPubkey->u.rsa.modulus.len; | 785 serverKeyStrengthInBits = srvPubkey->u.rsa.modulus.len; |
784 » » if (srvPubkey->u.rsa.modulus.data[0] == 0) { | 786 if (srvPubkey->u.rsa.modulus.data[0] == 0) { |
785 » » serverKeyStrengthInBits--; | 787 serverKeyStrengthInBits--; |
786 » » } | 788 } |
787 » » /* convert to strength in bits */ | 789 /* convert to strength in bits */ |
788 » » serverKeyStrengthInBits *= BPB; | 790 serverKeyStrengthInBits *= BPB; |
789 | 791 |
790 » » signatureKeyStrength = | 792 signatureKeyStrength = |
791 » » SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits); | 793 SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyStrengthInBits); |
792 | 794 |
793 » » if ( requiredECCbits > signatureKeyStrength ) | 795 if (requiredECCbits > signatureKeyStrength) |
794 » » requiredECCbits = signatureKeyStrength; | 796 requiredECCbits = signatureKeyStrength; |
795 | 797 |
796 » » ec_curve = | 798 ec_curve = |
797 » » ssl3_GetCurveWithECKeyStrength( | 799 ssl3_GetCurveWithECKeyStrength( |
798 » » » » » ssl3_GetSupportedECCurveMask(NULL), | 800 ssl3_GetSupportedECCurveMask(NULL), |
799 » » » » » requiredECCbits); | 801 requiredECCbits); |
800 » » rv = ssl3_ECName2Params(NULL, ec_curve, &ecParams); | 802 rv = ssl3_ECName2Params(NULL, ec_curve, &ecParams); |
801 » » if (rv == SECFailure) { | 803 if (rv == SECFailure) { |
802 » » break; | 804 break; |
803 » » } | 805 } |
804 » » pecParams = &ecParams; | 806 pecParams = &ecParams; |
805 » } | 807 } |
806 | 808 |
807 » if (testecdhe) { | 809 if (testecdhe) { |
808 » » /* generate server's ephemeral keys */ | 810 /* generate server's ephemeral keys */ |
809 » » keapriv = SECKEY_CreateECPrivateKey(pecParams, &keapub, NULL); | 811 keapriv = SECKEY_CreateECPrivateKey(pecParams, &keapub, NULL); |
810 » » if (!keapriv || !keapub) { | 812 if (!keapriv || !keapub) { |
811 » » if (keapriv) | 813 if (keapriv) |
812 » » » SECKEY_DestroyPrivateKey(keapriv); | 814 SECKEY_DestroyPrivateKey(keapriv); |
813 » » if (keapub) | 815 if (keapub) |
814 » » » SECKEY_DestroyPublicKey(keapub); | 816 SECKEY_DestroyPublicKey(keapub); |
815 » » PORT_SetError(SEC_ERROR_KEYGEN_FAIL); | 817 PORT_SetError(SEC_ERROR_KEYGEN_FAIL); |
816 » » rv = SECFailure; | 818 rv = SECFailure; |
817 » » break; | 819 break; |
818 » » } | 820 } |
819 » } else { | 821 } else { |
820 » » /* TLS_ECDH_ECDSA */ | 822 /* TLS_ECDH_ECDSA */ |
821 » » keapub = srvPubkey; | 823 keapub = srvPubkey; |
822 » » keapriv = srvPrivkey; | 824 keapriv = srvPrivkey; |
823 » » pecParams = &srvPubkey->u.ec.DEREncodedParams; | 825 pecParams = &srvPubkey->u.ec.DEREncodedParams; |
824 » } | 826 } |
825 | 827 |
826 » /* perform client side ops */ | 828 /* perform client side ops */ |
827 » /* generate a pair of ephemeral keys using server's parms */ | 829 /* generate a pair of ephemeral keys using server's parms */ |
828 » cpriv = SECKEY_CreateECPrivateKey(pecParams, &cpub, NULL); | 830 cpriv = SECKEY_CreateECPrivateKey(pecParams, &cpub, NULL); |
829 » if (!cpriv || !cpub) { | 831 if (!cpriv || !cpub) { |
830 » » if (testecdhe) { | 832 if (testecdhe) { |
831 » » SECKEY_DestroyPrivateKey(keapriv); | 833 SECKEY_DestroyPrivateKey(keapriv); |
832 » » SECKEY_DestroyPublicKey(keapub); | 834 SECKEY_DestroyPublicKey(keapub); |
833 » » } | 835 } |
834 » » PORT_SetError(SEC_ERROR_KEYGEN_FAIL); | 836 PORT_SetError(SEC_ERROR_KEYGEN_FAIL); |
835 » » rv = SECFailure; | 837 rv = SECFailure; |
836 » » break; | 838 break; |
837 » } | 839 } |
838 » /* now do the server side */ | 840 /* now do the server side */ |
839 » /* determine the PMS using client's public value */ | 841 /* determine the PMS using client's public value */ |
840 » target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE_DH | 842 target = isTLS ? CKM_TLS_MASTER_KEY_DERIVE_DH |
841 » » » : CKM_SSL3_MASTER_KEY_DERIVE_DH; | 843 : CKM_SSL3_MASTER_KEY_DERIVE_DH; |
842 » pms = PK11_PubDeriveWithKDF(keapriv, cpub, PR_FALSE, NULL, NULL, | 844 pms = PK11_PubDeriveWithKDF(keapriv, cpub, PR_FALSE, NULL, NULL, |
843 » » » » CKM_ECDH1_DERIVE, | 845 CKM_ECDH1_DERIVE, |
844 » » » » target, | 846 target, |
845 » » » » CKA_DERIVE, 0, CKD_NULL, NULL, NULL); | 847 CKA_DERIVE, 0, CKD_NULL, NULL, NULL); |
846 » rv = ssl_canExtractMS(pms, isTLS, PR_TRUE, pcanbypass); | 848 rv = ssl_canExtractMS(pms, isTLS, PR_TRUE, pcanbypass); |
847 » SECKEY_DestroyPrivateKey(cpriv); | 849 SECKEY_DestroyPrivateKey(cpriv); |
848 » SECKEY_DestroyPublicKey(cpub); | 850 SECKEY_DestroyPublicKey(cpub); |
849 » if (testecdhe) { | 851 if (testecdhe) { |
850 » » SECKEY_DestroyPrivateKey(keapriv); | 852 SECKEY_DestroyPrivateKey(keapriv); |
851 » » SECKEY_DestroyPublicKey(keapub); | 853 SECKEY_DestroyPublicKey(keapub); |
852 » } | 854 } |
853 » if (rv == SECSuccess && *pcanbypass == PR_FALSE) | 855 if (rv == SECSuccess && *pcanbypass == PR_FALSE) |
854 » » goto done; | 856 goto done; |
855 » break; | 857 break; |
856 » } | 858 } |
857 » /* Check for NULL to avoid double free. */ | 859 /* Check for NULL to avoid double free. */ |
858 » if (ecParams.data != NULL) { | 860 if (ecParams.data != NULL) { |
859 » PORT_Free(ecParams.data); | 861 PORT_Free(ecParams.data); |
860 » ecParams.data = NULL; | 862 ecParams.data = NULL; |
861 » } | 863 } |
862 #endif /* NSS_DISABLE_ECC */ | 864 #endif /* NSS_DISABLE_ECC */ |
863 » if (pms) | 865 if (pms) |
864 » PK11_FreeSymKey(pms); | 866 PK11_FreeSymKey(pms); |
865 } | 867 } |
866 | 868 |
867 /* *pcanbypass has been set */ | 869 /* *pcanbypass has been set */ |
868 rv = SECSuccess; | 870 rv = SECSuccess; |
869 | 871 |
870 done: | 872 done: |
871 if (pms) | 873 if (pms) |
872 » PK11_FreeSymKey(pms); | 874 PK11_FreeSymKey(pms); |
873 | 875 |
874 /* Check for NULL to avoid double free. | 876 /* Check for NULL to avoid double free. |
875 * SECItem_FreeItem sets data NULL in secitem.c#265 | 877 * SECItem_FreeItem sets data NULL in secitem.c#265 |
876 */ | 878 */ |
877 if (enc_pms.data != NULL) { | 879 if (enc_pms.data != NULL) { |
878 » SECITEM_FreeItem(&enc_pms, PR_FALSE); | 880 SECITEM_FreeItem(&enc_pms, PR_FALSE); |
879 } | 881 } |
880 #ifndef NSS_DISABLE_ECC | 882 #ifndef NSS_DISABLE_ECC |
881 if (ecParams.data != NULL) { | 883 if (ecParams.data != NULL) { |
882 PORT_Free(ecParams.data); | 884 PORT_Free(ecParams.data); |
883 ecParams.data = NULL; | 885 ecParams.data = NULL; |
884 } | 886 } |
885 #endif /* NSS_DISABLE_ECC */ | 887 #endif /* NSS_DISABLE_ECC */ |
886 | 888 |
887 if (srvPubkey) { | 889 if (srvPubkey) { |
888 » SECKEY_DestroyPublicKey(srvPubkey); | 890 SECKEY_DestroyPublicKey(srvPubkey); |
889 » srvPubkey = NULL; | 891 srvPubkey = NULL; |
890 } | 892 } |
891 | 893 |
892 | |
893 return rv; | 894 return rv; |
894 #endif /* NO_PKCS11_BYPASS */ | 895 #endif /* NO_PKCS11_BYPASS */ |
895 } | 896 } |
896 | |
OLD | NEW |