]> git.saurik.com Git - apple/security.git/blob - SecureTransport/sslHandshake.cpp
Security-177.tar.gz
[apple/security.git] / SecureTransport / sslHandshake.cpp
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: sslHandshake.cpp
21
22 Contains: SSL 3.0 handshake state machine.
23
24 Written by: Doug Mitchell
25
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
27
28 */
29
30 #include "sslContext.h"
31 #include "sslHandshake.h"
32 #include "sslMemory.h"
33 #include "sslAlertMessage.h"
34 #include "sslSession.h"
35 #include "sslUtils.h"
36 #include "sslDebug.h"
37 #include "appleCdsa.h"
38 #include "sslDigests.h"
39
40 #include <string.h>
41 #include <assert.h>
42
43 #define REQUEST_CERT_CORRECT 0
44
45 static OSStatus SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx);
46
47 OSStatus
48 SSLProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
49 { OSStatus err;
50 sint32 remaining;
51 UInt8 *p;
52 SSLHandshakeMsg message;
53 SSLBuffer messageData;
54
55 if (ctx->fragmentedMessageCache.data != 0)
56 { if ((err = SSLReallocBuffer(ctx->fragmentedMessageCache,
57 ctx->fragmentedMessageCache.length + rec.contents.length,
58 ctx)) != 0)
59 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
60 return err;
61 }
62 memcpy(ctx->fragmentedMessageCache.data + ctx->fragmentedMessageCache.length,
63 rec.contents.data, rec.contents.length);
64 remaining = ctx->fragmentedMessageCache.length;
65 p = ctx->fragmentedMessageCache.data;
66 }
67 else
68 { remaining = rec.contents.length;
69 p = rec.contents.data;
70 }
71
72 while (remaining > 0)
73 { if (remaining < 4)
74 break; /* we must have at least a header */
75
76 messageData.data = p;
77 message.type = (SSLHandshakeType)*p++;
78 message.contents.length = SSLDecodeInt(p, 3);
79 if (((int)(message.contents.length + 4)) > remaining)
80 break;
81
82 p += 3;
83 message.contents.data = p;
84 p += message.contents.length;
85 messageData.length = 4 + message.contents.length;
86 assert(p == messageData.data + messageData.length);
87
88 /* message fragmentation */
89 remaining -= messageData.length;
90 if ((err = SSLProcessHandshakeMessage(message, ctx)) != 0)
91 return err;
92
93 if (message.type != SSL_HdskHelloRequest)
94 { if ((err = SSLHashSHA1.update(ctx->shaState, messageData)) != 0 ||
95 (err = SSLHashMD5.update(ctx->md5State, messageData)) != 0)
96 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
97 return err;
98 }
99 }
100
101 if ((err = SSLAdvanceHandshake(message.type, ctx)) != 0)
102 return err;
103 }
104
105 if (remaining > 0) /* Fragmented handshake message */
106 { /* If there isn't a cache, allocate one */
107 if (ctx->fragmentedMessageCache.data == 0)
108 { if ((err = SSLAllocBuffer(ctx->fragmentedMessageCache, remaining, ctx)) != 0)
109 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
110 return err;
111 }
112 }
113 if (p != ctx->fragmentedMessageCache.data)
114 { memcpy(ctx->fragmentedMessageCache.data, p, remaining);
115 ctx->fragmentedMessageCache.length = remaining;
116 }
117 }
118 else if (ctx->fragmentedMessageCache.data != 0)
119 { if ((err = SSLFreeBuffer(ctx->fragmentedMessageCache, ctx)) != 0)
120 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
121 return err;
122 }
123 }
124
125 return noErr;
126 }
127
128 static OSStatus
129 SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx)
130 { OSStatus err;
131
132 err = noErr;
133 SSLLogHdskMsg(message.type, 0);
134 switch (message.type)
135 { case SSL_HdskHelloRequest:
136 if (ctx->protocolSide != SSL_ClientSide)
137 goto wrongMessage;
138 if (message.contents.length > 0)
139 err = errSSLProtocol;
140 break;
141 case SSL_HdskClientHello:
142 if (ctx->state != SSL_HdskStateServerUninit)
143 goto wrongMessage;
144 err = SSLProcessClientHello(message.contents, ctx);
145 break;
146 case SSL_HdskServerHello:
147 if (ctx->state != SSL_HdskStateServerHello &&
148 ctx->state != SSL_HdskStateServerHelloUnknownVersion)
149 goto wrongMessage;
150 err = SSLProcessServerHello(message.contents, ctx);
151 break;
152 case SSL_HdskCert:
153 if (ctx->state != SSL_HdskStateCert &&
154 ctx->state != SSL_HdskStateClientCert)
155 goto wrongMessage;
156 err = SSLProcessCertificate(message.contents, ctx);
157 if(ctx->protocolSide == SSL_ServerSide) {
158 if(err) {
159 /*
160 * Error could be from no cert (when we require one)
161 * or invalid cert
162 */
163 if(ctx->peerCert != NULL) {
164 ctx->clientCertState = kSSLClientCertRejected;
165 }
166 }
167 else if(ctx->peerCert != NULL) {
168 /*
169 * This still might change if cert verify msg
170 * fails. Note we avoid going to state
171 * if we get en empty cert message which is
172 * otherwise valid.
173 */
174 ctx->clientCertState = kSSLClientCertSent;
175 }
176 }
177 break;
178 case SSL_HdskCertRequest:
179 if (((ctx->state != SSL_HdskStateHelloDone) &&
180 (ctx->state != SSL_HdskStateKeyExchange))
181 || ctx->certRequested)
182 goto wrongMessage;
183 err = SSLProcessCertificateRequest(message.contents, ctx);
184 break;
185 case SSL_HdskServerKeyExchange:
186 /*
187 * Since this message is optional, and completely at the
188 * server's discretion, we need to be able to handle this
189 * in one of two states...
190 */
191 switch(ctx->state) {
192 case SSL_HdskStateKeyExchange: /* explicitly waiting for this */
193 case SSL_HdskStateHelloDone:
194 break;
195 default:
196 goto wrongMessage;
197 }
198 err = SSLProcessServerKeyExchange(message.contents, ctx);
199 break;
200 case SSL_HdskServerHelloDone:
201 if (ctx->state != SSL_HdskStateHelloDone)
202 goto wrongMessage;
203 err = SSLProcessServerHelloDone(message.contents, ctx);
204 break;
205 case SSL_HdskCertVerify:
206 if (ctx->state != SSL_HdskStateClientCertVerify)
207 goto wrongMessage;
208 err = SSLProcessCertificateVerify(message.contents, ctx);
209 assert(ctx->protocolSide == SSL_ServerSide);
210 if(err) {
211 ctx->clientCertState = kSSLClientCertRejected;
212 }
213 break;
214 case SSL_HdskClientKeyExchange:
215 if (ctx->state != SSL_HdskStateClientKeyExchange)
216 goto wrongMessage;
217 err = SSLProcessKeyExchange(message.contents, ctx);
218 break;
219 case SSL_HdskFinished:
220 if (ctx->state != SSL_HdskStateFinished)
221 goto wrongMessage;
222 err = SSLProcessFinished(message.contents, ctx);
223 break;
224 default:
225 goto wrongMessage;
226 break;
227 }
228
229 if (err && !ctx->sentFatalAlert)
230 { if (err == errSSLProtocol)
231 SSLFatalSessionAlert(SSL_AlertIllegalParam, ctx);
232 else if (err == errSSLNegotiation)
233 SSLFatalSessionAlert(SSL_AlertHandshakeFail, ctx);
234 else
235 SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
236 }
237 return err;
238
239 wrongMessage:
240 SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
241 return errSSLProtocol;
242 }
243
244 OSStatus
245 SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
246 { OSStatus err;
247 SSLBuffer sessionIdentifier;
248
249 switch (processed)
250 { case SSL_HdskHelloRequest:
251 /*
252 * Reset the client auth state machine in case this is
253 * a renegotiation.
254 */
255 ctx->certRequested = 0;
256 ctx->certSent = 0;
257 ctx->certReceived = 0;
258 ctx->x509Requested = 0;
259 ctx->clientCertState = kSSLClientCertNone;
260 if ((err = SSLPrepareAndQueueMessage(SSLEncodeClientHello, ctx)) != 0)
261 return err;
262 SSLChangeHdskState(ctx, SSL_HdskStateServerHello);
263 break;
264 case SSL_HdskClientHello:
265 assert(ctx->protocolSide == SSL_ServerSide);
266 ctx->sessionMatch = 0;
267 if (ctx->sessionID.data != 0)
268 /* If session ID != 0, client is trying to resume */
269 { if (ctx->resumableSession.data != 0)
270 {
271 SSLProtocolVersion sessionProt;
272 if ((err = SSLRetrieveSessionID(ctx->resumableSession,
273 &sessionIdentifier, ctx)) != 0)
274 return err;
275 if ((err = SSLRetrieveSessionProtocolVersion(ctx->resumableSession,
276 &sessionProt, ctx)) != 0)
277 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
278 return err;
279 }
280 if ((sessionIdentifier.length == ctx->sessionID.length) &&
281 (memcmp(sessionIdentifier.data, ctx->sessionID.data,
282 ctx->sessionID.length) == 0) &&
283 (sessionProt == ctx->negProtocolVersion))
284 { /* Everything matches; resume the session */
285 sslLogResumSessDebug("===RESUMING SSL3 server-side session");
286 if ((err = SSLInstallSessionFromData(ctx->resumableSession,
287 ctx)) != 0)
288 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
289 return err;
290 }
291 ctx->sessionMatch = 1;
292 if ((err = SSLPrepareAndQueueMessage(SSLEncodeServerHello,
293 ctx)) != 0)
294 return err;
295 if ((err = SSLInitPendingCiphers(ctx)) != 0 ||
296 (err = SSLFreeBuffer(sessionIdentifier, ctx)) != 0)
297 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
298 return err;
299 }
300 if ((err =
301 SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec,
302 ctx)) != 0)
303 return err;
304 /* Install new cipher spec on write side */
305 if ((err = SSLDisposeCipherSuite(&ctx->writeCipher,
306 ctx)) != 0)
307 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
308 return err;
309 }
310 ctx->writeCipher = ctx->writePending;
311 ctx->writeCipher.ready = 0;
312 /* Can't send data until Finished is sent */
313 memset(&ctx->writePending, 0, sizeof(CipherContext));
314 /* Zero out old data */
315 if ((err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage,
316 ctx)) != 0)
317 return err;
318 /* Finished has been sent; enable data t6ransfer on
319 * write channel */
320 ctx->writeCipher.ready = 1;
321 SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
322 break;
323 }
324 else {
325 sslLogResumSessDebug(
326 "===FAILED TO RESUME SSL3 server-side session");
327 }
328 if ((err = SSLFreeBuffer(sessionIdentifier, ctx)) != 0 ||
329 (err = SSLDeleteSessionData(ctx)) != 0)
330 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
331 return err;
332 }
333 }
334 if ((err = SSLFreeBuffer(ctx->sessionID, ctx)) != 0)
335 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
336 return err;
337 }
338 }
339
340 /*
341 * If we get here, we're not resuming; generate a new session ID
342 * if we know our peer
343 */
344 if (ctx->peerID.data != 0)
345 { /* Ignore errors; just treat as uncached session */
346 assert(ctx->sessionID.data == 0);
347 err = SSLAllocBuffer(ctx->sessionID, SSL_SESSION_ID_LEN, ctx);
348 if (err == 0)
349 {
350 if((err = sslRand(ctx, &ctx->sessionID)) != 0)
351 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
352 return err;
353 }
354 }
355 }
356
357 if ((err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
358 return err;
359 switch (ctx->selectedCipherSpec->keyExchangeMethod)
360 { case SSL_NULL_auth:
361 #if APPLE_DH
362 case SSL_DH_anon:
363 case SSL_DH_anon_EXPORT:
364 if(ctx->clientAuth == kAlwaysAuthenticate) {
365 /* app requires this; abort */
366 SSLFatalSessionAlert(SSL_AlertHandshakeFail, ctx);
367 return errSSLNegotiation;
368 }
369 ctx->tryClientAuth = false;
370 /* DH server side needs work */
371 break;
372 #endif /* APPLE_DH */
373 default: /* everything else */
374 if(ctx->localCert == NULL) {
375 /* no cert but configured for, and negotiated, a
376 * ciphersuite which requires one */
377 sslErrorLog("SSLAdvanceHandshake: No server key!\n");
378 return errSSLBadConfiguration;
379 }
380 if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificate,
381 ctx)) != 0)
382 return err;
383 break;
384 }
385 /*
386 * At this point we decide whether to send a server key exchange
387 * method. For Apple servers, I think we'll ALWAYS do this, because
388 * of key usage restrictions (can't decrypt and sign with the same
389 * private key), but conceptually in this code, we do it if
390 * enabled by the presence of encryptPrivKey.
391 */
392 {
393 bool doServerKeyExch = false;
394 switch(ctx->selectedCipherSpec->keyExchangeMethod) {
395 case SSL_RSA_EXPORT:
396 #if !SSL_SERVER_KEYEXCH_HACK
397 /* the "proper" way - app decides. */
398 case SSL_RSA:
399 #endif
400 if(ctx->encryptPrivKeyRef != NULL) {
401 doServerKeyExch = true;
402 }
403 break;
404 case SSL_DH_anon:
405 case SSL_DH_anon_EXPORT:
406 case SSL_DHE_RSA:
407 case SSL_DHE_RSA_EXPORT:
408 case SSL_DHE_DSS:
409 case SSL_DHE_DSS_EXPORT:
410 doServerKeyExch = true;
411 break;
412 default:
413 break;
414 }
415 if(doServerKeyExch) {
416 err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx);
417 if(err) {
418 return err;
419 }
420 }
421 }
422 if (ctx->tryClientAuth)
423 { if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificateRequest,
424 ctx)) != 0)
425 return err;
426 ctx->certRequested = 1;
427 ctx->clientCertState = kSSLClientCertRequested;
428 }
429 if ((err = SSLPrepareAndQueueMessage(SSLEncodeServerHelloDone, ctx)) != 0)
430 return err;
431 if (ctx->certRequested) {
432 SSLChangeHdskState(ctx, SSL_HdskStateClientCert);
433 }
434 else {
435 SSLChangeHdskState(ctx, SSL_HdskStateClientKeyExchange);
436 }
437 break;
438 case SSL_HdskServerHello:
439 ctx->sessionMatch = 0;
440 if (ctx->resumableSession.data != 0 && ctx->sessionID.data != 0)
441 {
442 SSLProtocolVersion sessionProt;
443 if ((err = SSLRetrieveSessionID(ctx->resumableSession,
444 &sessionIdentifier, ctx)) != 0)
445 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
446 return err;
447 }
448 if ((err = SSLRetrieveSessionProtocolVersion(ctx->resumableSession,
449 &sessionProt, ctx)) != 0)
450 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
451 return err;
452 }
453 if ((sessionIdentifier.length == ctx->sessionID.length) &&
454 (memcmp(sessionIdentifier.data, ctx->sessionID.data,
455 ctx->sessionID.length) == 0) &&
456 (sessionProt == ctx->negProtocolVersion))
457 { /* Everything matches; resume the session */
458 sslLogResumSessDebug("===RESUMING SSL3 client-side session");
459 if ((err = SSLInstallSessionFromData(ctx->resumableSession,
460 ctx)) != 0 ||
461 (err = SSLInitPendingCiphers(ctx)) != 0 ||
462 (err = SSLFreeBuffer(sessionIdentifier, ctx)) != 0)
463 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
464 return err;
465 }
466 ctx->sessionMatch = 1;
467 SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
468 break;
469 }
470 else {
471 sslLogResumSessDebug("===FAILED TO RESUME SSL3 client-side "
472 "session");
473 }
474 if ((err = SSLFreeBuffer(sessionIdentifier, ctx)) != 0)
475 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
476 return err;
477 }
478 }
479 switch (ctx->selectedCipherSpec->keyExchangeMethod)
480 {
481 /* these require a key exchange message */
482 case SSL_NULL_auth:
483 case SSL_DH_anon:
484 case SSL_DH_anon_EXPORT:
485 SSLChangeHdskState(ctx, SSL_HdskStateKeyExchange);
486 break;
487 case SSL_RSA:
488 case SSL_DH_DSS:
489 case SSL_DH_DSS_EXPORT:
490 case SSL_DH_RSA:
491 case SSL_DH_RSA_EXPORT:
492 case SSL_RSA_EXPORT:
493 case SSL_DHE_DSS:
494 case SSL_DHE_DSS_EXPORT:
495 case SSL_DHE_RSA:
496 case SSL_DHE_RSA_EXPORT:
497 case SSL_Fortezza:
498 SSLChangeHdskState(ctx, SSL_HdskStateCert);
499 break;
500 default:
501 assert("Unknown key exchange method");
502 break;
503 }
504 break;
505 case SSL_HdskCert:
506 if (ctx->state == SSL_HdskStateCert)
507 switch (ctx->selectedCipherSpec->keyExchangeMethod)
508 { case SSL_RSA:
509 /*
510 * I really think the two RSA cases should be
511 * handled the same here - the server key exchange is
512 * optional, and is up to the server.
513 * Note this isn't the same as SSL_SERVER_KEYEXCH_HACK;
514 * we're a client here.
515 */
516 case SSL_RSA_EXPORT:
517 case SSL_DH_DSS:
518 case SSL_DH_DSS_EXPORT:
519 case SSL_DH_RSA:
520 case SSL_DH_RSA_EXPORT:
521 SSLChangeHdskState(ctx, SSL_HdskStateHelloDone);
522 break;
523 case SSL_DHE_DSS:
524 case SSL_DHE_DSS_EXPORT:
525 case SSL_DHE_RSA:
526 case SSL_DHE_RSA_EXPORT:
527 case SSL_Fortezza:
528 SSLChangeHdskState(ctx, SSL_HdskStateKeyExchange);
529 break;
530 default:
531 assert("Unknown or unexpected key exchange method");
532 break;
533 }
534 else if (ctx->state == SSL_HdskStateClientCert)
535 { SSLChangeHdskState(ctx, SSL_HdskStateClientKeyExchange);
536 if (ctx->peerCert != 0)
537 ctx->certReceived = 1;
538 }
539 break;
540 case SSL_HdskCertRequest:
541 /* state stays in SSL_HdskStateHelloDone; distinction is in
542 * ctx->certRequested */
543 if (ctx->peerCert == 0)
544 { SSLFatalSessionAlert(SSL_AlertHandshakeFail, ctx);
545 return errSSLProtocol;
546 }
547 ctx->certRequested = 1;
548 ctx->clientCertState = kSSLClientCertRequested;
549 break;
550 case SSL_HdskServerKeyExchange:
551 SSLChangeHdskState(ctx, SSL_HdskStateHelloDone);
552 break;
553 case SSL_HdskServerHelloDone:
554 if (ctx->certRequested) {
555 /*
556 * Server wants a client authentication cert - do
557 * we have one?
558 */
559 if (ctx->localCert != 0 && ctx->x509Requested) {
560 if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificate,
561 ctx)) != 0) {
562 return err;
563 }
564 }
565 else {
566 /* response for no cert depends on protocol version */
567 if(ctx->negProtocolVersion == TLS_Version_1_0) {
568 /* TLS: send empty cert msg */
569 if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificate,
570 ctx)) != 0) {
571 return err;
572 }
573 }
574 else {
575 /* SSL3: "no cert" alert */
576 if ((err = SSLSendAlert(SSL_AlertLevelWarning, SSL_AlertNoCert,
577 ctx)) != 0) {
578 return err;
579 }
580 }
581 } /* no cert to send */
582 } /* server requested a cert */
583 if ((err = SSLPrepareAndQueueMessage(SSLEncodeKeyExchange, ctx)) != 0)
584 return err;
585 assert(ctx->sslTslCalls != NULL);
586 if ((err = ctx->sslTslCalls->generateMasterSecret(ctx)) != 0 ||
587 (err = SSLInitPendingCiphers(ctx)) != 0)
588 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
589 return err;
590 }
591 memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
592 if ((err = SSLFreeBuffer(ctx->preMasterSecret, ctx)) != 0) {
593 return err;
594 }
595 if (ctx->certSent) {
596 if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificateVerify,
597 ctx)) != 0) {
598 return err;
599 }
600 }
601 if ((err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec,
602 ctx)) != 0) {
603 return err;
604 }
605 /* Install new cipher spec on write side */
606 if ((err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
607 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
608 return err;
609 }
610 ctx->writeCipher = ctx->writePending;
611 /* Can't send data until Finished is sent */
612 ctx->writeCipher.ready = 0;
613
614 /* Zero out old data */
615 memset(&ctx->writePending, 0, sizeof(CipherContext));
616 ctx->writePending.encrypting = 1;
617 if ((err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
618 return err;
619 /* Finished has been sent; enable data transfer on write channel */
620 ctx->writeCipher.ready = 1;
621 SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
622 break;
623 case SSL_HdskCertVerify:
624 SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
625 break;
626 case SSL_HdskClientKeyExchange:
627 assert(ctx->sslTslCalls != NULL);
628 if ((err = ctx->sslTslCalls->generateMasterSecret(ctx)) != 0 ||
629 (err = SSLInitPendingCiphers(ctx)) != 0)
630 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
631 return err;
632 }
633 memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
634 if ((err = SSLFreeBuffer(ctx->preMasterSecret, ctx)) != 0)
635 return err;
636 if (ctx->certReceived) {
637 SSLChangeHdskState(ctx, SSL_HdskStateClientCertVerify);
638 }
639 else {
640 SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
641 }
642 break;
643 case SSL_HdskFinished:
644 /* Handshake is over; enable data transfer on read channel */
645 ctx->readCipher.ready = 1;
646 /* If writePending is set, we haven't yet sent a finished message;
647 * send it */
648 if (ctx->writePending.ready != 0)
649 { if ((err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec,
650 ctx)) != 0)
651 return err;
652
653 /* Install new cipher spec on write side */
654 if ((err = SSLDisposeCipherSuite(&ctx->writeCipher, ctx)) != 0)
655 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
656 return err;
657 }
658 ctx->writeCipher = ctx->writePending;
659 ctx->writeCipher.ready = 0;
660 /* Can't send data until Finished is sent */
661 memset(&ctx->writePending, 0, sizeof(CipherContext));
662 /* Zero out old data */
663 if ((err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage,
664 ctx)) != 0)
665 return err;
666 ctx->writeCipher.ready = 1;
667 }
668 if (ctx->protocolSide == SSL_ServerSide) {
669 SSLChangeHdskState(ctx, SSL_HdskStateServerReady);
670 }
671 else {
672 SSLChangeHdskState(ctx, SSL_HdskStateClientReady);
673 }
674 if (ctx->peerID.data != 0)
675 SSLAddSessionData(ctx);
676 break;
677 default:
678 assert("Unknown State");
679 break;
680 }
681
682 return noErr;
683 }
684
685 OSStatus
686 SSLPrepareAndQueueMessage(EncodeMessageFunc msgFunc, SSLContext *ctx)
687 { OSStatus err;
688 SSLRecord rec;
689
690 if ((err = msgFunc(rec, ctx)) != 0)
691 { SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
692 goto fail;
693 }
694
695 if (rec.contentType == SSL_RecordTypeHandshake)
696 { if ((err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
697 (err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
698 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
699 goto fail;
700 }
701 SSLLogHdskMsg((SSLHandshakeType)rec.contents.data[0], 1);
702 }
703
704 assert(ctx->sslTslCalls != NULL);
705 if ((err = ctx->sslTslCalls->writeRecord(rec, ctx)) != 0)
706 goto fail;
707
708 err = noErr;
709 fail:
710 SSLFreeBuffer(rec.contents, ctx);
711
712 return err;
713 }
714
715 OSStatus
716 SSL3ReceiveSSL2ClientHello(SSLRecord rec, SSLContext *ctx)
717 { OSStatus err;
718
719 if ((err = SSLInitMessageHashes(ctx)) != 0)
720 return err;
721
722 if ((err = SSLHashSHA1.update(ctx->shaState, rec.contents)) != 0 ||
723 (err = SSLHashMD5.update(ctx->md5State, rec.contents)) != 0)
724 { SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
725 return err;
726 }
727
728 if ((err = SSLAdvanceHandshake(SSL_HdskClientHello, ctx)) != 0)
729 return err;
730
731 return noErr;
732 }
733
734 /* log changes in handshake state */
735 #ifndef NDEBUG
736 #include <stdio.h>
737
738 char *hdskStateToStr(SSLHandshakeState state)
739 {
740 static char badStr[100];
741
742 switch(state) {
743 case SSL_HdskStateUninit:
744 return "Uninit";
745 case SSL_HdskStateServerUninit:
746 return "ServerUninit";
747 case SSL_HdskStateClientUninit:
748 return "ClientUninit";
749 case SSL_HdskStateGracefulClose:
750 return "GracefulClose";
751 case SSL_HdskStateErrorClose:
752 return "ErrorClose";
753 case SSL_HdskStateNoNotifyClose:
754 return "NoNotifyClose";
755 case SSL_HdskStateServerHello:
756 return "ServerHello";
757 case SSL_HdskStateServerHelloUnknownVersion:
758 return "ServerHelloUnknownVersion";
759 case SSL_HdskStateKeyExchange:
760 return "KeyExchange";
761 case SSL_HdskStateCert:
762 return "Cert";
763 case SSL_HdskStateHelloDone:
764 return "HelloDone";
765 case SSL_HdskStateClientCert:
766 return "ClientCert";
767 case SSL_HdskStateClientKeyExchange:
768 return "ClientKeyExchange";
769 case SSL_HdskStateClientCertVerify:
770 return "ClientCertVerify";
771 case SSL_HdskStateChangeCipherSpec:
772 return "ChangeCipherSpec";
773 case SSL_HdskStateFinished:
774 return "Finished";
775 case SSL2_HdskStateClientMasterKey:
776 return "SSL2_ClientMasterKey";
777 case SSL2_HdskStateClientFinished:
778 return "SSL2_ClientFinished";
779 case SSL2_HdskStateServerHello:
780 return "SSL2_ServerHello";
781 case SSL2_HdskStateServerVerify:
782 return "SSL2_ServerVerify";
783 case SSL2_HdskStateServerFinished:
784 return "SSL2_ServerFinished";
785 case SSL_HdskStateServerReady:
786 return "SSL_ServerReady";
787 case SSL_HdskStateClientReady:
788 return "SSL_ClientReady";
789 default:
790 sprintf(badStr, "Unknown state (%d(d)", state);
791 return badStr;
792 }
793 }
794
795 void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState)
796 {
797 /* FIXME - this ifndef should not be necessary */
798 #ifndef NDEBUG
799 sslHdskStateDebug("...hdskState = %s", hdskStateToStr(newState));
800 #endif
801 ctx->state = newState;
802 }
803
804
805 /* log handshake messages */
806
807 static char *hdskMsgToStr(SSLHandshakeType msg)
808 {
809 static char badStr[100];
810
811 switch(msg) {
812 case SSL_HdskHelloRequest:
813 return "SSL_HdskHelloRequest";
814 case SSL_HdskClientHello:
815 return "SSL_HdskClientHello";
816 case SSL_HdskServerHello:
817 return "SSL_HdskServerHello";
818 case SSL_HdskCert:
819 return "SSL_HdskCert";
820 case SSL_HdskServerKeyExchange:
821 return "SSL_HdskServerKeyExchange";
822 case SSL_HdskCertRequest:
823 return "SSL_HdskCertRequest";
824 case SSL_HdskServerHelloDone:
825 return "SSL_HdskServerHelloDone";
826 case SSL_HdskCertVerify:
827 return "SSL_HdskCertVerify";
828 case SSL_HdskClientKeyExchange:
829 return "SSL_HdskClientKeyExchange";
830 case SSL_HdskFinished:
831 return "SSL_HdskFinished";
832 case SSL_HdskNoCertAlert:
833 return "SSL_HdskNoCertAlert";
834 default:
835 sprintf(badStr, "Unknown state (%d(d)", msg);
836 return badStr;
837 }
838 }
839
840 void SSLLogHdskMsg(SSLHandshakeType msg, char sent)
841 {
842 sslHdskMsgDebug("---%s handshake msg %s",
843 hdskMsgToStr(msg), (sent ? "sent" : "recv"));
844 }
845
846 #endif /* NDEBUG */
847