]> git.saurik.com Git - apple/security.git/blob - SecureTransport/sslhdshk.c
0328d4acf7df88e322903f4cf2e5a5f8d3a289ca
[apple/security.git] / SecureTransport / sslhdshk.c
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 File: sslhdshk.c
21
22 Contains: SSL 3.0 handshake state machine.
23
24 Written by: Doug Mitchell, based on Netscape SSLRef 3.0
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28 */
29 /* *********************************************************************
30 File: sslhdshk.c
31
32 SSLRef 3.0 Final -- 11/19/96
33
34 Copyright (c)1996 by Netscape Communications Corp.
35
36 By retrieving this software you are bound by the licensing terms
37 disclosed in the file "LICENSE.txt". Please read it, and if you don't
38 accept the terms, delete this software.
39
40 SSLRef 3.0 was developed by Netscape Communications Corp. of Mountain
41 View, California <http://home.netscape.com/> and Consensus Development
42 Corporation of Berkeley, California <http://www.consensus.com/>.
43
44 *********************************************************************
45
46 File: sslhdshk.c SSL 3.0 handshake state machine
47
48 Support for SSL Handshake messages, including extracting handshake
49 messages from record layer records, processing those messages
50 (including verifying their appropriateness) and then advancing the
51 handshake by generating response messages and/or changing the state
52 such that different messages are expected. In addition, controls when
53 keys are generated.
54
55 ****************************************************************** */
56
57 #ifndef _SSLCTX_H_
58 #include "sslctx.h"
59 #endif
60
61 #ifndef _SSLHDSHK_H_
62 #include "sslhdshk.h"
63 #endif
64
65 #ifndef _SSLALLOC_H_
66 #include "sslalloc.h"
67 #endif
68
69 #ifndef _SSLALERT_H_
70 #include "sslalert.h"
71 #endif
72
73 #ifndef _SSLSESS_H_
74 #include "sslsess.h"
75 #endif
76
77 #ifndef _SSLUTIL_H_
78 #include "sslutil.h"
79 #endif
80
81 #ifndef _SSL_DEBUG_H_
82 #include "sslDebug.h"
83 #endif
84
85 #ifndef _APPLE_CDSA_H_
86 #include "appleCdsa.h"
87 #endif
88
89 #include "digests.h"
90 #include <string.h>
91 #include <assert.h>
92
93 #define REQUEST_CERT_CORRECT 0
94
95 static SSLErr SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx);
96
97 SSLErr
98 SSLProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
99 { SSLErr err;
100 sint32 remaining;
101 UInt8 *p;
102 SSLHandshakeMsg message;
103 SSLBuffer messageData;
104
105 if (ctx->fragmentedMessageCache.data != 0)
106 { if ((err = SSLReallocBuffer(&ctx->fragmentedMessageCache,
107 ctx->fragmentedMessageCache.length + rec.contents.length,
108 &ctx->sysCtx)) != 0)
109 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
110 return ERR(err);
111 }
112 memcpy(ctx->fragmentedMessageCache.data + ctx->fragmentedMessageCache.length,
113 rec.contents.data, rec.contents.length);
114 remaining = ctx->fragmentedMessageCache.length;
115 p = ctx->fragmentedMessageCache.data;
116 }
117 else
118 { remaining = rec.contents.length;
119 p = rec.contents.data;
120 }
121
122 while (remaining > 0)
123 { if (remaining < 4)
124 break; /* we must have at least a header */
125
126 messageData.data = p;
127 message.type = (SSLHandshakeType)*p++;
128 message.contents.length = SSLDecodeInt(p, 3);
129 if ((message.contents.length + 4) > remaining)
130 break;
131
132 p += 3;
133 message.contents.data = p;
134 p += message.contents.length;
135 messageData.length = 4 + message.contents.length;
136 CASSERT(p == messageData.data + messageData.length);
137
138 /* message fragmentation */
139 remaining -= messageData.length;
140 if (ERR(err = SSLProcessHandshakeMessage(message, ctx)) != 0)
141 return err;
142
143 if (message.type != SSL_hello_request)
144 { if (ERR(err = SSLHashSHA1.update(ctx->shaState, messageData)) != 0 ||
145 ERR(err = SSLHashMD5.update(ctx->md5State, messageData)) != 0)
146 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
147 return err;
148 }
149 }
150
151 if (ERR(err = SSLAdvanceHandshake(message.type, ctx)) != 0)
152 return err;
153 }
154
155 if (remaining > 0) /* Fragmented handshake message */
156 { /* If there isn't a cache, allocate one */
157 if (ctx->fragmentedMessageCache.data == 0)
158 { if (ERR(err = SSLAllocBuffer(&ctx->fragmentedMessageCache, remaining, &ctx->sysCtx)) != 0)
159 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
160 return err;
161 }
162 }
163 if (p != ctx->fragmentedMessageCache.data)
164 { memcpy(ctx->fragmentedMessageCache.data, p, remaining);
165 ctx->fragmentedMessageCache.length = remaining;
166 }
167 }
168 else if (ctx->fragmentedMessageCache.data != 0)
169 { if (ERR(err = SSLFreeBuffer(&ctx->fragmentedMessageCache, &ctx->sysCtx)) != 0)
170 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
171 return err;
172 }
173 }
174
175 return SSLNoErr;
176 }
177
178 static SSLErr
179 SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx)
180 { SSLErr err;
181
182 err = SSLNoErr;
183 SSLLogHdskMsg(message.type, 0);
184 switch (message.type)
185 { case SSL_hello_request:
186 if (ctx->protocolSide != SSL_ClientSide)
187 goto wrongMessage;
188 if (message.contents.length > 0)
189 err = ERR(SSLProtocolErr);
190 break;
191 case SSL_client_hello:
192 if (ctx->state != HandshakeServerUninit)
193 goto wrongMessage;
194 ERR(err = SSLProcessClientHello(message.contents, ctx));
195 break;
196 case SSL_server_hello:
197 if (ctx->state != HandshakeServerHello &&
198 ctx->state != HandshakeServerHelloUnknownVersion)
199 goto wrongMessage;
200 ERR(err = SSLProcessServerHello(message.contents, ctx));
201 break;
202 case SSL_certificate:
203 if (ctx->state != HandshakeCertificate &&
204 ctx->state != HandshakeClientCertificate)
205 goto wrongMessage;
206 ERR(err = SSLProcessCertificate(message.contents, ctx));
207 break;
208 case SSL_certificate_request:
209 if ((ctx->state != HandshakeHelloDone && ctx->state != HandshakeKeyExchange)
210 || ctx->certRequested)
211 goto wrongMessage;
212 ERR(err = SSLProcessCertificateRequest(message.contents, ctx));
213 break;
214 case SSL_server_key_exchange:
215 /*
216 * Since this message is optional, and completely at the
217 * server's discretion, we need to be able to handle this
218 * in one of two states...
219 */
220 switch(ctx->state) {
221 case HandshakeKeyExchange: /* explicitly waiting for this */
222 case HandshakeHelloDone:
223 break;
224 default:
225 goto wrongMessage;
226 }
227 ERR(err = SSLProcessServerKeyExchange(message.contents, ctx));
228 break;
229 case SSL_server_hello_done:
230 if (ctx->state != HandshakeHelloDone)
231 goto wrongMessage;
232 ERR(err = SSLProcessServerHelloDone(message.contents, ctx));
233 break;
234 case SSL_certificate_verify:
235 if (ctx->state != HandshakeClientCertVerify)
236 goto wrongMessage;
237 ERR(err = SSLProcessCertificateVerify(message.contents, ctx));
238 break;
239 case SSL_client_key_exchange:
240 if (ctx->state != HandshakeClientKeyExchange)
241 goto wrongMessage;
242 ERR(err = SSLProcessKeyExchange(message.contents, ctx));
243 break;
244 case SSL_finished:
245 if (ctx->state != HandshakeFinished)
246 goto wrongMessage;
247 ERR(err = SSLProcessFinished(message.contents, ctx));
248 break;
249 default:
250 goto wrongMessage;
251 break;
252 }
253
254 if (err)
255 { if (err == SSLProtocolErr)
256 ERR(SSLFatalSessionAlert(alert_illegal_parameter, ctx));
257 else if (err == SSLNegotiationErr)
258 ERR(SSLFatalSessionAlert(alert_handshake_failure, ctx));
259 else
260 ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
261 }
262 return ERR(err);
263
264 wrongMessage:
265 ERR(SSLFatalSessionAlert(alert_unexpected_message, ctx));
266 return ERR(SSLProtocolErr);
267 }
268
269 SSLErr
270 SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
271 { SSLErr err;
272 SSLBuffer sessionIdentifier;
273
274 switch (processed)
275 { case SSL_hello_request:
276 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeClientHello, ctx)) != 0)
277 return err;
278 SSLChangeHdskState(ctx, HandshakeServerHello);
279 break;
280 case SSL_client_hello:
281 CASSERT(ctx->protocolSide == SSL_ServerSide);
282 if (ctx->sessionID.data != 0) /* If session ID != 0, client is trying to resume */
283 { if (ctx->resumableSession.data != 0)
284 { if (ERR(err = SSLRetrieveSessionID(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
285 return err;
286 if (sessionIdentifier.length == ctx->sessionID.length &&
287 memcmp(sessionIdentifier.data, ctx->sessionID.data, ctx->sessionID.length) == 0)
288 { /* Everything matches; resume the session */
289 //DEBUGMSG("Using resumed SSL3 Session");
290 SSLLogResumSess("===RESUMING SSL3 server-side session\n");
291 if (ERR(err = SSLInstallSessionFromData(ctx->resumableSession,
292 ctx)) != 0)
293 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
294 return err;
295 }
296 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
297 return err;
298 if (ERR(err = SSLInitPendingCiphers(ctx)) != 0 ||
299 ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
300 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
301 return err;
302 }
303 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, ctx)) != 0)
304 return err;
305 /* Install new cipher spec on write side */
306 if (ERR(err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
307 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
308 return err;
309 }
310 ctx->writeCipher = ctx->writePending;
311 ctx->writeCipher.ready = 0; /* Can't send data until Finished is sent */
312 memset(&ctx->writePending, 0, sizeof(CipherContext)); /* Zero out old data */
313 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
314 return err;
315 /* Finished has been sent; enable data dransfer on write channel */
316 ctx->writeCipher.ready = 1;
317 SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
318 break;
319 }
320 else {
321 SSLLogResumSess(
322 "===FAILED TO RESUME SSL3 server-side session\n");
323 }
324 if (ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0 ||
325 ERR(err = SSLDeleteSessionData(ctx)) != 0)
326 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
327 return err;
328 }
329 }
330 if (ERR(err = SSLFreeBuffer(&ctx->sessionID, &ctx->sysCtx)) != 0)
331 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
332 return err;
333 }
334 }
335
336 /* If we get here, we're not resuming; generate a new session ID if we know our peer */
337 if (ctx->peerID.data != 0)
338 { /* Ignore errors; just treat as uncached session */
339 CASSERT(ctx->sessionID.data == 0);
340 ERR(err = SSLAllocBuffer(&ctx->sessionID, SSL_SESSION_ID_LEN, &ctx->sysCtx));
341 if (err == 0)
342 {
343 if((err = sslRand(ctx, &ctx->sessionID)) != 0)
344 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
345 return err;
346 }
347 }
348 }
349
350 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
351 return err;
352 switch (ctx->selectedCipherSpec->keyExchangeMethod)
353 { case SSL_NULL_auth:
354 #if APPLE_DH
355 case SSL_DH_anon:
356 #endif
357 case SSL_DH_anon_EXPORT:
358 #if ST_SERVER_MODE_ENABLE
359 if(ctx->clientAuth == kAlwaysAuthenticate) {
360 /* APPLE_CDSA change: app requires this; abort */
361 SSLFatalSessionAlert(alert_handshake_failure, ctx);
362 return SSLNegotiationErr;
363 }
364 ctx->tryClientAuth = false;
365 #else /* ST_SERVER_MODE_ENABLE */
366 /* server side needs work */
367 #endif /* ST_SERVER_MODE_ENABLE*/
368 break;
369 default: /* everything else */
370 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificate, ctx)) != 0)
371 return err;
372 break;
373 }
374 /*
375 * At this point we decide whether to send a server key exchange
376 * method. For Apple servers, I think we'll ALWAYS do this, because
377 * of key usage restrictions (can't decrypt and sign with the same
378 * private key), but conceptually in this code, we do it if
379 * enabled by the presence of encryptPrivKey.
380 */
381 #if SSL_SERVER_KEYEXCH_HACK
382 /*
383 * This is currently how we work with Netscape. It requires
384 * a CSP which can handle private keys which can both
385 * sign and decrypt.
386 */
387 if((ctx->selectedCipherSpec->keyExchangeMethod != SSL_RSA) &&
388 (ctx->encryptPrivKey != NULL)) {
389 err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx);
390 if(err) {
391 return err;
392 }
393 }
394 #else /* !SSL_SERVER_KEYEXCH_HACK */
395 /*
396 * This is, I believe the "right" way, but Netscape doesn't
397 * work this way.
398 */
399 if (ctx->encryptPrivKey != NULL) {
400 err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx);
401 if(err) {
402 return err;
403 }
404 }
405 #endif /* SSL_SERVER_KEYEXCH_HACK */
406
407 #if ST_SERVER_MODE_ENABLE
408 if (ctx->tryClientAuth)
409 { if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificateRequest, ctx)) != 0)
410 return err;
411 ctx->certRequested = 1;
412 }
413 #else /* !ST_SERVER_MODE_ENABLE */
414 /* disabled for now */
415 #endif /* ST_SERVER_MODE_ENABLE */
416 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHelloDone, ctx)) != 0)
417 return err;
418 if (ctx->certRequested) {
419 SSLChangeHdskState(ctx, HandshakeClientCertificate);
420 }
421 else {
422 SSLChangeHdskState(ctx, HandshakeClientKeyExchange);
423 }
424 break;
425 case SSL_server_hello:
426 if (ctx->resumableSession.data != 0 && ctx->sessionID.data != 0)
427 { if (ERR(err = SSLRetrieveSessionID(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
428 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
429 return err;
430 }
431 if (sessionIdentifier.length == ctx->sessionID.length &&
432 memcmp(sessionIdentifier.data, ctx->sessionID.data, ctx->sessionID.length) == 0)
433 { /* Everything matches; resume the session */
434 SSLLogResumSess("===RESUMING SSL3 client-side session\n");
435 if (ERR(err = SSLInstallSessionFromData(ctx->resumableSession,
436 ctx)) != 0 ||
437 ERR(err = SSLInitPendingCiphers(ctx)) != 0 ||
438 ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
439 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
440 return err;
441 }
442 SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
443 break;
444 }
445 else {
446 SSLLogResumSess("===FAILED TO RESUME SSL3 client-side session\n");
447 }
448 if (ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
449 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
450 return err;
451 }
452 }
453 switch (ctx->selectedCipherSpec->keyExchangeMethod)
454 {
455 /* these require a key exchange message */
456 case SSL_NULL_auth:
457 case SSL_DH_anon:
458 case SSL_DH_anon_EXPORT:
459 SSLChangeHdskState(ctx, HandshakeKeyExchange);
460 break;
461 case SSL_RSA:
462 case SSL_DH_DSS:
463 case SSL_DH_DSS_EXPORT:
464 case SSL_DH_RSA:
465 case SSL_DH_RSA_EXPORT:
466 case SSL_RSA_EXPORT:
467 case SSL_DHE_DSS:
468 case SSL_DHE_DSS_EXPORT:
469 case SSL_DHE_RSA:
470 case SSL_DHE_RSA_EXPORT:
471 case SSL_Fortezza:
472 SSLChangeHdskState(ctx, HandshakeCertificate);
473 break;
474 default:
475 ASSERTMSG("Unknown key exchange method");
476 break;
477 }
478 break;
479 case SSL_certificate:
480 if (ctx->state == HandshakeCertificate)
481 switch (ctx->selectedCipherSpec->keyExchangeMethod)
482 { case SSL_RSA:
483 /*
484 * I really think the two RSA cases should be
485 * handled the same here - the server key exchange is
486 * optional, and is up to the server.
487 * Note this isn't the same as SSL_SERVER_KEYEXCH_HACK;
488 * we're a client here.
489 */
490 case SSL_RSA_EXPORT:
491 case SSL_DH_DSS:
492 case SSL_DH_DSS_EXPORT:
493 case SSL_DH_RSA:
494 case SSL_DH_RSA_EXPORT:
495 SSLChangeHdskState(ctx, HandshakeHelloDone);
496 break;
497 case SSL_DHE_DSS:
498 case SSL_DHE_DSS_EXPORT:
499 case SSL_DHE_RSA:
500 case SSL_DHE_RSA_EXPORT:
501 case SSL_Fortezza:
502 SSLChangeHdskState(ctx, HandshakeKeyExchange);
503 break;
504 default:
505 ASSERTMSG("Unknown or unexpected key exchange method");
506 break;
507 }
508 else if (ctx->state == HandshakeClientCertificate)
509 { SSLChangeHdskState(ctx, HandshakeClientKeyExchange);
510 if (ctx->peerCert != 0)
511 ctx->certReceived = 1;
512 }
513 break;
514 case SSL_certificate_request: /* state stays in HandshakeHelloDone; distinction is in ctx->certRequested */
515 if (ctx->peerCert == 0)
516 { ERR(SSLFatalSessionAlert(alert_handshake_failure, ctx));
517 return ERR(SSLProtocolErr);
518 }
519 ctx->certRequested = 1;
520 break;
521 case SSL_server_key_exchange:
522 SSLChangeHdskState(ctx, HandshakeHelloDone);
523 break;
524 case SSL_server_hello_done:
525 if (ctx->certRequested)
526 { if (ctx->localCert != 0 && ctx->x509Requested)
527 { if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificate, ctx)) != 0)
528 return err;
529 }
530 else
531 { if (ERR(err = SSLSendAlert(alert_warning, alert_no_certificate, ctx)) != 0)
532 return err;
533 }
534 }
535 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeKeyExchange, ctx)) != 0)
536 return err;
537 assert(ctx->sslTslCalls != NULL);
538 if (ERR(err = ctx->sslTslCalls->generateMasterSecret(ctx)) != 0 ||
539 ERR(err = SSLInitPendingCiphers(ctx)) != 0)
540 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
541 return err;
542 }
543 memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
544 if (ERR(err = SSLFreeBuffer(&ctx->preMasterSecret, &ctx->sysCtx)) != 0)
545 return err;
546 if (ctx->certSent)
547 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificateVerify, ctx)) != 0)
548 return err;
549 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, ctx)) != 0)
550 return err;
551 /* Install new cipher spec on write side */
552 if (ERR(err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
553 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
554 return err;
555 }
556 ctx->writeCipher = ctx->writePending;
557 /* Can't send data until Finished is sent */
558 ctx->writeCipher.ready = 0;
559
560 /* Zero out old data */
561 memset(&ctx->writePending, 0, sizeof(CipherContext));
562 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
563 return err;
564 /* Finished has been sent; enable data dransfer on write channel */
565 ctx->writeCipher.ready = 1;
566 SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
567 break;
568 case SSL_certificate_verify:
569 SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
570 break;
571 case SSL_client_key_exchange:
572 assert(ctx->sslTslCalls != NULL);
573 if (ERR(err = ctx->sslTslCalls->generateMasterSecret(ctx)) != 0 ||
574 ERR(err = SSLInitPendingCiphers(ctx)) != 0)
575 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
576 return err;
577 }
578 memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
579 if (ERR(err = SSLFreeBuffer(&ctx->preMasterSecret, &ctx->sysCtx)) != 0)
580 return err;
581 if (ctx->certReceived) {
582 SSLChangeHdskState(ctx, HandshakeClientCertVerify);
583 }
584 else {
585 SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
586 }
587 break;
588 case SSL_finished:
589 /* Handshake is over; enable data transfer on read channel */
590 ctx->readCipher.ready = 1;
591 /* If writePending is set, we haven't yet sent a finished message; send it */
592 if (ctx->writePending.ready != 0)
593 { if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, ctx)) != 0)
594 return err;
595
596 /* Install new cipher spec on write side */
597 if (ERR(err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
598 { SSLFatalSessionAlert(alert_close_notify, ctx);
599 return err;
600 }
601 ctx->writeCipher = ctx->writePending;
602 ctx->writeCipher.ready = 0; /* Can't send data until Finished is sent */
603 memset(&ctx->writePending, 0, sizeof(CipherContext)); /* Zero out old data */
604 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
605 return err;
606 ctx->writeCipher.ready = 1;
607 }
608 if (ctx->protocolSide == SSL_ServerSide) {
609 SSLChangeHdskState(ctx, HandshakeServerReady);
610 }
611 else {
612 SSLChangeHdskState(ctx, HandshakeClientReady);
613 }
614 if (ctx->peerID.data != 0)
615 ERR(SSLAddSessionData(ctx));
616 break;
617 default:
618 ASSERTMSG("Unknown State");
619 break;
620 }
621
622 return SSLNoErr;
623 }
624
625 SSLErr
626 SSLPrepareAndQueueMessage(EncodeMessageFunc msgFunc, SSLContext *ctx)
627 { SSLErr err;
628 SSLRecord rec;
629
630 if (ERR(err = msgFunc(&rec, ctx)) != 0)
631 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
632 goto fail;
633 }
634
635 if (rec.contentType == SSL_handshake)
636 { if (ERR(err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
637 ERR(err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
638 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
639 goto fail;
640 }
641 SSLLogHdskMsg((SSLHandshakeType)rec.contents.data[0], 1);
642 }
643
644 assert(ctx->sslTslCalls != NULL);
645 if (ERR(err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
646 goto fail;
647
648 err = SSLNoErr;
649 fail:
650 SSLFreeBuffer(&rec.contents, &ctx->sysCtx);
651
652 return err;
653 }
654
655 SSLErr
656 SSL3ReceiveSSL2ClientHello(SSLRecord rec, SSLContext *ctx)
657 { SSLErr err;
658
659 if (ERR(err = SSLInitMessageHashes(ctx)) != 0)
660 return err;
661
662 if (ERR(err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
663 ERR(err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
664 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
665 return err;
666 }
667
668 if (ERR(err = SSLAdvanceHandshake(SSL_client_hello, ctx)) != 0)
669 return err;
670
671 return SSLNoErr;
672 }
673
674 /* log changes in handshake state */
675 #if LOG_HDSK_STATE
676
677 #include <stdio.h>
678
679 char *hdskStateToStr(SSLHandshakeState state)
680 {
681 static char badStr[100];
682
683 switch(state) {
684 case SSLUninitialized:
685 return "SSLUninitialized";
686 case HandshakeServerUninit:
687 return "HandshakeServerUninit";
688 case HandshakeClientUninit:
689 return "HandshakeClientUninit";
690 case SSLGracefulClose:
691 return "SSLGracefulClose";
692 case SSLErrorClose:
693 return "SSLErrorClose";
694 case SSLNoNotifyClose:
695 return "SSLNoNotifyClose";
696 case HandshakeServerHello:
697 return "HandshakeServerHello";
698 case HandshakeServerHelloUnknownVersion:
699 return "HandshakeServerHelloUnknownVersion";
700 case HandshakeKeyExchange:
701 return "HandshakeKeyExchange";
702 case HandshakeCertificate:
703 return "HandshakeCertificate";
704 case HandshakeHelloDone:
705 return "HandshakeHelloDone";
706 case HandshakeClientCertificate:
707 return "HandshakeClientCertificate";
708 case HandshakeClientKeyExchange:
709 return "HandshakeClientKeyExchange";
710 case HandshakeClientCertVerify:
711 return "HandshakeClientCertVerify";
712 case HandshakeChangeCipherSpec:
713 return "HandshakeChangeCipherSpec";
714 case HandshakeFinished:
715 return "HandshakeFinished";
716 case HandshakeSSL2ClientMasterKey:
717 return "HandshakeSSL2ClientMasterKey";
718 case HandshakeSSL2ClientFinished:
719 return "HandshakeSSL2ClientFinished";
720 case HandshakeSSL2ServerHello:
721 return "HandshakeSSL2ServerHello";
722 case HandshakeSSL2ServerVerify:
723 return "HandshakeSSL2ServerVerify";
724 case HandshakeSSL2ServerFinished:
725 return "HandshakeSSL2ServerFinished";
726 case HandshakeServerReady:
727 return "HandshakeServerReady";
728 case HandshakeClientReady:
729 return "HandshakeClientReady";
730 default:
731 sprintf(badStr, "Unknown state (%d(d)", state);
732 return badStr;
733 }
734 }
735
736 void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState)
737 {
738 printf("...hdskState = %s\n", hdskStateToStr(newState));
739 ctx->state = newState;
740 }
741
742 #endif /* LOG_HDSK_STATE */
743
744 /* log handshake messages */
745
746 #if LOG_HDSK_MSG
747
748 #include <stdio.h>
749
750 static char *hdskMsgToStr(SSLHandshakeType msg)
751 {
752 static char badStr[100];
753
754 switch(msg) {
755 case SSL_hello_request:
756 return "SSL_hello_request";
757 case SSL_client_hello:
758 return "SSL_client_hello";
759 case SSL_server_hello:
760 return "SSL_server_hello";
761 case SSL_certificate:
762 return "SSL_certificate";
763 case SSL_server_key_exchange:
764 return "SSL_server_key_exchange";
765 case SSL_certificate_request:
766 return "SSL_certificate_request";
767 case SSL_server_hello_done:
768 return "SSL_server_hello_done";
769 case SSL_certificate_verify:
770 return "SSL_certificate_verify";
771 case SSL_client_key_exchange:
772 return "SSL_client_key_exchange";
773 case SSL_finished:
774 return "SSL_finished";
775 case SSL_MAGIC_no_certificate_alert:
776 return "SSL_MAGIC_no_certificate_alert";
777 default:
778 sprintf(badStr, "Unknown state (%d(d)", msg);
779 return badStr;
780 }
781 }
782
783 void SSLLogHdskMsg(SSLHandshakeType msg, char sent)
784 {
785 printf("---%s handshake msg %s\n",
786 hdskMsgToStr(msg), (sent ? "sent" : "recv"));
787 }
788
789 #endif /* LOG_HDSK_MSG */
790