Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / net / third_party / nss / ssl / sslcon.c
blob8c5a5ad3deaeb550801e51b5363f6b22055159f8
1 /*
2 * SSL v2 handshake functions, and functions common to SSL2 and SSL3.
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/. */
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() */
23 static PRBool policyWasSet;
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
39 #define ssl2_NUM_SUITES_IMPLEMENTED 6
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.
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
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;
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, },
85 #define SET_ERROR_CODE /* reminder */
86 #define TEST_FOR_FAILURE /* reminder */
89 ** Put a string tag in the library so that we can examine an executable
90 ** and see what kind of security it supports.
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
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 */
117 /* bit-masks, showing which SSLv2 suites are allowed.
118 * lsb corresponds to first cipher suite in allCipherSuites[].
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 */
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)
141 /* Construct a socket's list of cipher specs from the global default values.
143 static SECStatus
144 ssl2_ConstructCipherSpecs(sslSocket *ss)
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;
154 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
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;
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().
171 ssl3_config_match_init(ss);
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;
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;
187 if (ss->cipherSpecs != NULL) {
188 PORT_Free(ss->cipherSpecs);
190 ss->cipherSpecs = cs;
191 ss->sizeCipherSpecs = count * 3;
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;
207 /* now have SSL3 add its suites onto the end */
208 rv = ssl3_ConstructV2CipherSpecsHack(ss, cs, &final_count);
210 /* adjust for any difference between first pass and second pass */
211 ss->sizeCipherSpecs -= (ssl3_count - final_count) * 3;
213 return rv;
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.
224 static SECStatus
225 ssl2_CheckConfigSanity(sslSocket *ss)
227 unsigned int allowed;
228 int ssl3CipherCount = 0;
229 SECStatus rv;
231 /* count the SSL2 and SSL3 enabled ciphers.
232 * if either is zero, clear the socket's enable for that protocol.
234 if (!ss->cipherSpecs)
235 goto disabled;
237 allowed = ss->allowedByPolicy & ss->chosenPreference;
238 if (! allowed)
239 ss->opt.enableSSL2 = PR_FALSE; /* not really enabled if no ciphers */
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;
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;
257 return SECSuccess;
261 * Since this is a global (not per-socket) setting, we cannot use the
262 * HandshakeLock to protect this. Probably want a global lock.
264 SECStatus
265 ssl2_SetPolicy(PRInt32 which, PRInt32 policy)
267 PRUint32 bitMask;
268 SECStatus rv = SECSuccess;
270 which &= 0x000f;
271 bitMask = 1 << which;
273 if (!(bitMask & SSL_CB_IMPLEMENTED)) {
274 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
275 return SECFailure;
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;
288 allowedByPolicy &= SSL_CB_IMPLEMENTED;
289 maybeAllowedByPolicy &= SSL_CB_IMPLEMENTED;
291 policyWasSet = PR_TRUE;
292 return rv;
295 SECStatus
296 ssl2_GetPolicy(PRInt32 which, PRInt32 *oPolicy)
298 PRUint32 bitMask;
299 PRInt32 policy;
301 which &= 0x000f;
302 bitMask = 1 << which;
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;
311 if (maybeAllowedByPolicy & bitMask) {
312 policy = (allowedByPolicy & bitMask) ? SSL_ALLOWED : SSL_RESTRICTED;
313 } else {
314 policy = SSL_NOT_ALLOWED;
317 *oPolicy = policy;
318 return SECSuccess;
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.
327 SECStatus
328 ssl2_CipherPrefSetDefault(PRInt32 which, PRBool enabled)
330 PRUint32 bitMask;
332 which &= 0x000f;
333 bitMask = 1 << which;
335 if (!(bitMask & SSL_CB_IMPLEMENTED)) {
336 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
337 return SECFailure;
340 if (enabled)
341 chosenPreference |= bitMask;
342 else
343 chosenPreference &= ~bitMask;
344 chosenPreference &= SSL_CB_IMPLEMENTED;
346 return SECSuccess;
349 SECStatus
350 ssl2_CipherPrefGetDefault(PRInt32 which, PRBool *enabled)
352 PRBool rv = PR_FALSE;
353 PRUint32 bitMask;
355 which &= 0x000f;
356 bitMask = 1 << which;
358 if (!(bitMask & SSL_CB_IMPLEMENTED)) {
359 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
360 *enabled = PR_FALSE;
361 return SECFailure;
364 rv = (PRBool)((chosenPreference & bitMask) != 0);
365 *enabled = rv;
366 return SECSuccess;
369 SECStatus
370 ssl2_CipherPrefSet(sslSocket *ss, PRInt32 which, PRBool enabled)
372 PRUint32 bitMask;
374 which &= 0x000f;
375 bitMask = 1 << which;
377 if (!(bitMask & SSL_CB_IMPLEMENTED)) {
378 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
379 return SECFailure;
382 if (enabled)
383 ss->chosenPreference |= bitMask;
384 else
385 ss->chosenPreference &= ~bitMask;
386 ss->chosenPreference &= SSL_CB_IMPLEMENTED;
388 return SECSuccess;
391 SECStatus
392 ssl2_CipherPrefGet(sslSocket *ss, PRInt32 which, PRBool *enabled)
394 PRBool rv = PR_FALSE;
395 PRUint32 bitMask;
397 which &= 0x000f;
398 bitMask = 1 << which;
400 if (!(bitMask & SSL_CB_IMPLEMENTED)) {
401 PORT_SetError(SSL_ERROR_UNKNOWN_CIPHER_SUITE);
402 *enabled = PR_FALSE;
403 return SECFailure;
406 rv = (PRBool)((ss->chosenPreference & bitMask) != 0);
407 *enabled = rv;
408 return SECSuccess;
412 /* copy global default policy into socket. */
413 void
414 ssl2_InitSocketPolicy(sslSocket *ss)
416 ss->allowedByPolicy = allowedByPolicy;
417 ss->maybeAllowedByPolicy = maybeAllowedByPolicy;
418 ss->chosenPreference = chosenPreference;
422 /************************************************************************/
424 /* Called from ssl2_CreateSessionCypher(), which already holds handshake lock.
426 static SECStatus
427 ssl2_CreateMAC(sslSecurityInfo *sec, SECItem *readKey, SECItem *writeKey,
428 int cipherChoice)
430 switch (cipherChoice) {
431 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
432 case SSL_CK_RC2_128_CBC_WITH_MD5:
433 case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
434 case SSL_CK_RC4_128_WITH_MD5:
435 case SSL_CK_DES_64_CBC_WITH_MD5:
436 case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
437 sec->hash = HASH_GetHashObject(HASH_AlgMD5);
438 if (SECITEM_CopyItem(0, &sec->sendSecret, writeKey) ||
439 SECITEM_CopyItem(0, &sec->rcvSecret, readKey)) {
440 return SECFailure;
442 break;
444 default:
445 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
446 return SECFailure;
448 sec->hashcx = (*sec->hash->create)();
449 if (sec->hashcx == NULL)
450 return SECFailure;
451 return SECSuccess;
454 /************************************************************************
455 * All the Send functions below must acquire and release the socket's
456 * xmitBufLock.
459 /* Called from all the Send* functions below. */
460 static SECStatus
461 ssl2_GetSendBuffer(sslSocket *ss, unsigned int len)
463 SECStatus rv = SECSuccess;
465 PORT_Assert(ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
467 if (len < 128) {
468 len = 128;
470 if (len > ss->sec.ci.sendBuf.space) {
471 rv = sslBuffer_Grow(&ss->sec.ci.sendBuf, len);
472 if (rv != SECSuccess) {
473 SSL_DBG(("%d: SSL[%d]: ssl2_GetSendBuffer failed, tried to get %d bytes",
474 SSL_GETPID(), ss->fd, len));
475 rv = SECFailure;
478 return rv;
481 /* Called from:
482 * ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
483 * ssl2_HandleRequestCertificate() <- ssl2_HandleMessage() <-
484 ssl_Do1stHandshake()
485 * ssl2_HandleMessage() <- ssl_Do1stHandshake()
486 * ssl2_HandleServerHelloMessage() <- ssl_Do1stHandshake()
487 after ssl2_BeginClientHandshake()
488 * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake()
489 after ssl2_BeginServerHandshake()
491 * Acquires and releases the socket's xmitBufLock.
494 ssl2_SendErrorMessage(sslSocket *ss, int error)
496 int rv;
497 PRUint8 msg[SSL_HL_ERROR_HBYTES];
499 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
501 msg[0] = SSL_MT_ERROR;
502 msg[1] = MSB(error);
503 msg[2] = LSB(error);
505 ssl_GetXmitBufLock(ss); /***************************************/
507 SSL_TRC(3, ("%d: SSL[%d]: sending error %d", SSL_GETPID(), ss->fd, error));
509 ss->handshakeBegun = 1;
510 rv = (*ss->sec.send)(ss, msg, sizeof(msg), 0);
511 if (rv >= 0) {
512 rv = SECSuccess;
514 ssl_ReleaseXmitBufLock(ss); /***************************************/
515 return rv;
518 /* Called from ssl2_TryToFinish().
519 * Acquires and releases the socket's xmitBufLock.
521 static SECStatus
522 ssl2_SendClientFinishedMessage(sslSocket *ss)
524 SECStatus rv = SECSuccess;
525 int sent;
526 PRUint8 msg[1 + SSL_CONNECTIONID_BYTES];
528 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
530 ssl_GetXmitBufLock(ss); /***************************************/
532 if (ss->sec.ci.sentFinished == 0) {
533 ss->sec.ci.sentFinished = 1;
535 SSL_TRC(3, ("%d: SSL[%d]: sending client-finished",
536 SSL_GETPID(), ss->fd));
538 msg[0] = SSL_MT_CLIENT_FINISHED;
539 PORT_Memcpy(msg+1, ss->sec.ci.connectionID,
540 sizeof(ss->sec.ci.connectionID));
542 DUMP_MSG(29, (ss, msg, 1 + sizeof(ss->sec.ci.connectionID)));
543 sent = (*ss->sec.send)(ss, msg, 1 + sizeof(ss->sec.ci.connectionID), 0);
544 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
546 ssl_ReleaseXmitBufLock(ss); /***************************************/
547 return rv;
550 /* Called from
551 * ssl2_HandleClientSessionKeyMessage() <- ssl2_HandleClientHelloMessage()
552 * ssl2_HandleClientHelloMessage() <- ssl_Do1stHandshake()
553 after ssl2_BeginServerHandshake()
554 * Acquires and releases the socket's xmitBufLock.
556 static SECStatus
557 ssl2_SendServerVerifyMessage(sslSocket *ss)
559 PRUint8 * msg;
560 int sendLen;
561 int sent;
562 SECStatus rv;
564 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
566 ssl_GetXmitBufLock(ss); /***************************************/
568 sendLen = 1 + SSL_CHALLENGE_BYTES;
569 rv = ssl2_GetSendBuffer(ss, sendLen);
570 if (rv != SECSuccess) {
571 goto done;
574 msg = ss->sec.ci.sendBuf.buf;
575 msg[0] = SSL_MT_SERVER_VERIFY;
576 PORT_Memcpy(msg+1, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
578 DUMP_MSG(29, (ss, msg, sendLen));
579 sent = (*ss->sec.send)(ss, msg, sendLen, 0);
581 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
583 done:
584 ssl_ReleaseXmitBufLock(ss); /***************************************/
585 return rv;
588 /* Called from ssl2_TryToFinish().
589 * Acquires and releases the socket's xmitBufLock.
591 static SECStatus
592 ssl2_SendServerFinishedMessage(sslSocket *ss)
594 sslSessionID * sid;
595 PRUint8 * msg;
596 int sendLen, sent;
597 SECStatus rv = SECSuccess;
599 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
601 ssl_GetXmitBufLock(ss); /***************************************/
603 if (ss->sec.ci.sentFinished == 0) {
604 ss->sec.ci.sentFinished = 1;
605 PORT_Assert(ss->sec.ci.sid != 0);
606 sid = ss->sec.ci.sid;
608 SSL_TRC(3, ("%d: SSL[%d]: sending server-finished",
609 SSL_GETPID(), ss->fd));
611 sendLen = 1 + sizeof(sid->u.ssl2.sessionID);
612 rv = ssl2_GetSendBuffer(ss, sendLen);
613 if (rv != SECSuccess) {
614 goto done;
617 msg = ss->sec.ci.sendBuf.buf;
618 msg[0] = SSL_MT_SERVER_FINISHED;
619 PORT_Memcpy(msg+1, sid->u.ssl2.sessionID,
620 sizeof(sid->u.ssl2.sessionID));
622 DUMP_MSG(29, (ss, msg, sendLen));
623 sent = (*ss->sec.send)(ss, msg, sendLen, 0);
625 if (sent < 0) {
626 /* If send failed, it is now a bogus session-id */
627 if (ss->sec.uncache)
628 (*ss->sec.uncache)(sid);
629 rv = (SECStatus)sent;
630 } else if (!ss->opt.noCache) {
631 if (sid->cached == never_cached) {
632 (*ss->sec.cache)(sid);
634 rv = SECSuccess;
636 ssl_FreeSID(sid);
637 ss->sec.ci.sid = 0;
639 done:
640 ssl_ReleaseXmitBufLock(ss); /***************************************/
641 return rv;
644 /* Called from ssl2_ClientSetupSessionCypher() <-
645 * ssl2_HandleServerHelloMessage()
646 * after ssl2_BeginClientHandshake()
647 * Acquires and releases the socket's xmitBufLock.
649 static SECStatus
650 ssl2_SendSessionKeyMessage(sslSocket *ss, int cipher, int keySize,
651 PRUint8 *ca, int caLen,
652 PRUint8 *ck, int ckLen,
653 PRUint8 *ek, int ekLen)
655 PRUint8 * msg;
656 int sendLen;
657 int sent;
658 SECStatus rv;
660 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
662 ssl_GetXmitBufLock(ss); /***************************************/
664 sendLen = SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen;
665 rv = ssl2_GetSendBuffer(ss, sendLen);
666 if (rv != SECSuccess)
667 goto done;
669 SSL_TRC(3, ("%d: SSL[%d]: sending client-session-key",
670 SSL_GETPID(), ss->fd));
672 msg = ss->sec.ci.sendBuf.buf;
673 msg[0] = SSL_MT_CLIENT_MASTER_KEY;
674 msg[1] = cipher;
675 msg[2] = MSB(keySize);
676 msg[3] = LSB(keySize);
677 msg[4] = MSB(ckLen);
678 msg[5] = LSB(ckLen);
679 msg[6] = MSB(ekLen);
680 msg[7] = LSB(ekLen);
681 msg[8] = MSB(caLen);
682 msg[9] = LSB(caLen);
683 PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES, ck, ckLen);
684 PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen, ek, ekLen);
685 PORT_Memcpy(msg+SSL_HL_CLIENT_MASTER_KEY_HBYTES+ckLen+ekLen, ca, caLen);
687 DUMP_MSG(29, (ss, msg, sendLen));
688 sent = (*ss->sec.send)(ss, msg, sendLen, 0);
689 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
690 done:
691 ssl_ReleaseXmitBufLock(ss); /***************************************/
692 return rv;
695 /* Called from ssl2_TriggerNextMessage() <- ssl2_HandleMessage()
696 * Acquires and releases the socket's xmitBufLock.
698 static SECStatus
699 ssl2_SendCertificateRequestMessage(sslSocket *ss)
701 PRUint8 * msg;
702 int sent;
703 int sendLen;
704 SECStatus rv;
706 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
708 ssl_GetXmitBufLock(ss); /***************************************/
710 sendLen = SSL_HL_REQUEST_CERTIFICATE_HBYTES + SSL_CHALLENGE_BYTES;
711 rv = ssl2_GetSendBuffer(ss, sendLen);
712 if (rv != SECSuccess)
713 goto done;
715 SSL_TRC(3, ("%d: SSL[%d]: sending certificate request",
716 SSL_GETPID(), ss->fd));
718 /* Generate random challenge for client to encrypt */
719 PK11_GenerateRandom(ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
721 msg = ss->sec.ci.sendBuf.buf;
722 msg[0] = SSL_MT_REQUEST_CERTIFICATE;
723 msg[1] = SSL_AT_MD5_WITH_RSA_ENCRYPTION;
724 PORT_Memcpy(msg + SSL_HL_REQUEST_CERTIFICATE_HBYTES,
725 ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
727 DUMP_MSG(29, (ss, msg, sendLen));
728 sent = (*ss->sec.send)(ss, msg, sendLen, 0);
729 rv = (sent >= 0) ? SECSuccess : (SECStatus)sent;
730 done:
731 ssl_ReleaseXmitBufLock(ss); /***************************************/
732 return rv;
735 /* Called from ssl2_HandleRequestCertificate() <- ssl2_HandleMessage()
736 * Acquires and releases the socket's xmitBufLock.
738 static int
739 ssl2_SendCertificateResponseMessage(sslSocket *ss, SECItem *cert,
740 SECItem *encCode)
742 PRUint8 *msg;
743 int rv, sendLen;
745 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
747 ssl_GetXmitBufLock(ss); /***************************************/
749 sendLen = SSL_HL_CLIENT_CERTIFICATE_HBYTES + encCode->len + cert->len;
750 rv = ssl2_GetSendBuffer(ss, sendLen);
751 if (rv)
752 goto done;
754 SSL_TRC(3, ("%d: SSL[%d]: sending certificate response",
755 SSL_GETPID(), ss->fd));
757 msg = ss->sec.ci.sendBuf.buf;
758 msg[0] = SSL_MT_CLIENT_CERTIFICATE;
759 msg[1] = SSL_CT_X509_CERTIFICATE;
760 msg[2] = MSB(cert->len);
761 msg[3] = LSB(cert->len);
762 msg[4] = MSB(encCode->len);
763 msg[5] = LSB(encCode->len);
764 PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES, cert->data, cert->len);
765 PORT_Memcpy(msg + SSL_HL_CLIENT_CERTIFICATE_HBYTES + cert->len,
766 encCode->data, encCode->len);
768 DUMP_MSG(29, (ss, msg, sendLen));
769 rv = (*ss->sec.send)(ss, msg, sendLen, 0);
770 if (rv >= 0) {
771 rv = SECSuccess;
773 done:
774 ssl_ReleaseXmitBufLock(ss); /***************************************/
775 return rv;
778 /********************************************************************
779 ** Send functions above this line must aquire & release the socket's
780 ** xmitBufLock.
781 ** All the ssl2_Send functions below this line are called vis ss->sec.send
782 ** and require that the caller hold the xmitBufLock.
786 ** Called from ssl2_SendStream, ssl2_SendBlock, but not from ssl2_SendClear.
788 static SECStatus
789 ssl2_CalcMAC(PRUint8 * result,
790 sslSecurityInfo * sec,
791 const PRUint8 * data,
792 unsigned int dataLen,
793 unsigned int paddingLen)
795 const PRUint8 * secret = sec->sendSecret.data;
796 unsigned int secretLen = sec->sendSecret.len;
797 unsigned long sequenceNumber = sec->sendSequence;
798 unsigned int nout;
799 PRUint8 seq[4];
800 PRUint8 padding[32];/* XXX max blocksize? */
802 if (!sec->hash || !sec->hash->length)
803 return SECSuccess;
804 if (!sec->hashcx)
805 return SECFailure;
807 /* Reset hash function */
808 (*sec->hash->begin)(sec->hashcx);
810 /* Feed hash the data */
811 (*sec->hash->update)(sec->hashcx, secret, secretLen);
812 (*sec->hash->update)(sec->hashcx, data, dataLen);
813 PORT_Memset(padding, paddingLen, paddingLen);
814 (*sec->hash->update)(sec->hashcx, padding, paddingLen);
816 seq[0] = (PRUint8) (sequenceNumber >> 24);
817 seq[1] = (PRUint8) (sequenceNumber >> 16);
818 seq[2] = (PRUint8) (sequenceNumber >> 8);
819 seq[3] = (PRUint8) (sequenceNumber);
821 PRINT_BUF(60, (0, "calc-mac secret:", secret, secretLen));
822 PRINT_BUF(60, (0, "calc-mac data:", data, dataLen));
823 PRINT_BUF(60, (0, "calc-mac padding:", padding, paddingLen));
824 PRINT_BUF(60, (0, "calc-mac seq:", seq, 4));
826 (*sec->hash->update)(sec->hashcx, seq, 4);
828 /* Get result */
829 (*sec->hash->end)(sec->hashcx, result, &nout, sec->hash->length);
831 return SECSuccess;
835 ** Maximum transmission amounts. These are tiny bit smaller than they
836 ** need to be (they account for the MAC length plus some padding),
837 ** assuming the MAC is 16 bytes long and the padding is a max of 7 bytes
838 ** long. This gives an additional 9 bytes of slop to work within.
840 #define MAX_STREAM_CYPHER_LEN 0x7fe0
841 #define MAX_BLOCK_CYPHER_LEN 0x3fe0
844 ** Send some data in the clear.
845 ** Package up data with the length header and send it.
847 ** Return count of bytes successfully written, or negative number (failure).
849 static PRInt32
850 ssl2_SendClear(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
852 PRUint8 * out;
853 int rv;
854 int amount;
855 int count = 0;
857 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
859 SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes in the clear",
860 SSL_GETPID(), ss->fd, len));
861 PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len));
863 while (len) {
864 amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN );
865 if (amount + 2 > ss->sec.writeBuf.space) {
866 rv = sslBuffer_Grow(&ss->sec.writeBuf, amount + 2);
867 if (rv != SECSuccess) {
868 count = rv;
869 break;
872 out = ss->sec.writeBuf.buf;
875 ** Construct message.
877 out[0] = 0x80 | MSB(amount);
878 out[1] = LSB(amount);
879 PORT_Memcpy(&out[2], in, amount);
881 /* Now send the data */
882 rv = ssl_DefSend(ss, out, amount + 2, flags & ~ssl_SEND_FLAG_MASK);
883 if (rv < 0) {
884 if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
885 rv = 0;
886 } else {
887 /* Return short write if some data already went out... */
888 if (count == 0)
889 count = rv;
890 break;
894 if ((unsigned)rv < (amount + 2)) {
895 /* Short write. Save the data and return. */
896 if (ssl_SaveWriteData(ss, out + rv, amount + 2 - rv)
897 == SECFailure) {
898 count = SECFailure;
899 } else {
900 count += amount;
901 ss->sec.sendSequence++;
903 break;
906 ss->sec.sendSequence++;
907 in += amount;
908 count += amount;
909 len -= amount;
912 return count;
916 ** Send some data, when using a stream cipher. Stream ciphers have a
917 ** block size of 1. Package up the data with the length header
918 ** and send it.
920 static PRInt32
921 ssl2_SendStream(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
923 PRUint8 * out;
924 int rv;
925 int count = 0;
927 int amount;
928 PRUint8 macLen;
929 int nout;
930 int buflen;
932 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
934 SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using stream cipher",
935 SSL_GETPID(), ss->fd, len));
936 PRINT_BUF(50, (ss, "clear data:", (PRUint8*) in, len));
938 while (len) {
939 ssl_GetSpecReadLock(ss); /*************************************/
941 macLen = ss->sec.hash->length;
942 amount = PR_MIN( len, MAX_STREAM_CYPHER_LEN );
943 buflen = amount + 2 + macLen;
944 if (buflen > ss->sec.writeBuf.space) {
945 rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen);
946 if (rv != SECSuccess) {
947 goto loser;
950 out = ss->sec.writeBuf.buf;
951 nout = amount + macLen;
952 out[0] = 0x80 | MSB(nout);
953 out[1] = LSB(nout);
955 /* Calculate MAC */
956 rv = ssl2_CalcMAC(out+2, /* put MAC here */
957 &ss->sec,
958 in, amount, /* input addr & length */
959 0); /* no padding */
960 if (rv != SECSuccess)
961 goto loser;
963 /* Encrypt MAC */
964 rv = (*ss->sec.enc)(ss->sec.writecx, out+2, &nout, macLen, out+2, macLen);
965 if (rv) goto loser;
967 /* Encrypt data from caller */
968 rv = (*ss->sec.enc)(ss->sec.writecx, out+2+macLen, &nout, amount, in, amount);
969 if (rv) goto loser;
971 ssl_ReleaseSpecReadLock(ss); /*************************************/
973 PRINT_BUF(50, (ss, "encrypted data:", out, buflen));
975 rv = ssl_DefSend(ss, out, buflen, flags & ~ssl_SEND_FLAG_MASK);
976 if (rv < 0) {
977 if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
978 SSL_TRC(50, ("%d: SSL[%d]: send stream would block, "
979 "saving data", SSL_GETPID(), ss->fd));
980 rv = 0;
981 } else {
982 SSL_TRC(10, ("%d: SSL[%d]: send stream error %d",
983 SSL_GETPID(), ss->fd, PORT_GetError()));
984 /* Return short write if some data already went out... */
985 if (count == 0)
986 count = rv;
987 goto done;
991 if ((unsigned)rv < buflen) {
992 /* Short write. Save the data and return. */
993 if (ssl_SaveWriteData(ss, out + rv, buflen - rv) == SECFailure) {
994 count = SECFailure;
995 } else {
996 count += amount;
997 ss->sec.sendSequence++;
999 goto done;
1002 ss->sec.sendSequence++;
1003 in += amount;
1004 count += amount;
1005 len -= amount;
1008 done:
1009 return count;
1011 loser:
1012 ssl_ReleaseSpecReadLock(ss);
1013 return SECFailure;
1017 ** Send some data, when using a block cipher. Package up the data with
1018 ** the length header and send it.
1020 /* XXX assumes blocksize is > 7 */
1021 static PRInt32
1022 ssl2_SendBlock(sslSocket *ss, const PRUint8 *in, PRInt32 len, PRInt32 flags)
1024 PRUint8 * out; /* begining of output buffer. */
1025 PRUint8 * op; /* next output byte goes here. */
1026 int rv; /* value from funcs we called. */
1027 int count = 0; /* this function's return value. */
1029 unsigned int hlen; /* output record hdr len, 2 or 3 */
1030 unsigned int macLen; /* MAC is this many bytes long. */
1031 int amount; /* of plaintext to go in record. */
1032 unsigned int padding; /* add this many padding byte. */
1033 int nout; /* ciphertext size after header. */
1034 int buflen; /* size of generated record. */
1036 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
1038 SSL_TRC(10, ("%d: SSL[%d]: sending %d bytes using block cipher",
1039 SSL_GETPID(), ss->fd, len));
1040 PRINT_BUF(50, (ss, "clear data:", in, len));
1042 while (len) {
1043 ssl_GetSpecReadLock(ss); /*************************************/
1045 macLen = ss->sec.hash->length;
1046 /* Figure out how much to send, including mac and padding */
1047 amount = PR_MIN( len, MAX_BLOCK_CYPHER_LEN );
1048 nout = amount + macLen;
1049 padding = nout & (ss->sec.blockSize - 1);
1050 if (padding) {
1051 hlen = 3;
1052 padding = ss->sec.blockSize - padding;
1053 nout += padding;
1054 } else {
1055 hlen = 2;
1057 buflen = hlen + nout;
1058 if (buflen > ss->sec.writeBuf.space) {
1059 rv = sslBuffer_Grow(&ss->sec.writeBuf, buflen);
1060 if (rv != SECSuccess) {
1061 goto loser;
1064 out = ss->sec.writeBuf.buf;
1066 /* Construct header */
1067 op = out;
1068 if (padding) {
1069 *op++ = MSB(nout);
1070 *op++ = LSB(nout);
1071 *op++ = padding;
1072 } else {
1073 *op++ = 0x80 | MSB(nout);
1074 *op++ = LSB(nout);
1077 /* Calculate MAC */
1078 rv = ssl2_CalcMAC(op, /* MAC goes here. */
1079 &ss->sec,
1080 in, amount, /* intput addr, len */
1081 padding);
1082 if (rv != SECSuccess)
1083 goto loser;
1084 op += macLen;
1086 /* Copy in the input data */
1087 /* XXX could eliminate the copy by folding it into the encryption */
1088 PORT_Memcpy(op, in, amount);
1089 op += amount;
1090 if (padding) {
1091 PORT_Memset(op, padding, padding);
1092 op += padding;
1095 /* Encrypt result */
1096 rv = (*ss->sec.enc)(ss->sec.writecx, out+hlen, &nout, buflen-hlen,
1097 out+hlen, op - (out + hlen));
1098 if (rv)
1099 goto loser;
1101 ssl_ReleaseSpecReadLock(ss); /*************************************/
1103 PRINT_BUF(50, (ss, "final xmit data:", out, op - out));
1105 rv = ssl_DefSend(ss, out, op - out, flags & ~ssl_SEND_FLAG_MASK);
1106 if (rv < 0) {
1107 if (PORT_GetError() == PR_WOULD_BLOCK_ERROR) {
1108 rv = 0;
1109 } else {
1110 SSL_TRC(10, ("%d: SSL[%d]: send block error %d",
1111 SSL_GETPID(), ss->fd, PORT_GetError()));
1112 /* Return short write if some data already went out... */
1113 if (count == 0)
1114 count = rv;
1115 goto done;
1119 if (rv < (op - out)) {
1120 /* Short write. Save the data and return. */
1121 if (ssl_SaveWriteData(ss, out + rv, op - out - rv) == SECFailure) {
1122 count = SECFailure;
1123 } else {
1124 count += amount;
1125 ss->sec.sendSequence++;
1127 goto done;
1130 ss->sec.sendSequence++;
1131 in += amount;
1132 count += amount;
1133 len -= amount;
1136 done:
1137 return count;
1139 loser:
1140 ssl_ReleaseSpecReadLock(ss);
1141 return SECFailure;
1145 ** Called from: ssl2_HandleServerHelloMessage,
1146 ** ssl2_HandleClientSessionKeyMessage,
1147 ** ssl2_HandleClientHelloMessage,
1150 static void
1151 ssl2_UseEncryptedSendFunc(sslSocket *ss)
1153 ssl_GetXmitBufLock(ss);
1154 PORT_Assert(ss->sec.hashcx != 0);
1156 ss->gs.encrypted = 1;
1157 ss->sec.send = (ss->sec.blockSize > 1) ? ssl2_SendBlock : ssl2_SendStream;
1158 ssl_ReleaseXmitBufLock(ss);
1161 /* Called while initializing socket in ssl_CreateSecurityInfo().
1162 ** This function allows us to keep the name of ssl2_SendClear static.
1164 void
1165 ssl2_UseClearSendFunc(sslSocket *ss)
1167 ss->sec.send = ssl2_SendClear;
1170 /************************************************************************
1171 ** END of Send functions. *
1172 *************************************************************************/
1174 /***********************************************************************
1175 * For SSL3, this gathers in and handles records/messages until either
1176 * the handshake is complete or application data is available.
1178 * For SSL2, this gathers in only the next SSLV2 record.
1180 * Called from ssl_Do1stHandshake() via function pointer ss->handshake.
1181 * Caller must hold handshake lock.
1182 * This function acquires and releases the RecvBufLock.
1184 * returns SECSuccess for success.
1185 * returns SECWouldBlock when that value is returned by ssl2_GatherRecord() or
1186 * ssl3_GatherCompleteHandshake().
1187 * returns SECFailure on all other errors.
1189 * The gather functions called by ssl_GatherRecord1stHandshake are expected
1190 * to return values interpreted as follows:
1191 * 1 : the function completed without error.
1192 * 0 : the function read EOF.
1193 * -1 : read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
1194 * -2 : the function wants ssl_GatherRecord1stHandshake to be called again
1195 * immediately, by ssl_Do1stHandshake.
1197 * This code is similar to, and easily confused with, DoRecv() in sslsecur.c
1199 * This function is called from ssl_Do1stHandshake().
1200 * The following functions put ssl_GatherRecord1stHandshake into ss->handshake:
1201 * ssl2_HandleMessage
1202 * ssl2_HandleVerifyMessage
1203 * ssl2_HandleServerHelloMessage
1204 * ssl2_BeginClientHandshake
1205 * ssl2_HandleClientSessionKeyMessage
1206 * ssl3_RestartHandshakeAfterCertReq
1207 * ssl3_RestartHandshakeAfterServerCert
1208 * ssl2_HandleClientHelloMessage
1209 * ssl2_BeginServerHandshake
1211 SECStatus
1212 ssl_GatherRecord1stHandshake(sslSocket *ss)
1214 int rv;
1216 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
1218 ssl_GetRecvBufLock(ss);
1220 /* The special case DTLS logic is needed here because the SSL/TLS
1221 * version wants to auto-detect SSL2 vs. SSL3 on the initial handshake
1222 * (ss->version == 0) but with DTLS it gets confused, so we force the
1223 * SSL3 version.
1225 if ((ss->version >= SSL_LIBRARY_VERSION_3_0) || IS_DTLS(ss)) {
1226 /* Wait for handshake to complete, or application data to arrive. */
1227 rv = ssl3_GatherCompleteHandshake(ss, 0);
1228 } else {
1229 /* See if we have a complete record */
1230 rv = ssl2_GatherRecord(ss, 0);
1232 SSL_TRC(10, ("%d: SSL[%d]: handshake gathering, rv=%d",
1233 SSL_GETPID(), ss->fd, rv));
1235 ssl_ReleaseRecvBufLock(ss);
1237 if (rv <= 0) {
1238 if (rv == SECWouldBlock) {
1239 /* Progress is blocked waiting for callback completion. */
1240 SSL_TRC(10, ("%d: SSL[%d]: handshake blocked (need %d)",
1241 SSL_GETPID(), ss->fd, ss->gs.remainder));
1242 return SECWouldBlock;
1244 if (rv == 0) {
1245 /* EOF. Loser */
1246 PORT_SetError(PR_END_OF_FILE_ERROR);
1248 return SECFailure; /* rv is < 0 here. */
1251 SSL_TRC(10, ("%d: SSL[%d]: got handshake record of %d bytes",
1252 SSL_GETPID(), ss->fd, ss->gs.recordLen));
1254 ss->handshake = 0; /* makes ssl_Do1stHandshake call ss->nextHandshake.*/
1255 return SECSuccess;
1258 /************************************************************************/
1260 /* Called from ssl2_ServerSetupSessionCypher()
1261 * ssl2_ClientSetupSessionCypher()
1263 static SECStatus
1264 ssl2_FillInSID(sslSessionID * sid,
1265 int cipher,
1266 PRUint8 *keyData,
1267 int keyLen,
1268 PRUint8 *ca,
1269 int caLen,
1270 int keyBits,
1271 int secretKeyBits,
1272 SSLSignType authAlgorithm,
1273 PRUint32 authKeyBits,
1274 SSLKEAType keaType,
1275 PRUint32 keaKeyBits)
1277 PORT_Assert(sid->references == 1);
1278 PORT_Assert(sid->cached == never_cached);
1279 PORT_Assert(sid->u.ssl2.masterKey.data == 0);
1280 PORT_Assert(sid->u.ssl2.cipherArg.data == 0);
1282 sid->version = SSL_LIBRARY_VERSION_2;
1284 sid->u.ssl2.cipherType = cipher;
1285 sid->u.ssl2.masterKey.data = (PRUint8*) PORT_Alloc(keyLen);
1286 if (!sid->u.ssl2.masterKey.data) {
1287 return SECFailure;
1289 PORT_Memcpy(sid->u.ssl2.masterKey.data, keyData, keyLen);
1290 sid->u.ssl2.masterKey.len = keyLen;
1291 sid->u.ssl2.keyBits = keyBits;
1292 sid->u.ssl2.secretKeyBits = secretKeyBits;
1293 sid->authAlgorithm = authAlgorithm;
1294 sid->authKeyBits = authKeyBits;
1295 sid->keaType = keaType;
1296 sid->keaKeyBits = keaKeyBits;
1297 sid->lastAccessTime = sid->creationTime = ssl_Time();
1298 sid->expirationTime = sid->creationTime + ssl_sid_timeout;
1300 if (caLen) {
1301 sid->u.ssl2.cipherArg.data = (PRUint8*) PORT_Alloc(caLen);
1302 if (!sid->u.ssl2.cipherArg.data) {
1303 return SECFailure;
1305 sid->u.ssl2.cipherArg.len = caLen;
1306 PORT_Memcpy(sid->u.ssl2.cipherArg.data, ca, caLen);
1308 return SECSuccess;
1312 ** Construct session keys given the masterKey (tied to the session-id),
1313 ** the client's challenge and the server's nonce.
1315 ** Called from ssl2_CreateSessionCypher() <-
1317 static SECStatus
1318 ssl2_ProduceKeys(sslSocket * ss,
1319 SECItem * readKey,
1320 SECItem * writeKey,
1321 SECItem * masterKey,
1322 PRUint8 * challenge,
1323 PRUint8 * nonce,
1324 int cipherType)
1326 PK11Context * cx = 0;
1327 unsigned nkm = 0; /* number of hashes to generate key mat. */
1328 unsigned nkd = 0; /* size of readKey and writeKey. */
1329 unsigned part;
1330 unsigned i;
1331 unsigned off;
1332 SECStatus rv;
1333 PRUint8 countChar;
1334 PRUint8 km[3*16]; /* buffer for key material. */
1336 readKey->data = 0;
1337 writeKey->data = 0;
1339 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
1341 rv = SECSuccess;
1342 cx = PK11_CreateDigestContext(SEC_OID_MD5);
1343 if (cx == NULL) {
1344 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
1345 return SECFailure;
1348 nkm = ssl_Specs[cipherType].nkm;
1349 nkd = ssl_Specs[cipherType].nkd;
1351 readKey->data = (PRUint8*) PORT_Alloc(nkd);
1352 if (!readKey->data)
1353 goto loser;
1354 readKey->len = nkd;
1356 writeKey->data = (PRUint8*) PORT_Alloc(nkd);
1357 if (!writeKey->data)
1358 goto loser;
1359 writeKey->len = nkd;
1361 /* Produce key material */
1362 countChar = '0';
1363 for (i = 0, off = 0; i < nkm; i++, off += 16) {
1364 rv = PK11_DigestBegin(cx);
1365 rv |= PK11_DigestOp(cx, masterKey->data, masterKey->len);
1366 rv |= PK11_DigestOp(cx, &countChar, 1);
1367 rv |= PK11_DigestOp(cx, challenge, SSL_CHALLENGE_BYTES);
1368 rv |= PK11_DigestOp(cx, nonce, SSL_CONNECTIONID_BYTES);
1369 rv |= PK11_DigestFinal(cx, km+off, &part, MD5_LENGTH);
1370 if (rv != SECSuccess) {
1371 ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
1372 rv = SECFailure;
1373 goto loser;
1375 countChar++;
1378 /* Produce keys */
1379 PORT_Memcpy(readKey->data, km, nkd);
1380 PORT_Memcpy(writeKey->data, km + nkd, nkd);
1382 loser:
1383 PK11_DestroyContext(cx, PR_TRUE);
1384 return rv;
1387 /* Called from ssl2_ServerSetupSessionCypher()
1388 ** <- ssl2_HandleClientSessionKeyMessage()
1389 ** <- ssl2_HandleClientHelloMessage()
1390 ** and from ssl2_ClientSetupSessionCypher()
1391 ** <- ssl2_HandleServerHelloMessage()
1393 static SECStatus
1394 ssl2_CreateSessionCypher(sslSocket *ss, sslSessionID *sid, PRBool isClient)
1396 SECItem * rk = NULL;
1397 SECItem * wk = NULL;
1398 SECItem * param;
1399 SECStatus rv;
1400 int cipherType = sid->u.ssl2.cipherType;
1401 PK11SlotInfo * slot = NULL;
1402 CK_MECHANISM_TYPE mechanism;
1403 SECItem readKey;
1404 SECItem writeKey;
1406 void *readcx = 0;
1407 void *writecx = 0;
1408 readKey.data = 0;
1409 writeKey.data = 0;
1411 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
1412 if (ss->sec.ci.sid == 0)
1413 goto sec_loser; /* don't crash if asserts are off */
1415 /* Trying to cut down on all these switch statements that should be tables.
1416 * So, test cipherType once, here, and then use tables below.
1418 switch (cipherType) {
1419 case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
1420 case SSL_CK_RC4_128_WITH_MD5:
1421 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
1422 case SSL_CK_RC2_128_CBC_WITH_MD5:
1423 case SSL_CK_DES_64_CBC_WITH_MD5:
1424 case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
1425 break;
1427 default:
1428 SSL_DBG(("%d: SSL[%d]: ssl2_CreateSessionCypher: unknown cipher=%d",
1429 SSL_GETPID(), ss->fd, cipherType));
1430 PORT_SetError(isClient ? SSL_ERROR_BAD_SERVER : SSL_ERROR_BAD_CLIENT);
1431 goto sec_loser;
1434 rk = isClient ? &readKey : &writeKey;
1435 wk = isClient ? &writeKey : &readKey;
1437 /* Produce the keys for this session */
1438 rv = ssl2_ProduceKeys(ss, &readKey, &writeKey, &sid->u.ssl2.masterKey,
1439 ss->sec.ci.clientChallenge, ss->sec.ci.connectionID,
1440 cipherType);
1441 if (rv != SECSuccess)
1442 goto loser;
1443 PRINT_BUF(7, (ss, "Session read-key: ", rk->data, rk->len));
1444 PRINT_BUF(7, (ss, "Session write-key: ", wk->data, wk->len));
1446 PORT_Memcpy(ss->sec.ci.readKey, readKey.data, readKey.len);
1447 PORT_Memcpy(ss->sec.ci.writeKey, writeKey.data, writeKey.len);
1448 ss->sec.ci.keySize = readKey.len;
1450 /* Setup the MAC */
1451 rv = ssl2_CreateMAC(&ss->sec, rk, wk, cipherType);
1452 if (rv != SECSuccess)
1453 goto loser;
1455 /* First create the session key object */
1456 SSL_TRC(3, ("%d: SSL[%d]: using %s", SSL_GETPID(), ss->fd,
1457 ssl_cipherName[cipherType]));
1460 mechanism = ssl_Specs[cipherType].mechanism;
1462 /* set destructer before we call loser... */
1463 ss->sec.destroy = (void (*)(void*, PRBool)) PK11_DestroyContext;
1464 slot = PK11_GetBestSlot(mechanism, ss->pkcs11PinArg);
1465 if (slot == NULL)
1466 goto loser;
1468 param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
1469 if (param == NULL)
1470 goto loser;
1471 readcx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
1472 CKA_DECRYPT, rk, param,
1473 ss->pkcs11PinArg);
1474 SECITEM_FreeItem(param, PR_TRUE);
1475 if (readcx == NULL)
1476 goto loser;
1478 /* build the client context */
1479 param = PK11_ParamFromIV(mechanism, &sid->u.ssl2.cipherArg);
1480 if (param == NULL)
1481 goto loser;
1482 writecx = PK11_CreateContextByRawKey(slot, mechanism, PK11_OriginUnwrap,
1483 CKA_ENCRYPT, wk, param,
1484 ss->pkcs11PinArg);
1485 SECITEM_FreeItem(param,PR_TRUE);
1486 if (writecx == NULL)
1487 goto loser;
1488 PK11_FreeSlot(slot);
1490 rv = SECSuccess;
1491 ss->sec.enc = (SSLCipher) PK11_CipherOp;
1492 ss->sec.dec = (SSLCipher) PK11_CipherOp;
1493 ss->sec.readcx = (void *) readcx;
1494 ss->sec.writecx = (void *) writecx;
1495 ss->sec.blockSize = ssl_Specs[cipherType].blockSize;
1496 ss->sec.blockShift = ssl_Specs[cipherType].blockShift;
1497 ss->sec.cipherType = sid->u.ssl2.cipherType;
1498 ss->sec.keyBits = sid->u.ssl2.keyBits;
1499 ss->sec.secretKeyBits = sid->u.ssl2.secretKeyBits;
1500 goto done;
1502 loser:
1503 if (ss->sec.destroy) {
1504 if (readcx) (*ss->sec.destroy)(readcx, PR_TRUE);
1505 if (writecx) (*ss->sec.destroy)(writecx, PR_TRUE);
1507 ss->sec.destroy = NULL;
1508 if (slot) PK11_FreeSlot(slot);
1510 sec_loser:
1511 rv = SECFailure;
1513 done:
1514 if (rk) {
1515 SECITEM_ZfreeItem(rk, PR_FALSE);
1517 if (wk) {
1518 SECITEM_ZfreeItem(wk, PR_FALSE);
1520 return rv;
1524 ** Setup the server ciphers given information from a CLIENT-MASTER-KEY
1525 ** message.
1526 ** "ss" pointer to the ssl-socket object
1527 ** "cipher" the cipher type to use
1528 ** "keyBits" the size of the final cipher key
1529 ** "ck" the clear-key data
1530 ** "ckLen" the number of bytes of clear-key data
1531 ** "ek" the encrypted-key data
1532 ** "ekLen" the number of bytes of encrypted-key data
1533 ** "ca" the cipher-arg data
1534 ** "caLen" the number of bytes of cipher-arg data
1536 ** The MASTER-KEY is constructed by first decrypting the encrypted-key
1537 ** data. This produces the SECRET-KEY-DATA. The MASTER-KEY is composed by
1538 ** concatenating the clear-key data with the SECRET-KEY-DATA. This code
1539 ** checks to make sure that the client didn't send us an improper amount
1540 ** of SECRET-KEY-DATA (it restricts the length of that data to match the
1541 ** spec).
1543 ** Called from ssl2_HandleClientSessionKeyMessage().
1545 static SECStatus
1546 ssl2_ServerSetupSessionCypher(sslSocket *ss, int cipher, unsigned int keyBits,
1547 PRUint8 *ck, unsigned int ckLen,
1548 PRUint8 *ek, unsigned int ekLen,
1549 PRUint8 *ca, unsigned int caLen)
1551 PRUint8 * dk = NULL; /* decrypted master key */
1552 sslSessionID * sid;
1553 sslServerCerts * sc = ss->serverCerts + kt_rsa;
1554 PRUint8 * kbuf = 0; /* buffer for RSA decrypted data. */
1555 unsigned int ddLen; /* length of RSA decrypted data in kbuf */
1556 unsigned int keySize;
1557 unsigned int dkLen; /* decrypted key length in bytes */
1558 int modulusLen;
1559 SECStatus rv;
1560 PRUint16 allowed; /* cipher kinds enabled and allowed by policy */
1561 PRUint8 mkbuf[SSL_MAX_MASTER_KEY_BYTES];
1563 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
1564 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
1565 PORT_Assert((sc->SERVERKEY != 0));
1566 PORT_Assert((ss->sec.ci.sid != 0));
1567 sid = ss->sec.ci.sid;
1569 /* Trying to cut down on all these switch statements that should be tables.
1570 * So, test cipherType once, here, and then use tables below.
1572 switch (cipher) {
1573 case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
1574 case SSL_CK_RC4_128_WITH_MD5:
1575 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
1576 case SSL_CK_RC2_128_CBC_WITH_MD5:
1577 case SSL_CK_DES_64_CBC_WITH_MD5:
1578 case SSL_CK_DES_192_EDE3_CBC_WITH_MD5:
1579 break;
1581 default:
1582 SSL_DBG(("%d: SSL[%d]: ssl2_ServerSetupSessionCypher: unknown cipher=%d",
1583 SSL_GETPID(), ss->fd, cipher));
1584 PORT_SetError(SSL_ERROR_BAD_CLIENT);
1585 goto loser;
1588 allowed = ss->allowedByPolicy & ss->chosenPreference & SSL_CB_IMPLEMENTED;
1589 if (!(allowed & (1 << cipher))) {
1590 /* client chose a kind we don't allow! */
1591 SSL_DBG(("%d: SSL[%d]: disallowed cipher=%d",
1592 SSL_GETPID(), ss->fd, cipher));
1593 PORT_SetError(SSL_ERROR_BAD_CLIENT);
1594 goto loser;
1597 keySize = ssl_Specs[cipher].keyLen;
1598 if (keyBits != keySize * BPB) {
1599 SSL_DBG(("%d: SSL[%d]: invalid master secret key length=%d (bits)!",
1600 SSL_GETPID(), ss->fd, keyBits));
1601 PORT_SetError(SSL_ERROR_BAD_CLIENT);
1602 goto loser;
1605 if (ckLen != ssl_Specs[cipher].pubLen) {
1606 SSL_DBG(("%d: SSL[%d]: invalid clear key length, ckLen=%d (bytes)!",
1607 SSL_GETPID(), ss->fd, ckLen));
1608 PORT_SetError(SSL_ERROR_BAD_CLIENT);
1609 goto loser;
1612 if (caLen != ssl_Specs[cipher].ivLen) {
1613 SSL_DBG(("%d: SSL[%d]: invalid key args length, caLen=%d (bytes)!",
1614 SSL_GETPID(), ss->fd, caLen));
1615 PORT_SetError(SSL_ERROR_BAD_CLIENT);
1616 goto loser;
1619 modulusLen = PK11_GetPrivateModulusLen(sc->SERVERKEY);
1620 if (modulusLen == -1) {
1621 /* XXX If the key is bad, then PK11_PubDecryptRaw will fail below. */
1622 modulusLen = ekLen;
1624 if (ekLen > modulusLen || ekLen + ckLen < keySize) {
1625 SSL_DBG(("%d: SSL[%d]: invalid encrypted key length, ekLen=%d (bytes)!",
1626 SSL_GETPID(), ss->fd, ekLen));
1627 PORT_SetError(SSL_ERROR_BAD_CLIENT);
1628 goto loser;
1631 /* allocate the buffer to hold the decrypted portion of the key. */
1632 kbuf = (PRUint8*)PORT_Alloc(modulusLen);
1633 if (!kbuf) {
1634 goto loser;
1636 dkLen = keySize - ckLen;
1637 dk = kbuf + modulusLen - dkLen;
1639 /* Decrypt encrypted half of the key.
1640 ** NOTE: PK11_PubDecryptRaw will barf on a non-RSA key. This is
1641 ** desired behavior here.
1643 rv = PK11_PubDecryptRaw(sc->SERVERKEY, kbuf, &ddLen, modulusLen, ek, ekLen);
1644 if (rv != SECSuccess)
1645 goto hide_loser;
1647 /* Is the length of the decrypted data (ddLen) the expected value? */
1648 if (modulusLen != ddLen)
1649 goto hide_loser;
1651 /* Cheaply verify that PKCS#1 was used to format the encryption block */
1652 if ((kbuf[0] != 0x00) || (kbuf[1] != 0x02) || (dk[-1] != 0x00)) {
1653 SSL_DBG(("%d: SSL[%d]: strange encryption block",
1654 SSL_GETPID(), ss->fd));
1655 PORT_SetError(SSL_ERROR_BAD_CLIENT);
1656 goto hide_loser;
1659 /* Make sure we're not subject to a version rollback attack. */
1660 if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
1661 static const PRUint8 threes[8] = { 0x03, 0x03, 0x03, 0x03,
1662 0x03, 0x03, 0x03, 0x03 };
1664 if (PORT_Memcmp(dk - 8 - 1, threes, 8) == 0) {
1665 PORT_SetError(SSL_ERROR_BAD_CLIENT);
1666 goto hide_loser;
1669 if (0) {
1670 hide_loser:
1671 /* Defense against the Bleichenbacher attack.
1672 * Provide the client with NO CLUES that the decrypted master key
1673 * was erroneous. Don't send any error messages.
1674 * Instead, Generate a completely bogus master key .
1676 PK11_GenerateRandom(dk, dkLen);
1680 ** Construct master key out of the pieces.
1682 if (ckLen) {
1683 PORT_Memcpy(mkbuf, ck, ckLen);
1685 PORT_Memcpy(mkbuf + ckLen, dk, dkLen);
1687 /* Fill in session-id */
1688 rv = ssl2_FillInSID(sid, cipher, mkbuf, keySize, ca, caLen,
1689 keyBits, keyBits - (ckLen<<3),
1690 ss->sec.authAlgorithm, ss->sec.authKeyBits,
1691 ss->sec.keaType, ss->sec.keaKeyBits);
1692 if (rv != SECSuccess) {
1693 goto loser;
1696 /* Create session ciphers */
1697 rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
1698 if (rv != SECSuccess) {
1699 goto loser;
1702 SSL_TRC(1, ("%d: SSL[%d]: server, using %s cipher, clear=%d total=%d",
1703 SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
1704 ckLen<<3, keySize<<3));
1705 rv = SECSuccess;
1706 goto done;
1708 loser:
1709 rv = SECFailure;
1711 done:
1712 PORT_Free(kbuf);
1713 return rv;
1716 /************************************************************************/
1719 ** Rewrite the incoming cipher specs, comparing to list of specs we support,
1720 ** (ss->cipherSpecs) and eliminating anything we don't support
1722 * Note: Our list may contain SSL v3 ciphers.
1723 * We MUST NOT match on any of those.
1724 * Fortunately, this is easy to detect because SSLv3 ciphers have zero
1725 * in the first byte, and none of the SSLv2 ciphers do.
1727 * Called from ssl2_HandleClientHelloMessage().
1728 * Returns the number of bytes of "qualified cipher specs",
1729 * which is typically a multiple of 3, but will be zero if there are none.
1731 static int
1732 ssl2_QualifyCypherSpecs(sslSocket *ss,
1733 PRUint8 * cs, /* cipher specs in client hello msg. */
1734 int csLen)
1736 PRUint8 * ms;
1737 PRUint8 * hs;
1738 PRUint8 * qs;
1739 int mc;
1740 int hc;
1741 PRUint8 qualifiedSpecs[ssl2_NUM_SUITES_IMPLEMENTED * 3];
1743 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
1744 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
1746 if (!ss->cipherSpecs) {
1747 SECStatus rv = ssl2_ConstructCipherSpecs(ss);
1748 if (rv != SECSuccess || !ss->cipherSpecs)
1749 return 0;
1752 PRINT_BUF(10, (ss, "specs from client:", cs, csLen));
1753 qs = qualifiedSpecs;
1754 ms = ss->cipherSpecs;
1755 for (mc = ss->sizeCipherSpecs; mc > 0; mc -= 3, ms += 3) {
1756 if (ms[0] == 0)
1757 continue;
1758 for (hs = cs, hc = csLen; hc > 0; hs += 3, hc -= 3) {
1759 if ((hs[0] == ms[0]) &&
1760 (hs[1] == ms[1]) &&
1761 (hs[2] == ms[2])) {
1762 /* Copy this cipher spec into the "keep" section */
1763 qs[0] = hs[0];
1764 qs[1] = hs[1];
1765 qs[2] = hs[2];
1766 qs += 3;
1767 break;
1771 hc = qs - qualifiedSpecs;
1772 PRINT_BUF(10, (ss, "qualified specs from client:", qualifiedSpecs, hc));
1773 PORT_Memcpy(cs, qualifiedSpecs, hc);
1774 return hc;
1778 ** Pick the best cipher we can find, given the array of server cipher
1779 ** specs. Returns cipher number (e.g. SSL_CK_*), or -1 for no overlap.
1780 ** If successful, stores the master key size (bytes) in *pKeyLen.
1782 ** This is correct only for the client side, but presently
1783 ** this function is only called from
1784 ** ssl2_ClientSetupSessionCypher() <- ssl2_HandleServerHelloMessage()
1786 ** Note that most servers only return a single cipher suite in their
1787 ** ServerHello messages. So, the code below for finding the "best" cipher
1788 ** suite usually has only one choice. The client and server should send
1789 ** their cipher suite lists sorted in descending order by preference.
1791 static int
1792 ssl2_ChooseSessionCypher(sslSocket *ss,
1793 int hc, /* number of cs's in hs. */
1794 PRUint8 * hs, /* server hello's cipher suites. */
1795 int * pKeyLen) /* out: sym key size in bytes. */
1797 PRUint8 * ms;
1798 unsigned int i;
1799 int bestKeySize;
1800 int bestRealKeySize;
1801 int bestCypher;
1802 int keySize;
1803 int realKeySize;
1804 PRUint8 * ohs = hs;
1805 const PRUint8 * preferred;
1806 static const PRUint8 noneSuch[3] = { 0, 0, 0 };
1808 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
1809 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
1811 if (!ss->cipherSpecs) {
1812 SECStatus rv = ssl2_ConstructCipherSpecs(ss);
1813 if (rv != SECSuccess || !ss->cipherSpecs)
1814 goto loser;
1817 if (!ss->preferredCipher) {
1818 unsigned int allowed = ss->allowedByPolicy & ss->chosenPreference &
1819 SSL_CB_IMPLEMENTED;
1820 if (allowed) {
1821 preferred = implementedCipherSuites;
1822 for (i = ssl2_NUM_SUITES_IMPLEMENTED; i > 0; --i) {
1823 if (0 != (allowed & (1U << preferred[0]))) {
1824 ss->preferredCipher = preferred;
1825 break;
1827 preferred += 3;
1831 preferred = ss->preferredCipher ? ss->preferredCipher : noneSuch;
1833 ** Scan list of ciphers received from peer and look for a match in
1834 ** our list.
1835 * Note: Our list may contain SSL v3 ciphers.
1836 * We MUST NOT match on any of those.
1837 * Fortunately, this is easy to detect because SSLv3 ciphers have zero
1838 * in the first byte, and none of the SSLv2 ciphers do.
1840 bestKeySize = bestRealKeySize = 0;
1841 bestCypher = -1;
1842 while (--hc >= 0) {
1843 for (i = 0, ms = ss->cipherSpecs; i < ss->sizeCipherSpecs; i += 3, ms += 3) {
1844 if ((hs[0] == preferred[0]) &&
1845 (hs[1] == preferred[1]) &&
1846 (hs[2] == preferred[2]) &&
1847 hs[0] != 0) {
1848 /* Pick this cipher immediately! */
1849 *pKeyLen = (((hs[1] << 8) | hs[2]) + 7) >> 3;
1850 return hs[0];
1852 if ((hs[0] == ms[0]) && (hs[1] == ms[1]) && (hs[2] == ms[2]) &&
1853 hs[0] != 0) {
1854 /* Found a match */
1856 /* Use secret keySize to determine which cipher is best */
1857 realKeySize = (hs[1] << 8) | hs[2];
1858 switch (hs[0]) {
1859 case SSL_CK_RC4_128_EXPORT40_WITH_MD5:
1860 case SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5:
1861 keySize = 40;
1862 break;
1863 default:
1864 keySize = realKeySize;
1865 break;
1867 if (keySize > bestKeySize) {
1868 bestCypher = hs[0];
1869 bestKeySize = keySize;
1870 bestRealKeySize = realKeySize;
1874 hs += 3;
1876 if (bestCypher < 0) {
1878 ** No overlap between server and client. Re-examine server list
1879 ** to see what kind of ciphers it does support so that we can set
1880 ** the error code appropriately.
1882 if ((ohs[0] == SSL_CK_RC4_128_WITH_MD5) ||
1883 (ohs[0] == SSL_CK_RC2_128_CBC_WITH_MD5)) {
1884 PORT_SetError(SSL_ERROR_US_ONLY_SERVER);
1885 } else if ((ohs[0] == SSL_CK_RC4_128_EXPORT40_WITH_MD5) ||
1886 (ohs[0] == SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5)) {
1887 PORT_SetError(SSL_ERROR_EXPORT_ONLY_SERVER);
1888 } else {
1889 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
1891 SSL_DBG(("%d: SSL[%d]: no cipher overlap", SSL_GETPID(), ss->fd));
1892 goto loser;
1894 *pKeyLen = (bestRealKeySize + 7) >> 3;
1895 return bestCypher;
1897 loser:
1898 return -1;
1901 static SECStatus
1902 ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen)
1904 CERTCertificate *cert = NULL;
1905 SECItem certItem;
1907 certItem.data = certData;
1908 certItem.len = certLen;
1910 /* decode the certificate */
1911 cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
1912 PR_FALSE, PR_TRUE);
1914 if (cert == NULL) {
1915 SSL_DBG(("%d: SSL[%d]: decode of server certificate fails",
1916 SSL_GETPID(), ss->fd));
1917 PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
1918 return SECFailure;
1921 #ifdef TRACE
1923 if (ssl_trace >= 1) {
1924 char *issuer;
1925 char *subject;
1926 issuer = CERT_NameToAscii(&cert->issuer);
1927 subject = CERT_NameToAscii(&cert->subject);
1928 SSL_TRC(1,("%d: server certificate issuer: '%s'",
1929 SSL_GETPID(), issuer ? issuer : "OOPS"));
1930 SSL_TRC(1,("%d: server name: '%s'",
1931 SSL_GETPID(), subject ? subject : "OOPS"));
1932 PORT_Free(issuer);
1933 PORT_Free(subject);
1936 #endif
1938 ss->sec.peerCert = cert;
1939 return SECSuccess;
1944 * Format one block of data for public/private key encryption using
1945 * the rules defined in PKCS #1. SSL2 does this itself to handle the
1946 * rollback detection.
1948 #define RSA_BLOCK_MIN_PAD_LEN 8
1949 #define RSA_BLOCK_FIRST_OCTET 0x00
1950 #define RSA_BLOCK_AFTER_PAD_OCTET 0x00
1951 #define RSA_BLOCK_PUBLIC_OCTET 0x02
1952 unsigned char *
1953 ssl_FormatSSL2Block(unsigned modulusLen, SECItem *data)
1955 unsigned char *block;
1956 unsigned char *bp;
1957 int padLen;
1958 SECStatus rv;
1959 int i;
1961 if (modulusLen < data->len + (3 + RSA_BLOCK_MIN_PAD_LEN)) {
1962 PORT_SetError(SEC_ERROR_BAD_KEY);
1963 return NULL;
1965 block = (unsigned char *) PORT_Alloc(modulusLen);
1966 if (block == NULL)
1967 return NULL;
1969 bp = block;
1972 * All RSA blocks start with two octets:
1973 * 0x00 || BlockType
1975 *bp++ = RSA_BLOCK_FIRST_OCTET;
1976 *bp++ = RSA_BLOCK_PUBLIC_OCTET;
1979 * 0x00 || BT || Pad || 0x00 || ActualData
1980 * 1 1 padLen 1 data->len
1981 * Pad is all non-zero random bytes.
1983 padLen = modulusLen - data->len - 3;
1984 PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
1985 rv = PK11_GenerateRandom(bp, padLen);
1986 if (rv == SECFailure) goto loser;
1987 /* replace all the 'zero' bytes */
1988 for (i = 0; i < padLen; i++) {
1989 while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET) {
1990 rv = PK11_GenerateRandom(bp+i, 1);
1991 if (rv == SECFailure) goto loser;
1994 bp += padLen;
1995 *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
1996 PORT_Memcpy (bp, data->data, data->len);
1998 return block;
1999 loser:
2000 if (block) PORT_Free(block);
2001 return NULL;
2005 ** Given the server's public key and cipher specs, generate a session key
2006 ** that is ready to use for encrypting/decrypting the byte stream. At
2007 ** the same time, generate the SSL_MT_CLIENT_MASTER_KEY message and
2008 ** send it to the server.
2010 ** Called from ssl2_HandleServerHelloMessage()
2012 static SECStatus
2013 ssl2_ClientSetupSessionCypher(sslSocket *ss, PRUint8 *cs, int csLen)
2015 sslSessionID * sid;
2016 PRUint8 * ca; /* points to iv data, or NULL if none. */
2017 PRUint8 * ekbuf = 0;
2018 CERTCertificate * cert = 0;
2019 SECKEYPublicKey * serverKey = 0;
2020 unsigned modulusLen = 0;
2021 SECStatus rv;
2022 int cipher;
2023 int keyLen; /* cipher symkey size in bytes. */
2024 int ckLen; /* publicly reveal this many bytes of key. */
2025 int caLen; /* length of IV data at *ca. */
2026 int nc;
2028 unsigned char *eblock; /* holds unencrypted PKCS#1 formatted key. */
2029 SECItem rek; /* holds portion of symkey to be encrypted. */
2031 PRUint8 keyData[SSL_MAX_MASTER_KEY_BYTES];
2032 PRUint8 iv [8];
2034 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
2036 eblock = NULL;
2038 sid = ss->sec.ci.sid;
2039 PORT_Assert(sid != 0);
2041 cert = ss->sec.peerCert;
2043 serverKey = CERT_ExtractPublicKey(cert);
2044 if (!serverKey) {
2045 SSL_DBG(("%d: SSL[%d]: extract public key failed: error=%d",
2046 SSL_GETPID(), ss->fd, PORT_GetError()));
2047 PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
2048 rv = SECFailure;
2049 goto loser2;
2052 ss->sec.authAlgorithm = ssl_sign_rsa;
2053 ss->sec.keaType = ssl_kea_rsa;
2054 ss->sec.keaKeyBits = \
2055 ss->sec.authKeyBits = SECKEY_PublicKeyStrengthInBits(serverKey);
2057 /* Choose a compatible cipher with the server */
2058 nc = csLen / 3;
2059 cipher = ssl2_ChooseSessionCypher(ss, nc, cs, &keyLen);
2060 if (cipher < 0) {
2061 /* ssl2_ChooseSessionCypher has set error code. */
2062 ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
2063 goto loser;
2066 /* Generate the random keys */
2067 PK11_GenerateRandom(keyData, sizeof(keyData));
2070 ** Next, carve up the keys into clear and encrypted portions. The
2071 ** clear data is taken from the start of keyData and the encrypted
2072 ** portion from the remainder. Note that each of these portions is
2073 ** carved in half, one half for the read-key and one for the
2074 ** write-key.
2076 ca = 0;
2078 /* We know that cipher is a legit value here, because
2079 * ssl2_ChooseSessionCypher doesn't return bogus values.
2081 ckLen = ssl_Specs[cipher].pubLen; /* cleartext key length. */
2082 caLen = ssl_Specs[cipher].ivLen; /* IV length. */
2083 if (caLen) {
2084 PORT_Assert(sizeof iv >= caLen);
2085 PK11_GenerateRandom(iv, caLen);
2086 ca = iv;
2089 /* Fill in session-id */
2090 rv = ssl2_FillInSID(sid, cipher, keyData, keyLen,
2091 ca, caLen, keyLen << 3, (keyLen - ckLen) << 3,
2092 ss->sec.authAlgorithm, ss->sec.authKeyBits,
2093 ss->sec.keaType, ss->sec.keaKeyBits);
2094 if (rv != SECSuccess) {
2095 goto loser;
2098 SSL_TRC(1, ("%d: SSL[%d]: client, using %s cipher, clear=%d total=%d",
2099 SSL_GETPID(), ss->fd, ssl_cipherName[cipher],
2100 ckLen<<3, keyLen<<3));
2102 /* Now setup read and write ciphers */
2103 rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
2104 if (rv != SECSuccess) {
2105 goto loser;
2109 ** Fill in the encryption buffer with some random bytes. Then
2110 ** copy in the portion of the session key we are encrypting.
2112 modulusLen = SECKEY_PublicKeyStrength(serverKey);
2113 rek.data = keyData + ckLen;
2114 rek.len = keyLen - ckLen;
2115 eblock = ssl_FormatSSL2Block(modulusLen, &rek);
2116 if (eblock == NULL)
2117 goto loser;
2119 /* Set up the padding for version 2 rollback detection. */
2120 /* XXX We should really use defines here */
2121 if (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
2122 PORT_Assert((modulusLen - rek.len) > 12);
2123 PORT_Memset(eblock + modulusLen - rek.len - 8 - 1, 0x03, 8);
2125 ekbuf = (PRUint8*) PORT_Alloc(modulusLen);
2126 if (!ekbuf)
2127 goto loser;
2128 PRINT_BUF(10, (ss, "master key encryption block:",
2129 eblock, modulusLen));
2131 /* Encrypt ekitem */
2132 rv = PK11_PubEncryptRaw(serverKey, ekbuf, eblock, modulusLen,
2133 ss->pkcs11PinArg);
2134 if (rv)
2135 goto loser;
2137 /* Now we have everything ready to send */
2138 rv = ssl2_SendSessionKeyMessage(ss, cipher, keyLen << 3, ca, caLen,
2139 keyData, ckLen, ekbuf, modulusLen);
2140 if (rv != SECSuccess) {
2141 goto loser;
2143 rv = SECSuccess;
2144 goto done;
2146 loser:
2147 rv = SECFailure;
2149 loser2:
2150 done:
2151 PORT_Memset(keyData, 0, sizeof(keyData));
2152 PORT_ZFree(ekbuf, modulusLen);
2153 PORT_ZFree(eblock, modulusLen);
2154 SECKEY_DestroyPublicKey(serverKey);
2155 return rv;
2158 /************************************************************************/
2161 * Called from ssl2_HandleMessage in response to SSL_MT_SERVER_FINISHED message.
2162 * Caller holds recvBufLock and handshakeLock
2164 static void
2165 ssl2_ClientRegSessionID(sslSocket *ss, PRUint8 *s)
2167 sslSessionID *sid = ss->sec.ci.sid;
2169 /* Record entry in nonce cache */
2170 if (sid->peerCert == NULL) {
2171 PORT_Memcpy(sid->u.ssl2.sessionID, s, sizeof(sid->u.ssl2.sessionID));
2172 sid->peerCert = CERT_DupCertificate(ss->sec.peerCert);
2175 if (!ss->opt.noCache && sid->cached == never_cached)
2176 (*ss->sec.cache)(sid);
2179 /* Called from ssl2_HandleMessage() */
2180 static SECStatus
2181 ssl2_TriggerNextMessage(sslSocket *ss)
2183 SECStatus rv;
2185 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
2187 if ((ss->sec.ci.requiredElements & CIS_HAVE_CERTIFICATE) &&
2188 !(ss->sec.ci.sentElements & CIS_HAVE_CERTIFICATE)) {
2189 ss->sec.ci.sentElements |= CIS_HAVE_CERTIFICATE;
2190 rv = ssl2_SendCertificateRequestMessage(ss);
2191 return rv;
2193 return SECSuccess;
2196 /* See if it's time to send our finished message, or if the handshakes are
2197 ** complete. Send finished message if appropriate.
2198 ** Returns SECSuccess unless anything goes wrong.
2200 ** Called from ssl2_HandleMessage,
2201 ** ssl2_HandleVerifyMessage
2202 ** ssl2_HandleServerHelloMessage
2203 ** ssl2_HandleClientSessionKeyMessage
2205 static SECStatus
2206 ssl2_TryToFinish(sslSocket *ss)
2208 SECStatus rv;
2209 char e, ef;
2211 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
2213 e = ss->sec.ci.elements;
2214 ef = e | CIS_HAVE_FINISHED;
2215 if ((ef & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
2216 if (ss->sec.isServer) {
2217 /* Send server finished message if we already didn't */
2218 rv = ssl2_SendServerFinishedMessage(ss);
2219 } else {
2220 /* Send client finished message if we already didn't */
2221 rv = ssl2_SendClientFinishedMessage(ss);
2223 if (rv != SECSuccess) {
2224 return rv;
2226 if ((e & ss->sec.ci.requiredElements) == ss->sec.ci.requiredElements) {
2227 /* Totally finished */
2228 ss->handshake = 0;
2229 return SECSuccess;
2232 return SECSuccess;
2236 ** Called from ssl2_HandleRequestCertificate
2238 static SECStatus
2239 ssl2_SignResponse(sslSocket *ss,
2240 SECKEYPrivateKey *key,
2241 SECItem *response)
2243 SGNContext * sgn = NULL;
2244 PRUint8 * challenge;
2245 unsigned int len;
2246 SECStatus rv = SECFailure;
2248 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
2250 challenge = ss->sec.ci.serverChallenge;
2251 len = ss->sec.ci.serverChallengeLen;
2253 /* Sign the expected data... */
2254 sgn = SGN_NewContext(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,key);
2255 if (!sgn)
2256 goto done;
2257 rv = SGN_Begin(sgn);
2258 if (rv != SECSuccess)
2259 goto done;
2260 rv = SGN_Update(sgn, ss->sec.ci.readKey, ss->sec.ci.keySize);
2261 if (rv != SECSuccess)
2262 goto done;
2263 rv = SGN_Update(sgn, ss->sec.ci.writeKey, ss->sec.ci.keySize);
2264 if (rv != SECSuccess)
2265 goto done;
2266 rv = SGN_Update(sgn, challenge, len);
2267 if (rv != SECSuccess)
2268 goto done;
2269 rv = SGN_Update(sgn, ss->sec.peerCert->derCert.data,
2270 ss->sec.peerCert->derCert.len);
2271 if (rv != SECSuccess)
2272 goto done;
2273 rv = SGN_End(sgn, response);
2274 if (rv != SECSuccess)
2275 goto done;
2277 done:
2278 SGN_DestroyContext(sgn, PR_TRUE);
2279 return rv == SECSuccess ? SECSuccess : SECFailure;
2283 ** Try to handle a request-certificate message. Get client's certificate
2284 ** and private key and sign a message for the server to see.
2285 ** Caller must hold handshakeLock
2287 ** Called from ssl2_HandleMessage().
2289 static int
2290 ssl2_HandleRequestCertificate(sslSocket *ss)
2292 CERTCertificate * cert = NULL; /* app-selected client cert. */
2293 SECKEYPrivateKey *key = NULL; /* priv key for cert. */
2294 SECStatus rv;
2295 SECItem response;
2296 int ret = 0;
2297 PRUint8 authType;
2301 * These things all need to be initialized before we can "goto loser".
2303 response.data = NULL;
2305 /* get challenge info from connectionInfo */
2306 authType = ss->sec.ci.authType;
2308 if (authType != SSL_AT_MD5_WITH_RSA_ENCRYPTION) {
2309 SSL_TRC(7, ("%d: SSL[%d]: unsupported auth type 0x%x", SSL_GETPID(),
2310 ss->fd, authType));
2311 goto no_cert_error;
2314 /* Get certificate and private-key from client */
2315 if (!ss->getClientAuthData) {
2316 SSL_TRC(7, ("%d: SSL[%d]: client doesn't support client-auth",
2317 SSL_GETPID(), ss->fd));
2318 goto no_cert_error;
2320 ret = (*ss->getClientAuthData)(ss->getClientAuthDataArg, ss->fd,
2321 NULL, &cert, &key);
2322 if ( ret == SECWouldBlock ) {
2323 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
2324 ret = -1;
2325 goto loser;
2328 if (ret) {
2329 goto no_cert_error;
2332 /* check what the callback function returned */
2333 if ((!cert) || (!key)) {
2334 /* we are missing either the key or cert */
2335 if (cert) {
2336 /* got a cert, but no key - free it */
2337 CERT_DestroyCertificate(cert);
2338 cert = NULL;
2340 if (key) {
2341 /* got a key, but no cert - free it */
2342 SECKEY_DestroyPrivateKey(key);
2343 key = NULL;
2345 goto no_cert_error;
2348 rv = ssl2_SignResponse(ss, key, &response);
2349 if ( rv != SECSuccess ) {
2350 ret = -1;
2351 goto loser;
2354 /* Send response message */
2355 ret = ssl2_SendCertificateResponseMessage(ss, &cert->derCert, &response);
2357 /* Now, remember the cert we sent. But first, forget any previous one. */
2358 if (ss->sec.localCert) {
2359 CERT_DestroyCertificate(ss->sec.localCert);
2361 ss->sec.localCert = CERT_DupCertificate(cert);
2362 PORT_Assert(!ss->sec.ci.sid->localCert);
2363 if (ss->sec.ci.sid->localCert) {
2364 CERT_DestroyCertificate(ss->sec.ci.sid->localCert);
2366 ss->sec.ci.sid->localCert = cert;
2367 cert = NULL;
2369 goto done;
2371 no_cert_error:
2372 SSL_TRC(7, ("%d: SSL[%d]: no certificate (ret=%d)", SSL_GETPID(),
2373 ss->fd, ret));
2374 ret = ssl2_SendErrorMessage(ss, SSL_PE_NO_CERTIFICATE);
2376 loser:
2377 done:
2378 if ( cert ) {
2379 CERT_DestroyCertificate(cert);
2381 if ( key ) {
2382 SECKEY_DestroyPrivateKey(key);
2384 if ( response.data ) {
2385 PORT_Free(response.data);
2388 return ret;
2392 ** Called from ssl2_HandleMessage for SSL_MT_CLIENT_CERTIFICATE message.
2393 ** Caller must hold HandshakeLock and RecvBufLock, since cd and response
2394 ** are contained in the gathered input data.
2396 static SECStatus
2397 ssl2_HandleClientCertificate(sslSocket * ss,
2398 PRUint8 certType, /* XXX unused */
2399 PRUint8 * cd,
2400 unsigned int cdLen,
2401 PRUint8 * response,
2402 unsigned int responseLen)
2404 CERTCertificate *cert = NULL;
2405 SECKEYPublicKey *pubKey = NULL;
2406 VFYContext * vfy = NULL;
2407 SECItem * derCert;
2408 SECStatus rv = SECFailure;
2409 SECItem certItem;
2410 SECItem rep;
2412 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
2413 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
2415 /* Extract the certificate */
2416 certItem.data = cd;
2417 certItem.len = cdLen;
2419 cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
2420 PR_FALSE, PR_TRUE);
2421 if (cert == NULL) {
2422 goto loser;
2425 /* save the certificate, since the auth routine will need it */
2426 ss->sec.peerCert = cert;
2428 /* Extract the public key */
2429 pubKey = CERT_ExtractPublicKey(cert);
2430 if (!pubKey)
2431 goto loser;
2433 /* Verify the response data... */
2434 rep.data = response;
2435 rep.len = responseLen;
2436 /* SSL 2.0 only supports RSA certs, so we don't have to worry about
2437 * DSA here. */
2438 vfy = VFY_CreateContext(pubKey, &rep, SEC_OID_PKCS1_RSA_ENCRYPTION,
2439 ss->pkcs11PinArg);
2440 if (!vfy)
2441 goto loser;
2442 rv = VFY_Begin(vfy);
2443 if (rv)
2444 goto loser;
2446 rv = VFY_Update(vfy, ss->sec.ci.readKey, ss->sec.ci.keySize);
2447 if (rv)
2448 goto loser;
2449 rv = VFY_Update(vfy, ss->sec.ci.writeKey, ss->sec.ci.keySize);
2450 if (rv)
2451 goto loser;
2452 rv = VFY_Update(vfy, ss->sec.ci.serverChallenge, SSL_CHALLENGE_BYTES);
2453 if (rv)
2454 goto loser;
2456 derCert = &ss->serverCerts[kt_rsa].serverCert->derCert;
2457 rv = VFY_Update(vfy, derCert->data, derCert->len);
2458 if (rv)
2459 goto loser;
2460 rv = VFY_End(vfy);
2461 if (rv)
2462 goto loser;
2464 /* Now ask the server application if it likes the certificate... */
2465 rv = (SECStatus) (*ss->authCertificate)(ss->authCertificateArg,
2466 ss->fd, PR_TRUE, PR_TRUE);
2467 /* Hey, it liked it. */
2468 if (SECSuccess == rv)
2469 goto done;
2471 loser:
2472 ss->sec.peerCert = NULL;
2473 CERT_DestroyCertificate(cert);
2475 done:
2476 VFY_DestroyContext(vfy, PR_TRUE);
2477 SECKEY_DestroyPublicKey(pubKey);
2478 return rv;
2482 ** Handle remaining messages between client/server. Process finished
2483 ** messages from either side and any authentication requests.
2484 ** This should only be called for SSLv2 handshake messages,
2485 ** not for application data records.
2486 ** Caller must hold handshake lock.
2488 ** Called from ssl_Do1stHandshake().
2491 static SECStatus
2492 ssl2_HandleMessage(sslSocket *ss)
2494 PRUint8 * data;
2495 PRUint8 * cid;
2496 unsigned len, certType, certLen, responseLen;
2497 int rv;
2498 int rv2;
2500 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
2502 ssl_GetRecvBufLock(ss);
2504 data = ss->gs.buf.buf + ss->gs.recordOffset;
2506 if (ss->gs.recordLen < 1) {
2507 goto bad_peer;
2509 SSL_TRC(3, ("%d: SSL[%d]: received %d message",
2510 SSL_GETPID(), ss->fd, data[0]));
2511 DUMP_MSG(29, (ss, data, ss->gs.recordLen));
2513 switch (data[0]) {
2514 case SSL_MT_CLIENT_FINISHED:
2515 if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
2516 SSL_DBG(("%d: SSL[%d]: dup client-finished message",
2517 SSL_GETPID(), ss->fd));
2518 goto bad_peer;
2521 /* See if nonce matches */
2522 len = ss->gs.recordLen - 1;
2523 cid = data + 1;
2524 if ((len != sizeof(ss->sec.ci.connectionID)) ||
2525 (PORT_Memcmp(ss->sec.ci.connectionID, cid, len) != 0)) {
2526 SSL_DBG(("%d: SSL[%d]: bad connection-id", SSL_GETPID(), ss->fd));
2527 PRINT_BUF(5, (ss, "sent connection-id",
2528 ss->sec.ci.connectionID,
2529 sizeof(ss->sec.ci.connectionID)));
2530 PRINT_BUF(5, (ss, "rcvd connection-id", cid, len));
2531 goto bad_peer;
2534 SSL_TRC(5, ("%d: SSL[%d]: got client finished, waiting for 0x%d",
2535 SSL_GETPID(), ss->fd,
2536 ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
2537 ss->sec.ci.elements |= CIS_HAVE_FINISHED;
2538 break;
2540 case SSL_MT_SERVER_FINISHED:
2541 if (ss->sec.ci.elements & CIS_HAVE_FINISHED) {
2542 SSL_DBG(("%d: SSL[%d]: dup server-finished message",
2543 SSL_GETPID(), ss->fd));
2544 goto bad_peer;
2547 if (ss->gs.recordLen - 1 != SSL2_SESSIONID_BYTES) {
2548 SSL_DBG(("%d: SSL[%d]: bad server-finished message, len=%d",
2549 SSL_GETPID(), ss->fd, ss->gs.recordLen));
2550 goto bad_peer;
2552 ssl2_ClientRegSessionID(ss, data+1);
2553 SSL_TRC(5, ("%d: SSL[%d]: got server finished, waiting for 0x%d",
2554 SSL_GETPID(), ss->fd,
2555 ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
2556 ss->sec.ci.elements |= CIS_HAVE_FINISHED;
2557 break;
2559 case SSL_MT_REQUEST_CERTIFICATE:
2560 len = ss->gs.recordLen - 2;
2561 if ((len < SSL_MIN_CHALLENGE_BYTES) ||
2562 (len > SSL_MAX_CHALLENGE_BYTES)) {
2563 /* Bad challenge */
2564 SSL_DBG(("%d: SSL[%d]: bad cert request message: code len=%d",
2565 SSL_GETPID(), ss->fd, len));
2566 goto bad_peer;
2569 /* save auth request info */
2570 ss->sec.ci.authType = data[1];
2571 ss->sec.ci.serverChallengeLen = len;
2572 PORT_Memcpy(ss->sec.ci.serverChallenge, data + 2, len);
2574 rv = ssl2_HandleRequestCertificate(ss);
2575 if (rv == SECWouldBlock) {
2576 SSL_TRC(3, ("%d: SSL[%d]: async cert request",
2577 SSL_GETPID(), ss->fd));
2578 /* someone is handling this asynchronously */
2579 ssl_ReleaseRecvBufLock(ss);
2580 return SECWouldBlock;
2582 if (rv) {
2583 SET_ERROR_CODE
2584 goto loser;
2586 break;
2588 case SSL_MT_CLIENT_CERTIFICATE:
2589 if (!ss->authCertificate) {
2590 /* Server asked for authentication and can't handle it */
2591 PORT_SetError(SSL_ERROR_BAD_SERVER);
2592 goto loser;
2594 if (ss->gs.recordLen < SSL_HL_CLIENT_CERTIFICATE_HBYTES) {
2595 SET_ERROR_CODE
2596 goto loser;
2598 certType = data[1];
2599 certLen = (data[2] << 8) | data[3];
2600 responseLen = (data[4] << 8) | data[5];
2601 if (certType != SSL_CT_X509_CERTIFICATE) {
2602 PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
2603 goto loser;
2605 if (certLen + responseLen + SSL_HL_CLIENT_CERTIFICATE_HBYTES
2606 > ss->gs.recordLen) {
2607 /* prevent overflow crash. */
2608 rv = SECFailure;
2609 } else
2610 rv = ssl2_HandleClientCertificate(ss, data[1],
2611 data + SSL_HL_CLIENT_CERTIFICATE_HBYTES,
2612 certLen,
2613 data + SSL_HL_CLIENT_CERTIFICATE_HBYTES + certLen,
2614 responseLen);
2615 if (rv) {
2616 rv2 = ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
2617 SET_ERROR_CODE
2618 goto loser;
2620 ss->sec.ci.elements |= CIS_HAVE_CERTIFICATE;
2621 break;
2623 case SSL_MT_ERROR:
2624 rv = (data[1] << 8) | data[2];
2625 SSL_TRC(2, ("%d: SSL[%d]: got error message, error=0x%x",
2626 SSL_GETPID(), ss->fd, rv));
2628 /* Convert protocol error number into API error number */
2629 switch (rv) {
2630 case SSL_PE_NO_CYPHERS:
2631 rv = SSL_ERROR_NO_CYPHER_OVERLAP;
2632 break;
2633 case SSL_PE_NO_CERTIFICATE:
2634 rv = SSL_ERROR_NO_CERTIFICATE;
2635 break;
2636 case SSL_PE_BAD_CERTIFICATE:
2637 rv = SSL_ERROR_BAD_CERTIFICATE;
2638 break;
2639 case SSL_PE_UNSUPPORTED_CERTIFICATE_TYPE:
2640 rv = SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE;
2641 break;
2642 default:
2643 goto bad_peer;
2645 /* XXX make certificate-request optionally fail... */
2646 PORT_SetError(rv);
2647 goto loser;
2649 default:
2650 SSL_DBG(("%d: SSL[%d]: unknown message %d",
2651 SSL_GETPID(), ss->fd, data[0]));
2652 goto loser;
2655 SSL_TRC(3, ("%d: SSL[%d]: handled %d message, required=0x%x got=0x%x",
2656 SSL_GETPID(), ss->fd, data[0],
2657 ss->sec.ci.requiredElements, ss->sec.ci.elements));
2659 rv = ssl2_TryToFinish(ss);
2660 if (rv != SECSuccess)
2661 goto loser;
2663 ss->gs.recordLen = 0;
2664 ssl_ReleaseRecvBufLock(ss);
2666 if (ss->handshake == 0) {
2667 return SECSuccess;
2670 ss->handshake = ssl_GatherRecord1stHandshake;
2671 ss->nextHandshake = ssl2_HandleMessage;
2672 return ssl2_TriggerNextMessage(ss);
2674 bad_peer:
2675 PORT_SetError(ss->sec.isServer ? SSL_ERROR_BAD_CLIENT : SSL_ERROR_BAD_SERVER);
2676 /* FALL THROUGH */
2678 loser:
2679 ssl_ReleaseRecvBufLock(ss);
2680 return SECFailure;
2683 /************************************************************************/
2685 /* Called from ssl_Do1stHandshake, after ssl2_HandleServerHelloMessage.
2687 static SECStatus
2688 ssl2_HandleVerifyMessage(sslSocket *ss)
2690 PRUint8 * data;
2691 SECStatus rv;
2693 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
2694 ssl_GetRecvBufLock(ss);
2696 data = ss->gs.buf.buf + ss->gs.recordOffset;
2697 DUMP_MSG(29, (ss, data, ss->gs.recordLen));
2698 if ((ss->gs.recordLen != 1 + SSL_CHALLENGE_BYTES) ||
2699 (data[0] != SSL_MT_SERVER_VERIFY) ||
2700 NSS_SecureMemcmp(data+1, ss->sec.ci.clientChallenge,
2701 SSL_CHALLENGE_BYTES)) {
2702 /* Bad server */
2703 PORT_SetError(SSL_ERROR_BAD_SERVER);
2704 goto loser;
2706 ss->sec.ci.elements |= CIS_HAVE_VERIFY;
2708 SSL_TRC(5, ("%d: SSL[%d]: got server-verify, required=0x%d got=0x%x",
2709 SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
2710 ss->sec.ci.elements));
2712 rv = ssl2_TryToFinish(ss);
2713 if (rv)
2714 goto loser;
2716 ss->gs.recordLen = 0;
2717 ssl_ReleaseRecvBufLock(ss);
2719 if (ss->handshake == 0) {
2720 return SECSuccess;
2722 ss->handshake = ssl_GatherRecord1stHandshake;
2723 ss->nextHandshake = ssl2_HandleMessage;
2724 return SECSuccess;
2727 loser:
2728 ssl_ReleaseRecvBufLock(ss);
2729 return SECFailure;
2732 /* Not static because ssl2_GatherData() tests ss->nextHandshake for this value.
2733 * ICK!
2734 * Called from ssl_Do1stHandshake after ssl2_BeginClientHandshake()
2736 SECStatus
2737 ssl2_HandleServerHelloMessage(sslSocket *ss)
2739 sslSessionID * sid;
2740 PRUint8 * cert;
2741 PRUint8 * cs;
2742 PRUint8 * data;
2743 SECStatus rv;
2744 int needed, sidHit, certLen, csLen, cidLen, certType, err;
2746 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
2748 if (!ss->opt.enableSSL2) {
2749 PORT_SetError(SSL_ERROR_SSL2_DISABLED);
2750 return SECFailure;
2753 ssl_GetRecvBufLock(ss);
2755 PORT_Assert(ss->sec.ci.sid != 0);
2756 sid = ss->sec.ci.sid;
2758 data = ss->gs.buf.buf + ss->gs.recordOffset;
2759 DUMP_MSG(29, (ss, data, ss->gs.recordLen));
2761 /* Make sure first message has some data and is the server hello message */
2762 if ((ss->gs.recordLen < SSL_HL_SERVER_HELLO_HBYTES)
2763 || (data[0] != SSL_MT_SERVER_HELLO)) {
2764 if ((data[0] == SSL_MT_ERROR) && (ss->gs.recordLen == 3)) {
2765 err = (data[1] << 8) | data[2];
2766 if (err == SSL_PE_NO_CYPHERS) {
2767 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
2768 goto loser;
2771 goto bad_server;
2774 sidHit = data[1];
2775 certType = data[2];
2776 ss->version = (data[3] << 8) | data[4];
2777 certLen = (data[5] << 8) | data[6];
2778 csLen = (data[7] << 8) | data[8];
2779 cidLen = (data[9] << 8) | data[10];
2780 cert = data + SSL_HL_SERVER_HELLO_HBYTES;
2781 cs = cert + certLen;
2783 SSL_TRC(5,
2784 ("%d: SSL[%d]: server-hello, hit=%d vers=%x certLen=%d csLen=%d cidLen=%d",
2785 SSL_GETPID(), ss->fd, sidHit, ss->version, certLen,
2786 csLen, cidLen));
2787 if (ss->version != SSL_LIBRARY_VERSION_2) {
2788 if (ss->version < SSL_LIBRARY_VERSION_2) {
2789 SSL_TRC(3, ("%d: SSL[%d]: demoting self (%x) to server version (%x)",
2790 SSL_GETPID(), ss->fd, SSL_LIBRARY_VERSION_2,
2791 ss->version));
2792 } else {
2793 SSL_TRC(1, ("%d: SSL[%d]: server version is %x (we are %x)",
2794 SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
2795 /* server claims to be newer but does not follow protocol */
2796 PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
2797 goto loser;
2801 if ((SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen + cidLen
2802 > ss->gs.recordLen)
2803 || (csLen % 3) != 0
2804 /* || cidLen < SSL_CONNECTIONID_BYTES || cidLen > 32 */
2806 goto bad_server;
2809 /* Save connection-id.
2810 ** This code only saves the first 16 byte of the connectionID.
2811 ** If the connectionID is shorter than 16 bytes, it is zero-padded.
2813 if (cidLen < sizeof ss->sec.ci.connectionID)
2814 memset(ss->sec.ci.connectionID, 0, sizeof ss->sec.ci.connectionID);
2815 cidLen = PR_MIN(cidLen, sizeof ss->sec.ci.connectionID);
2816 PORT_Memcpy(ss->sec.ci.connectionID, cs + csLen, cidLen);
2818 /* See if session-id hit */
2819 needed = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED | CIS_HAVE_VERIFY;
2820 if (sidHit) {
2821 if (certLen || csLen) {
2822 /* Uh oh - bogus server */
2823 SSL_DBG(("%d: SSL[%d]: client, huh? hit=%d certLen=%d csLen=%d",
2824 SSL_GETPID(), ss->fd, sidHit, certLen, csLen));
2825 goto bad_server;
2828 /* Total winner. */
2829 SSL_TRC(1, ("%d: SSL[%d]: client, using nonce for peer=0x%08x "
2830 "port=0x%04x",
2831 SSL_GETPID(), ss->fd, ss->sec.ci.peer, ss->sec.ci.port));
2832 ss->sec.peerCert = CERT_DupCertificate(sid->peerCert);
2833 ss->sec.authAlgorithm = sid->authAlgorithm;
2834 ss->sec.authKeyBits = sid->authKeyBits;
2835 ss->sec.keaType = sid->keaType;
2836 ss->sec.keaKeyBits = sid->keaKeyBits;
2837 rv = ssl2_CreateSessionCypher(ss, sid, PR_TRUE);
2838 if (rv != SECSuccess) {
2839 goto loser;
2841 } else {
2842 if (certType != SSL_CT_X509_CERTIFICATE) {
2843 PORT_SetError(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
2844 goto loser;
2846 if (csLen == 0) {
2847 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
2848 SSL_DBG(("%d: SSL[%d]: no cipher overlap",
2849 SSL_GETPID(), ss->fd));
2850 goto loser;
2852 if (certLen == 0) {
2853 SSL_DBG(("%d: SSL[%d]: client, huh? certLen=%d csLen=%d",
2854 SSL_GETPID(), ss->fd, certLen, csLen));
2855 goto bad_server;
2858 if (sid->cached != never_cached) {
2859 /* Forget our session-id - server didn't like it */
2860 SSL_TRC(7, ("%d: SSL[%d]: server forgot me, uncaching session-id",
2861 SSL_GETPID(), ss->fd));
2862 if (ss->sec.uncache)
2863 (*ss->sec.uncache)(sid);
2864 ssl_FreeSID(sid);
2865 ss->sec.ci.sid = sid = PORT_ZNew(sslSessionID);
2866 if (!sid) {
2867 goto loser;
2869 sid->references = 1;
2870 sid->addr = ss->sec.ci.peer;
2871 sid->port = ss->sec.ci.port;
2874 /* decode the server's certificate */
2875 rv = ssl2_ClientHandleServerCert(ss, cert, certLen);
2876 if (rv != SECSuccess) {
2877 if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
2878 (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
2880 goto loser;
2883 /* Setup new session cipher */
2884 rv = ssl2_ClientSetupSessionCypher(ss, cs, csLen);
2885 if (rv != SECSuccess) {
2886 if (PORT_GetError() == SSL_ERROR_BAD_CERTIFICATE) {
2887 (void) ssl2_SendErrorMessage(ss, SSL_PE_BAD_CERTIFICATE);
2889 goto loser;
2893 /* Build up final list of required elements */
2894 ss->sec.ci.elements = CIS_HAVE_MASTER_KEY;
2895 ss->sec.ci.requiredElements = needed;
2897 if (!sidHit) {
2898 /* verify the server's certificate. if sidHit, don't check signatures */
2899 rv = (* ss->authCertificate)(ss->authCertificateArg, ss->fd,
2900 (PRBool)(!sidHit), PR_FALSE);
2901 if (rv) {
2902 if (ss->handleBadCert) {
2903 rv = (*ss->handleBadCert)(ss->badCertArg, ss->fd);
2904 if ( rv ) {
2905 if ( rv == SECWouldBlock ) {
2906 SSL_DBG(("%d: SSL[%d]: SSL2 bad cert handler returned "
2907 "SECWouldBlock", SSL_GETPID(), ss->fd));
2908 PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
2909 rv = SECFailure;
2910 } else {
2911 /* cert is bad */
2912 SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
2913 SSL_GETPID(), ss->fd, PORT_GetError()));
2915 goto loser;
2917 /* cert is good */
2918 } else {
2919 SSL_DBG(("%d: SSL[%d]: server certificate is no good: error=%d",
2920 SSL_GETPID(), ss->fd, PORT_GetError()));
2921 goto loser;
2926 ** At this point we have a completed session key and our session
2927 ** cipher is setup and ready to go. Switch to encrypted write routine
2928 ** as all future message data is to be encrypted.
2930 ssl2_UseEncryptedSendFunc(ss);
2932 rv = ssl2_TryToFinish(ss);
2933 if (rv != SECSuccess)
2934 goto loser;
2936 ss->gs.recordLen = 0;
2938 ssl_ReleaseRecvBufLock(ss);
2940 if (ss->handshake == 0) {
2941 return SECSuccess;
2944 SSL_TRC(5, ("%d: SSL[%d]: got server-hello, required=0x%d got=0x%x",
2945 SSL_GETPID(), ss->fd, ss->sec.ci.requiredElements,
2946 ss->sec.ci.elements));
2947 ss->handshake = ssl_GatherRecord1stHandshake;
2948 ss->nextHandshake = ssl2_HandleVerifyMessage;
2949 return SECSuccess;
2951 bad_server:
2952 PORT_SetError(SSL_ERROR_BAD_SERVER);
2953 /* FALL THROUGH */
2955 loser:
2956 ssl_ReleaseRecvBufLock(ss);
2957 return SECFailure;
2960 /* Sends out the initial client Hello message on the connection.
2961 * Acquires and releases the socket's xmitBufLock.
2963 SECStatus
2964 ssl2_BeginClientHandshake(sslSocket *ss)
2966 sslSessionID *sid;
2967 PRUint8 *msg;
2968 PRUint8 *cp;
2969 PRUint8 *localCipherSpecs = NULL;
2970 unsigned int localCipherSize;
2971 unsigned int i;
2972 int sendLen, sidLen = 0;
2973 SECStatus rv;
2974 TLSExtensionData *xtnData;
2976 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
2978 ss->sec.isServer = 0;
2979 ss->sec.sendSequence = 0;
2980 ss->sec.rcvSequence = 0;
2981 ssl_ChooseSessionIDProcs(&ss->sec);
2983 if (!ss->cipherSpecs) {
2984 rv = ssl2_ConstructCipherSpecs(ss);
2985 if (rv != SECSuccess)
2986 goto loser;
2989 /* count the SSL2 and SSL3 enabled ciphers.
2990 * if either is zero, clear the socket's enable for that protocol.
2992 rv = ssl2_CheckConfigSanity(ss);
2993 if (rv != SECSuccess)
2994 goto loser;
2996 /* Get peer name of server */
2997 rv = ssl_GetPeerInfo(ss);
2998 if (rv < 0) {
2999 #ifdef HPUX11
3001 * On some HP-UX B.11.00 systems, getpeername() occasionally
3002 * fails with ENOTCONN after a successful completion of
3003 * non-blocking connect. I found that if we do a write()
3004 * and then retry getpeername(), it will work.
3006 if (PR_GetError() == PR_NOT_CONNECTED_ERROR) {
3007 char dummy;
3008 (void) PR_Write(ss->fd->lower, &dummy, 0);
3009 rv = ssl_GetPeerInfo(ss);
3010 if (rv < 0) {
3011 goto loser;
3014 #else
3015 goto loser;
3016 #endif
3019 SSL_TRC(3, ("%d: SSL[%d]: sending client-hello", SSL_GETPID(), ss->fd));
3021 /* Try to find server in our session-id cache */
3022 if (ss->opt.noCache) {
3023 sid = NULL;
3024 } else {
3025 sid = ssl_LookupSID(&ss->sec.ci.peer, ss->sec.ci.port, ss->peerID,
3026 ss->url);
3028 while (sid) { /* this isn't really a loop */
3029 PRBool sidVersionEnabled =
3030 (!SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) &&
3031 sid->version >= ss->vrange.min &&
3032 sid->version <= ss->vrange.max) ||
3033 (sid->version < SSL_LIBRARY_VERSION_3_0 && ss->opt.enableSSL2);
3035 /* if we're not doing this SID's protocol any more, drop it. */
3036 if (!sidVersionEnabled) {
3037 if (ss->sec.uncache)
3038 ss->sec.uncache(sid);
3039 ssl_FreeSID(sid);
3040 sid = NULL;
3041 break;
3043 if (sid->version < SSL_LIBRARY_VERSION_3_0) {
3044 /* If the cipher in this sid is not enabled, drop it. */
3045 for (i = 0; i < ss->sizeCipherSpecs; i += 3) {
3046 if (ss->cipherSpecs[i] == sid->u.ssl2.cipherType)
3047 break;
3049 if (i >= ss->sizeCipherSpecs) {
3050 if (ss->sec.uncache)
3051 ss->sec.uncache(sid);
3052 ssl_FreeSID(sid);
3053 sid = NULL;
3054 break;
3057 sidLen = sizeof(sid->u.ssl2.sessionID);
3058 PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl2.sessionID,
3059 sidLen));
3060 ss->version = sid->version;
3061 PORT_Assert(!ss->sec.localCert);
3062 if (ss->sec.localCert) {
3063 CERT_DestroyCertificate(ss->sec.localCert);
3065 ss->sec.localCert = CERT_DupCertificate(sid->localCert);
3066 break; /* this isn't really a loop */
3068 if (!sid) {
3069 sidLen = 0;
3070 sid = PORT_ZNew(sslSessionID);
3071 if (!sid) {
3072 goto loser;
3074 sid->references = 1;
3075 sid->cached = never_cached;
3076 sid->addr = ss->sec.ci.peer;
3077 sid->port = ss->sec.ci.port;
3078 if (ss->peerID != NULL) {
3079 sid->peerID = PORT_Strdup(ss->peerID);
3081 if (ss->url != NULL) {
3082 sid->urlSvrName = PORT_Strdup(ss->url);
3085 ss->sec.ci.sid = sid;
3087 PORT_Assert(sid != NULL);
3089 if ((sid->version >= SSL_LIBRARY_VERSION_3_0 || !ss->opt.v2CompatibleHello) &&
3090 !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
3091 ss->gs.state = GS_INIT;
3092 ss->handshake = ssl_GatherRecord1stHandshake;
3094 /* ssl3_SendClientHello will override this if it succeeds. */
3095 ss->version = SSL_LIBRARY_VERSION_3_0;
3097 ssl_GetSSL3HandshakeLock(ss);
3098 ssl_GetXmitBufLock(ss);
3099 rv = ssl3_SendClientHello(ss, PR_FALSE);
3100 ssl_ReleaseXmitBufLock(ss);
3101 ssl_ReleaseSSL3HandshakeLock(ss);
3103 return rv;
3105 #ifndef NSS_DISABLE_ECC
3106 /* ensure we don't neogtiate ECC cipher suites with SSL2 hello */
3107 ssl3_DisableECCSuites(ss, NULL); /* disable all ECC suites */
3108 if (ss->cipherSpecs != NULL) {
3109 PORT_Free(ss->cipherSpecs);
3110 ss->cipherSpecs = NULL;
3111 ss->sizeCipherSpecs = 0;
3113 #endif /* NSS_DISABLE_ECC */
3115 if (!ss->cipherSpecs) {
3116 rv = ssl2_ConstructCipherSpecs(ss);
3117 if (rv < 0) {
3118 return rv;
3121 localCipherSpecs = ss->cipherSpecs;
3122 localCipherSize = ss->sizeCipherSpecs;
3124 /* Add 3 for SCSV */
3125 sendLen = SSL_HL_CLIENT_HELLO_HBYTES + localCipherSize + 3 + sidLen +
3126 SSL_CHALLENGE_BYTES;
3128 /* Generate challenge bytes for server */
3129 PK11_GenerateRandom(ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
3131 ssl_GetXmitBufLock(ss); /***************************************/
3133 rv = ssl2_GetSendBuffer(ss, sendLen);
3134 if (rv)
3135 goto unlock_loser;
3137 /* Construct client-hello message */
3138 cp = msg = ss->sec.ci.sendBuf.buf;
3139 msg[0] = SSL_MT_CLIENT_HELLO;
3140 ss->clientHelloVersion = SSL3_ALL_VERSIONS_DISABLED(&ss->vrange) ?
3141 SSL_LIBRARY_VERSION_2 : ss->vrange.max;
3143 msg[1] = MSB(ss->clientHelloVersion);
3144 msg[2] = LSB(ss->clientHelloVersion);
3145 /* Add 3 for SCSV */
3146 msg[3] = MSB(localCipherSize + 3);
3147 msg[4] = LSB(localCipherSize + 3);
3148 msg[5] = MSB(sidLen);
3149 msg[6] = LSB(sidLen);
3150 msg[7] = MSB(SSL_CHALLENGE_BYTES);
3151 msg[8] = LSB(SSL_CHALLENGE_BYTES);
3152 cp += SSL_HL_CLIENT_HELLO_HBYTES;
3153 PORT_Memcpy(cp, localCipherSpecs, localCipherSize);
3154 cp += localCipherSize;
3156 * Add SCSV. SSL 2.0 cipher suites are listed before SSL 3.0 cipher
3157 * suites in localCipherSpecs for compatibility with SSL 2.0 servers.
3158 * Since SCSV looks like an SSL 3.0 cipher suite, we can't add it at
3159 * the beginning.
3161 cp[0] = 0x00;
3162 cp[1] = 0x00;
3163 cp[2] = 0xff;
3164 cp += 3;
3165 if (sidLen) {
3166 PORT_Memcpy(cp, sid->u.ssl2.sessionID, sidLen);
3167 cp += sidLen;
3169 PORT_Memcpy(cp, ss->sec.ci.clientChallenge, SSL_CHALLENGE_BYTES);
3171 /* Send it to the server */
3172 DUMP_MSG(29, (ss, msg, sendLen));
3173 ss->handshakeBegun = 1;
3174 rv = (*ss->sec.send)(ss, msg, sendLen, 0);
3176 ssl_ReleaseXmitBufLock(ss); /***************************************/
3178 if (rv < 0) {
3179 goto loser;
3182 rv = ssl3_StartHandshakeHash(ss, msg, sendLen);
3183 if (rv < 0) {
3184 goto loser;
3188 * Since we sent the SCSV, pretend we sent empty RI extension. We need
3189 * to record the extension has been advertised after ssl3_InitState has
3190 * been called, which ssl3_StartHandshakeHash took care for us above.
3192 xtnData = &ss->xtnData;
3193 xtnData->advertised[xtnData->numAdvertised++] = ssl_renegotiation_info_xtn;
3195 /* Setup to receive servers hello message */
3196 ssl_GetRecvBufLock(ss);
3197 ss->gs.recordLen = 0;
3198 ssl_ReleaseRecvBufLock(ss);
3200 ss->handshake = ssl_GatherRecord1stHandshake;
3201 ss->nextHandshake = ssl2_HandleServerHelloMessage;
3202 return SECSuccess;
3204 unlock_loser:
3205 ssl_ReleaseXmitBufLock(ss);
3206 loser:
3207 return SECFailure;
3210 /************************************************************************/
3212 /* Handle the CLIENT-MASTER-KEY message.
3213 ** Acquires and releases RecvBufLock.
3214 ** Called from ssl2_HandleClientHelloMessage().
3216 static SECStatus
3217 ssl2_HandleClientSessionKeyMessage(sslSocket *ss)
3219 PRUint8 * data;
3220 unsigned int caLen;
3221 unsigned int ckLen;
3222 unsigned int ekLen;
3223 unsigned int keyBits;
3224 int cipher;
3225 SECStatus rv;
3228 ssl_GetRecvBufLock(ss);
3230 data = ss->gs.buf.buf + ss->gs.recordOffset;
3231 DUMP_MSG(29, (ss, data, ss->gs.recordLen));
3233 if ((ss->gs.recordLen < SSL_HL_CLIENT_MASTER_KEY_HBYTES)
3234 || (data[0] != SSL_MT_CLIENT_MASTER_KEY)) {
3235 goto bad_client;
3237 cipher = data[1];
3238 keyBits = (data[2] << 8) | data[3];
3239 ckLen = (data[4] << 8) | data[5];
3240 ekLen = (data[6] << 8) | data[7];
3241 caLen = (data[8] << 8) | data[9];
3243 SSL_TRC(5, ("%d: SSL[%d]: session-key, cipher=%d keyBits=%d ckLen=%d ekLen=%d caLen=%d",
3244 SSL_GETPID(), ss->fd, cipher, keyBits, ckLen, ekLen, caLen));
3246 if (ss->gs.recordLen <
3247 SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen + caLen) {
3248 SSL_DBG(("%d: SSL[%d]: protocol size mismatch dataLen=%d",
3249 SSL_GETPID(), ss->fd, ss->gs.recordLen));
3250 goto bad_client;
3253 /* Use info from client to setup session key */
3254 rv = ssl2_ServerSetupSessionCypher(ss, cipher, keyBits,
3255 data + SSL_HL_CLIENT_MASTER_KEY_HBYTES, ckLen,
3256 data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen, ekLen,
3257 data + SSL_HL_CLIENT_MASTER_KEY_HBYTES + ckLen + ekLen, caLen);
3258 ss->gs.recordLen = 0; /* we're done with this record. */
3260 ssl_ReleaseRecvBufLock(ss);
3262 if (rv != SECSuccess) {
3263 goto loser;
3265 ss->sec.ci.elements |= CIS_HAVE_MASTER_KEY;
3266 ssl2_UseEncryptedSendFunc(ss);
3268 /* Send server verify message now that keys are established */
3269 rv = ssl2_SendServerVerifyMessage(ss);
3270 if (rv != SECSuccess)
3271 goto loser;
3273 rv = ssl2_TryToFinish(ss);
3274 if (rv != SECSuccess)
3275 goto loser;
3276 if (ss->handshake == 0) {
3277 return SECSuccess;
3280 SSL_TRC(5, ("%d: SSL[%d]: server: waiting for elements=0x%d",
3281 SSL_GETPID(), ss->fd,
3282 ss->sec.ci.requiredElements ^ ss->sec.ci.elements));
3283 ss->handshake = ssl_GatherRecord1stHandshake;
3284 ss->nextHandshake = ssl2_HandleMessage;
3286 return ssl2_TriggerNextMessage(ss);
3288 bad_client:
3289 ssl_ReleaseRecvBufLock(ss);
3290 PORT_SetError(SSL_ERROR_BAD_CLIENT);
3291 /* FALLTHROUGH */
3293 loser:
3294 return SECFailure;
3298 ** Handle the initial hello message from the client
3300 ** not static because ssl2_GatherData() tests ss->nextHandshake for this value.
3302 SECStatus
3303 ssl2_HandleClientHelloMessage(sslSocket *ss)
3305 sslSessionID *sid;
3306 sslServerCerts * sc;
3307 CERTCertificate *serverCert;
3308 PRUint8 *msg;
3309 PRUint8 *data;
3310 PRUint8 *cs;
3311 PRUint8 *sd;
3312 PRUint8 *cert = NULL;
3313 PRUint8 *challenge;
3314 unsigned int challengeLen;
3315 SECStatus rv;
3316 int csLen;
3317 int sendLen;
3318 int sdLen;
3319 int certLen;
3320 int pid;
3321 int sent;
3322 int gotXmitBufLock = 0;
3323 #if defined(SOLARIS) && defined(i386)
3324 volatile PRUint8 hit;
3325 #else
3326 int hit;
3327 #endif
3328 PRUint8 csImpl[sizeof implementedCipherSuites];
3330 PORT_Assert( ss->opt.noLocks || ssl_Have1stHandshakeLock(ss) );
3332 sc = ss->serverCerts + kt_rsa;
3333 serverCert = sc->serverCert;
3335 ssl_GetRecvBufLock(ss);
3338 data = ss->gs.buf.buf + ss->gs.recordOffset;
3339 DUMP_MSG(29, (ss, data, ss->gs.recordLen));
3341 /* Make sure first message has some data and is the client hello message */
3342 if ((ss->gs.recordLen < SSL_HL_CLIENT_HELLO_HBYTES)
3343 || (data[0] != SSL_MT_CLIENT_HELLO)) {
3344 goto bad_client;
3347 /* Get peer name of client */
3348 rv = ssl_GetPeerInfo(ss);
3349 if (rv != SECSuccess) {
3350 goto loser;
3353 /* Examine version information */
3355 * See if this might be a V2 client hello asking to use the V3 protocol
3357 if ((data[0] == SSL_MT_CLIENT_HELLO) &&
3358 (data[1] >= MSB(SSL_LIBRARY_VERSION_3_0)) &&
3359 !SSL3_ALL_VERSIONS_DISABLED(&ss->vrange)) {
3360 rv = ssl3_HandleV2ClientHello(ss, data, ss->gs.recordLen);
3361 if (rv != SECFailure) { /* Success */
3362 ss->handshake = NULL;
3363 ss->nextHandshake = ssl_GatherRecord1stHandshake;
3364 ss->securityHandshake = NULL;
3365 ss->gs.state = GS_INIT;
3367 /* ssl3_HandleV3ClientHello has set ss->version,
3368 ** and has gotten us a brand new sid.
3370 ss->sec.ci.sid->version = ss->version;
3372 ssl_ReleaseRecvBufLock(ss);
3373 return rv;
3375 /* Previously, there was a test here to see if SSL2 was enabled.
3376 ** If not, an error code was set, and SECFailure was returned,
3377 ** without sending any error code to the other end of the connection.
3378 ** That test has been removed. If SSL2 has been disabled, there
3379 ** should be no SSL2 ciphers enabled, and consequently, the code
3380 ** below should send the ssl2 error message SSL_PE_NO_CYPHERS.
3381 ** We now believe this is the correct thing to do, even when SSL2
3382 ** has been explicitly disabled by the application.
3385 /* Extract info from message */
3386 ss->version = (data[1] << 8) | data[2];
3388 /* If some client thinks ssl v2 is 2.0 instead of 0.2, we'll allow it. */
3389 if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
3390 ss->version = SSL_LIBRARY_VERSION_2;
3393 csLen = (data[3] << 8) | data[4];
3394 sdLen = (data[5] << 8) | data[6];
3395 challengeLen = (data[7] << 8) | data[8];
3396 cs = data + SSL_HL_CLIENT_HELLO_HBYTES;
3397 sd = cs + csLen;
3398 challenge = sd + sdLen;
3399 PRINT_BUF(7, (ss, "server, client session-id value:", sd, sdLen));
3401 if (!csLen || (csLen % 3) != 0 ||
3402 (sdLen != 0 && sdLen != SSL2_SESSIONID_BYTES) ||
3403 challengeLen < SSL_MIN_CHALLENGE_BYTES ||
3404 challengeLen > SSL_MAX_CHALLENGE_BYTES ||
3405 (unsigned)ss->gs.recordLen !=
3406 SSL_HL_CLIENT_HELLO_HBYTES + csLen + sdLen + challengeLen) {
3407 SSL_DBG(("%d: SSL[%d]: bad client hello message, len=%d should=%d",
3408 SSL_GETPID(), ss->fd, ss->gs.recordLen,
3409 SSL_HL_CLIENT_HELLO_HBYTES+csLen+sdLen+challengeLen));
3410 goto bad_client;
3413 SSL_TRC(3, ("%d: SSL[%d]: client version is %x",
3414 SSL_GETPID(), ss->fd, ss->version));
3415 if (ss->version != SSL_LIBRARY_VERSION_2) {
3416 if (ss->version > SSL_LIBRARY_VERSION_2) {
3418 ** Newer client than us. Things are ok because new clients
3419 ** are required to be backwards compatible with old servers.
3420 ** Change version number to our version number so that client
3421 ** knows whats up.
3423 ss->version = SSL_LIBRARY_VERSION_2;
3424 } else {
3425 SSL_TRC(1, ("%d: SSL[%d]: client version is %x (we are %x)",
3426 SSL_GETPID(), ss->fd, ss->version, SSL_LIBRARY_VERSION_2));
3427 PORT_SetError(SSL_ERROR_UNSUPPORTED_VERSION);
3428 goto loser;
3432 /* Qualify cipher specs before returning them to client */
3433 csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
3434 if (csLen == 0) {
3435 /* no overlap, send client our list of supported SSL v2 ciphers. */
3436 cs = csImpl;
3437 csLen = sizeof implementedCipherSuites;
3438 PORT_Memcpy(cs, implementedCipherSuites, csLen);
3439 csLen = ssl2_QualifyCypherSpecs(ss, cs, csLen);
3440 if (csLen == 0) {
3441 /* We don't support any SSL v2 ciphers! */
3442 ssl2_SendErrorMessage(ss, SSL_PE_NO_CYPHERS);
3443 PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);
3444 goto loser;
3446 /* Since this handhsake is going to fail, don't cache it. */
3447 ss->opt.noCache = 1;
3450 /* Squirrel away the challenge for later */
3451 PORT_Memcpy(ss->sec.ci.clientChallenge, challenge, challengeLen);
3453 /* Examine message and see if session-id is good */
3454 ss->sec.ci.elements = 0;
3455 if (sdLen > 0 && !ss->opt.noCache) {
3456 SSL_TRC(7, ("%d: SSL[%d]: server, lookup client session-id for 0x%08x%08x%08x%08x",
3457 SSL_GETPID(), ss->fd, ss->sec.ci.peer.pr_s6_addr32[0],
3458 ss->sec.ci.peer.pr_s6_addr32[1],
3459 ss->sec.ci.peer.pr_s6_addr32[2],
3460 ss->sec.ci.peer.pr_s6_addr32[3]));
3461 sid = (*ssl_sid_lookup)(&ss->sec.ci.peer, sd, sdLen, ss->dbHandle);
3462 } else {
3463 sid = NULL;
3465 if (sid) {
3466 /* Got a good session-id. Short cut! */
3467 SSL_TRC(1, ("%d: SSL[%d]: server, using session-id for 0x%08x (age=%d)",
3468 SSL_GETPID(), ss->fd, ss->sec.ci.peer,
3469 ssl_Time() - sid->creationTime));
3470 PRINT_BUF(1, (ss, "session-id value:", sd, sdLen));
3471 ss->sec.ci.sid = sid;
3472 ss->sec.ci.elements = CIS_HAVE_MASTER_KEY;
3473 hit = 1;
3474 certLen = 0;
3475 csLen = 0;
3477 ss->sec.authAlgorithm = sid->authAlgorithm;
3478 ss->sec.authKeyBits = sid->authKeyBits;
3479 ss->sec.keaType = sid->keaType;
3480 ss->sec.keaKeyBits = sid->keaKeyBits;
3482 rv = ssl2_CreateSessionCypher(ss, sid, PR_FALSE);
3483 if (rv != SECSuccess) {
3484 goto loser;
3486 } else {
3487 SECItem * derCert = &serverCert->derCert;
3489 SSL_TRC(7, ("%d: SSL[%d]: server, lookup nonce missed",
3490 SSL_GETPID(), ss->fd));
3491 if (!serverCert) {
3492 SET_ERROR_CODE
3493 goto loser;
3495 hit = 0;
3496 sid = PORT_ZNew(sslSessionID);
3497 if (!sid) {
3498 goto loser;
3500 sid->references = 1;
3501 sid->addr = ss->sec.ci.peer;
3502 sid->port = ss->sec.ci.port;
3504 /* Invent a session-id */
3505 ss->sec.ci.sid = sid;
3506 PK11_GenerateRandom(sid->u.ssl2.sessionID+2, SSL2_SESSIONID_BYTES-2);
3508 pid = SSL_GETPID();
3509 sid->u.ssl2.sessionID[0] = MSB(pid);
3510 sid->u.ssl2.sessionID[1] = LSB(pid);
3511 cert = derCert->data;
3512 certLen = derCert->len;
3514 /* pretend that server sids remember the local cert. */
3515 PORT_Assert(!sid->localCert);
3516 if (sid->localCert) {
3517 CERT_DestroyCertificate(sid->localCert);
3519 sid->localCert = CERT_DupCertificate(serverCert);
3521 ss->sec.authAlgorithm = ssl_sign_rsa;
3522 ss->sec.keaType = ssl_kea_rsa;
3523 ss->sec.keaKeyBits = \
3524 ss->sec.authKeyBits = ss->serverCerts[kt_rsa].serverKeyBits;
3527 /* server sids don't remember the local cert, so whether we found
3528 ** a sid or not, just "remember" we used the rsa server cert.
3530 if (ss->sec.localCert) {
3531 CERT_DestroyCertificate(ss->sec.localCert);
3533 ss->sec.localCert = CERT_DupCertificate(serverCert);
3535 /* Build up final list of required elements */
3536 ss->sec.ci.requiredElements = CIS_HAVE_MASTER_KEY | CIS_HAVE_FINISHED;
3537 if (ss->opt.requestCertificate) {
3538 ss->sec.ci.requiredElements |= CIS_HAVE_CERTIFICATE;
3540 ss->sec.ci.sentElements = 0;
3542 /* Send hello message back to client */
3543 sendLen = SSL_HL_SERVER_HELLO_HBYTES + certLen + csLen
3544 + SSL_CONNECTIONID_BYTES;
3546 ssl_GetXmitBufLock(ss); gotXmitBufLock = 1;
3547 rv = ssl2_GetSendBuffer(ss, sendLen);
3548 if (rv != SECSuccess) {
3549 goto loser;
3552 SSL_TRC(3, ("%d: SSL[%d]: sending server-hello (%d)",
3553 SSL_GETPID(), ss->fd, sendLen));
3555 msg = ss->sec.ci.sendBuf.buf;
3556 msg[0] = SSL_MT_SERVER_HELLO;
3557 msg[1] = hit;
3558 msg[2] = SSL_CT_X509_CERTIFICATE;
3559 msg[3] = MSB(ss->version);
3560 msg[4] = LSB(ss->version);
3561 msg[5] = MSB(certLen);
3562 msg[6] = LSB(certLen);
3563 msg[7] = MSB(csLen);
3564 msg[8] = LSB(csLen);
3565 msg[9] = MSB(SSL_CONNECTIONID_BYTES);
3566 msg[10] = LSB(SSL_CONNECTIONID_BYTES);
3567 if (certLen) {
3568 PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES, cert, certLen);
3570 if (csLen) {
3571 PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen, cs, csLen);
3573 PORT_Memcpy(msg+SSL_HL_SERVER_HELLO_HBYTES+certLen+csLen,
3574 ss->sec.ci.connectionID, SSL_CONNECTIONID_BYTES);
3576 DUMP_MSG(29, (ss, msg, sendLen));
3578 ss->handshakeBegun = 1;
3579 sent = (*ss->sec.send)(ss, msg, sendLen, 0);
3580 if (sent < 0) {
3581 goto loser;
3583 ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;
3585 ss->gs.recordLen = 0;
3586 ss->handshake = ssl_GatherRecord1stHandshake;
3587 if (hit) {
3588 /* Old SID Session key is good. Go encrypted */
3589 ssl2_UseEncryptedSendFunc(ss);
3591 /* Send server verify message now that keys are established */
3592 rv = ssl2_SendServerVerifyMessage(ss);
3593 if (rv != SECSuccess)
3594 goto loser;
3596 ss->nextHandshake = ssl2_HandleMessage;
3597 ssl_ReleaseRecvBufLock(ss);
3598 rv = ssl2_TriggerNextMessage(ss);
3599 return rv;
3601 ss->nextHandshake = ssl2_HandleClientSessionKeyMessage;
3602 ssl_ReleaseRecvBufLock(ss);
3603 return SECSuccess;
3605 bad_client:
3606 PORT_SetError(SSL_ERROR_BAD_CLIENT);
3607 /* FALLTHROUGH */
3609 loser:
3610 if (gotXmitBufLock) {
3611 ssl_ReleaseXmitBufLock(ss); gotXmitBufLock = 0;
3613 SSL_TRC(10, ("%d: SSL[%d]: server, wait for client-hello lossage",
3614 SSL_GETPID(), ss->fd));
3615 ssl_ReleaseRecvBufLock(ss);
3616 return SECFailure;
3619 SECStatus
3620 ssl2_BeginServerHandshake(sslSocket *ss)
3622 SECStatus rv;
3623 sslServerCerts * rsaAuth = ss->serverCerts + kt_rsa;
3625 ss->sec.isServer = 1;
3626 ssl_ChooseSessionIDProcs(&ss->sec);
3627 ss->sec.sendSequence = 0;
3628 ss->sec.rcvSequence = 0;
3630 /* don't turn on SSL2 if we don't have an RSA key and cert */
3631 if (!rsaAuth->serverKeyPair || !rsaAuth->SERVERKEY ||
3632 !rsaAuth->serverCert) {
3633 ss->opt.enableSSL2 = PR_FALSE;
3636 if (!ss->cipherSpecs) {
3637 rv = ssl2_ConstructCipherSpecs(ss);
3638 if (rv != SECSuccess)
3639 goto loser;
3642 /* count the SSL2 and SSL3 enabled ciphers.
3643 * if either is zero, clear the socket's enable for that protocol.
3645 rv = ssl2_CheckConfigSanity(ss);
3646 if (rv != SECSuccess)
3647 goto loser;
3650 ** Generate connection-id. Always do this, even if things fail
3651 ** immediately. This way the random number generator is always
3652 ** rolling around, every time we get a connection.
3654 PK11_GenerateRandom(ss->sec.ci.connectionID,
3655 sizeof(ss->sec.ci.connectionID));
3657 ss->gs.recordLen = 0;
3658 ss->handshake = ssl_GatherRecord1stHandshake;
3659 ss->nextHandshake = ssl2_HandleClientHelloMessage;
3660 return SECSuccess;
3662 loser:
3663 return SECFailure;
3666 /* This function doesn't really belong in this file.
3667 ** It's here to keep AIX compilers from optimizing it away,
3668 ** and not including it in the DSO.
3671 #include "nss.h"
3672 extern const char __nss_ssl_rcsid[];
3673 extern const char __nss_ssl_sccsid[];
3675 PRBool
3676 NSSSSL_VersionCheck(const char *importedVersion)
3679 * This is the secret handshake algorithm.
3681 * This release has a simple version compatibility
3682 * check algorithm. This release is not backward
3683 * compatible with previous major releases. It is
3684 * not compatible with future major, minor, or
3685 * patch releases.
3687 volatile char c; /* force a reference that won't get optimized away */
3689 c = __nss_ssl_rcsid[0] + __nss_ssl_sccsid[0];
3690 return NSS_VersionCheck(importedVersion);
3693 const char *
3694 NSSSSL_GetVersion(void)
3696 return NSS_VERSION;