]> git.saurik.com Git - apple/security.git/blob - SecureTransport/sslhdshk.c
Security-30.1.tar.gz
[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 RSARef 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 <string.h>
90
91 #define REQUEST_CERT_CORRECT 0
92
93 static SSLErr SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx);
94
95 SSLErr
96 SSLProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
97 { SSLErr err;
98 sint32 remaining;
99 UInt8 *p;
100 SSLHandshakeMsg message;
101 SSLBuffer messageData;
102
103 if (ctx->fragmentedMessageCache.data != 0)
104 { if ((err = SSLReallocBuffer(&ctx->fragmentedMessageCache,
105 ctx->fragmentedMessageCache.length + rec.contents.length,
106 &ctx->sysCtx)) != 0)
107 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
108 return ERR(err);
109 }
110 memcpy(ctx->fragmentedMessageCache.data + ctx->fragmentedMessageCache.length,
111 rec.contents.data, rec.contents.length);
112 remaining = ctx->fragmentedMessageCache.length;
113 p = ctx->fragmentedMessageCache.data;
114 }
115 else
116 { remaining = rec.contents.length;
117 p = rec.contents.data;
118 }
119
120 while (remaining > 0)
121 { if (remaining < 4)
122 break; /* we must have at least a header */
123
124 messageData.data = p;
125 message.type = (SSLHandshakeType)*p++;
126 message.contents.length = SSLDecodeInt(p, 3);
127 if ((message.contents.length + 4) > remaining)
128 break;
129
130 p += 3;
131 message.contents.data = p;
132 p += message.contents.length;
133 messageData.length = 4 + message.contents.length;
134 CASSERT(p == messageData.data + messageData.length);
135
136 /* message fragmentation */
137 remaining -= messageData.length;
138 if (ERR(err = SSLProcessHandshakeMessage(message, ctx)) != 0)
139 return err;
140
141 if (message.type != SSL_hello_request)
142 { if (ERR(err = SSLHashSHA1.update(ctx->shaState, messageData)) != 0 ||
143 ERR(err = SSLHashMD5.update(ctx->md5State, messageData)) != 0)
144 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
145 return err;
146 }
147 }
148
149 if (ERR(err = SSLAdvanceHandshake(message.type, ctx)) != 0)
150 return err;
151 }
152
153 if (remaining > 0) /* Fragmented handshake message */
154 { /* If there isn't a cache, allocate one */
155 if (ctx->fragmentedMessageCache.data == 0)
156 { if (ERR(err = SSLAllocBuffer(&ctx->fragmentedMessageCache, remaining, &ctx->sysCtx)) != 0)
157 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
158 return err;
159 }
160 }
161 if (p != ctx->fragmentedMessageCache.data)
162 { memcpy(ctx->fragmentedMessageCache.data, p, remaining);
163 ctx->fragmentedMessageCache.length = remaining;
164 }
165 }
166 else if (ctx->fragmentedMessageCache.data != 0)
167 { if (ERR(err = SSLFreeBuffer(&ctx->fragmentedMessageCache, &ctx->sysCtx)) != 0)
168 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
169 return err;
170 }
171 }
172
173 return SSLNoErr;
174 }
175
176 static SSLErr
177 SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx)
178 { SSLErr err;
179
180 err = SSLNoErr;
181 SSLLogHdskMsg(message.type, 0);
182 switch (message.type)
183 { case SSL_hello_request:
184 if (ctx->protocolSide != SSL_ClientSide)
185 goto wrongMessage;
186 if (message.contents.length > 0)
187 err = ERR(SSLProtocolErr);
188 break;
189 case SSL_client_hello:
190 if (ctx->state != HandshakeServerUninit)
191 goto wrongMessage;
192 ERR(err = SSLProcessClientHello(message.contents, ctx));
193 break;
194 case SSL_server_hello:
195 if (ctx->state != HandshakeServerHello &&
196 ctx->state != HandshakeServerHelloUnknownVersion)
197 goto wrongMessage;
198 ERR(err = SSLProcessServerHello(message.contents, ctx));
199 break;
200 case SSL_certificate:
201 if (ctx->state != HandshakeCertificate &&
202 ctx->state != HandshakeClientCertificate)
203 goto wrongMessage;
204 ERR(err = SSLProcessCertificate(message.contents, ctx));
205 break;
206 case SSL_certificate_request:
207 if ((ctx->state != HandshakeHelloDone && ctx->state != HandshakeKeyExchange)
208 || ctx->certRequested)
209 goto wrongMessage;
210 ERR(err = SSLProcessCertificateRequest(message.contents, ctx));
211 break;
212 case SSL_server_key_exchange:
213 #if _APPLE_CDSA_
214 /*
215 * Since this message is optional, and completely at the
216 * server's discretion, we need to be able to handle this
217 * in one of two states...
218 */
219 switch(ctx->state) {
220 case HandshakeKeyExchange: /* explicitly waiting for this */
221 case HandshakeHelloDone:
222 break;
223 default:
224 goto wrongMessage;
225 }
226 #else
227 if (ctx->state != HandshakeKeyExchange)
228 goto wrongMessage;
229 #endif /* _APPLE_CDSA_ */
230 ERR(err = SSLProcessServerKeyExchange(message.contents, ctx));
231 break;
232 case SSL_server_hello_done:
233 if (ctx->state != HandshakeHelloDone)
234 goto wrongMessage;
235 ERR(err = SSLProcessServerHelloDone(message.contents, ctx));
236 break;
237 case SSL_certificate_verify:
238 if (ctx->state != HandshakeClientCertVerify)
239 goto wrongMessage;
240 ERR(err = SSLProcessCertificateVerify(message.contents, ctx));
241 break;
242 case SSL_client_key_exchange:
243 if (ctx->state != HandshakeClientKeyExchange)
244 goto wrongMessage;
245 ERR(err = SSLProcessKeyExchange(message.contents, ctx));
246 break;
247 case SSL_finished:
248 if (ctx->state != HandshakeFinished)
249 goto wrongMessage;
250 ERR(err = SSLProcessFinished(message.contents, ctx));
251 break;
252 default:
253 goto wrongMessage;
254 break;
255 }
256
257 if (err)
258 { if (err == SSLProtocolErr)
259 ERR(SSLFatalSessionAlert(alert_illegal_parameter, ctx));
260 else if (err == SSLNegotiationErr)
261 ERR(SSLFatalSessionAlert(alert_handshake_failure, ctx));
262 else
263 ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
264 }
265 return ERR(err);
266
267 wrongMessage:
268 ERR(SSLFatalSessionAlert(alert_unexpected_message, ctx));
269 return ERR(SSLProtocolErr);
270 }
271
272 SSLErr
273 SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
274 { SSLErr err;
275 SSLBuffer sessionIdentifier;
276
277 switch (processed)
278 { case SSL_hello_request:
279 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeClientHello, ctx)) != 0)
280 return err;
281 SSLChangeHdskState(ctx, HandshakeServerHello);
282 break;
283 case SSL_client_hello:
284 CASSERT(ctx->protocolSide == SSL_ServerSide);
285 if (ctx->sessionID.data != 0) /* If session ID != 0, client is trying to resume */
286 { if (ctx->resumableSession.data != 0)
287 { if (ERR(err = SSLRetrieveSessionIDIdentifier(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
288 return err;
289 if (sessionIdentifier.length == ctx->sessionID.length &&
290 memcmp(sessionIdentifier.data, ctx->sessionID.data, ctx->sessionID.length) == 0)
291 { /* Everything matches; resume the session */
292 //DEBUGMSG("Using resumed SSL3 Session");
293 if (ERR(err = SSLInstallSessionID(ctx->resumableSession, ctx)) != 0)
294 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
295 return err;
296 }
297 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
298 return err;
299 if (ERR(err = SSLInitPendingCiphers(ctx)) != 0 ||
300 ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
301 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
302 return err;
303 }
304 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, ctx)) != 0)
305 return err;
306 /* Install new cipher spec on write side */
307 if (ERR(err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
308 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
309 return err;
310 }
311 ctx->writeCipher = ctx->writePending;
312 ctx->writeCipher.ready = 0; /* Can't send data until Finished is sent */
313 memset(&ctx->writePending, 0, sizeof(CipherContext)); /* Zero out old data */
314 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
315 return err;
316 /* Finished has been sent; enable data dransfer on write channel */
317 ctx->writeCipher.ready = 1;
318 SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
319 break;
320 }
321 if (ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0 ||
322 ERR(err = SSLDeleteSessionID(ctx)) != 0)
323 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
324 return err;
325 }
326 }
327 if (ERR(err = SSLFreeBuffer(&ctx->sessionID, &ctx->sysCtx)) != 0)
328 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
329 return err;
330 }
331 }
332
333 /* If we get here, we're not resuming; generate a new session ID if we know our peer */
334 if (ctx->peerID.data != 0)
335 { /* Ignore errors; just treat as uncached session */
336 CASSERT(ctx->sessionID.data == 0);
337 ERR(err = SSLAllocBuffer(&ctx->sessionID, SSL_SESSION_ID_LEN, &ctx->sysCtx));
338 if (err == 0)
339 {
340 #ifdef _APPLE_CDSA_
341 if((err = sslRand(ctx, &ctx->sessionID)) != 0)
342 #else
343 if (ERR(err = ctx->sysCtx.random(ctx->sessionID, ctx->sysCtx.randomRef)) != 0)
344 #endif
345 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
346 return err;
347 }
348 }
349 }
350
351 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
352 return err;
353 switch (ctx->selectedCipherSpec->keyExchangeMethod)
354 { case SSL_NULL_auth:
355 #if APPLE_DH
356 case SSL_DH_anon:
357 #endif
358 case SSL_DH_anon_EXPORT:
359 #if ST_SERVER_MODE_ENABLE
360 if(ctx->clientAuth == kAlwaysAuthenticate) {
361 /* APPLE_CDSA change: app requires this; abort */
362 SSLFatalSessionAlert(alert_handshake_failure, ctx);
363 return SSLNegotiationErr;
364 }
365 ctx->tryClientAuth = false;
366 #else /* ST_SERVER_MODE_ENABLE */
367 /* server side needs work */
368 #endif /* ST_SERVER_MODE_ENABLE*/
369 break;
370 default: /* everything else */
371 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificate, ctx)) != 0)
372 return err;
373 break;
374 }
375 #ifdef _APPLE_CDSA_
376 /*
377 * At this point we decide whether to send a server key exchange
378 * method. For Apple servers, I think we'll ALWAYS do this, because
379 * of key usage restrictions (can't decrypt and sign with the same
380 * private key), but conceptually in this code, we do it if
381 * enabled by the presence of encryptPrivKey.
382 */
383 #if SSL_SERVER_KEYEXCH_HACK
384 /*
385 * This is currently how we work with Netscape. It requires
386 * a CSP which can handle private keys which can both
387 * sign and decrypt.
388 */
389 if((ctx->selectedCipherSpec->keyExchangeMethod != SSL_RSA) &&
390 (ctx->encryptPrivKey != NULL)) {
391 err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx);
392 if(err) {
393 return err;
394 }
395 }
396 #else /* !SSL_SERVER_KEYEXCH_HACK */
397 /*
398 * This is, I believe the "right" way, but Netscape doesn't
399 * work this way.
400 */
401 if (ctx->encryptPrivKey != NULL) {
402 err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx);
403 if(err) {
404 return err;
405 }
406 }
407 #endif /* SSL_SERVER_KEYEXCH_HACK */
408 #else /* !_APPLE_CDSA_ */
409 /* original SSLRef3.... */
410 if (ctx->selectedCipherSpec->keyExchangeMethod != SSL_RSA)
411 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx)) != 0)
412 return err;
413 #endif /* _APPLE_CDSA_ */
414 #if ST_SERVER_MODE_ENABLE
415 if (ctx->tryClientAuth)
416 { if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificateRequest, ctx)) != 0)
417 return err;
418 ctx->certRequested = 1;
419 }
420 #else /* !ST_SERVER_MODE_ENABLE */
421 /* disabled for now */
422 #endif /* ST_SERVER_MODE_ENABLE */
423 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeServerHelloDone, ctx)) != 0)
424 return err;
425 if (ctx->certRequested) {
426 SSLChangeHdskState(ctx, HandshakeClientCertificate);
427 }
428 else {
429 SSLChangeHdskState(ctx, HandshakeClientKeyExchange);
430 }
431 break;
432 case SSL_server_hello:
433 if (ctx->resumableSession.data != 0 && ctx->sessionID.data != 0)
434 { if (ERR(err = SSLRetrieveSessionIDIdentifier(ctx->resumableSession, &sessionIdentifier, ctx)) != 0)
435 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
436 return err;
437 }
438 if (sessionIdentifier.length == ctx->sessionID.length &&
439 memcmp(sessionIdentifier.data, ctx->sessionID.data, ctx->sessionID.length) == 0)
440 { /* Everything matches; resume the session */
441 if (ERR(err = SSLInstallSessionID(ctx->resumableSession, ctx)) != 0 ||
442 ERR(err = SSLInitPendingCiphers(ctx)) != 0 ||
443 ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
444 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
445 return err;
446 }
447 SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
448 break;
449 }
450 if (ERR(err = SSLFreeBuffer(&sessionIdentifier, &ctx->sysCtx)) != 0)
451 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
452 return err;
453 }
454 }
455 switch (ctx->selectedCipherSpec->keyExchangeMethod)
456 {
457 /* these require a key exchange message */
458 case SSL_NULL_auth:
459 case SSL_DH_anon:
460 case SSL_DH_anon_EXPORT:
461 SSLChangeHdskState(ctx, HandshakeKeyExchange);
462 break;
463 case SSL_RSA:
464 case SSL_DH_DSS:
465 case SSL_DH_DSS_EXPORT:
466 case SSL_DH_RSA:
467 case SSL_DH_RSA_EXPORT:
468 case SSL_RSA_EXPORT:
469 case SSL_DHE_DSS:
470 case SSL_DHE_DSS_EXPORT:
471 case SSL_DHE_RSA:
472 case SSL_DHE_RSA_EXPORT:
473 case SSL_Fortezza:
474 SSLChangeHdskState(ctx, HandshakeCertificate);
475 break;
476 default:
477 ASSERTMSG("Unknown key exchange method");
478 break;
479 }
480 break;
481 case SSL_certificate:
482 if (ctx->state == HandshakeCertificate)
483 switch (ctx->selectedCipherSpec->keyExchangeMethod)
484 { case SSL_RSA:
485 #ifdef _APPLE_CDSA_
486 /*
487 * I really think the two RSA cases should be
488 * handled the same here - the server key exchange is
489 * optional, and is up to the server.
490 * Note this isn't the same as SSL_SERVER_KEYEXCH_HACK;
491 * we're a client here.
492 */
493 case SSL_RSA_EXPORT:
494 #endif
495 case SSL_DH_DSS:
496 case SSL_DH_DSS_EXPORT:
497 case SSL_DH_RSA:
498 case SSL_DH_RSA_EXPORT:
499 SSLChangeHdskState(ctx, HandshakeHelloDone);
500 break;
501 #ifndef _APPLE_CDSA_
502 case SSL_RSA_EXPORT:
503 #endif
504 case SSL_DHE_DSS:
505 case SSL_DHE_DSS_EXPORT:
506 case SSL_DHE_RSA:
507 case SSL_DHE_RSA_EXPORT:
508 case SSL_Fortezza:
509 SSLChangeHdskState(ctx, HandshakeKeyExchange);
510 break;
511 default:
512 ASSERTMSG("Unknown or unexpected key exchange method");
513 break;
514 }
515 else if (ctx->state == HandshakeClientCertificate)
516 { SSLChangeHdskState(ctx, HandshakeClientKeyExchange);
517 if (ctx->peerCert != 0)
518 ctx->certReceived = 1;
519 }
520 break;
521 case SSL_certificate_request: /* state stays in HandshakeHelloDone; distinction is in ctx->certRequested */
522 if (ctx->peerCert == 0)
523 { ERR(SSLFatalSessionAlert(alert_handshake_failure, ctx));
524 return ERR(SSLProtocolErr);
525 }
526 ctx->certRequested = 1;
527 break;
528 case SSL_server_key_exchange:
529 SSLChangeHdskState(ctx, HandshakeHelloDone);
530 break;
531 case SSL_server_hello_done:
532 if (ctx->certRequested)
533 { if (ctx->localCert != 0 && ctx->x509Requested)
534 { if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificate, ctx)) != 0)
535 return err;
536 }
537 else
538 { if (ERR(err = SSLSendAlert(alert_warning, alert_no_certificate, ctx)) != 0)
539 return err;
540 }
541 }
542 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeKeyExchange, ctx)) != 0)
543 return err;
544 if (ERR(err = SSLCalculateMasterSecret(ctx)) != 0 ||
545 ERR(err = SSLInitPendingCiphers(ctx)) != 0)
546 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
547 return err;
548 }
549 if (ERR(err = SSLFreeBuffer(&ctx->preMasterSecret, &ctx->sysCtx)) != 0)
550 return err;
551 if (ctx->certSent)
552 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeCertificateVerify, ctx)) != 0)
553 return err;
554 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec, ctx)) != 0)
555 return err;
556 /* Install new cipher spec on write side */
557 if (ERR(err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
558 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
559 return err;
560 }
561 ctx->writeCipher = ctx->writePending;
562 ctx->writeCipher.ready = 0; /* Can't send data until Finished is sent */
563 memset(&ctx->writePending, 0, sizeof(CipherContext)); /* Zero out old data */
564 if (ERR(err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
565 return err;
566 /* Finished has been sent; enable data dransfer on write channel */
567 ctx->writeCipher.ready = 1;
568 SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
569 break;
570 case SSL_certificate_verify:
571 SSLChangeHdskState(ctx, HandshakeChangeCipherSpec);
572 break;
573 case SSL_client_key_exchange:
574 if (ERR(err = SSLCalculateMasterSecret(ctx)) != 0 ||
575 ERR(err = SSLInitPendingCiphers(ctx)) != 0)
576 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
577 return err;
578 }
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(SSLAddSessionID(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 if (ERR(err = SSLWriteRecord(rec, ctx)) != 0)
645 goto fail;
646
647 err = SSLNoErr;
648 fail:
649 SSLFreeBuffer(&rec.contents, &ctx->sysCtx);
650
651 return err;
652 }
653
654 SSLErr
655 SSL3ReceiveSSL2ClientHello(SSLRecord rec, SSLContext *ctx)
656 { SSLErr err;
657
658 if (ERR(err = SSLInitMessageHashes(ctx)) != 0)
659 return err;
660
661 if (ERR(err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
662 ERR(err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
663 { ERR(SSLFatalSessionAlert(alert_close_notify, ctx));
664 return err;
665 }
666
667 if (ERR(err = SSLAdvanceHandshake(SSL_client_hello, ctx)) != 0)
668 return err;
669
670 return SSLNoErr;
671 }
672
673 /* log changes in handshake state */
674 #if LOG_HDSK_STATE
675
676 #include <stdio.h>
677
678 char *hdskStateToStr(SSLHandshakeState state)
679 {
680 static char badStr[100];
681
682 switch(state) {
683 case SSLUninitialized:
684 return "SSLUninitialized";
685 case HandshakeServerUninit:
686 return "HandshakeServerUninit";
687 case HandshakeClientUninit:
688 return "HandshakeClientUninit";
689 case SSLGracefulClose:
690 return "SSLGracefulClose";
691 case SSLErrorClose:
692 return "SSLErrorClose";
693 case SSLNoNotifyClose:
694 return "SSLNoNotifyClose";
695 case HandshakeServerHello:
696 return "HandshakeServerHello";
697 case HandshakeServerHelloUnknownVersion:
698 return "HandshakeServerHelloUnknownVersion";
699 case HandshakeKeyExchange:
700 return "HandshakeKeyExchange";
701 case HandshakeCertificate:
702 return "HandshakeCertificate";
703 case HandshakeHelloDone:
704 return "HandshakeHelloDone";
705 case HandshakeClientCertificate:
706 return "HandshakeClientCertificate";
707 case HandshakeClientKeyExchange:
708 return "HandshakeClientKeyExchange";
709 case HandshakeClientCertVerify:
710 return "HandshakeClientCertVerify";
711 case HandshakeChangeCipherSpec:
712 return "HandshakeChangeCipherSpec";
713 case HandshakeFinished:
714 return "HandshakeFinished";
715 case HandshakeSSL2ClientMasterKey:
716 return "HandshakeSSL2ClientMasterKey";
717 case HandshakeSSL2ClientFinished:
718 return "HandshakeSSL2ClientFinished";
719 case HandshakeSSL2ServerHello:
720 return "HandshakeSSL2ServerHello";
721 case HandshakeSSL2ServerVerify:
722 return "HandshakeSSL2ServerVerify";
723 case HandshakeSSL2ServerFinished:
724 return "HandshakeSSL2ServerFinished";
725 case HandshakeServerReady:
726 return "HandshakeServerReady";
727 case HandshakeClientReady:
728 return "HandshakeClientReady";
729 default:
730 sprintf(badStr, "Unknown state (%d(d)", state);
731 return badStr;
732 }
733 }
734
735 void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState)
736 {
737 printf("...hdskState = %s\n", hdskStateToStr(newState));
738 ctx->state = newState;
739 }
740
741 #endif /* LOG_HDSK_STATE */
742
743 /* log handshake messages */
744
745 #if LOG_HDSK_MSG
746
747 #include <stdio.h>
748
749 static char *hdskMsgToStr(SSLHandshakeType msg)
750 {
751 static char badStr[100];
752
753 switch(msg) {
754 case SSL_hello_request:
755 return "SSL_hello_request";
756 case SSL_client_hello:
757 return "SSL_client_hello";
758 case SSL_server_hello:
759 return "SSL_server_hello";
760 case SSL_certificate:
761 return "SSL_certificate";
762 case SSL_server_key_exchange:
763 return "SSL_server_key_exchange";
764 case SSL_certificate_request:
765 return "SSL_certificate_request";
766 case SSL_server_hello_done:
767 return "SSL_server_hello_done";
768 case SSL_certificate_verify:
769 return "SSL_certificate_verify";
770 case SSL_client_key_exchange:
771 return "SSL_client_key_exchange";
772 case SSL_finished:
773 return "SSL_finished";
774 case SSL_MAGIC_no_certificate_alert:
775 return "SSL_MAGIC_no_certificate_alert";
776 default:
777 sprintf(badStr, "Unknown state (%d(d)", msg);
778 return badStr;
779 }
780 }
781
782 void SSLLogHdskMsg(SSLHandshakeType msg, char sent)
783 {
784 printf("---%s handshake msg %s\n",
785 hdskMsgToStr(msg), (sent ? "sent" : "recv"));
786 }
787
788 #endif /* LOG_HDSK_MSG */