|
1 /* |
|
2 * SSL v2 handshake functions, and functions common to SSL2 and SSL3. |
|
3 * |
|
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 |
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
7 |
|
8 #include "nssrenam.h" |
|
9 #include "cert.h" |
|
10 #include "secitem.h" |
|
11 #include "sechash.h" |
|
12 #include "cryptohi.h" /* for SGN_ funcs */ |
|
13 #include "keyhi.h" /* for SECKEY_ high level functions. */ |
|
14 #include "ssl.h" |
|
15 #include "sslimpl.h" |
|
16 #include "sslproto.h" |
|
17 #include "ssl3prot.h" |
|
18 #include "sslerr.h" |
|
19 #include "pk11func.h" |
|
20 #include "prinit.h" |
|
21 #include "prtime.h" /* for PR_Now() */ |
|
22 |
|
23 static PRBool policyWasSet; |
|
24 |
|
25 /* This ordered list is indexed by (SSL_CK_xx * 3) */ |
|
26 /* Second and third bytes are MSB and LSB of master key length. */ |
|
27 static const PRUint8 allCipherSuites[] = { |
|
28 0, 0, 0, |
|
29 SSL_CK_RC4_128_WITH_MD5, 0x00, 0x80, |
|
30 SSL_CK_RC4_128_EXPORT40_WITH_MD5, 0x00, 0x80, |
|
31 SSL_CK_RC2_128_CBC_WITH_MD5, 0x00, 0x80, |
|
32 SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, 0x00, 0x80, |
|
33 SSL_CK_IDEA_128_CBC_WITH_MD5, 0x00, 0x80, |
|
34 SSL_CK_DES_64_CBC_WITH_MD5, 0x00, 0x40, |
|
35 SSL_CK_DES_192_EDE3_CBC_WITH_MD5, 0x00, 0xC0, |
|
36 0, 0, 0 |
|
37 }; |
|
38 |
|
39 #define ssl2_NUM_SUITES_IMPLEMENTED 6 |
|
40 |
|
41 /* This list is sent back to the client when the client-hello message |
|
42 * contains no overlapping ciphers, so the client can report what ciphers |
|
43 * are supported by the server. Unlike allCipherSuites (above), this list |
|
44 * is sorted by descending preference, not by cipherSuite number. |
|
45 */ |
|
46 static const PRUint8 implementedCipherSuites[ssl2_NUM_SUITES_IMPLEMENTED * 3] = { |
|
47 SSL_CK_RC4_128_WITH_MD5, 0x00, 0x80, |
|
48 SSL_CK_RC2_128_CBC_WITH_MD5, 0x00, 0x80, |
|
49 SSL_CK_DES_192_EDE3_CBC_WITH_MD5, 0x00, 0xC0, |
|
50 SSL_CK_DES_64_CBC_WITH_MD5, 0x00, 0x40, |
|
51 SSL_CK_RC4_128_EXPORT40_WITH_MD5, 0x00, 0x80, |
|
52 SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5, 0x00, 0x80 |
|
53 }; |
|
54 |
|
55 typedef struct ssl2SpecsStr { |
|
56 PRUint8 nkm; /* do this many hashes to generate key material. */ |
|
57 PRUint8 nkd; /* size of readKey and writeKey in bytes. */ |
|
58 PRUint8 blockSize; |
|
59 PRUint8 blockShift; |
|
60 CK_MECHANISM_TYPE mechanism; |
|
61 PRUint8 keyLen; /* cipher symkey size in bytes. */ |
|
62 PRUint8 pubLen; /* publicly reveal this many bytes of key. */ |
|
63 PRUint8 ivLen; /* length of IV data at *ca. */ |
|
64 } ssl2Specs; |
|
65 |
|
66 static const ssl2Specs ssl_Specs[] = { |
|
67 /* NONE */ |
|
68 { 0, 0, 0, 0, }, |
|
69 /* SSL_CK_RC4_128_WITH_MD5 */ |
|
70 { 2, 16, 1, 0, CKM_RC4, 16, 0, 0, }, |
|
71 /* SSL_CK_RC4_128_EXPORT40_WITH_MD5 */ |
|
72 { 2, 16, 1, 0, CKM_RC4, 16, 11, 0, }, |
|
73 /* SSL_CK_RC2_128_CBC_WITH_MD5 */ |
|
74 { 2, 16, 8, 3, CKM_RC2_CBC, 16, 0, 8, }, |
|
75 /* SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 */ |
|
76 { 2, 16, 8, 3, CKM_RC2_CBC, 16, 11, 8, }, |
|
77 /* SSL_CK_IDEA_128_CBC_WITH_MD5 */ |
|
78 { 0, 0, 0, 0, }, |
|
79 /* SSL_CK_DES_64_CBC_WITH_MD5 */ |
|
80 { 1, 8, 8, 3, CKM_DES_CBC, 8, 0, 8, }, |
|
81 /* SSL_CK_DES_192_EDE3_CBC_WITH_MD5 */ |
|
82 { 3, 24, 8, 3, CKM_DES3_CBC, 24, 0, 8, }, |
|
83 }; |
|
84 |
|
85 #define SET_ERROR_CODE /* reminder */ |
|
86 #define TEST_FOR_FAILURE /* reminder */ |
|
87 |
|
88 /* |
|
89 ** Put a string tag in the library so that we can examine an executable |
|
90 ** and see what kind of security it supports. |
|
91 */ |
|
92 const char *ssl_version = "SECURITY_VERSION:" |
|
93 " +us" |
|
94 " +export" |
|
95 #ifdef TRACE |
|
96 " +trace" |
|
97 #endif |
|
98 #ifdef DEBUG |
|
99 " +debug" |
|
100 #endif |
|
101 ; |
|
102 |
|
103 const char * const ssl_cipherName[] = { |
|
104 "unknown", |
|
105 "RC4", |
|
106 "RC4-Export", |
|
107 "RC2-CBC", |
|
108 "RC2-CBC-Export", |
|
109 "IDEA-CBC", |
|
110 "DES-CBC", |
|
111 "DES-EDE3-CBC", |
|
112 "unknown", |
|
113 "unknown", /* was fortezza, NO LONGER USED */ |
|
114 }; |
|
115 |
|
116 |
|
117 /* bit-masks, showing which SSLv2 suites are allowed. |
|
118 * lsb corresponds to first cipher suite in allCipherSuites[]. |
|
119 */ |
|
120 static PRUint16 allowedByPolicy; /* all off by default */ |
|
121 static PRUint16 maybeAllowedByPolicy; /* all off by default */ |
|
122 static PRUint16 chosenPreference = 0xff; /* all on by default */ |
|
123 |
|
124 /* bit values for the above two bit masks */ |
|
125 #define SSL_CB_RC4_128_WITH_MD5 (1 << SSL_CK_RC4_128_WITH_MD5) |
|
126 #define SSL_CB_RC4_128_EXPORT40_WITH_MD5 (1 << SSL_CK_RC4_128_EXPORT40_WITH_MD5) |
|
127 #define SSL_CB_RC2_128_CBC_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_WITH_MD5) |
|
128 #define SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 (1 << SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5) |
|
129 #define SSL_CB_IDEA_128_CBC_WITH_MD5 (1 << SSL_CK_IDEA_128_CBC_WITH_MD5) |
|
130 #define SSL_CB_DES_64_CBC_WITH_MD5 (1 << SSL_CK_DES_64_CBC_WITH_MD5) |
|
131 #define SSL_CB_DES_192_EDE3_CBC_WITH_MD5 (1 << SSL_CK_DES_192_EDE3_CBC_WITH_MD5) |
|
132 #define SSL_CB_IMPLEMENTED \ |
|
133 (SSL_CB_RC4_128_WITH_MD5 | \ |
|
134 SSL_CB_RC4_128_EXPORT40_WITH_MD5 | \ |
|
135 SSL_CB_RC2_128_CBC_WITH_MD5 | \ |
|
136 SSL_CB_RC2_128_CBC_EXPORT40_WITH_MD5 | \ |
|
137 SSL_CB_DES_64_CBC_WITH_MD5 | \ |
|
138 SSL_CB_DES_192_EDE3_CBC_WITH_MD5) |
|
139 |
|
140 |
|
141 /* Construct a socket's list of cipher specs from the global default values. |
|
142 */ |
|
143 static SECStatus |
|
144 ssl2_ConstructCipherSpecs(sslSocket *ss) |
|
145 { |
|
146 PRUint8 * cs = NULL; |
|
147 unsigned int allowed; |
|
148 unsigned int count; |
|
149 int ssl3_count = 0; |
|
150 int final_count; |
|
151 int i; |
|
152 SECStatus rv; |
|
153 |
|
154 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
155 |
|
156 count = 0; |
|
157 PORT_Assert(ss != 0); |
|
158 allowed = !ss->opt.enableSSL2 ? 0 : |
|
159 (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED); |
|
160 while (allowed) { |
|
161 if (allowed & 1) |
|
162 ++count; |
|
163 allowed >>= 1; |
|
164 } |
|
165 |
|
166 /* Call ssl3_config_match_init() once here, |
|
167 * instead of inside ssl3_ConstructV2CipherSpecsHack(), |
|
168 * because the latter gets called twice below, |
|
169 * and then again in ssl2_BeginClientHandshake(). |
|
170 */ |
|
171 ssl3_config_match_init(ss); |
|
172 |
|
173 /* ask SSL3 how many cipher suites it has. */ |
|
174 rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3_count); |
|
175 if (rv < 0) |
|
176 return rv; |
|
177 count += ssl3_count; |
|
178 |
|
179 /* Allocate memory to hold cipher specs */ |
|
180 if (count > 0) |
|
181 cs = (PRUint8*) PORT_Alloc(count * 3); |
|
182 else |
|
183 PORT_SetError(SSL_ERROR_SSL_DISABLED); |
|
184 if (cs == NULL) |
|
185 return SECFailure; |
|
186 |
|
187 if (ss->cipherSpecs != NULL) { |
|
188 PORT_Free(ss->cipherSpecs); |
|
189 } |
|
190 ss->cipherSpecs = cs; |
|
191 ss->sizeCipherSpecs = count * 3; |
|
192 |
|
193 /* fill in cipher specs for SSL2 cipher suites */ |
|
194 allowed = !ss->opt.enableSSL2 ? 0 : |
|
195 (ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED); |
|
196 for (i = 0; i < ssl2_NUM_SUITES_IMPLEMENTED * 3; i += 3) { |
|
197 const PRUint8 * hs = implementedCipherSuites + i; |
|
198 int ok = allowed & (1U << hs[0]); |
|
199 if (ok) { |
|
200 cs[0] = hs[0]; |
|
201 cs[1] = hs[1]; |
|
202 cs[2] = hs[2]; |
|
203 cs += 3; |
|
204 } |
|
205 } |
|
206 |
|
207 /* now have SSL3 add its suites onto the end */ |
|
208 rv = ssl3_ConstructV2CipherSpecsHack(ss, cs, &final_count); |
|
209 |
|
210 /* adjust for any difference between first pass and second pass */ |
|
211 ss->sizeCipherSpecs -= (ssl3_count - final_count) * 3; |
|
212 |
|
213 return rv; |
|
214 } |
|
215 |
|
216 /* This function is called immediately after ssl2_ConstructCipherSpecs() |
|
217 ** at the beginning of a handshake. It detects cases where a protocol |
|
218 ** (e.g. SSL2 or SSL3) is logically enabled, but all its cipher suites |
|
219 ** for that protocol have been disabled. If such cases, it clears the |
|
220 ** enable bit for the protocol. If no protocols remain enabled, or |
|
221 ** if no cipher suites are found, it sets the error code and returns |
|
222 ** SECFailure, otherwise it returns SECSuccess. |
|
223 */ |
|
224 static SECStatus |
|
225 ssl2_CheckConfigSanity(sslSocket *ss) |
|
226 { |
|
227 unsigned int allowed; |
|
228 int ssl3CipherCount = 0; |
|
229 SECStatus rv; |
|
230 |
|
231 /* count the SSL2 and SSL3 enabled ciphers. |
|
232 * if either is zero, clear the socket's enable for that protocol. |
|
233 */ |
|
234 if (!ss->cipherSpecs) |
|
235 goto disabled; |
|
236 |
|
237 allowed = ss->allowedByPolicy & ss->chosenPreference; |
|
238 if (! allowed) |
|
239 ss->opt.enableSSL2 = PR_FALSE; /* not really enabled if no ciphers */ |
|
240 |
|
241 /* ssl3_config_match_init was called in ssl2_ConstructCipherSpecs(). */ |
|
242 /* Ask how many ssl3 CipherSuites were enabled. */ |
|
243 rv = ssl3_ConstructV2CipherSpecsHack(ss, NULL, &ssl3CipherCount); |
|
244 if (rv != SECSuccess || ssl3CipherCount <= 0) { |
|
245 /* SSL3/TLS not really enabled if no ciphers */ |
|
246 ss->vrange.min = SSL_LIBRARY_VERSION_NONE; |
|
247 ss->vrange.max = SSL_LIBRARY_VERSION_NONE; |
|
248 } |
|
249 |
|
250 if (!ss->opt.enableSSL2 && SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { |
|
251 SSL_DBG(("%d: SSL[%d]: Can't handshake! all versions disabled.", |
|
252 SSL_GETPID(), ss->fd)); |
|
253 disabled: |
|
254 PORT_SetError(SSL_ERROR_SSL_DISABLED); |
|
255 return SECFailure; |
|
256 } |
|
257 return SECSuccess; |
|
258 } |
|
259 |
|
260 /* |
|
261 * Since this is a global (not per-socket) setting, we cannot use the |
|
262 * HandshakeLock to protect this. Probably want a global lock. |
|
263 */ |
|
264 SECStatus |
|
265 ssl2_SetPolicy(PRInt32 which, PRInt32 policy) |
|
266 { |
|
267 PRUint32 bitMask; |
|
268 SECStatus rv = SECSuccess; |
|
269 |
|
270 which &= 0x000f; |
|
271 bitMask = 1 << which; |
|
272 |
|
273 if (!(bitMask & SSL_CB_IMPLEMENTED)) { |
|
274 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
|
275 return SECFailure; |
|
276 } |
|
277 |
|
278 if (policy == SSL_ALLOWED) { |
|
279 allowedByPolicy |= bitMask; |
|
280 maybeAllowedByPolicy |= bitMask; |
|
281 } else if (policy == SSL_RESTRICTED) { |
|
282 allowedByPolicy &= ~bitMask; |
|
283 maybeAllowedByPolicy |= bitMask; |
|
284 } else { |
|
285 allowedByPolicy &= ~bitMask; |
|
286 maybeAllowedByPolicy &= ~bitMask; |
|
287 } |
|
288 allowedByPolicy &= SSL_CB_IMPLEMENTED; |
|
289 maybeAllowedByPolicy &= SSL_CB_IMPLEMENTED; |
|
290 |
|
291 policyWasSet = PR_TRUE; |
|
292 return rv; |
|
293 } |
|
294 |
|
295 SECStatus |
|
296 ssl2_GetPolicy(PRInt32 which, PRInt32 *oPolicy) |
|
297 { |
|
298 PRUint32 bitMask; |
|
299 PRInt32 policy; |
|
300 |
|
301 which &= 0x000f; |
|
302 bitMask = 1 << which; |
|
303 |
|
304 /* Caller assures oPolicy is not null. */ |
|
305 if (!(bitMask & SSL_CB_IMPLEMENTED)) { |
|
306 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
|
307 *oPolicy = SSL_NOT_ALLOWED; |
|
308 return SECFailure; |
|
309 } |
|
310 |
|
311 if (maybeAllowedByPolicy & bitMask) { |
|
312 policy = (allowedByPolicy & bitMask) ? SSL_ALLOWED : SSL_RESTRICTED; |
|
313 } else { |
|
314 policy = SSL_NOT_ALLOWED; |
|
315 } |
|
316 |
|
317 *oPolicy = policy; |
|
318 return SECSuccess; |
|
319 } |
|
320 |
|
321 /* |
|
322 * Since this is a global (not per-socket) setting, we cannot use the |
|
323 * HandshakeLock to protect this. Probably want a global lock. |
|
324 * Called from SSL_CipherPrefSetDefault in sslsock.c |
|
325 * These changes have no effect on any sslSockets already created. |
|
326 */ |
|
327 SECStatus |
|
328 ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled) |
|
329 { |
|
330 PRUint32 bitMask; |
|
331 |
|
332 which &= 0x000f; |
|
333 bitMask = 1 << which; |
|
334 |
|
335 if (!(bitMask & SSL_CB_IMPLEMENTED)) { |
|
336 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
|
337 return SECFailure; |
|
338 } |
|
339 |
|
340 if (enabled) |
|
341 chosenPreference |= bitMask; |
|
342 else |
|
343 chosenPreference &= ~bitMask; |
|
344 chosenPreference &= SSL_CB_IMPLEMENTED; |
|
345 |
|
346 return SECSuccess; |
|
347 } |
|
348 |
|
349 SECStatus |
|
350 ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled) |
|
351 { |
|
352 PRBool rv = PR_FALSE; |
|
353 PRUint32 bitMask; |
|
354 |
|
355 which &= 0x000f; |
|
356 bitMask = 1 << which; |
|
357 |
|
358 if (!(bitMask & SSL_CB_IMPLEMENTED)) { |
|
359 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
|
360 *enabled = PR_FALSE; |
|
361 return SECFailure; |
|
362 } |
|
363 |
|
364 rv = (PRBool)((chosenPreference & bitMask) != 0); |
|
365 *enabled = rv; |
|
366 return SECSuccess; |
|
367 } |
|
368 |
|
369 SECStatus |
|
370 ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled) |
|
371 { |
|
372 PRUint32 bitMask; |
|
373 |
|
374 which &= 0x000f; |
|
375 bitMask = 1 << which; |
|
376 |
|
377 if (!(bitMask & SSL_CB_IMPLEMENTED)) { |
|
378 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
|
379 return SECFailure; |
|
380 } |
|
381 |
|
382 if (enabled) |
|
383 ss->chosenPreference |= bitMask; |
|
384 else |
|
385 ss->chosenPreference &= ~bitMask; |
|
386 ss->chosenPreference &= SSL_CB_IMPLEMENTED; |
|
387 |
|
388 return SECSuccess; |
|
389 } |
|
390 |
|
391 SECStatus |
|
392 ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled) |
|
393 { |
|
394 PRBool rv = PR_FALSE; |
|
395 PRUint32 bitMask; |
|
396 |
|
397 which &= 0x000f; |
|
398 bitMask = 1 << which; |
|
399 |
|
400 if (!(bitMask & SSL_CB_IMPLEMENTED)) { |
|
401 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE); |
|
402 *enabled = PR_FALSE; |
|
403 return SECFailure; |
|
404 } |
|
405 |
|
406 rv = (PRBool)((ss->chosenPreference & bitMask) != 0); |
|
407 *enabled = rv; |
|
408 return SECSuccess; |
|
409 } |
|
410 |
|
411 |
|
412 /* copy global default policy into socket. */ |
|
413 void |
|
414 ssl2_InitSocketPolicy(sslSocket *ss) |
|
415 { |
|
416 ss->allowedByPolicy = allowedByPolicy; |
|
417 ss->maybeAllowedByPolicy = maybeAllowedByPolicy; |
|
418 ss->chosenPreference = chosenPreference; |
|
419 } |
|
420 |
|
421 |
|
422 /************************************************************************/ |
|
423 |
|
424 /* Called from ssl2_CreateSessionCypher(), which already holds handshake lock. |
|
425 */ |
|
426 static SECStatus |
|
427 ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey, |
|
428 int cipherChoice) |
|
429 { |
|
430 switch (cipherChoice) { |
|
431 |
|
432 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: |
|
433 case SSL_CK_RC2_128_CBC_WITH_MD5: |
|
434 case SSL_CK_RC4_128_EXPORT40_WITH_MD5: |
|
435 case SSL_CK_RC4_128_WITH_MD5: |
|
436 case SSL_CK_DES_64_CBC_WITH_MD5: |
|
437 case SSL_CK_DES_192_EDE3_CBC_WITH_MD5: |
|
438 sec->hash = HASH_GetHashObject(HASH_AlgMD5); |
|
439 SECITEM_CopyItem(0, &sec->sendSecret, writeKey); |
|
440 SECITEM_CopyItem(0, &sec->rcvSecret, readKey); |
|
441 break; |
|
442 |
|
443 default: |
|
444 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
|
445 return SECFailure; |
|
446 } |
|
447 sec->hashcx = (*sec->hash->create)(); |
|
448 if (sec->hashcx == NULL) |
|
449 return SECFailure; |
|
450 return SECSuccess; |
|
451 } |
|
452 |
|
453 /************************************************************************ |
|
454 * All the Send functions below must acquire and release the socket's |
|
455 * xmitBufLock. |
|
456 */ |
|
457 |
|
458 /* Called from all the Send* functions below. */ |
|
459 static SECStatus |
|
460 ssl2_GetSendBuffer(sslSocket *ss, unsigned int len) |
|
461 { |
|
462 SECStatus rv = SECSuccess; |
|
463 |
|
464 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
|
465 |
|
466 if (len < 128) { |
|
467 len = 128; |
|
468 } |
|
469 if (len > ss->sec.ci.sendBuf.space) { |
|
470 rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, len); |
|
471 if (rv != SECSuccess) { |
|
472 SSL_DBG(("%d: SSL[%d]: ssl2_GetSendBuffer failed, tried to get %d bytes", |
|
473 SSL_GETPID(), ss->fd, len)); |
|
474 rv = SECFailure; |
|
475 } |
|
476 } |
|
477 return rv; |
|
478 } |
|
479 |
|
480 /* Called from: |
|
481 * ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage() |
|
482 * ssl2_HandleRequestCertificate() <- ssl2_HandleMessage() <- |
|
483 ssl_Do1stHandshake() |
|
484 * ssl2_HandleMessage() <- ssl_Do1stHandshake() |
|
485 * ssl2_HandleServerHelloMessage() <- ssl_Do1stHandshake() |
|
486 after ssl2_BeginClientHandshake() |
|
487 * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake() |
|
488 after ssl2_BeginServerHandshake() |
|
489 * |
|
490 * Acquires and releases the socket's xmitBufLock. |
|
491 */ |
|
492 int |
|
493 ssl2_SendErrorMessage(sslSocket *ss, int error) |
|
494 { |
|
495 int rv; |
|
496 PRUint8 msg[SSL_HL_ERROR_HBYTES]; |
|
497 |
|
498 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
499 |
|
500 msg[0] = SSL_MT_ERROR; |
|
501 msg[1] = MSB(error); |
|
502 msg[2] = LSB(error); |
|
503 |
|
504 ssl_GetXmitBufLock(ss); /***************************************/ |
|
505 |
|
506 SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error)); |
|
507 |
|
508 ss->handshakeBegun = 1; |
|
509 rv = (*ss->sec.send)(ss, msg, sizeof(msg), 0); |
|
510 if (rv >= 0) { |
|
511 rv = SECSuccess; |
|
512 } |
|
513 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
|
514 return rv; |
|
515 } |
|
516 |
|
517 /* Called from ssl2_TryToFinish(). |
|
518 * Acquires and releases the socket's xmitBufLock. |
|
519 */ |
|
520 static SECStatus |
|
521 ssl2_SendClientFinishedMessage(sslSocket *ss) |
|
522 { |
|
523 SECStatus rv = SECSuccess; |
|
524 int sent; |
|
525 PRUint8 msg[1 + SSL_CONNECTIONID_BYTES]; |
|
526 |
|
527 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
528 |
|
529 ssl_GetXmitBufLock(ss); /***************************************/ |
|
530 |
|
531 if (ss->sec.ci.sentFinished == 0) { |
|
532 ss->sec.ci.sentFinished = 1; |
|
533 |
|
534 SSL_TRC(3, ("%d: SSL[%d]: sending client-finished", |
|
535 SSL_GETPID(), ss->fd)); |
|
536 |
|
537 msg[0] = SSL_MT_CLIENT_FINISHED; |
|
538 PORT_Memcpy(msg+1, ss->sec.ci.connectionID, |
|
539 sizeof(ss->sec.ci.connectionID)); |
|
540 |
|
541 DUMP_MSG(29, (ss, msg, 1 + sizeof(ss->sec.ci.connectionID))); |
|
542 sent = (*ss->sec.send)(ss, msg, 1 + sizeof(ss->sec.ci.connectionID), 0); |
|
543 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; |
|
544 } |
|
545 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
|
546 return rv; |
|
547 } |
|
548 |
|
549 /* Called from |
|
550 * ssl2_HandleClientSessionKeyMessage() <- ssl2_HandleClientHelloMessage() |
|
551 * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake() |
|
552 after ssl2_BeginServerHandshake() |
|
553 * Acquires and releases the socket's xmitBufLock. |
|
554 */ |
|
555 static SECStatus |
|
556 ssl2_SendServerVerifyMessage(sslSocket *ss) |
|
557 { |
|
558 PRUint8 * msg; |
|
559 int sendLen; |
|
560 int sent; |
|
561 SECStatus rv; |
|
562 |
|
563 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
564 |
|
565 ssl_GetXmitBufLock(ss); /***************************************/ |
|
566 |
|
567 sendLen = 1 + SSL_CHALLENGE_BYTES; |
|
568 rv = ssl2_GetSendBuffer(ss, sendLen); |
|
569 if (rv != SECSuccess) { |
|
570 goto done; |
|
571 } |
|
572 |
|
573 msg = ss->sec.ci.sendBuf.buf; |
|
574 msg[0] = SSL_MT_SERVER_VERIFY; |
|
575 PORT_Memcpy(msg+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); |
|
576 |
|
577 DUMP_MSG(29, (ss, msg, sendLen)); |
|
578 sent = (*ss->sec.send)(ss, msg, sendLen, 0); |
|
579 |
|
580 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; |
|
581 |
|
582 done: |
|
583 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
|
584 return rv; |
|
585 } |
|
586 |
|
587 /* Called from ssl2_TryToFinish(). |
|
588 * Acquires and releases the socket's xmitBufLock. |
|
589 */ |
|
590 static SECStatus |
|
591 ssl2_SendServerFinishedMessage(sslSocket *ss) |
|
592 { |
|
593 sslSessionID * sid; |
|
594 PRUint8 * msg; |
|
595 int sendLen, sent; |
|
596 SECStatus rv = SECSuccess; |
|
597 |
|
598 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
599 |
|
600 ssl_GetXmitBufLock(ss); /***************************************/ |
|
601 |
|
602 if (ss->sec.ci.sentFinished == 0) { |
|
603 ss->sec.ci.sentFinished = 1; |
|
604 PORT_Assert(ss->sec.ci.sid != 0); |
|
605 sid = ss->sec.ci.sid; |
|
606 |
|
607 SSL_TRC(3, ("%d: SSL[%d]: sending server-finished", |
|
608 SSL_GETPID(), ss->fd)); |
|
609 |
|
610 sendLen = 1 + sizeof(sid->u.ssl2.sessionID); |
|
611 rv = ssl2_GetSendBuffer(ss, sendLen); |
|
612 if (rv != SECSuccess) { |
|
613 goto done; |
|
614 } |
|
615 |
|
616 msg = ss->sec.ci.sendBuf.buf; |
|
617 msg[0] = SSL_MT_SERVER_FINISHED; |
|
618 PORT_Memcpy(msg+1, sid->u.ssl2.sessionID, |
|
619 sizeof(sid->u.ssl2.sessionID)); |
|
620 |
|
621 DUMP_MSG(29, (ss, msg, sendLen)); |
|
622 sent = (*ss->sec.send)(ss, msg, sendLen, 0); |
|
623 |
|
624 if (sent < 0) { |
|
625 /* If send failed, it is now a bogus session-id */ |
|
626 if (ss->sec.uncache) |
|
627 (*ss->sec.uncache)(sid); |
|
628 rv = (SECStatus)sent; |
|
629 } else if (!ss->opt.noCache) { |
|
630 if (sid->cached == never_cached) { |
|
631 (*ss->sec.cache)(sid); |
|
632 } |
|
633 rv = SECSuccess; |
|
634 } |
|
635 ssl_FreeSID(sid); |
|
636 ss->sec.ci.sid = 0; |
|
637 } |
|
638 done: |
|
639 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
|
640 return rv; |
|
641 } |
|
642 |
|
643 /* Called from ssl2_ClientSetupSessionCypher() <- |
|
644 * ssl2_HandleServerHelloMessage() |
|
645 * after ssl2_BeginClientHandshake() |
|
646 * Acquires and releases the socket's xmitBufLock. |
|
647 */ |
|
648 static SECStatus |
|
649 ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize, |
|
650 PRUint8 *ca, int caLen, |
|
651 PRUint8 *ck, int ckLen, |
|
652 PRUint8 *ek, int ekLen) |
|
653 { |
|
654 PRUint8 * msg; |
|
655 int sendLen; |
|
656 int sent; |
|
657 SECStatus rv; |
|
658 |
|
659 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
660 |
|
661 ssl_GetXmitBufLock(ss); /***************************************/ |
|
662 |
|
663 sendLen = SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen; |
|
664 rv = ssl2_GetSendBuffer(ss, sendLen); |
|
665 if (rv != SECSuccess) |
|
666 goto done; |
|
667 |
|
668 SSL_TRC(3, ("%d: SSL[%d]: sending client-session-key", |
|
669 SSL_GETPID(), ss->fd)); |
|
670 |
|
671 msg = ss->sec.ci.sendBuf.buf; |
|
672 msg[0] = SSL_MT_CLIENT_MASTER_KEY; |
|
673 msg[1] = cipher; |
|
674 msg[2] = MSB(keySize); |
|
675 msg[3] = LSB(keySize); |
|
676 msg[4] = MSB(ckLen); |
|
677 msg[5] = LSB(ckLen); |
|
678 msg[6] = MSB(ekLen); |
|
679 msg[7] = LSB(ekLen); |
|
680 msg[8] = MSB(caLen); |
|
681 msg[9] = LSB(caLen); |
|
682 PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES, ck, ckLen); |
|
683 PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen, ek, ekLen); |
|
684 PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen+ekLen, ca, caLen); |
|
685 |
|
686 DUMP_MSG(29, (ss, msg, sendLen)); |
|
687 sent = (*ss->sec.send)(ss, msg, sendLen, 0); |
|
688 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; |
|
689 done: |
|
690 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
|
691 return rv; |
|
692 } |
|
693 |
|
694 /* Called from ssl2_TriggerNextMessage() <- ssl2_HandleMessage() |
|
695 * Acquires and releases the socket's xmitBufLock. |
|
696 */ |
|
697 static SECStatus |
|
698 ssl2_SendCertificateRequestMessage(sslSocket *ss) |
|
699 { |
|
700 PRUint8 * msg; |
|
701 int sent; |
|
702 int sendLen; |
|
703 SECStatus rv; |
|
704 |
|
705 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
706 |
|
707 ssl_GetXmitBufLock(ss); /***************************************/ |
|
708 |
|
709 sendLen = SSL_HL_REQUEST_CERTIFICATE_HBYTES + SSL_CHALLENGE_BYTES; |
|
710 rv = ssl2_GetSendBuffer(ss, sendLen); |
|
711 if (rv != SECSuccess) |
|
712 goto done; |
|
713 |
|
714 SSL_TRC(3, ("%d: SSL[%d]: sending certificate request", |
|
715 SSL_GETPID(), ss->fd)); |
|
716 |
|
717 /* Generate random challenge for client to encrypt */ |
|
718 PK11_GenerateRandom(ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); |
|
719 |
|
720 msg = ss->sec.ci.sendBuf.buf; |
|
721 msg[0] = SSL_MT_REQUEST_CERTIFICATE; |
|
722 msg[1] = SSL_AT_MD5_WITH_RSA_ENCRYPTION; |
|
723 PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES, |
|
724 ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); |
|
725 |
|
726 DUMP_MSG(29, (ss, msg, sendLen)); |
|
727 sent = (*ss->sec.send)(ss, msg, sendLen, 0); |
|
728 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent; |
|
729 done: |
|
730 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
|
731 return rv; |
|
732 } |
|
733 |
|
734 /* Called from ssl2_HandleRequestCertificate() <- ssl2_HandleMessage() |
|
735 * Acquires and releases the socket's xmitBufLock. |
|
736 */ |
|
737 static int |
|
738 ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert, |
|
739 SECItem *encCode) |
|
740 { |
|
741 PRUint8 *msg; |
|
742 int rv, sendLen; |
|
743 |
|
744 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
745 |
|
746 ssl_GetXmitBufLock(ss); /***************************************/ |
|
747 |
|
748 sendLen = SSL_HL_CLIENT_CERTIFICATE_HBYTES + encCode->len + cert->len; |
|
749 rv = ssl2_GetSendBuffer(ss, sendLen); |
|
750 if (rv) |
|
751 goto done; |
|
752 |
|
753 SSL_TRC(3, ("%d: SSL[%d]: sending certificate response", |
|
754 SSL_GETPID(), ss->fd)); |
|
755 |
|
756 msg = ss->sec.ci.sendBuf.buf; |
|
757 msg[0] = SSL_MT_CLIENT_CERTIFICATE; |
|
758 msg[1] = SSL_CT_X509_CERTIFICATE; |
|
759 msg[2] = MSB(cert->len); |
|
760 msg[3] = LSB(cert->len); |
|
761 msg[4] = MSB(encCode->len); |
|
762 msg[5] = LSB(encCode->len); |
|
763 PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES, cert->data, cert->len); |
|
764 PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES + cert->len, |
|
765 encCode->data, encCode->len); |
|
766 |
|
767 DUMP_MSG(29, (ss, msg, sendLen)); |
|
768 rv = (*ss->sec.send)(ss, msg, sendLen, 0); |
|
769 if (rv >= 0) { |
|
770 rv = SECSuccess; |
|
771 } |
|
772 done: |
|
773 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
|
774 return rv; |
|
775 } |
|
776 |
|
777 /******************************************************************** |
|
778 ** Send functions above this line must aquire & release the socket's |
|
779 ** xmitBufLock. |
|
780 ** All the ssl2_Send functions below this line are called vis ss->sec.send |
|
781 ** and require that the caller hold the xmitBufLock. |
|
782 */ |
|
783 |
|
784 /* |
|
785 ** Called from ssl2_SendStream, ssl2_SendBlock, but not from ssl2_SendClear. |
|
786 */ |
|
787 static SECStatus |
|
788 ssl2_CalcMAC(PRUint8 * result, |
|
789 sslSecurityInfo * sec, |
|
790 const PRUint8 * data, |
|
791 unsigned int dataLen, |
|
792 unsigned int paddingLen) |
|
793 { |
|
794 const PRUint8 * secret = sec->sendSecret.data; |
|
795 unsigned int secretLen = sec->sendSecret.len; |
|
796 unsigned long sequenceNumber = sec->sendSequence; |
|
797 unsigned int nout; |
|
798 PRUint8 seq[4]; |
|
799 PRUint8 padding[32];/* XXX max blocksize? */ |
|
800 |
|
801 if (!sec->hash || !sec->hash->length) |
|
802 return SECSuccess; |
|
803 if (!sec->hashcx) |
|
804 return SECFailure; |
|
805 |
|
806 /* Reset hash function */ |
|
807 (*sec->hash->begin)(sec->hashcx); |
|
808 |
|
809 /* Feed hash the data */ |
|
810 (*sec->hash->update)(sec->hashcx, secret, secretLen); |
|
811 (*sec->hash->update)(sec->hashcx, data, dataLen); |
|
812 PORT_Memset(padding, paddingLen, paddingLen); |
|
813 (*sec->hash->update)(sec->hashcx, padding, paddingLen); |
|
814 |
|
815 seq[0] = (PRUint8) (sequenceNumber >> 24); |
|
816 seq[1] = (PRUint8) (sequenceNumber >> 16); |
|
817 seq[2] = (PRUint8) (sequenceNumber >> 8); |
|
818 seq[3] = (PRUint8) (sequenceNumber); |
|
819 |
|
820 PRINT_BUF(60, (0, "calc-mac secret:", secret, secretLen)); |
|
821 PRINT_BUF(60, (0, "calc-mac data:", data, dataLen)); |
|
822 PRINT_BUF(60, (0, "calc-mac padding:", padding, paddingLen)); |
|
823 PRINT_BUF(60, (0, "calc-mac seq:", seq, 4)); |
|
824 |
|
825 (*sec->hash->update)(sec->hashcx, seq, 4); |
|
826 |
|
827 /* Get result */ |
|
828 (*sec->hash->end)(sec->hashcx, result, &nout, sec->hash->length); |
|
829 |
|
830 return SECSuccess; |
|
831 } |
|
832 |
|
833 /* |
|
834 ** Maximum transmission amounts. These are tiny bit smaller than they |
|
835 ** need to be (they account for the MAC length plus some padding), |
|
836 ** assuming the MAC is 16 bytes long and the padding is a max of 7 bytes |
|
837 ** long. This gives an additional 9 bytes of slop to work within. |
|
838 */ |
|
839 #define MAX_STREAM_CYPHER_LEN 0x7fe0 |
|
840 #define MAX_BLOCK_CYPHER_LEN 0x3fe0 |
|
841 |
|
842 /* |
|
843 ** Send some data in the clear. |
|
844 ** Package up data with the length header and send it. |
|
845 ** |
|
846 ** Return count of bytes successfully written, or negative number (failure). |
|
847 */ |
|
848 static PRInt32 |
|
849 ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) |
|
850 { |
|
851 PRUint8 * out; |
|
852 int rv; |
|
853 int amount; |
|
854 int count = 0; |
|
855 |
|
856 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); |
|
857 |
|
858 SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes in the clear", |
|
859 SSL_GETPID(), ss->fd, len)); |
|
860 PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len)); |
|
861 |
|
862 while (len) { |
|
863 amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN ); |
|
864 if (amount + 2 > ss->sec.writeBuf.space) { |
|
865 rv = sslBuffer_Grow(&ss->sec.writeBuf, amount + 2); |
|
866 if (rv != SECSuccess) { |
|
867 count = rv; |
|
868 break; |
|
869 } |
|
870 } |
|
871 out = ss->sec.writeBuf.buf; |
|
872 |
|
873 /* |
|
874 ** Construct message. |
|
875 */ |
|
876 out[0] = 0x80 | MSB(amount); |
|
877 out[1] = LSB(amount); |
|
878 PORT_Memcpy(&out[2], in, amount); |
|
879 |
|
880 /* Now send the data */ |
|
881 rv = ssl_DefSend(ss, out, amount + 2, flags & ~ssl_SEND_FLAG_MASK); |
|
882 if (rv < 0) { |
|
883 if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) { |
|
884 rv = 0; |
|
885 } else { |
|
886 /* Return short write if some data already went out... */ |
|
887 if (count == 0) |
|
888 count = rv; |
|
889 break; |
|
890 } |
|
891 } |
|
892 |
|
893 if ((unsigned)rv < (amount + 2)) { |
|
894 /* Short write. Save the data and return. */ |
|
895 if (ssl_SaveWriteData(ss, out + rv, amount + 2 - rv) |
|
896 == SECFailure) { |
|
897 count = SECFailure; |
|
898 } else { |
|
899 count += amount; |
|
900 ss->sec.sendSequence++; |
|
901 } |
|
902 break; |
|
903 } |
|
904 |
|
905 ss->sec.sendSequence++; |
|
906 in += amount; |
|
907 count += amount; |
|
908 len -= amount; |
|
909 } |
|
910 |
|
911 return count; |
|
912 } |
|
913 |
|
914 /* |
|
915 ** Send some data, when using a stream cipher. Stream ciphers have a |
|
916 ** block size of 1. Package up the data with the length header |
|
917 ** and send it. |
|
918 */ |
|
919 static PRInt32 |
|
920 ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) |
|
921 { |
|
922 PRUint8 * out; |
|
923 int rv; |
|
924 int count = 0; |
|
925 |
|
926 int amount; |
|
927 PRUint8 macLen; |
|
928 int nout; |
|
929 int buflen; |
|
930 |
|
931 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); |
|
932 |
|
933 SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using stream cipher", |
|
934 SSL_GETPID(), ss->fd, len)); |
|
935 PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len)); |
|
936 |
|
937 while (len) { |
|
938 ssl_GetSpecReadLock(ss); /*************************************/ |
|
939 |
|
940 macLen = ss->sec.hash->length; |
|
941 amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN ); |
|
942 buflen = amount + 2 + macLen; |
|
943 if (buflen > ss->sec.writeBuf.space) { |
|
944 rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen); |
|
945 if (rv != SECSuccess) { |
|
946 goto loser; |
|
947 } |
|
948 } |
|
949 out = ss->sec.writeBuf.buf; |
|
950 nout = amount + macLen; |
|
951 out[0] = 0x80 | MSB(nout); |
|
952 out[1] = LSB(nout); |
|
953 |
|
954 /* Calculate MAC */ |
|
955 rv = ssl2_CalcMAC(out+2, /* put MAC here */ |
|
956 &ss->sec, |
|
957 in, amount, /* input addr & length */ |
|
958 0); /* no padding */ |
|
959 if (rv != SECSuccess) |
|
960 goto loser; |
|
961 |
|
962 /* Encrypt MAC */ |
|
963 rv = (*ss->sec.enc)(ss->sec.writecx, out+2, &nout, macLen, out+2, macLen); |
|
964 if (rv) goto loser; |
|
965 |
|
966 /* Encrypt data from caller */ |
|
967 rv = (*ss->sec.enc)(ss->sec.writecx, out+2+macLen, &nout, amount, in, amount); |
|
968 if (rv) goto loser; |
|
969 |
|
970 ssl_ReleaseSpecReadLock(ss); /*************************************/ |
|
971 |
|
972 PRINT_BUF(50, (ss, "encrypted data:", out, buflen)); |
|
973 |
|
974 rv = ssl_DefSend(ss, out, buflen, flags & ~ssl_SEND_FLAG_MASK); |
|
975 if (rv < 0) { |
|
976 if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) { |
|
977 SSL_TRC(50, ("%d: SSL[%d]: send stream would block, " |
|
978 "saving data", SSL_GETPID(), ss->fd)); |
|
979 rv = 0; |
|
980 } else { |
|
981 SSL_TRC(10, ("%d: SSL[%d]: send stream error %d", |
|
982 SSL_GETPID(), ss->fd, PORT_GetError())); |
|
983 /* Return short write if some data already went out... */ |
|
984 if (count == 0) |
|
985 count = rv; |
|
986 goto done; |
|
987 } |
|
988 } |
|
989 |
|
990 if ((unsigned)rv < buflen) { |
|
991 /* Short write. Save the data and return. */ |
|
992 if (ssl_SaveWriteData(ss, out + rv, buflen - rv) == SECFailure) { |
|
993 count = SECFailure; |
|
994 } else { |
|
995 count += amount; |
|
996 ss->sec.sendSequence++; |
|
997 } |
|
998 goto done; |
|
999 } |
|
1000 |
|
1001 ss->sec.sendSequence++; |
|
1002 in += amount; |
|
1003 count += amount; |
|
1004 len -= amount; |
|
1005 } |
|
1006 |
|
1007 done: |
|
1008 return count; |
|
1009 |
|
1010 loser: |
|
1011 ssl_ReleaseSpecReadLock(ss); |
|
1012 return SECFailure; |
|
1013 } |
|
1014 |
|
1015 /* |
|
1016 ** Send some data, when using a block cipher. Package up the data with |
|
1017 ** the length header and send it. |
|
1018 */ |
|
1019 /* XXX assumes blocksize is > 7 */ |
|
1020 static PRInt32 |
|
1021 ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags) |
|
1022 { |
|
1023 PRUint8 * out; /* begining of output buffer. */ |
|
1024 PRUint8 * op; /* next output byte goes here. */ |
|
1025 int rv; /* value from funcs we called. */ |
|
1026 int count = 0; /* this function's return value. */ |
|
1027 |
|
1028 unsigned int hlen; /* output record hdr len, 2 or 3 */ |
|
1029 unsigned int macLen; /* MAC is this many bytes long. */ |
|
1030 int amount; /* of plaintext to go in record. */ |
|
1031 unsigned int padding; /* add this many padding byte. */ |
|
1032 int nout; /* ciphertext size after header. */ |
|
1033 int buflen; /* size of generated record. */ |
|
1034 |
|
1035 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); |
|
1036 |
|
1037 SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using block cipher", |
|
1038 SSL_GETPID(), ss->fd, len)); |
|
1039 PRINT_BUF(50, (ss, "clear data:", in, len)); |
|
1040 |
|
1041 while (len) { |
|
1042 ssl_GetSpecReadLock(ss); /*************************************/ |
|
1043 |
|
1044 macLen = ss->sec.hash->length; |
|
1045 /* Figure out how much to send, including mac and padding */ |
|
1046 amount = PR_MIN( len, MAX_BLOCK_CYPHER_LEN ); |
|
1047 nout = amount + macLen; |
|
1048 padding = nout & (ss->sec.blockSize - 1); |
|
1049 if (padding) { |
|
1050 hlen = 3; |
|
1051 padding = ss->sec.blockSize - padding; |
|
1052 nout += padding; |
|
1053 } else { |
|
1054 hlen = 2; |
|
1055 } |
|
1056 buflen = hlen + nout; |
|
1057 if (buflen > ss->sec.writeBuf.space) { |
|
1058 rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen); |
|
1059 if (rv != SECSuccess) { |
|
1060 goto loser; |
|
1061 } |
|
1062 } |
|
1063 out = ss->sec.writeBuf.buf; |
|
1064 |
|
1065 /* Construct header */ |
|
1066 op = out; |
|
1067 if (padding) { |
|
1068 *op++ = MSB(nout); |
|
1069 *op++ = LSB(nout); |
|
1070 *op++ = padding; |
|
1071 } else { |
|
1072 *op++ = 0x80 | MSB(nout); |
|
1073 *op++ = LSB(nout); |
|
1074 } |
|
1075 |
|
1076 /* Calculate MAC */ |
|
1077 rv = ssl2_CalcMAC(op, /* MAC goes here. */ |
|
1078 &ss->sec, |
|
1079 in, amount, /* intput addr, len */ |
|
1080 padding); |
|
1081 if (rv != SECSuccess) |
|
1082 goto loser; |
|
1083 op += macLen; |
|
1084 |
|
1085 /* Copy in the input data */ |
|
1086 /* XXX could eliminate the copy by folding it into the encryption */ |
|
1087 PORT_Memcpy(op, in, amount); |
|
1088 op += amount; |
|
1089 if (padding) { |
|
1090 PORT_Memset(op, padding, padding); |
|
1091 op += padding; |
|
1092 } |
|
1093 |
|
1094 /* Encrypt result */ |
|
1095 rv = (*ss->sec.enc)(ss->sec.writecx, out+hlen, &nout, buflen-hlen, |
|
1096 out+hlen, op - (out + hlen)); |
|
1097 if (rv) |
|
1098 goto loser; |
|
1099 |
|
1100 ssl_ReleaseSpecReadLock(ss); /*************************************/ |
|
1101 |
|
1102 PRINT_BUF(50, (ss, "final xmit data:", out, op - out)); |
|
1103 |
|
1104 rv = ssl_DefSend(ss, out, op - out, flags & ~ssl_SEND_FLAG_MASK); |
|
1105 if (rv < 0) { |
|
1106 if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) { |
|
1107 rv = 0; |
|
1108 } else { |
|
1109 SSL_TRC(10, ("%d: SSL[%d]: send block error %d", |
|
1110 SSL_GETPID(), ss->fd, PORT_GetError())); |
|
1111 /* Return short write if some data already went out... */ |
|
1112 if (count == 0) |
|
1113 count = rv; |
|
1114 goto done; |
|
1115 } |
|
1116 } |
|
1117 |
|
1118 if (rv < (op - out)) { |
|
1119 /* Short write. Save the data and return. */ |
|
1120 if (ssl_SaveWriteData(ss, out + rv, op - out - rv) == SECFailure) { |
|
1121 count = SECFailure; |
|
1122 } else { |
|
1123 count += amount; |
|
1124 ss->sec.sendSequence++; |
|
1125 } |
|
1126 goto done; |
|
1127 } |
|
1128 |
|
1129 ss->sec.sendSequence++; |
|
1130 in += amount; |
|
1131 count += amount; |
|
1132 len -= amount; |
|
1133 } |
|
1134 |
|
1135 done: |
|
1136 return count; |
|
1137 |
|
1138 loser: |
|
1139 ssl_ReleaseSpecReadLock(ss); |
|
1140 return SECFailure; |
|
1141 } |
|
1142 |
|
1143 /* |
|
1144 ** Called from: ssl2_HandleServerHelloMessage, |
|
1145 ** ssl2_HandleClientSessionKeyMessage, |
|
1146 ** ssl2_HandleClientHelloMessage, |
|
1147 ** |
|
1148 */ |
|
1149 static void |
|
1150 ssl2_UseEncryptedSendFunc(sslSocket *ss) |
|
1151 { |
|
1152 ssl_GetXmitBufLock(ss); |
|
1153 PORT_Assert(ss->sec.hashcx != 0); |
|
1154 |
|
1155 ss->gs.encrypted = 1; |
|
1156 ss->sec.send = (ss->sec.blockSize > 1) ? ssl2_SendBlock : ssl2_SendStream; |
|
1157 ssl_ReleaseXmitBufLock(ss); |
|
1158 } |
|
1159 |
|
1160 /* Called while initializing socket in ssl_CreateSecurityInfo(). |
|
1161 ** This function allows us to keep the name of ssl2_SendClear static. |
|
1162 */ |
|
1163 void |
|
1164 ssl2_UseClearSendFunc(sslSocket *ss) |
|
1165 { |
|
1166 ss->sec.send = ssl2_SendClear; |
|
1167 } |
|
1168 |
|
1169 /************************************************************************ |
|
1170 ** END of Send functions. * |
|
1171 *************************************************************************/ |
|
1172 |
|
1173 /*********************************************************************** |
|
1174 * For SSL3, this gathers in and handles records/messages until either |
|
1175 * the handshake is complete or application data is available. |
|
1176 * |
|
1177 * For SSL2, this gathers in only the next SSLV2 record. |
|
1178 * |
|
1179 * Called from ssl_Do1stHandshake() via function pointer ss->handshake. |
|
1180 * Caller must hold handshake lock. |
|
1181 * This function acquires and releases the RecvBufLock. |
|
1182 * |
|
1183 * returns SECSuccess for success. |
|
1184 * returns SECWouldBlock when that value is returned by ssl2_GatherRecord() or |
|
1185 * ssl3_GatherCompleteHandshake(). |
|
1186 * returns SECFailure on all other errors. |
|
1187 * |
|
1188 * The gather functions called by ssl_GatherRecord1stHandshake are expected |
|
1189 * to return values interpreted as follows: |
|
1190 * 1 : the function completed without error. |
|
1191 * 0 : the function read EOF. |
|
1192 * -1 : read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error. |
|
1193 * -2 : the function wants ssl_GatherRecord1stHandshake to be called again |
|
1194 * immediately, by ssl_Do1stHandshake. |
|
1195 * |
|
1196 * This code is similar to, and easily confused with, DoRecv() in sslsecur.c |
|
1197 * |
|
1198 * This function is called from ssl_Do1stHandshake(). |
|
1199 * The following functions put ssl_GatherRecord1stHandshake into ss->handshake: |
|
1200 * ssl2_HandleMessage |
|
1201 * ssl2_HandleVerifyMessage |
|
1202 * ssl2_HandleServerHelloMessage |
|
1203 * ssl2_BeginClientHandshake |
|
1204 * ssl2_HandleClientSessionKeyMessage |
|
1205 * ssl3_RestartHandshakeAfterCertReq |
|
1206 * ssl3_RestartHandshakeAfterServerCert |
|
1207 * ssl2_HandleClientHelloMessage |
|
1208 * ssl2_BeginServerHandshake |
|
1209 */ |
|
1210 SECStatus |
|
1211 ssl_GatherRecord1stHandshake(sslSocket *ss) |
|
1212 { |
|
1213 int rv; |
|
1214 |
|
1215 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
1216 |
|
1217 ssl_GetRecvBufLock(ss); |
|
1218 |
|
1219 /* The special case DTLS logic is needed here because the SSL/TLS |
|
1220 * version wants to auto-detect SSL2 vs. SSL3 on the initial handshake |
|
1221 * (ss->version == 0) but with DTLS it gets confused, so we force the |
|
1222 * SSL3 version. |
|
1223 */ |
|
1224 if ((ss->version >= SSL_LIBRARY_VERSION_3_0) || IS_DTLS(ss)) { |
|
1225 /* Wait for handshake to complete, or application data to arrive. */ |
|
1226 rv = ssl3_GatherCompleteHandshake(ss, 0); |
|
1227 } else { |
|
1228 /* See if we have a complete record */ |
|
1229 rv = ssl2_GatherRecord(ss, 0); |
|
1230 } |
|
1231 SSL_TRC(10, ("%d: SSL[%d]: handshake gathering, rv=%d", |
|
1232 SSL_GETPID(), ss->fd, rv)); |
|
1233 |
|
1234 ssl_ReleaseRecvBufLock(ss); |
|
1235 |
|
1236 if (rv <= 0) { |
|
1237 if (rv == SECWouldBlock) { |
|
1238 /* Progress is blocked waiting for callback completion. */ |
|
1239 SSL_TRC(10, ("%d: SSL[%d]: handshake blocked (need %d)", |
|
1240 SSL_GETPID(), ss->fd, ss->gs.remainder)); |
|
1241 return SECWouldBlock; |
|
1242 } |
|
1243 if (rv == 0) { |
|
1244 /* EOF. Loser */ |
|
1245 PORT_SetError(PR_END_OF_FILE_ERROR); |
|
1246 } |
|
1247 return SECFailure; /* rv is < 0 here. */ |
|
1248 } |
|
1249 |
|
1250 SSL_TRC(10, ("%d: SSL[%d]: got handshake record of %d bytes", |
|
1251 SSL_GETPID(), ss->fd, ss->gs.recordLen)); |
|
1252 |
|
1253 ss->handshake = 0; /* makes ssl_Do1stHandshake call ss->nextHandshake.*/ |
|
1254 return SECSuccess; |
|
1255 } |
|
1256 |
|
1257 /************************************************************************/ |
|
1258 |
|
1259 /* Called from ssl2_ServerSetupSessionCypher() |
|
1260 * ssl2_ClientSetupSessionCypher() |
|
1261 */ |
|
1262 static SECStatus |
|
1263 ssl2_FillInSID(sslSessionID * sid, |
|
1264 int cipher, |
|
1265 PRUint8 *keyData, |
|
1266 int keyLen, |
|
1267 PRUint8 *ca, |
|
1268 int caLen, |
|
1269 int keyBits, |
|
1270 int secretKeyBits, |
|
1271 SSLSignType authAlgorithm, |
|
1272 PRUint32 authKeyBits, |
|
1273 SSLKEAType keaType, |
|
1274 PRUint32 keaKeyBits) |
|
1275 { |
|
1276 PORT_Assert(sid->references == 1); |
|
1277 PORT_Assert(sid->cached == never_cached); |
|
1278 PORT_Assert(sid->u.ssl2.masterKey.data == 0); |
|
1279 PORT_Assert(sid->u.ssl2.cipherArg.data == 0); |
|
1280 |
|
1281 sid->version = SSL_LIBRARY_VERSION_2; |
|
1282 |
|
1283 sid->u.ssl2.cipherType = cipher; |
|
1284 sid->u.ssl2.masterKey.data = (PRUint8*) PORT_Alloc(keyLen); |
|
1285 if (!sid->u.ssl2.masterKey.data) { |
|
1286 return SECFailure; |
|
1287 } |
|
1288 PORT_Memcpy(sid->u.ssl2.masterKey.data, keyData, keyLen); |
|
1289 sid->u.ssl2.masterKey.len = keyLen; |
|
1290 sid->u.ssl2.keyBits = keyBits; |
|
1291 sid->u.ssl2.secretKeyBits = secretKeyBits; |
|
1292 sid->authAlgorithm = authAlgorithm; |
|
1293 sid->authKeyBits = authKeyBits; |
|
1294 sid->keaType = keaType; |
|
1295 sid->keaKeyBits = keaKeyBits; |
|
1296 sid->lastAccessTime = sid->creationTime = ssl_Time(); |
|
1297 sid->expirationTime = sid->creationTime + ssl_sid_timeout; |
|
1298 |
|
1299 if (caLen) { |
|
1300 sid->u.ssl2.cipherArg.data = (PRUint8*) PORT_Alloc(caLen); |
|
1301 if (!sid->u.ssl2.cipherArg.data) { |
|
1302 return SECFailure; |
|
1303 } |
|
1304 sid->u.ssl2.cipherArg.len = caLen; |
|
1305 PORT_Memcpy(sid->u.ssl2.cipherArg.data, ca, caLen); |
|
1306 } |
|
1307 return SECSuccess; |
|
1308 } |
|
1309 |
|
1310 /* |
|
1311 ** Construct session keys given the masterKey (tied to the session-id), |
|
1312 ** the client's challenge and the server's nonce. |
|
1313 ** |
|
1314 ** Called from ssl2_CreateSessionCypher() <- |
|
1315 */ |
|
1316 static SECStatus |
|
1317 ssl2_ProduceKeys(sslSocket * ss, |
|
1318 SECItem * readKey, |
|
1319 SECItem * writeKey, |
|
1320 SECItem * masterKey, |
|
1321 PRUint8 * challenge, |
|
1322 PRUint8 * nonce, |
|
1323 int cipherType) |
|
1324 { |
|
1325 PK11Context * cx = 0; |
|
1326 unsigned nkm = 0; /* number of hashes to generate key mat. */ |
|
1327 unsigned nkd = 0; /* size of readKey and writeKey. */ |
|
1328 unsigned part; |
|
1329 unsigned i; |
|
1330 unsigned off; |
|
1331 SECStatus rv; |
|
1332 PRUint8 countChar; |
|
1333 PRUint8 km[3*16]; /* buffer for key material. */ |
|
1334 |
|
1335 readKey->data = 0; |
|
1336 writeKey->data = 0; |
|
1337 |
|
1338 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
1339 |
|
1340 rv = SECSuccess; |
|
1341 cx = PK11_CreateDigestContext(SEC_OID_MD5); |
|
1342 if (cx == NULL) { |
|
1343 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
|
1344 return SECFailure; |
|
1345 } |
|
1346 |
|
1347 nkm = ssl_Specs[cipherType].nkm; |
|
1348 nkd = ssl_Specs[cipherType].nkd; |
|
1349 |
|
1350 readKey->data = (PRUint8*) PORT_Alloc(nkd); |
|
1351 if (!readKey->data) |
|
1352 goto loser; |
|
1353 readKey->len = nkd; |
|
1354 |
|
1355 writeKey->data = (PRUint8*) PORT_Alloc(nkd); |
|
1356 if (!writeKey->data) |
|
1357 goto loser; |
|
1358 writeKey->len = nkd; |
|
1359 |
|
1360 /* Produce key material */ |
|
1361 countChar = '0'; |
|
1362 for (i = 0, off = 0; i < nkm; i++, off += 16) { |
|
1363 rv = PK11_DigestBegin(cx); |
|
1364 rv |= PK11_DigestOp(cx, masterKey->data, masterKey->len); |
|
1365 rv |= PK11_DigestOp(cx, &countChar, 1); |
|
1366 rv |= PK11_DigestOp(cx, challenge, SSL_CHALLENGE_BYTES); |
|
1367 rv |= PK11_DigestOp(cx, nonce, SSL_CONNECTIONID_BYTES); |
|
1368 rv |= PK11_DigestFinal(cx, km+off, &part, MD5_LENGTH); |
|
1369 if (rv != SECSuccess) { |
|
1370 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE); |
|
1371 rv = SECFailure; |
|
1372 goto loser; |
|
1373 } |
|
1374 countChar++; |
|
1375 } |
|
1376 |
|
1377 /* Produce keys */ |
|
1378 PORT_Memcpy(readKey->data, km, nkd); |
|
1379 PORT_Memcpy(writeKey->data, km + nkd, nkd); |
|
1380 |
|
1381 loser: |
|
1382 PK11_DestroyContext(cx, PR_TRUE); |
|
1383 return rv; |
|
1384 } |
|
1385 |
|
1386 /* Called from ssl2_ServerSetupSessionCypher() |
|
1387 ** <- ssl2_HandleClientSessionKeyMessage() |
|
1388 ** <- ssl2_HandleClientHelloMessage() |
|
1389 ** and from ssl2_ClientSetupSessionCypher() |
|
1390 ** <- ssl2_HandleServerHelloMessage() |
|
1391 */ |
|
1392 static SECStatus |
|
1393 ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient) |
|
1394 { |
|
1395 SECItem * rk = NULL; |
|
1396 SECItem * wk = NULL; |
|
1397 SECItem * param; |
|
1398 SECStatus rv; |
|
1399 int cipherType = sid->u.ssl2.cipherType; |
|
1400 PK11SlotInfo * slot = NULL; |
|
1401 CK_MECHANISM_TYPE mechanism; |
|
1402 SECItem readKey; |
|
1403 SECItem writeKey; |
|
1404 |
|
1405 void *readcx = 0; |
|
1406 void *writecx = 0; |
|
1407 readKey.data = 0; |
|
1408 writeKey.data = 0; |
|
1409 |
|
1410 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
1411 if (ss->sec.ci.sid == 0) |
|
1412 goto sec_loser; /* don't crash if asserts are off */ |
|
1413 |
|
1414 /* Trying to cut down on all these switch statements that should be tables. |
|
1415 * So, test cipherType once, here, and then use tables below. |
|
1416 */ |
|
1417 switch (cipherType) { |
|
1418 case SSL_CK_RC4_128_EXPORT40_WITH_MD5: |
|
1419 case SSL_CK_RC4_128_WITH_MD5: |
|
1420 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: |
|
1421 case SSL_CK_RC2_128_CBC_WITH_MD5: |
|
1422 case SSL_CK_DES_64_CBC_WITH_MD5: |
|
1423 case SSL_CK_DES_192_EDE3_CBC_WITH_MD5: |
|
1424 break; |
|
1425 |
|
1426 default: |
|
1427 SSL_DBG(("%d: SSL[%d]: ssl2_CreateSessionCypher: unknown cipher=%d", |
|
1428 SSL_GETPID(), ss->fd, cipherType)); |
|
1429 PORT_SetError(isClient ? SSL_ERROR_BAD_SERVER : SSL_ERROR_BAD_CLIENT); |
|
1430 goto sec_loser; |
|
1431 } |
|
1432 |
|
1433 rk = isClient ? &readKey : &writeKey; |
|
1434 wk = isClient ? &writeKey : &readKey; |
|
1435 |
|
1436 /* Produce the keys for this session */ |
|
1437 rv = ssl2_ProduceKeys(ss, &readKey, &writeKey, &sid->u.ssl2.masterKey, |
|
1438 ss->sec.ci.clientChallenge, ss->sec.ci.connectionID, |
|
1439 cipherType); |
|
1440 if (rv != SECSuccess) |
|
1441 goto loser; |
|
1442 PRINT_BUF(7, (ss, "Session read-key: ", rk->data, rk->len)); |
|
1443 PRINT_BUF(7, (ss, "Session write-key: ", wk->data, wk->len)); |
|
1444 |
|
1445 PORT_Memcpy(ss->sec.ci.readKey, readKey.data, readKey.len); |
|
1446 PORT_Memcpy(ss->sec.ci.writeKey, writeKey.data, writeKey.len); |
|
1447 ss->sec.ci.keySize = readKey.len; |
|
1448 |
|
1449 /* Setup the MAC */ |
|
1450 rv = ssl2_CreateMAC(&ss->sec, rk, wk, cipherType); |
|
1451 if (rv != SECSuccess) |
|
1452 goto loser; |
|
1453 |
|
1454 /* First create the session key object */ |
|
1455 SSL_TRC(3, ("%d: SSL[%d]: using %s", SSL_GETPID(), ss->fd, |
|
1456 ssl_cipherName[cipherType])); |
|
1457 |
|
1458 |
|
1459 mechanism = ssl_Specs[cipherType].mechanism; |
|
1460 |
|
1461 /* set destructer before we call loser... */ |
|
1462 ss->sec.destroy = (void (*)(void*, PRBool)) PK11_DestroyContext; |
|
1463 slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg); |
|
1464 if (slot == NULL) |
|
1465 goto loser; |
|
1466 |
|
1467 param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg); |
|
1468 if (param == NULL) |
|
1469 goto loser; |
|
1470 readcx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap, |
|
1471 CKA_DECRYPT, rk, param, |
|
1472 ss->pkcs11PinArg); |
|
1473 SECITEM_FreeItem(param, PR_TRUE); |
|
1474 if (readcx == NULL) |
|
1475 goto loser; |
|
1476 |
|
1477 /* build the client context */ |
|
1478 param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg); |
|
1479 if (param == NULL) |
|
1480 goto loser; |
|
1481 writecx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap, |
|
1482 CKA_ENCRYPT, wk, param, |
|
1483 ss->pkcs11PinArg); |
|
1484 SECITEM_FreeItem(param,PR_TRUE); |
|
1485 if (writecx == NULL) |
|
1486 goto loser; |
|
1487 PK11_FreeSlot(slot); |
|
1488 |
|
1489 rv = SECSuccess; |
|
1490 ss->sec.enc = (SSLCipher) PK11_CipherOp; |
|
1491 ss->sec.dec = (SSLCipher) PK11_CipherOp; |
|
1492 ss->sec.readcx = (void *) readcx; |
|
1493 ss->sec.writecx = (void *) writecx; |
|
1494 ss->sec.blockSize = ssl_Specs[cipherType].blockSize; |
|
1495 ss->sec.blockShift = ssl_Specs[cipherType].blockShift; |
|
1496 ss->sec.cipherType = sid->u.ssl2.cipherType; |
|
1497 ss->sec.keyBits = sid->u.ssl2.keyBits; |
|
1498 ss->sec.secretKeyBits = sid->u.ssl2.secretKeyBits; |
|
1499 goto done; |
|
1500 |
|
1501 loser: |
|
1502 if (ss->sec.destroy) { |
|
1503 if (readcx) (*ss->sec.destroy)(readcx, PR_TRUE); |
|
1504 if (writecx) (*ss->sec.destroy)(writecx, PR_TRUE); |
|
1505 } |
|
1506 ss->sec.destroy = NULL; |
|
1507 if (slot) PK11_FreeSlot(slot); |
|
1508 |
|
1509 sec_loser: |
|
1510 rv = SECFailure; |
|
1511 |
|
1512 done: |
|
1513 if (rk) { |
|
1514 SECITEM_ZfreeItem(rk, PR_FALSE); |
|
1515 } |
|
1516 if (wk) { |
|
1517 SECITEM_ZfreeItem(wk, PR_FALSE); |
|
1518 } |
|
1519 return rv; |
|
1520 } |
|
1521 |
|
1522 /* |
|
1523 ** Setup the server ciphers given information from a CLIENT-MASTER-KEY |
|
1524 ** message. |
|
1525 ** "ss" pointer to the ssl-socket object |
|
1526 ** "cipher" the cipher type to use |
|
1527 ** "keyBits" the size of the final cipher key |
|
1528 ** "ck" the clear-key data |
|
1529 ** "ckLen" the number of bytes of clear-key data |
|
1530 ** "ek" the encrypted-key data |
|
1531 ** "ekLen" the number of bytes of encrypted-key data |
|
1532 ** "ca" the cipher-arg data |
|
1533 ** "caLen" the number of bytes of cipher-arg data |
|
1534 ** |
|
1535 ** The MASTER-KEY is constructed by first decrypting the encrypted-key |
|
1536 ** data. This produces the SECRET-KEY-DATA. The MASTER-KEY is composed by |
|
1537 ** concatenating the clear-key data with the SECRET-KEY-DATA. This code |
|
1538 ** checks to make sure that the client didn't send us an improper amount |
|
1539 ** of SECRET-KEY-DATA (it restricts the length of that data to match the |
|
1540 ** spec). |
|
1541 ** |
|
1542 ** Called from ssl2_HandleClientSessionKeyMessage(). |
|
1543 */ |
|
1544 static SECStatus |
|
1545 ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits, |
|
1546 PRUint8 *ck, unsigned int ckLen, |
|
1547 PRUint8 *ek, unsigned int ekLen, |
|
1548 PRUint8 *ca, unsigned int caLen) |
|
1549 { |
|
1550 PRUint8 * dk = NULL; /* decrypted master key */ |
|
1551 sslSessionID * sid; |
|
1552 sslServerCerts * sc = ss->serverCerts + kt_rsa; |
|
1553 PRUint8 * kbuf = 0; /* buffer for RSA decrypted data. */ |
|
1554 unsigned int ddLen; /* length of RSA decrypted data in kbuf */ |
|
1555 unsigned int keySize; |
|
1556 unsigned int dkLen; /* decrypted key length in bytes */ |
|
1557 int modulusLen; |
|
1558 SECStatus rv; |
|
1559 PRUint16 allowed; /* cipher kinds enabled and allowed by policy */ |
|
1560 PRUint8 mkbuf[SSL_MAX_MASTER_KEY_BYTES]; |
|
1561 |
|
1562 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
1563 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
|
1564 PORT_Assert((sc->SERVERKEY != 0)); |
|
1565 PORT_Assert((ss->sec.ci.sid != 0)); |
|
1566 sid = ss->sec.ci.sid; |
|
1567 |
|
1568 /* Trying to cut down on all these switch statements that should be tables. |
|
1569 * So, test cipherType once, here, and then use tables below. |
|
1570 */ |
|
1571 switch (cipher) { |
|
1572 case SSL_CK_RC4_128_EXPORT40_WITH_MD5: |
|
1573 case SSL_CK_RC4_128_WITH_MD5: |
|
1574 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: |
|
1575 case SSL_CK_RC2_128_CBC_WITH_MD5: |
|
1576 case SSL_CK_DES_64_CBC_WITH_MD5: |
|
1577 case SSL_CK_DES_192_EDE3_CBC_WITH_MD5: |
|
1578 break; |
|
1579 |
|
1580 default: |
|
1581 SSL_DBG(("%d: SSL[%d]: ssl2_ServerSetupSessionCypher: unknown cipher=%d", |
|
1582 SSL_GETPID(), ss->fd, cipher)); |
|
1583 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
|
1584 goto loser; |
|
1585 } |
|
1586 |
|
1587 allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED; |
|
1588 if (!(allowed & (1 << cipher))) { |
|
1589 /* client chose a kind we don't allow! */ |
|
1590 SSL_DBG(("%d: SSL[%d]: disallowed cipher=%d", |
|
1591 SSL_GETPID(), ss->fd, cipher)); |
|
1592 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
|
1593 goto loser; |
|
1594 } |
|
1595 |
|
1596 keySize = ssl_Specs[cipher].keyLen; |
|
1597 if (keyBits != keySize * BPB) { |
|
1598 SSL_DBG(("%d: SSL[%d]: invalid master secret key length=%d (bits)!", |
|
1599 SSL_GETPID(), ss->fd, keyBits)); |
|
1600 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
|
1601 goto loser; |
|
1602 } |
|
1603 |
|
1604 if (ckLen != ssl_Specs[cipher].pubLen) { |
|
1605 SSL_DBG(("%d: SSL[%d]: invalid clear key length, ckLen=%d (bytes)!", |
|
1606 SSL_GETPID(), ss->fd, ckLen)); |
|
1607 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
|
1608 goto loser; |
|
1609 } |
|
1610 |
|
1611 if (caLen != ssl_Specs[cipher].ivLen) { |
|
1612 SSL_DBG(("%d: SSL[%d]: invalid key args length, caLen=%d (bytes)!", |
|
1613 SSL_GETPID(), ss->fd, caLen)); |
|
1614 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
|
1615 goto loser; |
|
1616 } |
|
1617 |
|
1618 modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY); |
|
1619 if (modulusLen == -1) { |
|
1620 /* XXX If the key is bad, then PK11_PubDecryptRaw will fail below. */ |
|
1621 modulusLen = ekLen; |
|
1622 } |
|
1623 if (ekLen > modulusLen || ekLen + ckLen < keySize) { |
|
1624 SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!", |
|
1625 SSL_GETPID(), ss->fd, ekLen)); |
|
1626 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
|
1627 goto loser; |
|
1628 } |
|
1629 |
|
1630 /* allocate the buffer to hold the decrypted portion of the key. */ |
|
1631 kbuf = (PRUint8*)PORT_Alloc(modulusLen); |
|
1632 if (!kbuf) { |
|
1633 goto loser; |
|
1634 } |
|
1635 dkLen = keySize - ckLen; |
|
1636 dk = kbuf + modulusLen - dkLen; |
|
1637 |
|
1638 /* Decrypt encrypted half of the key. |
|
1639 ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is |
|
1640 ** desired behavior here. |
|
1641 */ |
|
1642 rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &ddLen, modulusLen, ek, ekLen); |
|
1643 if (rv != SECSuccess) |
|
1644 goto hide_loser; |
|
1645 |
|
1646 /* Is the length of the decrypted data (ddLen) the expected value? */ |
|
1647 if (modulusLen != ddLen) |
|
1648 goto hide_loser; |
|
1649 |
|
1650 /* Cheaply verify that PKCS#1 was used to format the encryption block */ |
|
1651 if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (dk[-1] != 0x00)) { |
|
1652 SSL_DBG(("%d: SSL[%d]: strange encryption block", |
|
1653 SSL_GETPID(), ss->fd)); |
|
1654 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
|
1655 goto hide_loser; |
|
1656 } |
|
1657 |
|
1658 /* Make sure we're not subject to a version rollback attack. */ |
|
1659 if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { |
|
1660 static const PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03, |
|
1661 0x03, 0x03, 0x03, 0x03 }; |
|
1662 |
|
1663 if (PORT_Memcmp(dk - 8 - 1, threes, 8) == 0) { |
|
1664 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
|
1665 goto hide_loser; |
|
1666 } |
|
1667 } |
|
1668 if (0) { |
|
1669 hide_loser: |
|
1670 /* Defense against the Bleichenbacher attack. |
|
1671 * Provide the client with NO CLUES that the decrypted master key |
|
1672 * was erroneous. Don't send any error messages. |
|
1673 * Instead, Generate a completely bogus master key . |
|
1674 */ |
|
1675 PK11_GenerateRandom(dk, dkLen); |
|
1676 } |
|
1677 |
|
1678 /* |
|
1679 ** Construct master key out of the pieces. |
|
1680 */ |
|
1681 if (ckLen) { |
|
1682 PORT_Memcpy(mkbuf, ck, ckLen); |
|
1683 } |
|
1684 PORT_Memcpy(mkbuf + ckLen, dk, dkLen); |
|
1685 |
|
1686 /* Fill in session-id */ |
|
1687 rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen, |
|
1688 keyBits, keyBits - (ckLen<<3), |
|
1689 ss->sec.authAlgorithm, ss->sec.authKeyBits, |
|
1690 ss->sec.keaType, ss->sec.keaKeyBits); |
|
1691 if (rv != SECSuccess) { |
|
1692 goto loser; |
|
1693 } |
|
1694 |
|
1695 /* Create session ciphers */ |
|
1696 rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE); |
|
1697 if (rv != SECSuccess) { |
|
1698 goto loser; |
|
1699 } |
|
1700 |
|
1701 SSL_TRC(1, ("%d: SSL[%d]: server, using %s cipher, clear=%d total=%d", |
|
1702 SSL_GETPID(), ss->fd, ssl_cipherName[cipher], |
|
1703 ckLen<<3, keySize<<3)); |
|
1704 rv = SECSuccess; |
|
1705 goto done; |
|
1706 |
|
1707 loser: |
|
1708 rv = SECFailure; |
|
1709 |
|
1710 done: |
|
1711 PORT_Free(kbuf); |
|
1712 return rv; |
|
1713 } |
|
1714 |
|
1715 /************************************************************************/ |
|
1716 |
|
1717 /* |
|
1718 ** Rewrite the incoming cipher specs, comparing to list of specs we support, |
|
1719 ** (ss->cipherSpecs) and eliminating anything we don't support |
|
1720 ** |
|
1721 * Note: Our list may contain SSL v3 ciphers. |
|
1722 * We MUST NOT match on any of those. |
|
1723 * Fortunately, this is easy to detect because SSLv3 ciphers have zero |
|
1724 * in the first byte, and none of the SSLv2 ciphers do. |
|
1725 * |
|
1726 * Called from ssl2_HandleClientHelloMessage(). |
|
1727 * Returns the number of bytes of "qualified cipher specs", |
|
1728 * which is typically a multiple of 3, but will be zero if there are none. |
|
1729 */ |
|
1730 static int |
|
1731 ssl2_QualifyCypherSpecs(sslSocket *ss, |
|
1732 PRUint8 * cs, /* cipher specs in client hello msg. */ |
|
1733 int csLen) |
|
1734 { |
|
1735 PRUint8 * ms; |
|
1736 PRUint8 * hs; |
|
1737 PRUint8 * qs; |
|
1738 int mc; |
|
1739 int hc; |
|
1740 PRUint8 qualifiedSpecs[ssl2_NUM_SUITES_IMPLEMENTED * 3]; |
|
1741 |
|
1742 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
1743 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
|
1744 |
|
1745 if (!ss->cipherSpecs) { |
|
1746 SECStatus rv = ssl2_ConstructCipherSpecs(ss); |
|
1747 if (rv != SECSuccess || !ss->cipherSpecs) |
|
1748 return 0; |
|
1749 } |
|
1750 |
|
1751 PRINT_BUF(10, (ss, "specs from client:", cs, csLen)); |
|
1752 qs = qualifiedSpecs; |
|
1753 ms = ss->cipherSpecs; |
|
1754 for (mc = ss->sizeCipherSpecs; mc > 0; mc -= 3, ms += 3) { |
|
1755 if (ms[0] == 0) |
|
1756 continue; |
|
1757 for (hs = cs, hc = csLen; hc > 0; hs += 3, hc -= 3) { |
|
1758 if ((hs[0] == ms[0]) && |
|
1759 (hs[1] == ms[1]) && |
|
1760 (hs[2] == ms[2])) { |
|
1761 /* Copy this cipher spec into the "keep" section */ |
|
1762 qs[0] = hs[0]; |
|
1763 qs[1] = hs[1]; |
|
1764 qs[2] = hs[2]; |
|
1765 qs += 3; |
|
1766 break; |
|
1767 } |
|
1768 } |
|
1769 } |
|
1770 hc = qs - qualifiedSpecs; |
|
1771 PRINT_BUF(10, (ss, "qualified specs from client:", qualifiedSpecs, hc)); |
|
1772 PORT_Memcpy(cs, qualifiedSpecs, hc); |
|
1773 return hc; |
|
1774 } |
|
1775 |
|
1776 /* |
|
1777 ** Pick the best cipher we can find, given the array of server cipher |
|
1778 ** specs. Returns cipher number (e.g. SSL_CK_*), or -1 for no overlap. |
|
1779 ** If successful, stores the master key size (bytes) in *pKeyLen. |
|
1780 ** |
|
1781 ** This is correct only for the client side, but presently |
|
1782 ** this function is only called from |
|
1783 ** ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage() |
|
1784 ** |
|
1785 ** Note that most servers only return a single cipher suite in their |
|
1786 ** ServerHello messages. So, the code below for finding the "best" cipher |
|
1787 ** suite usually has only one choice. The client and server should send |
|
1788 ** their cipher suite lists sorted in descending order by preference. |
|
1789 */ |
|
1790 static int |
|
1791 ssl2_ChooseSessionCypher(sslSocket *ss, |
|
1792 int hc, /* number of cs's in hs. */ |
|
1793 PRUint8 * hs, /* server hello's cipher suites. */ |
|
1794 int * pKeyLen) /* out: sym key size in bytes. */ |
|
1795 { |
|
1796 PRUint8 * ms; |
|
1797 unsigned int i; |
|
1798 int bestKeySize; |
|
1799 int bestRealKeySize; |
|
1800 int bestCypher; |
|
1801 int keySize; |
|
1802 int realKeySize; |
|
1803 PRUint8 * ohs = hs; |
|
1804 const PRUint8 * preferred; |
|
1805 static const PRUint8 noneSuch[3] = { 0, 0, 0 }; |
|
1806 |
|
1807 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
1808 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
|
1809 |
|
1810 if (!ss->cipherSpecs) { |
|
1811 SECStatus rv = ssl2_ConstructCipherSpecs(ss); |
|
1812 if (rv != SECSuccess || !ss->cipherSpecs) |
|
1813 goto loser; |
|
1814 } |
|
1815 |
|
1816 if (!ss->preferredCipher) { |
|
1817 unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference & |
|
1818 SSL_CB_IMPLEMENTED; |
|
1819 if (allowed) { |
|
1820 preferred = implementedCipherSuites; |
|
1821 for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) { |
|
1822 if (0 != (allowed & (1U << preferred[0]))) { |
|
1823 ss->preferredCipher = preferred; |
|
1824 break; |
|
1825 } |
|
1826 preferred += 3; |
|
1827 } |
|
1828 } |
|
1829 } |
|
1830 preferred = ss->preferredCipher ? ss->preferredCipher : noneSuch; |
|
1831 /* |
|
1832 ** Scan list of ciphers received from peer and look for a match in |
|
1833 ** our list. |
|
1834 * Note: Our list may contain SSL v3 ciphers. |
|
1835 * We MUST NOT match on any of those. |
|
1836 * Fortunately, this is easy to detect because SSLv3 ciphers have zero |
|
1837 * in the first byte, and none of the SSLv2 ciphers do. |
|
1838 */ |
|
1839 bestKeySize = bestRealKeySize = 0; |
|
1840 bestCypher = -1; |
|
1841 while (--hc >= 0) { |
|
1842 for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms += 3) { |
|
1843 if ((hs[0] == preferred[0]) && |
|
1844 (hs[1] == preferred[1]) && |
|
1845 (hs[2] == preferred[2]) && |
|
1846 hs[0] != 0) { |
|
1847 /* Pick this cipher immediately! */ |
|
1848 *pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3; |
|
1849 return hs[0]; |
|
1850 } |
|
1851 if ((hs[0] == ms[0]) && (hs[1] == ms[1]) && (hs[2] == ms[2]) && |
|
1852 hs[0] != 0) { |
|
1853 /* Found a match */ |
|
1854 |
|
1855 /* Use secret keySize to determine which cipher is best */ |
|
1856 realKeySize = (hs[1] << 8) | hs[2]; |
|
1857 switch (hs[0]) { |
|
1858 case SSL_CK_RC4_128_EXPORT40_WITH_MD5: |
|
1859 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5: |
|
1860 keySize = 40; |
|
1861 break; |
|
1862 default: |
|
1863 keySize = realKeySize; |
|
1864 break; |
|
1865 } |
|
1866 if (keySize > bestKeySize) { |
|
1867 bestCypher = hs[0]; |
|
1868 bestKeySize = keySize; |
|
1869 bestRealKeySize = realKeySize; |
|
1870 } |
|
1871 } |
|
1872 } |
|
1873 hs += 3; |
|
1874 } |
|
1875 if (bestCypher < 0) { |
|
1876 /* |
|
1877 ** No overlap between server and client. Re-examine server list |
|
1878 ** to see what kind of ciphers it does support so that we can set |
|
1879 ** the error code appropriately. |
|
1880 */ |
|
1881 if ((ohs[0] == SSL_CK_RC4_128_WITH_MD5) || |
|
1882 (ohs[0] == SSL_CK_RC2_128_CBC_WITH_MD5)) { |
|
1883 PORT_SetError(SSL_ERROR_US_ONLY_SERVER); |
|
1884 } else if ((ohs[0] == SSL_CK_RC4_128_EXPORT40_WITH_MD5) || |
|
1885 (ohs[0] == SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)) { |
|
1886 PORT_SetError(SSL_ERROR_EXPORT_ONLY_SERVER); |
|
1887 } else { |
|
1888 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
|
1889 } |
|
1890 SSL_DBG(("%d: SSL[%d]: no cipher overlap", SSL_GETPID(), ss->fd)); |
|
1891 goto loser; |
|
1892 } |
|
1893 *pKeyLen = (bestRealKeySize + 7) >> 3; |
|
1894 return bestCypher; |
|
1895 |
|
1896 loser: |
|
1897 return -1; |
|
1898 } |
|
1899 |
|
1900 static SECStatus |
|
1901 ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen) |
|
1902 { |
|
1903 CERTCertificate *cert = NULL; |
|
1904 SECItem certItem; |
|
1905 |
|
1906 certItem.data = certData; |
|
1907 certItem.len = certLen; |
|
1908 |
|
1909 /* decode the certificate */ |
|
1910 cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, |
|
1911 PR_FALSE, PR_TRUE); |
|
1912 |
|
1913 if (cert == NULL) { |
|
1914 SSL_DBG(("%d: SSL[%d]: decode of server certificate fails", |
|
1915 SSL_GETPID(), ss->fd)); |
|
1916 PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); |
|
1917 return SECFailure; |
|
1918 } |
|
1919 |
|
1920 #ifdef TRACE |
|
1921 { |
|
1922 if (ssl_trace >= 1) { |
|
1923 char *issuer; |
|
1924 char *subject; |
|
1925 issuer = CERT_NameToAscii(&cert->issuer); |
|
1926 subject = CERT_NameToAscii(&cert->subject); |
|
1927 SSL_TRC(1,("%d: server certificate issuer: '%s'", |
|
1928 SSL_GETPID(), issuer ? issuer : "OOPS")); |
|
1929 SSL_TRC(1,("%d: server name: '%s'", |
|
1930 SSL_GETPID(), subject ? subject : "OOPS")); |
|
1931 PORT_Free(issuer); |
|
1932 PORT_Free(subject); |
|
1933 } |
|
1934 } |
|
1935 #endif |
|
1936 |
|
1937 ss->sec.peerCert = cert; |
|
1938 return SECSuccess; |
|
1939 } |
|
1940 |
|
1941 |
|
1942 /* |
|
1943 * Format one block of data for public/private key encryption using |
|
1944 * the rules defined in PKCS #1. SSL2 does this itself to handle the |
|
1945 * rollback detection. |
|
1946 */ |
|
1947 #define RSA_BLOCK_MIN_PAD_LEN 8 |
|
1948 #define RSA_BLOCK_FIRST_OCTET 0x00 |
|
1949 #define RSA_BLOCK_AFTER_PAD_OCTET 0x00 |
|
1950 #define RSA_BLOCK_PUBLIC_OCTET 0x02 |
|
1951 unsigned char * |
|
1952 ssl_FormatSSL2Block(unsigned modulusLen, SECItem *data) |
|
1953 { |
|
1954 unsigned char *block; |
|
1955 unsigned char *bp; |
|
1956 int padLen; |
|
1957 SECStatus rv; |
|
1958 int i; |
|
1959 |
|
1960 if (modulusLen < data->len + (3 + RSA_BLOCK_MIN_PAD_LEN)) { |
|
1961 PORT_SetError(SEC_ERROR_BAD_KEY); |
|
1962 return NULL; |
|
1963 } |
|
1964 block = (unsigned char *) PORT_Alloc(modulusLen); |
|
1965 if (block == NULL) |
|
1966 return NULL; |
|
1967 |
|
1968 bp = block; |
|
1969 |
|
1970 /* |
|
1971 * All RSA blocks start with two octets: |
|
1972 * 0x00 || BlockType |
|
1973 */ |
|
1974 *bp++ = RSA_BLOCK_FIRST_OCTET; |
|
1975 *bp++ = RSA_BLOCK_PUBLIC_OCTET; |
|
1976 |
|
1977 /* |
|
1978 * 0x00 || BT || Pad || 0x00 || ActualData |
|
1979 * 1 1 padLen 1 data->len |
|
1980 * Pad is all non-zero random bytes. |
|
1981 */ |
|
1982 padLen = modulusLen - data->len - 3; |
|
1983 PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN); |
|
1984 rv = PK11_GenerateRandom(bp, padLen); |
|
1985 if (rv == SECFailure) goto loser; |
|
1986 /* replace all the 'zero' bytes */ |
|
1987 for (i = 0; i < padLen; i++) { |
|
1988 while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET) { |
|
1989 rv = PK11_GenerateRandom(bp+i, 1); |
|
1990 if (rv == SECFailure) goto loser; |
|
1991 } |
|
1992 } |
|
1993 bp += padLen; |
|
1994 *bp++ = RSA_BLOCK_AFTER_PAD_OCTET; |
|
1995 PORT_Memcpy (bp, data->data, data->len); |
|
1996 |
|
1997 return block; |
|
1998 loser: |
|
1999 if (block) PORT_Free(block); |
|
2000 return NULL; |
|
2001 } |
|
2002 |
|
2003 /* |
|
2004 ** Given the server's public key and cipher specs, generate a session key |
|
2005 ** that is ready to use for encrypting/decrypting the byte stream. At |
|
2006 ** the same time, generate the SSL_MT_CLIENT_MASTER_KEY message and |
|
2007 ** send it to the server. |
|
2008 ** |
|
2009 ** Called from ssl2_HandleServerHelloMessage() |
|
2010 */ |
|
2011 static SECStatus |
|
2012 ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen) |
|
2013 { |
|
2014 sslSessionID * sid; |
|
2015 PRUint8 * ca; /* points to iv data, or NULL if none. */ |
|
2016 PRUint8 * ekbuf = 0; |
|
2017 CERTCertificate * cert = 0; |
|
2018 SECKEYPublicKey * serverKey = 0; |
|
2019 unsigned modulusLen = 0; |
|
2020 SECStatus rv; |
|
2021 int cipher; |
|
2022 int keyLen; /* cipher symkey size in bytes. */ |
|
2023 int ckLen; /* publicly reveal this many bytes of key. */ |
|
2024 int caLen; /* length of IV data at *ca. */ |
|
2025 int nc; |
|
2026 |
|
2027 unsigned char *eblock; /* holds unencrypted PKCS#1 formatted key. */ |
|
2028 SECItem rek; /* holds portion of symkey to be encrypted. */ |
|
2029 |
|
2030 PRUint8 keyData[SSL_MAX_MASTER_KEY_BYTES]; |
|
2031 PRUint8 iv [8]; |
|
2032 |
|
2033 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
2034 |
|
2035 eblock = NULL; |
|
2036 |
|
2037 sid = ss->sec.ci.sid; |
|
2038 PORT_Assert(sid != 0); |
|
2039 |
|
2040 cert = ss->sec.peerCert; |
|
2041 |
|
2042 serverKey = CERT_ExtractPublicKey(cert); |
|
2043 if (!serverKey) { |
|
2044 SSL_DBG(("%d: SSL[%d]: extract public key failed: error=%d", |
|
2045 SSL_GETPID(), ss->fd, PORT_GetError())); |
|
2046 PORT_SetError(SSL_ERROR_BAD_CERTIFICATE); |
|
2047 rv = SECFailure; |
|
2048 goto loser2; |
|
2049 } |
|
2050 |
|
2051 ss->sec.authAlgorithm = ssl_sign_rsa; |
|
2052 ss->sec.keaType = ssl_kea_rsa; |
|
2053 ss->sec.keaKeyBits = \ |
|
2054 ss->sec.authKeyBits = SECKEY_PublicKeyStrengthInBits(serverKey); |
|
2055 |
|
2056 /* Choose a compatible cipher with the server */ |
|
2057 nc = csLen / 3; |
|
2058 cipher = ssl2_ChooseSessionCypher(ss, nc, cs, &keyLen); |
|
2059 if (cipher < 0) { |
|
2060 /* ssl2_ChooseSessionCypher has set error code. */ |
|
2061 ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS); |
|
2062 goto loser; |
|
2063 } |
|
2064 |
|
2065 /* Generate the random keys */ |
|
2066 PK11_GenerateRandom(keyData, sizeof(keyData)); |
|
2067 |
|
2068 /* |
|
2069 ** Next, carve up the keys into clear and encrypted portions. The |
|
2070 ** clear data is taken from the start of keyData and the encrypted |
|
2071 ** portion from the remainder. Note that each of these portions is |
|
2072 ** carved in half, one half for the read-key and one for the |
|
2073 ** write-key. |
|
2074 */ |
|
2075 ca = 0; |
|
2076 |
|
2077 /* We know that cipher is a legit value here, because |
|
2078 * ssl2_ChooseSessionCypher doesn't return bogus values. |
|
2079 */ |
|
2080 ckLen = ssl_Specs[cipher].pubLen; /* cleartext key length. */ |
|
2081 caLen = ssl_Specs[cipher].ivLen; /* IV length. */ |
|
2082 if (caLen) { |
|
2083 PORT_Assert(sizeof iv >= caLen); |
|
2084 PK11_GenerateRandom(iv, caLen); |
|
2085 ca = iv; |
|
2086 } |
|
2087 |
|
2088 /* Fill in session-id */ |
|
2089 rv = ssl2_FillInSID(sid, cipher, keyData, keyLen, |
|
2090 ca, caLen, keyLen << 3, (keyLen - ckLen) << 3, |
|
2091 ss->sec.authAlgorithm, ss->sec.authKeyBits, |
|
2092 ss->sec.keaType, ss->sec.keaKeyBits); |
|
2093 if (rv != SECSuccess) { |
|
2094 goto loser; |
|
2095 } |
|
2096 |
|
2097 SSL_TRC(1, ("%d: SSL[%d]: client, using %s cipher, clear=%d total=%d", |
|
2098 SSL_GETPID(), ss->fd, ssl_cipherName[cipher], |
|
2099 ckLen<<3, keyLen<<3)); |
|
2100 |
|
2101 /* Now setup read and write ciphers */ |
|
2102 rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE); |
|
2103 if (rv != SECSuccess) { |
|
2104 goto loser; |
|
2105 } |
|
2106 |
|
2107 /* |
|
2108 ** Fill in the encryption buffer with some random bytes. Then |
|
2109 ** copy in the portion of the session key we are encrypting. |
|
2110 */ |
|
2111 modulusLen = SECKEY_PublicKeyStrength(serverKey); |
|
2112 rek.data = keyData + ckLen; |
|
2113 rek.len = keyLen - ckLen; |
|
2114 eblock = ssl_FormatSSL2Block(modulusLen, &rek); |
|
2115 if (eblock == NULL) |
|
2116 goto loser; |
|
2117 |
|
2118 /* Set up the padding for version 2 rollback detection. */ |
|
2119 /* XXX We should really use defines here */ |
|
2120 if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { |
|
2121 PORT_Assert((modulusLen - rek.len) > 12); |
|
2122 PORT_Memset(eblock + modulusLen - rek.len - 8 - 1, 0x03, 8); |
|
2123 } |
|
2124 ekbuf = (PRUint8*) PORT_Alloc(modulusLen); |
|
2125 if (!ekbuf) |
|
2126 goto loser; |
|
2127 PRINT_BUF(10, (ss, "master key encryption block:", |
|
2128 eblock, modulusLen)); |
|
2129 |
|
2130 /* Encrypt ekitem */ |
|
2131 rv = PK11_PubEncryptRaw(serverKey, ekbuf, eblock, modulusLen, |
|
2132 ss->pkcs11PinArg); |
|
2133 if (rv) |
|
2134 goto loser; |
|
2135 |
|
2136 /* Now we have everything ready to send */ |
|
2137 rv = ssl2_SendSessionKeyMessage(ss, cipher, keyLen << 3, ca, caLen, |
|
2138 keyData, ckLen, ekbuf, modulusLen); |
|
2139 if (rv != SECSuccess) { |
|
2140 goto loser; |
|
2141 } |
|
2142 rv = SECSuccess; |
|
2143 goto done; |
|
2144 |
|
2145 loser: |
|
2146 rv = SECFailure; |
|
2147 |
|
2148 loser2: |
|
2149 done: |
|
2150 PORT_Memset(keyData, 0, sizeof(keyData)); |
|
2151 PORT_ZFree(ekbuf, modulusLen); |
|
2152 PORT_ZFree(eblock, modulusLen); |
|
2153 SECKEY_DestroyPublicKey(serverKey); |
|
2154 return rv; |
|
2155 } |
|
2156 |
|
2157 /************************************************************************/ |
|
2158 |
|
2159 /* |
|
2160 * Called from ssl2_HandleMessage in response to SSL_MT_SERVER_FINISHED message. |
|
2161 * Caller holds recvBufLock and handshakeLock |
|
2162 */ |
|
2163 static void |
|
2164 ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s) |
|
2165 { |
|
2166 sslSessionID *sid = ss->sec.ci.sid; |
|
2167 |
|
2168 /* Record entry in nonce cache */ |
|
2169 if (sid->peerCert == NULL) { |
|
2170 PORT_Memcpy(sid->u.ssl2.sessionID, s, sizeof(sid->u.ssl2.sessionID)); |
|
2171 sid->peerCert = CERT_DupCertificate(ss->sec.peerCert); |
|
2172 |
|
2173 } |
|
2174 if (!ss->opt.noCache && sid->cached == never_cached) |
|
2175 (*ss->sec.cache)(sid); |
|
2176 } |
|
2177 |
|
2178 /* Called from ssl2_HandleMessage() */ |
|
2179 static SECStatus |
|
2180 ssl2_TriggerNextMessage(sslSocket *ss) |
|
2181 { |
|
2182 SECStatus rv; |
|
2183 |
|
2184 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
2185 |
|
2186 if ((ss->sec.ci.requiredElements & CIS_HAVE_CERTIFICATE) && |
|
2187 !(ss->sec.ci.sentElements & CIS_HAVE_CERTIFICATE)) { |
|
2188 ss->sec.ci.sentElements |= CIS_HAVE_CERTIFICATE; |
|
2189 rv = ssl2_SendCertificateRequestMessage(ss); |
|
2190 return rv; |
|
2191 } |
|
2192 return SECSuccess; |
|
2193 } |
|
2194 |
|
2195 /* See if it's time to send our finished message, or if the handshakes are |
|
2196 ** complete. Send finished message if appropriate. |
|
2197 ** Returns SECSuccess unless anything goes wrong. |
|
2198 ** |
|
2199 ** Called from ssl2_HandleMessage, |
|
2200 ** ssl2_HandleVerifyMessage |
|
2201 ** ssl2_HandleServerHelloMessage |
|
2202 ** ssl2_HandleClientSessionKeyMessage |
|
2203 */ |
|
2204 static SECStatus |
|
2205 ssl2_TryToFinish(sslSocket *ss) |
|
2206 { |
|
2207 SECStatus rv; |
|
2208 char e, ef; |
|
2209 |
|
2210 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
2211 |
|
2212 e = ss->sec.ci.elements; |
|
2213 ef = e | CIS_HAVE_FINISHED; |
|
2214 if ((ef & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) { |
|
2215 if (ss->sec.isServer) { |
|
2216 /* Send server finished message if we already didn't */ |
|
2217 rv = ssl2_SendServerFinishedMessage(ss); |
|
2218 } else { |
|
2219 /* Send client finished message if we already didn't */ |
|
2220 rv = ssl2_SendClientFinishedMessage(ss); |
|
2221 } |
|
2222 if (rv != SECSuccess) { |
|
2223 return rv; |
|
2224 } |
|
2225 if ((e & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) { |
|
2226 /* Totally finished */ |
|
2227 ss->handshake = 0; |
|
2228 return SECSuccess; |
|
2229 } |
|
2230 } |
|
2231 return SECSuccess; |
|
2232 } |
|
2233 |
|
2234 /* |
|
2235 ** Called from ssl2_HandleRequestCertificate |
|
2236 */ |
|
2237 static SECStatus |
|
2238 ssl2_SignResponse(sslSocket *ss, |
|
2239 SECKEYPrivateKey *key, |
|
2240 SECItem *response) |
|
2241 { |
|
2242 SGNContext * sgn = NULL; |
|
2243 PRUint8 * challenge; |
|
2244 unsigned int len; |
|
2245 SECStatus rv = SECFailure; |
|
2246 |
|
2247 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
2248 |
|
2249 challenge = ss->sec.ci.serverChallenge; |
|
2250 len = ss->sec.ci.serverChallengeLen; |
|
2251 |
|
2252 /* Sign the expected data... */ |
|
2253 sgn = SGN_NewContext(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,key); |
|
2254 if (!sgn) |
|
2255 goto done; |
|
2256 rv = SGN_Begin(sgn); |
|
2257 if (rv != SECSuccess) |
|
2258 goto done; |
|
2259 rv = SGN_Update(sgn, ss->sec.ci.readKey, ss->sec.ci.keySize); |
|
2260 if (rv != SECSuccess) |
|
2261 goto done; |
|
2262 rv = SGN_Update(sgn, ss->sec.ci.writeKey, ss->sec.ci.keySize); |
|
2263 if (rv != SECSuccess) |
|
2264 goto done; |
|
2265 rv = SGN_Update(sgn, challenge, len); |
|
2266 if (rv != SECSuccess) |
|
2267 goto done; |
|
2268 rv = SGN_Update(sgn, ss->sec.peerCert->derCert.data, |
|
2269 ss->sec.peerCert->derCert.len); |
|
2270 if (rv != SECSuccess) |
|
2271 goto done; |
|
2272 rv = SGN_End(sgn, response); |
|
2273 if (rv != SECSuccess) |
|
2274 goto done; |
|
2275 |
|
2276 done: |
|
2277 SGN_DestroyContext(sgn, PR_TRUE); |
|
2278 return rv == SECSuccess ? SECSuccess : SECFailure; |
|
2279 } |
|
2280 |
|
2281 /* |
|
2282 ** Try to handle a request-certificate message. Get client's certificate |
|
2283 ** and private key and sign a message for the server to see. |
|
2284 ** Caller must hold handshakeLock |
|
2285 ** |
|
2286 ** Called from ssl2_HandleMessage(). |
|
2287 */ |
|
2288 static int |
|
2289 ssl2_HandleRequestCertificate(sslSocket *ss) |
|
2290 { |
|
2291 CERTCertificate * cert = NULL; /* app-selected client cert. */ |
|
2292 SECKEYPrivateKey *key = NULL; /* priv key for cert. */ |
|
2293 SECStatus rv; |
|
2294 SECItem response; |
|
2295 int ret = 0; |
|
2296 PRUint8 authType; |
|
2297 |
|
2298 |
|
2299 /* |
|
2300 * These things all need to be initialized before we can "goto loser". |
|
2301 */ |
|
2302 response.data = NULL; |
|
2303 |
|
2304 /* get challenge info from connectionInfo */ |
|
2305 authType = ss->sec.ci.authType; |
|
2306 |
|
2307 if (authType != SSL_AT_MD5_WITH_RSA_ENCRYPTION) { |
|
2308 SSL_TRC(7, ("%d: SSL[%d]: unsupported auth type 0x%x", SSL_GETPID(), |
|
2309 ss->fd, authType)); |
|
2310 goto no_cert_error; |
|
2311 } |
|
2312 |
|
2313 /* Get certificate and private-key from client */ |
|
2314 if (!ss->getClientAuthData) { |
|
2315 SSL_TRC(7, ("%d: SSL[%d]: client doesn't support client-auth", |
|
2316 SSL_GETPID(), ss->fd)); |
|
2317 goto no_cert_error; |
|
2318 } |
|
2319 ret = (*ss->getClientAuthData)(ss->getClientAuthDataArg, ss->fd, |
|
2320 NULL, &cert, &key); |
|
2321 if ( ret == SECWouldBlock ) { |
|
2322 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
|
2323 ret = -1; |
|
2324 goto loser; |
|
2325 } |
|
2326 |
|
2327 if (ret) { |
|
2328 goto no_cert_error; |
|
2329 } |
|
2330 |
|
2331 /* check what the callback function returned */ |
|
2332 if ((!cert) || (!key)) { |
|
2333 /* we are missing either the key or cert */ |
|
2334 if (cert) { |
|
2335 /* got a cert, but no key - free it */ |
|
2336 CERT_DestroyCertificate(cert); |
|
2337 cert = NULL; |
|
2338 } |
|
2339 if (key) { |
|
2340 /* got a key, but no cert - free it */ |
|
2341 SECKEY_DestroyPrivateKey(key); |
|
2342 key = NULL; |
|
2343 } |
|
2344 goto no_cert_error; |
|
2345 } |
|
2346 |
|
2347 rv = ssl2_SignResponse(ss, key, &response); |
|
2348 if ( rv != SECSuccess ) { |
|
2349 ret = -1; |
|
2350 goto loser; |
|
2351 } |
|
2352 |
|
2353 /* Send response message */ |
|
2354 ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response); |
|
2355 |
|
2356 /* Now, remember the cert we sent. But first, forget any previous one. */ |
|
2357 if (ss->sec.localCert) { |
|
2358 CERT_DestroyCertificate(ss->sec.localCert); |
|
2359 } |
|
2360 ss->sec.localCert = CERT_DupCertificate(cert); |
|
2361 PORT_Assert(!ss->sec.ci.sid->localCert); |
|
2362 if (ss->sec.ci.sid->localCert) { |
|
2363 CERT_DestroyCertificate(ss->sec.ci.sid->localCert); |
|
2364 } |
|
2365 ss->sec.ci.sid->localCert = cert; |
|
2366 cert = NULL; |
|
2367 |
|
2368 goto done; |
|
2369 |
|
2370 no_cert_error: |
|
2371 SSL_TRC(7, ("%d: SSL[%d]: no certificate (ret=%d)", SSL_GETPID(), |
|
2372 ss->fd, ret)); |
|
2373 ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE); |
|
2374 |
|
2375 loser: |
|
2376 done: |
|
2377 if ( cert ) { |
|
2378 CERT_DestroyCertificate(cert); |
|
2379 } |
|
2380 if ( key ) { |
|
2381 SECKEY_DestroyPrivateKey(key); |
|
2382 } |
|
2383 if ( response.data ) { |
|
2384 PORT_Free(response.data); |
|
2385 } |
|
2386 |
|
2387 return ret; |
|
2388 } |
|
2389 |
|
2390 /* |
|
2391 ** Called from ssl2_HandleMessage for SSL_MT_CLIENT_CERTIFICATE message. |
|
2392 ** Caller must hold HandshakeLock and RecvBufLock, since cd and response |
|
2393 ** are contained in the gathered input data. |
|
2394 */ |
|
2395 static SECStatus |
|
2396 ssl2_HandleClientCertificate(sslSocket * ss, |
|
2397 PRUint8 certType, /* XXX unused */ |
|
2398 PRUint8 * cd, |
|
2399 unsigned int cdLen, |
|
2400 PRUint8 * response, |
|
2401 unsigned int responseLen) |
|
2402 { |
|
2403 CERTCertificate *cert = NULL; |
|
2404 SECKEYPublicKey *pubKey = NULL; |
|
2405 VFYContext * vfy = NULL; |
|
2406 SECItem * derCert; |
|
2407 SECStatus rv = SECFailure; |
|
2408 SECItem certItem; |
|
2409 SECItem rep; |
|
2410 |
|
2411 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
2412 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
|
2413 |
|
2414 /* Extract the certificate */ |
|
2415 certItem.data = cd; |
|
2416 certItem.len = cdLen; |
|
2417 |
|
2418 cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL, |
|
2419 PR_FALSE, PR_TRUE); |
|
2420 if (cert == NULL) { |
|
2421 goto loser; |
|
2422 } |
|
2423 |
|
2424 /* save the certificate, since the auth routine will need it */ |
|
2425 ss->sec.peerCert = cert; |
|
2426 |
|
2427 /* Extract the public key */ |
|
2428 pubKey = CERT_ExtractPublicKey(cert); |
|
2429 if (!pubKey) |
|
2430 goto loser; |
|
2431 |
|
2432 /* Verify the response data... */ |
|
2433 rep.data = response; |
|
2434 rep.len = responseLen; |
|
2435 /* SSL 2.0 only supports RSA certs, so we don't have to worry about |
|
2436 * DSA here. */ |
|
2437 vfy = VFY_CreateContext(pubKey, &rep, SEC_OID_PKCS1_RSA_ENCRYPTION, |
|
2438 ss->pkcs11PinArg); |
|
2439 if (!vfy) |
|
2440 goto loser; |
|
2441 rv = VFY_Begin(vfy); |
|
2442 if (rv) |
|
2443 goto loser; |
|
2444 |
|
2445 rv = VFY_Update(vfy, ss->sec.ci.readKey, ss->sec.ci.keySize); |
|
2446 if (rv) |
|
2447 goto loser; |
|
2448 rv = VFY_Update(vfy, ss->sec.ci.writeKey, ss->sec.ci.keySize); |
|
2449 if (rv) |
|
2450 goto loser; |
|
2451 rv = VFY_Update(vfy, ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES); |
|
2452 if (rv) |
|
2453 goto loser; |
|
2454 |
|
2455 derCert = &ss->serverCerts[kt_rsa].serverCert->derCert; |
|
2456 rv = VFY_Update(vfy, derCert->data, derCert->len); |
|
2457 if (rv) |
|
2458 goto loser; |
|
2459 rv = VFY_End(vfy); |
|
2460 if (rv) |
|
2461 goto loser; |
|
2462 |
|
2463 /* Now ask the server application if it likes the certificate... */ |
|
2464 rv = (SECStatus) (*ss->authCertificate)(ss->authCertificateArg, |
|
2465 ss->fd, PR_TRUE, PR_TRUE); |
|
2466 /* Hey, it liked it. */ |
|
2467 if (SECSuccess == rv) |
|
2468 goto done; |
|
2469 |
|
2470 loser: |
|
2471 ss->sec.peerCert = NULL; |
|
2472 CERT_DestroyCertificate(cert); |
|
2473 |
|
2474 done: |
|
2475 VFY_DestroyContext(vfy, PR_TRUE); |
|
2476 SECKEY_DestroyPublicKey(pubKey); |
|
2477 return rv; |
|
2478 } |
|
2479 |
|
2480 /* |
|
2481 ** Handle remaining messages between client/server. Process finished |
|
2482 ** messages from either side and any authentication requests. |
|
2483 ** This should only be called for SSLv2 handshake messages, |
|
2484 ** not for application data records. |
|
2485 ** Caller must hold handshake lock. |
|
2486 ** |
|
2487 ** Called from ssl_Do1stHandshake(). |
|
2488 ** |
|
2489 */ |
|
2490 static SECStatus |
|
2491 ssl2_HandleMessage(sslSocket *ss) |
|
2492 { |
|
2493 PRUint8 * data; |
|
2494 PRUint8 * cid; |
|
2495 unsigned len, certType, certLen, responseLen; |
|
2496 int rv; |
|
2497 int rv2; |
|
2498 |
|
2499 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
2500 |
|
2501 ssl_GetRecvBufLock(ss); |
|
2502 |
|
2503 data = ss->gs.buf.buf + ss->gs.recordOffset; |
|
2504 |
|
2505 if (ss->gs.recordLen < 1) { |
|
2506 goto bad_peer; |
|
2507 } |
|
2508 SSL_TRC(3, ("%d: SSL[%d]: received %d message", |
|
2509 SSL_GETPID(), ss->fd, data[0])); |
|
2510 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); |
|
2511 |
|
2512 switch (data[0]) { |
|
2513 case SSL_MT_CLIENT_FINISHED: |
|
2514 if (ss->sec.ci.elements & CIS_HAVE_FINISHED) { |
|
2515 SSL_DBG(("%d: SSL[%d]: dup client-finished message", |
|
2516 SSL_GETPID(), ss->fd)); |
|
2517 goto bad_peer; |
|
2518 } |
|
2519 |
|
2520 /* See if nonce matches */ |
|
2521 len = ss->gs.recordLen - 1; |
|
2522 cid = data + 1; |
|
2523 if ((len != sizeof(ss->sec.ci.connectionID)) || |
|
2524 (PORT_Memcmp(ss->sec.ci.connectionID, cid, len) != 0)) { |
|
2525 SSL_DBG(("%d: SSL[%d]: bad connection-id", SSL_GETPID(), ss->fd)); |
|
2526 PRINT_BUF(5, (ss, "sent connection-id", |
|
2527 ss->sec.ci.connectionID, |
|
2528 sizeof(ss->sec.ci.connectionID))); |
|
2529 PRINT_BUF(5, (ss, "rcvd connection-id", cid, len)); |
|
2530 goto bad_peer; |
|
2531 } |
|
2532 |
|
2533 SSL_TRC(5, ("%d: SSL[%d]: got client finished, waiting for 0x%d", |
|
2534 SSL_GETPID(), ss->fd, |
|
2535 ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); |
|
2536 ss->sec.ci.elements |= CIS_HAVE_FINISHED; |
|
2537 break; |
|
2538 |
|
2539 case SSL_MT_SERVER_FINISHED: |
|
2540 if (ss->sec.ci.elements & CIS_HAVE_FINISHED) { |
|
2541 SSL_DBG(("%d: SSL[%d]: dup server-finished message", |
|
2542 SSL_GETPID(), ss->fd)); |
|
2543 goto bad_peer; |
|
2544 } |
|
2545 |
|
2546 if (ss->gs.recordLen - 1 != SSL2_SESSIONID_BYTES) { |
|
2547 SSL_DBG(("%d: SSL[%d]: bad server-finished message, len=%d", |
|
2548 SSL_GETPID(), ss->fd, ss->gs.recordLen)); |
|
2549 goto bad_peer; |
|
2550 } |
|
2551 ssl2_ClientRegSessionID(ss, data+1); |
|
2552 SSL_TRC(5, ("%d: SSL[%d]: got server finished, waiting for 0x%d", |
|
2553 SSL_GETPID(), ss->fd, |
|
2554 ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); |
|
2555 ss->sec.ci.elements |= CIS_HAVE_FINISHED; |
|
2556 break; |
|
2557 |
|
2558 case SSL_MT_REQUEST_CERTIFICATE: |
|
2559 len = ss->gs.recordLen - 2; |
|
2560 if ((len < SSL_MIN_CHALLENGE_BYTES) || |
|
2561 (len > SSL_MAX_CHALLENGE_BYTES)) { |
|
2562 /* Bad challenge */ |
|
2563 SSL_DBG(("%d: SSL[%d]: bad cert request message: code len=%d", |
|
2564 SSL_GETPID(), ss->fd, len)); |
|
2565 goto bad_peer; |
|
2566 } |
|
2567 |
|
2568 /* save auth request info */ |
|
2569 ss->sec.ci.authType = data[1]; |
|
2570 ss->sec.ci.serverChallengeLen = len; |
|
2571 PORT_Memcpy(ss->sec.ci.serverChallenge, data + 2, len); |
|
2572 |
|
2573 rv = ssl2_HandleRequestCertificate(ss); |
|
2574 if (rv == SECWouldBlock) { |
|
2575 SSL_TRC(3, ("%d: SSL[%d]: async cert request", |
|
2576 SSL_GETPID(), ss->fd)); |
|
2577 /* someone is handling this asynchronously */ |
|
2578 ssl_ReleaseRecvBufLock(ss); |
|
2579 return SECWouldBlock; |
|
2580 } |
|
2581 if (rv) { |
|
2582 SET_ERROR_CODE |
|
2583 goto loser; |
|
2584 } |
|
2585 break; |
|
2586 |
|
2587 case SSL_MT_CLIENT_CERTIFICATE: |
|
2588 if (!ss->authCertificate) { |
|
2589 /* Server asked for authentication and can't handle it */ |
|
2590 PORT_SetError(SSL_ERROR_BAD_SERVER); |
|
2591 goto loser; |
|
2592 } |
|
2593 if (ss->gs.recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) { |
|
2594 SET_ERROR_CODE |
|
2595 goto loser; |
|
2596 } |
|
2597 certType = data[1]; |
|
2598 certLen = (data[2] << 8) | data[3]; |
|
2599 responseLen = (data[4] << 8) | data[5]; |
|
2600 if (certType != SSL_CT_X509_CERTIFICATE) { |
|
2601 PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); |
|
2602 goto loser; |
|
2603 } |
|
2604 if (certLen + responseLen + SSL_HL_CLIENT_CERTIFICATE_HBYTES |
|
2605 > ss->gs.recordLen) { |
|
2606 /* prevent overflow crash. */ |
|
2607 rv = SECFailure; |
|
2608 } else |
|
2609 rv = ssl2_HandleClientCertificate(ss, data[1], |
|
2610 data + SSL_HL_CLIENT_CERTIFICATE_HBYTES, |
|
2611 certLen, |
|
2612 data + SSL_HL_CLIENT_CERTIFICATE_HBYTES + certLen, |
|
2613 responseLen); |
|
2614 if (rv) { |
|
2615 rv2 = ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); |
|
2616 SET_ERROR_CODE |
|
2617 goto loser; |
|
2618 } |
|
2619 ss->sec.ci.elements |= CIS_HAVE_CERTIFICATE; |
|
2620 break; |
|
2621 |
|
2622 case SSL_MT_ERROR: |
|
2623 rv = (data[1] << 8) | data[2]; |
|
2624 SSL_TRC(2, ("%d: SSL[%d]: got error message, error=0x%x", |
|
2625 SSL_GETPID(), ss->fd, rv)); |
|
2626 |
|
2627 /* Convert protocol error number into API error number */ |
|
2628 switch (rv) { |
|
2629 case SSL_PE_NO_CYPHERS: |
|
2630 rv = SSL_ERROR_NO_CYPHER_OVERLAP; |
|
2631 break; |
|
2632 case SSL_PE_NO_CERTIFICATE: |
|
2633 rv = SSL_ERROR_NO_CERTIFICATE; |
|
2634 break; |
|
2635 case SSL_PE_BAD_CERTIFICATE: |
|
2636 rv = SSL_ERROR_BAD_CERTIFICATE; |
|
2637 break; |
|
2638 case SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE: |
|
2639 rv = SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE; |
|
2640 break; |
|
2641 default: |
|
2642 goto bad_peer; |
|
2643 } |
|
2644 /* XXX make certificate-request optionally fail... */ |
|
2645 PORT_SetError(rv); |
|
2646 goto loser; |
|
2647 |
|
2648 default: |
|
2649 SSL_DBG(("%d: SSL[%d]: unknown message %d", |
|
2650 SSL_GETPID(), ss->fd, data[0])); |
|
2651 goto loser; |
|
2652 } |
|
2653 |
|
2654 SSL_TRC(3, ("%d: SSL[%d]: handled %d message, required=0x%x got=0x%x", |
|
2655 SSL_GETPID(), ss->fd, data[0], |
|
2656 ss->sec.ci.requiredElements, ss->sec.ci.elements)); |
|
2657 |
|
2658 rv = ssl2_TryToFinish(ss); |
|
2659 if (rv != SECSuccess) |
|
2660 goto loser; |
|
2661 |
|
2662 ss->gs.recordLen = 0; |
|
2663 ssl_ReleaseRecvBufLock(ss); |
|
2664 |
|
2665 if (ss->handshake == 0) { |
|
2666 return SECSuccess; |
|
2667 } |
|
2668 |
|
2669 ss->handshake = ssl_GatherRecord1stHandshake; |
|
2670 ss->nextHandshake = ssl2_HandleMessage; |
|
2671 return ssl2_TriggerNextMessage(ss); |
|
2672 |
|
2673 bad_peer: |
|
2674 PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER); |
|
2675 /* FALL THROUGH */ |
|
2676 |
|
2677 loser: |
|
2678 ssl_ReleaseRecvBufLock(ss); |
|
2679 return SECFailure; |
|
2680 } |
|
2681 |
|
2682 /************************************************************************/ |
|
2683 |
|
2684 /* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage. |
|
2685 */ |
|
2686 static SECStatus |
|
2687 ssl2_HandleVerifyMessage(sslSocket *ss) |
|
2688 { |
|
2689 PRUint8 * data; |
|
2690 SECStatus rv; |
|
2691 |
|
2692 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
2693 ssl_GetRecvBufLock(ss); |
|
2694 |
|
2695 data = ss->gs.buf.buf + ss->gs.recordOffset; |
|
2696 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); |
|
2697 if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) || |
|
2698 (data[0] != SSL_MT_SERVER_VERIFY) || |
|
2699 NSS_SecureMemcmp(data+1, ss->sec.ci.clientChallenge, |
|
2700 SSL_CHALLENGE_BYTES)) { |
|
2701 /* Bad server */ |
|
2702 PORT_SetError(SSL_ERROR_BAD_SERVER); |
|
2703 goto loser; |
|
2704 } |
|
2705 ss->sec.ci.elements |= CIS_HAVE_VERIFY; |
|
2706 |
|
2707 SSL_TRC(5, ("%d: SSL[%d]: got server-verify, required=0x%d got=0x%x", |
|
2708 SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, |
|
2709 ss->sec.ci.elements)); |
|
2710 |
|
2711 rv = ssl2_TryToFinish(ss); |
|
2712 if (rv) |
|
2713 goto loser; |
|
2714 |
|
2715 ss->gs.recordLen = 0; |
|
2716 ssl_ReleaseRecvBufLock(ss); |
|
2717 |
|
2718 if (ss->handshake == 0) { |
|
2719 return SECSuccess; |
|
2720 } |
|
2721 ss->handshake = ssl_GatherRecord1stHandshake; |
|
2722 ss->nextHandshake = ssl2_HandleMessage; |
|
2723 return SECSuccess; |
|
2724 |
|
2725 |
|
2726 loser: |
|
2727 ssl_ReleaseRecvBufLock(ss); |
|
2728 return SECFailure; |
|
2729 } |
|
2730 |
|
2731 /* Not static because ssl2_GatherData() tests ss->nextHandshake for this value. |
|
2732 * ICK! |
|
2733 * Called from ssl_Do1stHandshake after ssl2_BeginClientHandshake() |
|
2734 */ |
|
2735 SECStatus |
|
2736 ssl2_HandleServerHelloMessage(sslSocket *ss) |
|
2737 { |
|
2738 sslSessionID * sid; |
|
2739 PRUint8 * cert; |
|
2740 PRUint8 * cs; |
|
2741 PRUint8 * data; |
|
2742 SECStatus rv; |
|
2743 int needed, sidHit, certLen, csLen, cidLen, certType, err; |
|
2744 |
|
2745 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
2746 |
|
2747 if (!ss->opt.enableSSL2) { |
|
2748 PORT_SetError(SSL_ERROR_SSL2_DISABLED); |
|
2749 return SECFailure; |
|
2750 } |
|
2751 |
|
2752 ssl_GetRecvBufLock(ss); |
|
2753 |
|
2754 PORT_Assert(ss->sec.ci.sid != 0); |
|
2755 sid = ss->sec.ci.sid; |
|
2756 |
|
2757 data = ss->gs.buf.buf + ss->gs.recordOffset; |
|
2758 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); |
|
2759 |
|
2760 /* Make sure first message has some data and is the server hello message */ |
|
2761 if ((ss->gs.recordLen < SSL_HL_SERVER_HELLO_HBYTES) |
|
2762 || (data[0] != SSL_MT_SERVER_HELLO)) { |
|
2763 if ((data[0] == SSL_MT_ERROR) && (ss->gs.recordLen == 3)) { |
|
2764 err = (data[1] << 8) | data[2]; |
|
2765 if (err == SSL_PE_NO_CYPHERS) { |
|
2766 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
|
2767 goto loser; |
|
2768 } |
|
2769 } |
|
2770 goto bad_server; |
|
2771 } |
|
2772 |
|
2773 sidHit = data[1]; |
|
2774 certType = data[2]; |
|
2775 ss->version = (data[3] << 8) | data[4]; |
|
2776 certLen = (data[5] << 8) | data[6]; |
|
2777 csLen = (data[7] << 8) | data[8]; |
|
2778 cidLen = (data[9] << 8) | data[10]; |
|
2779 cert = data + SSL_HL_SERVER_HELLO_HBYTES; |
|
2780 cs = cert + certLen; |
|
2781 |
|
2782 SSL_TRC(5, |
|
2783 ("%d: SSL[%d]: server-hello, hit=%d vers=%x certLen=%d csLen=%d cidLen=%d", |
|
2784 SSL_GETPID(), ss->fd, sidHit, ss->version, certLen, |
|
2785 csLen, cidLen)); |
|
2786 if (ss->version != SSL_LIBRARY_VERSION_2) { |
|
2787 if (ss->version < SSL_LIBRARY_VERSION_2) { |
|
2788 SSL_TRC(3, ("%d: SSL[%d]: demoting self (%x) to server version (%x)", |
|
2789 SSL_GETPID(), ss->fd, SSL_LIBRARY_VERSION_2, |
|
2790 ss->version)); |
|
2791 } else { |
|
2792 SSL_TRC(1, ("%d: SSL[%d]: server version is %x (we are %x)", |
|
2793 SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2)); |
|
2794 /* server claims to be newer but does not follow protocol */ |
|
2795 PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); |
|
2796 goto loser; |
|
2797 } |
|
2798 } |
|
2799 |
|
2800 if ((SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen + cidLen |
|
2801 > ss->gs.recordLen) |
|
2802 || (csLen % 3) != 0 |
|
2803 /* || cidLen < SSL_CONNECTIONID_BYTES || cidLen > 32 */ |
|
2804 ) { |
|
2805 goto bad_server; |
|
2806 } |
|
2807 |
|
2808 /* Save connection-id. |
|
2809 ** This code only saves the first 16 byte of the connectionID. |
|
2810 ** If the connectionID is shorter than 16 bytes, it is zero-padded. |
|
2811 */ |
|
2812 if (cidLen < sizeof ss->sec.ci.connectionID) |
|
2813 memset(ss->sec.ci.connectionID, 0, sizeof ss->sec.ci.connectionID); |
|
2814 cidLen = PR_MIN(cidLen, sizeof ss->sec.ci.connectionID); |
|
2815 PORT_Memcpy(ss->sec.ci.connectionID, cs + csLen, cidLen); |
|
2816 |
|
2817 /* See if session-id hit */ |
|
2818 needed = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED | CIS_HAVE_VERIFY; |
|
2819 if (sidHit) { |
|
2820 if (certLen || csLen) { |
|
2821 /* Uh oh - bogus server */ |
|
2822 SSL_DBG(("%d: SSL[%d]: client, huh? hit=%d certLen=%d csLen=%d", |
|
2823 SSL_GETPID(), ss->fd, sidHit, certLen, csLen)); |
|
2824 goto bad_server; |
|
2825 } |
|
2826 |
|
2827 /* Total winner. */ |
|
2828 SSL_TRC(1, ("%d: SSL[%d]: client, using nonce for peer=0x%08x " |
|
2829 "port=0x%04x", |
|
2830 SSL_GETPID(), ss->fd, ss->sec.ci.peer, ss->sec.ci.port)); |
|
2831 ss->sec.peerCert = CERT_DupCertificate(sid->peerCert); |
|
2832 ss->sec.authAlgorithm = sid->authAlgorithm; |
|
2833 ss->sec.authKeyBits = sid->authKeyBits; |
|
2834 ss->sec.keaType = sid->keaType; |
|
2835 ss->sec.keaKeyBits = sid->keaKeyBits; |
|
2836 rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE); |
|
2837 if (rv != SECSuccess) { |
|
2838 goto loser; |
|
2839 } |
|
2840 } else { |
|
2841 if (certType != SSL_CT_X509_CERTIFICATE) { |
|
2842 PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); |
|
2843 goto loser; |
|
2844 } |
|
2845 if (csLen == 0) { |
|
2846 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
|
2847 SSL_DBG(("%d: SSL[%d]: no cipher overlap", |
|
2848 SSL_GETPID(), ss->fd)); |
|
2849 goto loser; |
|
2850 } |
|
2851 if (certLen == 0) { |
|
2852 SSL_DBG(("%d: SSL[%d]: client, huh? certLen=%d csLen=%d", |
|
2853 SSL_GETPID(), ss->fd, certLen, csLen)); |
|
2854 goto bad_server; |
|
2855 } |
|
2856 |
|
2857 if (sid->cached != never_cached) { |
|
2858 /* Forget our session-id - server didn't like it */ |
|
2859 SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id", |
|
2860 SSL_GETPID(), ss->fd)); |
|
2861 if (ss->sec.uncache) |
|
2862 (*ss->sec.uncache)(sid); |
|
2863 ssl_FreeSID(sid); |
|
2864 ss->sec.ci.sid = sid = PORT_ZNew(sslSessionID); |
|
2865 if (!sid) { |
|
2866 goto loser; |
|
2867 } |
|
2868 sid->references = 1; |
|
2869 sid->addr = ss->sec.ci.peer; |
|
2870 sid->port = ss->sec.ci.port; |
|
2871 } |
|
2872 |
|
2873 /* decode the server's certificate */ |
|
2874 rv = ssl2_ClientHandleServerCert(ss, cert, certLen); |
|
2875 if (rv != SECSuccess) { |
|
2876 if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) { |
|
2877 (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); |
|
2878 } |
|
2879 goto loser; |
|
2880 } |
|
2881 |
|
2882 /* Setup new session cipher */ |
|
2883 rv = ssl2_ClientSetupSessionCypher(ss, cs, csLen); |
|
2884 if (rv != SECSuccess) { |
|
2885 if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) { |
|
2886 (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE); |
|
2887 } |
|
2888 goto loser; |
|
2889 } |
|
2890 } |
|
2891 |
|
2892 /* Build up final list of required elements */ |
|
2893 ss->sec.ci.elements = CIS_HAVE_MASTER_KEY; |
|
2894 ss->sec.ci.requiredElements = needed; |
|
2895 |
|
2896 if (!sidHit) { |
|
2897 /* verify the server's certificate. if sidHit, don't check signatures */ |
|
2898 rv = (* ss->authCertificate)(ss->authCertificateArg, ss->fd, |
|
2899 (PRBool)(!sidHit), PR_FALSE); |
|
2900 if (rv) { |
|
2901 if (ss->handleBadCert) { |
|
2902 rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd); |
|
2903 if ( rv ) { |
|
2904 if ( rv == SECWouldBlock ) { |
|
2905 SSL_DBG(("%d: SSL[%d]: SSL2 bad cert handler returned " |
|
2906 "SECWouldBlock", SSL_GETPID(), ss->fd)); |
|
2907 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2); |
|
2908 rv = SECFailure; |
|
2909 } else { |
|
2910 /* cert is bad */ |
|
2911 SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d", |
|
2912 SSL_GETPID(), ss->fd, PORT_GetError())); |
|
2913 } |
|
2914 goto loser; |
|
2915 } |
|
2916 /* cert is good */ |
|
2917 } else { |
|
2918 SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d", |
|
2919 SSL_GETPID(), ss->fd, PORT_GetError())); |
|
2920 goto loser; |
|
2921 } |
|
2922 } |
|
2923 } |
|
2924 /* |
|
2925 ** At this point we have a completed session key and our session |
|
2926 ** cipher is setup and ready to go. Switch to encrypted write routine |
|
2927 ** as all future message data is to be encrypted. |
|
2928 */ |
|
2929 ssl2_UseEncryptedSendFunc(ss); |
|
2930 |
|
2931 rv = ssl2_TryToFinish(ss); |
|
2932 if (rv != SECSuccess) |
|
2933 goto loser; |
|
2934 |
|
2935 ss->gs.recordLen = 0; |
|
2936 |
|
2937 ssl_ReleaseRecvBufLock(ss); |
|
2938 |
|
2939 if (ss->handshake == 0) { |
|
2940 return SECSuccess; |
|
2941 } |
|
2942 |
|
2943 SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x", |
|
2944 SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements, |
|
2945 ss->sec.ci.elements)); |
|
2946 ss->handshake = ssl_GatherRecord1stHandshake; |
|
2947 ss->nextHandshake = ssl2_HandleVerifyMessage; |
|
2948 return SECSuccess; |
|
2949 |
|
2950 bad_server: |
|
2951 PORT_SetError(SSL_ERROR_BAD_SERVER); |
|
2952 /* FALL THROUGH */ |
|
2953 |
|
2954 loser: |
|
2955 ssl_ReleaseRecvBufLock(ss); |
|
2956 return SECFailure; |
|
2957 } |
|
2958 |
|
2959 /* Sends out the initial client Hello message on the connection. |
|
2960 * Acquires and releases the socket's xmitBufLock. |
|
2961 */ |
|
2962 SECStatus |
|
2963 ssl2_BeginClientHandshake(sslSocket *ss) |
|
2964 { |
|
2965 sslSessionID *sid; |
|
2966 PRUint8 *msg; |
|
2967 PRUint8 *cp; |
|
2968 PRUint8 *localCipherSpecs = NULL; |
|
2969 unsigned int localCipherSize; |
|
2970 unsigned int i; |
|
2971 int sendLen, sidLen = 0; |
|
2972 SECStatus rv; |
|
2973 TLSExtensionData *xtnData; |
|
2974 |
|
2975 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
2976 |
|
2977 ss->sec.isServer = 0; |
|
2978 ss->sec.sendSequence = 0; |
|
2979 ss->sec.rcvSequence = 0; |
|
2980 ssl_ChooseSessionIDProcs(&ss->sec); |
|
2981 |
|
2982 if (!ss->cipherSpecs) { |
|
2983 rv = ssl2_ConstructCipherSpecs(ss); |
|
2984 if (rv != SECSuccess) |
|
2985 goto loser; |
|
2986 } |
|
2987 |
|
2988 /* count the SSL2 and SSL3 enabled ciphers. |
|
2989 * if either is zero, clear the socket's enable for that protocol. |
|
2990 */ |
|
2991 rv = ssl2_CheckConfigSanity(ss); |
|
2992 if (rv != SECSuccess) |
|
2993 goto loser; |
|
2994 |
|
2995 /* Get peer name of server */ |
|
2996 rv = ssl_GetPeerInfo(ss); |
|
2997 if (rv < 0) { |
|
2998 #ifdef HPUX11 |
|
2999 /* |
|
3000 * On some HP-UX B.11.00 systems, getpeername() occasionally |
|
3001 * fails with ENOTCONN after a successful completion of |
|
3002 * non-blocking connect. I found that if we do a write() |
|
3003 * and then retry getpeername(), it will work. |
|
3004 */ |
|
3005 if (PR_GetError() == PR_NOT_CONNECTED_ERROR) { |
|
3006 char dummy; |
|
3007 (void) PR_Write(ss->fd->lower, &dummy, 0); |
|
3008 rv = ssl_GetPeerInfo(ss); |
|
3009 if (rv < 0) { |
|
3010 goto loser; |
|
3011 } |
|
3012 } |
|
3013 #else |
|
3014 goto loser; |
|
3015 #endif |
|
3016 } |
|
3017 |
|
3018 SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd)); |
|
3019 |
|
3020 /* Try to find server in our session-id cache */ |
|
3021 if (ss->opt.noCache) { |
|
3022 sid = NULL; |
|
3023 } else { |
|
3024 sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID, |
|
3025 ss->url); |
|
3026 } |
|
3027 while (sid) { /* this isn't really a loop */ |
|
3028 PRBool sidVersionEnabled = |
|
3029 (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) && |
|
3030 sid->version >= ss->vrange.min && |
|
3031 sid->version <= ss->vrange.max) || |
|
3032 (sid->version < SSL_LIBRARY_VERSION_3_0 && ss->opt.enableSSL2); |
|
3033 |
|
3034 /* if we're not doing this SID's protocol any more, drop it. */ |
|
3035 if (!sidVersionEnabled) { |
|
3036 if (ss->sec.uncache) |
|
3037 ss->sec.uncache(sid); |
|
3038 ssl_FreeSID(sid); |
|
3039 sid = NULL; |
|
3040 break; |
|
3041 } |
|
3042 if (sid->version < SSL_LIBRARY_VERSION_3_0) { |
|
3043 /* If the cipher in this sid is not enabled, drop it. */ |
|
3044 for (i = 0; i < ss->sizeCipherSpecs; i += 3) { |
|
3045 if (ss->cipherSpecs[i] == sid->u.ssl2.cipherType) |
|
3046 break; |
|
3047 } |
|
3048 if (i >= ss->sizeCipherSpecs) { |
|
3049 if (ss->sec.uncache) |
|
3050 ss->sec.uncache(sid); |
|
3051 ssl_FreeSID(sid); |
|
3052 sid = NULL; |
|
3053 break; |
|
3054 } |
|
3055 } |
|
3056 sidLen = sizeof(sid->u.ssl2.sessionID); |
|
3057 PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl2.sessionID, |
|
3058 sidLen)); |
|
3059 ss->version = sid->version; |
|
3060 PORT_Assert(!ss->sec.localCert); |
|
3061 if (ss->sec.localCert) { |
|
3062 CERT_DestroyCertificate(ss->sec.localCert); |
|
3063 } |
|
3064 ss->sec.localCert = CERT_DupCertificate(sid->localCert); |
|
3065 break; /* this isn't really a loop */ |
|
3066 } |
|
3067 if (!sid) { |
|
3068 sidLen = 0; |
|
3069 sid = PORT_ZNew(sslSessionID); |
|
3070 if (!sid) { |
|
3071 goto loser; |
|
3072 } |
|
3073 sid->references = 1; |
|
3074 sid->cached = never_cached; |
|
3075 sid->addr = ss->sec.ci.peer; |
|
3076 sid->port = ss->sec.ci.port; |
|
3077 if (ss->peerID != NULL) { |
|
3078 sid->peerID = PORT_Strdup(ss->peerID); |
|
3079 } |
|
3080 if (ss->url != NULL) { |
|
3081 sid->urlSvrName = PORT_Strdup(ss->url); |
|
3082 } |
|
3083 } |
|
3084 ss->sec.ci.sid = sid; |
|
3085 |
|
3086 PORT_Assert(sid != NULL); |
|
3087 |
|
3088 if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->opt.v2CompatibleHello) && |
|
3089 !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { |
|
3090 ss->gs.state = GS_INIT; |
|
3091 ss->handshake = ssl_GatherRecord1stHandshake; |
|
3092 |
|
3093 /* ssl3_SendClientHello will override this if it succeeds. */ |
|
3094 ss->version = SSL_LIBRARY_VERSION_3_0; |
|
3095 |
|
3096 ssl_GetSSL3HandshakeLock(ss); |
|
3097 ssl_GetXmitBufLock(ss); |
|
3098 rv = ssl3_SendClientHello(ss, PR_FALSE); |
|
3099 ssl_ReleaseXmitBufLock(ss); |
|
3100 ssl_ReleaseSSL3HandshakeLock(ss); |
|
3101 |
|
3102 return rv; |
|
3103 } |
|
3104 #ifndef NSS_DISABLE_ECC |
|
3105 /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */ |
|
3106 ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */ |
|
3107 if (ss->cipherSpecs != NULL) { |
|
3108 PORT_Free(ss->cipherSpecs); |
|
3109 ss->cipherSpecs = NULL; |
|
3110 ss->sizeCipherSpecs = 0; |
|
3111 } |
|
3112 #endif /* NSS_DISABLE_ECC */ |
|
3113 |
|
3114 if (!ss->cipherSpecs) { |
|
3115 rv = ssl2_ConstructCipherSpecs(ss); |
|
3116 if (rv < 0) { |
|
3117 return rv; |
|
3118 } |
|
3119 } |
|
3120 localCipherSpecs = ss->cipherSpecs; |
|
3121 localCipherSize = ss->sizeCipherSpecs; |
|
3122 |
|
3123 /* Add 3 for SCSV */ |
|
3124 sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + 3 + sidLen + |
|
3125 SSL_CHALLENGE_BYTES; |
|
3126 |
|
3127 /* Generate challenge bytes for server */ |
|
3128 PK11_GenerateRandom(ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); |
|
3129 |
|
3130 ssl_GetXmitBufLock(ss); /***************************************/ |
|
3131 |
|
3132 rv = ssl2_GetSendBuffer(ss, sendLen); |
|
3133 if (rv) |
|
3134 goto unlock_loser; |
|
3135 |
|
3136 /* Construct client-hello message */ |
|
3137 cp = msg = ss->sec.ci.sendBuf.buf; |
|
3138 msg[0] = SSL_MT_CLIENT_HELLO; |
|
3139 ss->clientHelloVersion = SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) ? |
|
3140 SSL_LIBRARY_VERSION_2 : ss->vrange.max; |
|
3141 |
|
3142 msg[1] = MSB(ss->clientHelloVersion); |
|
3143 msg[2] = LSB(ss->clientHelloVersion); |
|
3144 /* Add 3 for SCSV */ |
|
3145 msg[3] = MSB(localCipherSize + 3); |
|
3146 msg[4] = LSB(localCipherSize + 3); |
|
3147 msg[5] = MSB(sidLen); |
|
3148 msg[6] = LSB(sidLen); |
|
3149 msg[7] = MSB(SSL_CHALLENGE_BYTES); |
|
3150 msg[8] = LSB(SSL_CHALLENGE_BYTES); |
|
3151 cp += SSL_HL_CLIENT_HELLO_HBYTES; |
|
3152 PORT_Memcpy(cp, localCipherSpecs, localCipherSize); |
|
3153 cp += localCipherSize; |
|
3154 /* |
|
3155 * Add SCSV. SSL 2.0 cipher suites are listed before SSL 3.0 cipher |
|
3156 * suites in localCipherSpecs for compatibility with SSL 2.0 servers. |
|
3157 * Since SCSV looks like an SSL 3.0 cipher suite, we can't add it at |
|
3158 * the beginning. |
|
3159 */ |
|
3160 cp[0] = 0x00; |
|
3161 cp[1] = 0x00; |
|
3162 cp[2] = 0xff; |
|
3163 cp += 3; |
|
3164 if (sidLen) { |
|
3165 PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen); |
|
3166 cp += sidLen; |
|
3167 } |
|
3168 PORT_Memcpy(cp, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES); |
|
3169 |
|
3170 /* Send it to the server */ |
|
3171 DUMP_MSG(29, (ss, msg, sendLen)); |
|
3172 ss->handshakeBegun = 1; |
|
3173 rv = (*ss->sec.send)(ss, msg, sendLen, 0); |
|
3174 |
|
3175 ssl_ReleaseXmitBufLock(ss); /***************************************/ |
|
3176 |
|
3177 if (rv < 0) { |
|
3178 goto loser; |
|
3179 } |
|
3180 |
|
3181 rv = ssl3_StartHandshakeHash(ss, msg, sendLen); |
|
3182 if (rv < 0) { |
|
3183 goto loser; |
|
3184 } |
|
3185 |
|
3186 /* |
|
3187 * Since we sent the SCSV, pretend we sent empty RI extension. We need |
|
3188 * to record the extension has been advertised after ssl3_InitState has |
|
3189 * been called, which ssl3_StartHandshakeHash took care for us above. |
|
3190 */ |
|
3191 xtnData = &ss->xtnData; |
|
3192 xtnData->advertised[xtnData->numAdvertised++] = ssl_renegotiation_info_xtn; |
|
3193 |
|
3194 /* Setup to receive servers hello message */ |
|
3195 ssl_GetRecvBufLock(ss); |
|
3196 ss->gs.recordLen = 0; |
|
3197 ssl_ReleaseRecvBufLock(ss); |
|
3198 |
|
3199 ss->handshake = ssl_GatherRecord1stHandshake; |
|
3200 ss->nextHandshake = ssl2_HandleServerHelloMessage; |
|
3201 return SECSuccess; |
|
3202 |
|
3203 unlock_loser: |
|
3204 ssl_ReleaseXmitBufLock(ss); |
|
3205 loser: |
|
3206 return SECFailure; |
|
3207 } |
|
3208 |
|
3209 /************************************************************************/ |
|
3210 |
|
3211 /* Handle the CLIENT-MASTER-KEY message. |
|
3212 ** Acquires and releases RecvBufLock. |
|
3213 ** Called from ssl2_HandleClientHelloMessage(). |
|
3214 */ |
|
3215 static SECStatus |
|
3216 ssl2_HandleClientSessionKeyMessage(sslSocket *ss) |
|
3217 { |
|
3218 PRUint8 * data; |
|
3219 unsigned int caLen; |
|
3220 unsigned int ckLen; |
|
3221 unsigned int ekLen; |
|
3222 unsigned int keyBits; |
|
3223 int cipher; |
|
3224 SECStatus rv; |
|
3225 |
|
3226 |
|
3227 ssl_GetRecvBufLock(ss); |
|
3228 |
|
3229 data = ss->gs.buf.buf + ss->gs.recordOffset; |
|
3230 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); |
|
3231 |
|
3232 if ((ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES) |
|
3233 || (data[0] != SSL_MT_CLIENT_MASTER_KEY)) { |
|
3234 goto bad_client; |
|
3235 } |
|
3236 cipher = data[1]; |
|
3237 keyBits = (data[2] << 8) | data[3]; |
|
3238 ckLen = (data[4] << 8) | data[5]; |
|
3239 ekLen = (data[6] << 8) | data[7]; |
|
3240 caLen = (data[8] << 8) | data[9]; |
|
3241 |
|
3242 SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keyBits=%d ckLen=%d ekLen=%d caLen=%d", |
|
3243 SSL_GETPID(), ss->fd, cipher, keyBits, ckLen, ekLen, caLen)); |
|
3244 |
|
3245 if (ss->gs.recordLen < |
|
3246 SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) { |
|
3247 SSL_DBG(("%d: SSL[%d]: protocol size mismatch dataLen=%d", |
|
3248 SSL_GETPID(), ss->fd, ss->gs.recordLen)); |
|
3249 goto bad_client; |
|
3250 } |
|
3251 |
|
3252 /* Use info from client to setup session key */ |
|
3253 rv = ssl2_ServerSetupSessionCypher(ss, cipher, keyBits, |
|
3254 data + SSL_HL_CLIENT_MASTER_KEY_HBYTES, ckLen, |
|
3255 data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen, ekLen, |
|
3256 data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, caLen); |
|
3257 ss->gs.recordLen = 0; /* we're done with this record. */ |
|
3258 |
|
3259 ssl_ReleaseRecvBufLock(ss); |
|
3260 |
|
3261 if (rv != SECSuccess) { |
|
3262 goto loser; |
|
3263 } |
|
3264 ss->sec.ci.elements |= CIS_HAVE_MASTER_KEY; |
|
3265 ssl2_UseEncryptedSendFunc(ss); |
|
3266 |
|
3267 /* Send server verify message now that keys are established */ |
|
3268 rv = ssl2_SendServerVerifyMessage(ss); |
|
3269 if (rv != SECSuccess) |
|
3270 goto loser; |
|
3271 |
|
3272 rv = ssl2_TryToFinish(ss); |
|
3273 if (rv != SECSuccess) |
|
3274 goto loser; |
|
3275 if (ss->handshake == 0) { |
|
3276 return SECSuccess; |
|
3277 } |
|
3278 |
|
3279 SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d", |
|
3280 SSL_GETPID(), ss->fd, |
|
3281 ss->sec.ci.requiredElements ^ ss->sec.ci.elements)); |
|
3282 ss->handshake = ssl_GatherRecord1stHandshake; |
|
3283 ss->nextHandshake = ssl2_HandleMessage; |
|
3284 |
|
3285 return ssl2_TriggerNextMessage(ss); |
|
3286 |
|
3287 bad_client: |
|
3288 ssl_ReleaseRecvBufLock(ss); |
|
3289 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
|
3290 /* FALLTHROUGH */ |
|
3291 |
|
3292 loser: |
|
3293 return SECFailure; |
|
3294 } |
|
3295 |
|
3296 /* |
|
3297 ** Handle the initial hello message from the client |
|
3298 ** |
|
3299 ** not static because ssl2_GatherData() tests ss->nextHandshake for this value. |
|
3300 */ |
|
3301 SECStatus |
|
3302 ssl2_HandleClientHelloMessage(sslSocket *ss) |
|
3303 { |
|
3304 sslSessionID *sid; |
|
3305 sslServerCerts * sc; |
|
3306 CERTCertificate *serverCert; |
|
3307 PRUint8 *msg; |
|
3308 PRUint8 *data; |
|
3309 PRUint8 *cs; |
|
3310 PRUint8 *sd; |
|
3311 PRUint8 *cert = NULL; |
|
3312 PRUint8 *challenge; |
|
3313 unsigned int challengeLen; |
|
3314 SECStatus rv; |
|
3315 int csLen; |
|
3316 int sendLen; |
|
3317 int sdLen; |
|
3318 int certLen; |
|
3319 int pid; |
|
3320 int sent; |
|
3321 int gotXmitBufLock = 0; |
|
3322 #if defined(SOLARIS) && defined(i386) |
|
3323 volatile PRUint8 hit; |
|
3324 #else |
|
3325 int hit; |
|
3326 #endif |
|
3327 PRUint8 csImpl[sizeof implementedCipherSuites]; |
|
3328 |
|
3329 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) ); |
|
3330 |
|
3331 sc = ss->serverCerts + kt_rsa; |
|
3332 serverCert = sc->serverCert; |
|
3333 |
|
3334 ssl_GetRecvBufLock(ss); |
|
3335 |
|
3336 |
|
3337 data = ss->gs.buf.buf + ss->gs.recordOffset; |
|
3338 DUMP_MSG(29, (ss, data, ss->gs.recordLen)); |
|
3339 |
|
3340 /* Make sure first message has some data and is the client hello message */ |
|
3341 if ((ss->gs.recordLen < SSL_HL_CLIENT_HELLO_HBYTES) |
|
3342 || (data[0] != SSL_MT_CLIENT_HELLO)) { |
|
3343 goto bad_client; |
|
3344 } |
|
3345 |
|
3346 /* Get peer name of client */ |
|
3347 rv = ssl_GetPeerInfo(ss); |
|
3348 if (rv != SECSuccess) { |
|
3349 goto loser; |
|
3350 } |
|
3351 |
|
3352 /* Examine version information */ |
|
3353 /* |
|
3354 * See if this might be a V2 client hello asking to use the V3 protocol |
|
3355 */ |
|
3356 if ((data[0] == SSL_MT_CLIENT_HELLO) && |
|
3357 (data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) && |
|
3358 !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) { |
|
3359 rv = ssl3_HandleV2ClientHello(ss, data, ss->gs.recordLen); |
|
3360 if (rv != SECFailure) { /* Success */ |
|
3361 ss->handshake = NULL; |
|
3362 ss->nextHandshake = ssl_GatherRecord1stHandshake; |
|
3363 ss->securityHandshake = NULL; |
|
3364 ss->gs.state = GS_INIT; |
|
3365 |
|
3366 /* ssl3_HandleV3ClientHello has set ss->version, |
|
3367 ** and has gotten us a brand new sid. |
|
3368 */ |
|
3369 ss->sec.ci.sid->version = ss->version; |
|
3370 } |
|
3371 ssl_ReleaseRecvBufLock(ss); |
|
3372 return rv; |
|
3373 } |
|
3374 /* Previously, there was a test here to see if SSL2 was enabled. |
|
3375 ** If not, an error code was set, and SECFailure was returned, |
|
3376 ** without sending any error code to the other end of the connection. |
|
3377 ** That test has been removed. If SSL2 has been disabled, there |
|
3378 ** should be no SSL2 ciphers enabled, and consequently, the code |
|
3379 ** below should send the ssl2 error message SSL_PE_NO_CYPHERS. |
|
3380 ** We now believe this is the correct thing to do, even when SSL2 |
|
3381 ** has been explicitly disabled by the application. |
|
3382 */ |
|
3383 |
|
3384 /* Extract info from message */ |
|
3385 ss->version = (data[1] << 8) | data[2]; |
|
3386 |
|
3387 /* If some client thinks ssl v2 is 2.0 instead of 0.2, we'll allow it. */ |
|
3388 if (ss->version >= SSL_LIBRARY_VERSION_3_0) { |
|
3389 ss->version = SSL_LIBRARY_VERSION_2; |
|
3390 } |
|
3391 |
|
3392 csLen = (data[3] << 8) | data[4]; |
|
3393 sdLen = (data[5] << 8) | data[6]; |
|
3394 challengeLen = (data[7] << 8) | data[8]; |
|
3395 cs = data + SSL_HL_CLIENT_HELLO_HBYTES; |
|
3396 sd = cs + csLen; |
|
3397 challenge = sd + sdLen; |
|
3398 PRINT_BUF(7, (ss, "server, client session-id value:", sd, sdLen)); |
|
3399 |
|
3400 if (!csLen || (csLen % 3) != 0 || |
|
3401 (sdLen != 0 && sdLen != SSL2_SESSIONID_BYTES) || |
|
3402 challengeLen < SSL_MIN_CHALLENGE_BYTES || |
|
3403 challengeLen > SSL_MAX_CHALLENGE_BYTES || |
|
3404 (unsigned)ss->gs.recordLen != |
|
3405 SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen) { |
|
3406 SSL_DBG(("%d: SSL[%d]: bad client hello message, len=%d should=%d", |
|
3407 SSL_GETPID(), ss->fd, ss->gs.recordLen, |
|
3408 SSL_HL_CLIENT_HELLO_HBYTES+csLen+sdLen+challengeLen)); |
|
3409 goto bad_client; |
|
3410 } |
|
3411 |
|
3412 SSL_TRC(3, ("%d: SSL[%d]: client version is %x", |
|
3413 SSL_GETPID(), ss->fd, ss->version)); |
|
3414 if (ss->version != SSL_LIBRARY_VERSION_2) { |
|
3415 if (ss->version > SSL_LIBRARY_VERSION_2) { |
|
3416 /* |
|
3417 ** Newer client than us. Things are ok because new clients |
|
3418 ** are required to be backwards compatible with old servers. |
|
3419 ** Change version number to our version number so that client |
|
3420 ** knows whats up. |
|
3421 */ |
|
3422 ss->version = SSL_LIBRARY_VERSION_2; |
|
3423 } else { |
|
3424 SSL_TRC(1, ("%d: SSL[%d]: client version is %x (we are %x)", |
|
3425 SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2)); |
|
3426 PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION); |
|
3427 goto loser; |
|
3428 } |
|
3429 } |
|
3430 |
|
3431 /* Qualify cipher specs before returning them to client */ |
|
3432 csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen); |
|
3433 if (csLen == 0) { |
|
3434 /* no overlap, send client our list of supported SSL v2 ciphers. */ |
|
3435 cs = csImpl; |
|
3436 csLen = sizeof implementedCipherSuites; |
|
3437 PORT_Memcpy(cs, implementedCipherSuites, csLen); |
|
3438 csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen); |
|
3439 if (csLen == 0) { |
|
3440 /* We don't support any SSL v2 ciphers! */ |
|
3441 ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS); |
|
3442 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP); |
|
3443 goto loser; |
|
3444 } |
|
3445 /* Since this handhsake is going to fail, don't cache it. */ |
|
3446 ss->opt.noCache = 1; |
|
3447 } |
|
3448 |
|
3449 /* Squirrel away the challenge for later */ |
|
3450 PORT_Memcpy(ss->sec.ci.clientChallenge, challenge, challengeLen); |
|
3451 |
|
3452 /* Examine message and see if session-id is good */ |
|
3453 ss->sec.ci.elements = 0; |
|
3454 if (sdLen > 0 && !ss->opt.noCache) { |
|
3455 SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x", |
|
3456 SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0], |
|
3457 ss->sec.ci.peer.pr_s6_addr32[1], |
|
3458 ss->sec.ci.peer.pr_s6_addr32[2], |
|
3459 ss->sec.ci.peer.pr_s6_addr32[3])); |
|
3460 sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sd, sdLen, ss->dbHandle); |
|
3461 } else { |
|
3462 sid = NULL; |
|
3463 } |
|
3464 if (sid) { |
|
3465 /* Got a good session-id. Short cut! */ |
|
3466 SSL_TRC(1, ("%d: SSL[%d]: server, using session-id for 0x%08x (age=%d)", |
|
3467 SSL_GETPID(), ss->fd, ss->sec.ci.peer, |
|
3468 ssl_Time() - sid->creationTime)); |
|
3469 PRINT_BUF(1, (ss, "session-id value:", sd, sdLen)); |
|
3470 ss->sec.ci.sid = sid; |
|
3471 ss->sec.ci.elements = CIS_HAVE_MASTER_KEY; |
|
3472 hit = 1; |
|
3473 certLen = 0; |
|
3474 csLen = 0; |
|
3475 |
|
3476 ss->sec.authAlgorithm = sid->authAlgorithm; |
|
3477 ss->sec.authKeyBits = sid->authKeyBits; |
|
3478 ss->sec.keaType = sid->keaType; |
|
3479 ss->sec.keaKeyBits = sid->keaKeyBits; |
|
3480 |
|
3481 rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE); |
|
3482 if (rv != SECSuccess) { |
|
3483 goto loser; |
|
3484 } |
|
3485 } else { |
|
3486 SECItem * derCert = &serverCert->derCert; |
|
3487 |
|
3488 SSL_TRC(7, ("%d: SSL[%d]: server, lookup nonce missed", |
|
3489 SSL_GETPID(), ss->fd)); |
|
3490 if (!serverCert) { |
|
3491 SET_ERROR_CODE |
|
3492 goto loser; |
|
3493 } |
|
3494 hit = 0; |
|
3495 sid = PORT_ZNew(sslSessionID); |
|
3496 if (!sid) { |
|
3497 goto loser; |
|
3498 } |
|
3499 sid->references = 1; |
|
3500 sid->addr = ss->sec.ci.peer; |
|
3501 sid->port = ss->sec.ci.port; |
|
3502 |
|
3503 /* Invent a session-id */ |
|
3504 ss->sec.ci.sid = sid; |
|
3505 PK11_GenerateRandom(sid->u.ssl2.sessionID+2, SSL2_SESSIONID_BYTES-2); |
|
3506 |
|
3507 pid = SSL_GETPID(); |
|
3508 sid->u.ssl2.sessionID[0] = MSB(pid); |
|
3509 sid->u.ssl2.sessionID[1] = LSB(pid); |
|
3510 cert = derCert->data; |
|
3511 certLen = derCert->len; |
|
3512 |
|
3513 /* pretend that server sids remember the local cert. */ |
|
3514 PORT_Assert(!sid->localCert); |
|
3515 if (sid->localCert) { |
|
3516 CERT_DestroyCertificate(sid->localCert); |
|
3517 } |
|
3518 sid->localCert = CERT_DupCertificate(serverCert); |
|
3519 |
|
3520 ss->sec.authAlgorithm = ssl_sign_rsa; |
|
3521 ss->sec.keaType = ssl_kea_rsa; |
|
3522 ss->sec.keaKeyBits = \ |
|
3523 ss->sec.authKeyBits = ss->serverCerts[kt_rsa].serverKeyBits; |
|
3524 } |
|
3525 |
|
3526 /* server sids don't remember the local cert, so whether we found |
|
3527 ** a sid or not, just "remember" we used the rsa server cert. |
|
3528 */ |
|
3529 if (ss->sec.localCert) { |
|
3530 CERT_DestroyCertificate(ss->sec.localCert); |
|
3531 } |
|
3532 ss->sec.localCert = CERT_DupCertificate(serverCert); |
|
3533 |
|
3534 /* Build up final list of required elements */ |
|
3535 ss->sec.ci.requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED; |
|
3536 if (ss->opt.requestCertificate) { |
|
3537 ss->sec.ci.requiredElements |= CIS_HAVE_CERTIFICATE; |
|
3538 } |
|
3539 ss->sec.ci.sentElements = 0; |
|
3540 |
|
3541 /* Send hello message back to client */ |
|
3542 sendLen = SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen |
|
3543 + SSL_CONNECTIONID_BYTES; |
|
3544 |
|
3545 ssl_GetXmitBufLock(ss); gotXmitBufLock = 1; |
|
3546 rv = ssl2_GetSendBuffer(ss, sendLen); |
|
3547 if (rv != SECSuccess) { |
|
3548 goto loser; |
|
3549 } |
|
3550 |
|
3551 SSL_TRC(3, ("%d: SSL[%d]: sending server-hello (%d)", |
|
3552 SSL_GETPID(), ss->fd, sendLen)); |
|
3553 |
|
3554 msg = ss->sec.ci.sendBuf.buf; |
|
3555 msg[0] = SSL_MT_SERVER_HELLO; |
|
3556 msg[1] = hit; |
|
3557 msg[2] = SSL_CT_X509_CERTIFICATE; |
|
3558 msg[3] = MSB(ss->version); |
|
3559 msg[4] = LSB(ss->version); |
|
3560 msg[5] = MSB(certLen); |
|
3561 msg[6] = LSB(certLen); |
|
3562 msg[7] = MSB(csLen); |
|
3563 msg[8] = LSB(csLen); |
|
3564 msg[9] = MSB(SSL_CONNECTIONID_BYTES); |
|
3565 msg[10] = LSB(SSL_CONNECTIONID_BYTES); |
|
3566 if (certLen) { |
|
3567 PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES, cert, certLen); |
|
3568 } |
|
3569 if (csLen) { |
|
3570 PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen, cs, csLen); |
|
3571 } |
|
3572 PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen+csLen, |
|
3573 ss->sec.ci.connectionID, SSL_CONNECTIONID_BYTES); |
|
3574 |
|
3575 DUMP_MSG(29, (ss, msg, sendLen)); |
|
3576 |
|
3577 ss->handshakeBegun = 1; |
|
3578 sent = (*ss->sec.send)(ss, msg, sendLen, 0); |
|
3579 if (sent < 0) { |
|
3580 goto loser; |
|
3581 } |
|
3582 ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0; |
|
3583 |
|
3584 ss->gs.recordLen = 0; |
|
3585 ss->handshake = ssl_GatherRecord1stHandshake; |
|
3586 if (hit) { |
|
3587 /* Old SID Session key is good. Go encrypted */ |
|
3588 ssl2_UseEncryptedSendFunc(ss); |
|
3589 |
|
3590 /* Send server verify message now that keys are established */ |
|
3591 rv = ssl2_SendServerVerifyMessage(ss); |
|
3592 if (rv != SECSuccess) |
|
3593 goto loser; |
|
3594 |
|
3595 ss->nextHandshake = ssl2_HandleMessage; |
|
3596 ssl_ReleaseRecvBufLock(ss); |
|
3597 rv = ssl2_TriggerNextMessage(ss); |
|
3598 return rv; |
|
3599 } |
|
3600 ss->nextHandshake = ssl2_HandleClientSessionKeyMessage; |
|
3601 ssl_ReleaseRecvBufLock(ss); |
|
3602 return SECSuccess; |
|
3603 |
|
3604 bad_client: |
|
3605 PORT_SetError(SSL_ERROR_BAD_CLIENT); |
|
3606 /* FALLTHROUGH */ |
|
3607 |
|
3608 loser: |
|
3609 if (gotXmitBufLock) { |
|
3610 ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0; |
|
3611 } |
|
3612 SSL_TRC(10, ("%d: SSL[%d]: server, wait for client-hello lossage", |
|
3613 SSL_GETPID(), ss->fd)); |
|
3614 ssl_ReleaseRecvBufLock(ss); |
|
3615 return SECFailure; |
|
3616 } |
|
3617 |
|
3618 SECStatus |
|
3619 ssl2_BeginServerHandshake(sslSocket *ss) |
|
3620 { |
|
3621 SECStatus rv; |
|
3622 sslServerCerts * rsaAuth = ss->serverCerts + kt_rsa; |
|
3623 |
|
3624 ss->sec.isServer = 1; |
|
3625 ssl_ChooseSessionIDProcs(&ss->sec); |
|
3626 ss->sec.sendSequence = 0; |
|
3627 ss->sec.rcvSequence = 0; |
|
3628 |
|
3629 /* don't turn on SSL2 if we don't have an RSA key and cert */ |
|
3630 if (!rsaAuth->serverKeyPair || !rsaAuth->SERVERKEY || |
|
3631 !rsaAuth->serverCert) { |
|
3632 ss->opt.enableSSL2 = PR_FALSE; |
|
3633 } |
|
3634 |
|
3635 if (!ss->cipherSpecs) { |
|
3636 rv = ssl2_ConstructCipherSpecs(ss); |
|
3637 if (rv != SECSuccess) |
|
3638 goto loser; |
|
3639 } |
|
3640 |
|
3641 /* count the SSL2 and SSL3 enabled ciphers. |
|
3642 * if either is zero, clear the socket's enable for that protocol. |
|
3643 */ |
|
3644 rv = ssl2_CheckConfigSanity(ss); |
|
3645 if (rv != SECSuccess) |
|
3646 goto loser; |
|
3647 |
|
3648 /* |
|
3649 ** Generate connection-id. Always do this, even if things fail |
|
3650 ** immediately. This way the random number generator is always |
|
3651 ** rolling around, every time we get a connection. |
|
3652 */ |
|
3653 PK11_GenerateRandom(ss->sec.ci.connectionID, |
|
3654 sizeof(ss->sec.ci.connectionID)); |
|
3655 |
|
3656 ss->gs.recordLen = 0; |
|
3657 ss->handshake = ssl_GatherRecord1stHandshake; |
|
3658 ss->nextHandshake = ssl2_HandleClientHelloMessage; |
|
3659 return SECSuccess; |
|
3660 |
|
3661 loser: |
|
3662 return SECFailure; |
|
3663 } |
|
3664 |
|
3665 /* This function doesn't really belong in this file. |
|
3666 ** It's here to keep AIX compilers from optimizing it away, |
|
3667 ** and not including it in the DSO. |
|
3668 */ |
|
3669 |
|
3670 #include "nss.h" |
|
3671 extern const char __nss_ssl_rcsid[]; |
|
3672 extern const char __nss_ssl_sccsid[]; |
|
3673 |
|
3674 PRBool |
|
3675 NSSSSL_VersionCheck(const char *importedVersion) |
|
3676 { |
|
3677 /* |
|
3678 * This is the secret handshake algorithm. |
|
3679 * |
|
3680 * This release has a simple version compatibility |
|
3681 * check algorithm. This release is not backward |
|
3682 * compatible with previous major releases. It is |
|
3683 * not compatible with future major, minor, or |
|
3684 * patch releases. |
|
3685 */ |
|
3686 volatile char c; /* force a reference that won't get optimized away */ |
|
3687 |
|
3688 c = __nss_ssl_rcsid[0] + __nss_ssl_sccsid[0]; |
|
3689 return NSS_VersionCheck(importedVersion); |
|
3690 } |
|
3691 |
|
3692 const char * |
|
3693 NSSSSL_GetVersion(void) |
|
3694 { |
|
3695 return NSS_VERSION; |
|
3696 } |