2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 File: sslHandshake.cpp
22 Contains: SSL 3.0 handshake state machine.
24 Written by: Doug Mitchell
26 Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved.
30 #include "sslContext.h"
31 #include "sslHandshake.h"
32 #include "sslMemory.h"
33 #include "sslAlertMessage.h"
34 #include "sslSession.h"
37 #include "appleCdsa.h"
38 #include "sslDigests.h"
43 #define REQUEST_CERT_CORRECT 0
45 static OSStatus
SSLProcessHandshakeMessage(SSLHandshakeMsg message
, SSLContext
*ctx
);
48 SSLProcessHandshakeRecord(SSLRecord rec
, SSLContext
*ctx
)
52 SSLHandshakeMsg message
;
53 SSLBuffer messageData
;
55 if (ctx
->fragmentedMessageCache
.data
!= 0)
56 { if ((err
= SSLReallocBuffer(ctx
->fragmentedMessageCache
,
57 ctx
->fragmentedMessageCache
.length
+ rec
.contents
.length
,
59 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
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
;
68 { remaining
= rec
.contents
.length
;
69 p
= rec
.contents
.data
;
74 break; /* we must have at least a header */
77 message
.type
= (SSLHandshakeType
)*p
++;
78 message
.contents
.length
= SSLDecodeInt(p
, 3);
79 if (((int)(message
.contents
.length
+ 4)) > remaining
)
83 message
.contents
.data
= p
;
84 p
+= message
.contents
.length
;
85 messageData
.length
= 4 + message
.contents
.length
;
86 assert(p
== messageData
.data
+ messageData
.length
);
88 /* message fragmentation */
89 remaining
-= messageData
.length
;
90 if ((err
= SSLProcessHandshakeMessage(message
, ctx
)) != 0)
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
);
101 if ((err
= SSLAdvanceHandshake(message
.type
, ctx
)) != 0)
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
);
113 if (p
!= ctx
->fragmentedMessageCache
.data
)
114 { memcpy(ctx
->fragmentedMessageCache
.data
, p
, remaining
);
115 ctx
->fragmentedMessageCache
.length
= remaining
;
118 else if (ctx
->fragmentedMessageCache
.data
!= 0)
119 { if ((err
= SSLFreeBuffer(ctx
->fragmentedMessageCache
, ctx
)) != 0)
120 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
129 SSLProcessHandshakeMessage(SSLHandshakeMsg message
, SSLContext
*ctx
)
133 SSLLogHdskMsg(message
.type
, 0);
134 switch (message
.type
)
135 { case SSL_HdskHelloRequest
:
136 if (ctx
->protocolSide
!= SSL_ClientSide
)
138 if (message
.contents
.length
> 0)
139 err
= errSSLProtocol
;
141 case SSL_HdskClientHello
:
142 if (ctx
->state
!= SSL_HdskStateServerUninit
)
144 err
= SSLProcessClientHello(message
.contents
, ctx
);
146 case SSL_HdskServerHello
:
147 if (ctx
->state
!= SSL_HdskStateServerHello
&&
148 ctx
->state
!= SSL_HdskStateServerHelloUnknownVersion
)
150 err
= SSLProcessServerHello(message
.contents
, ctx
);
153 if (ctx
->state
!= SSL_HdskStateCert
&&
154 ctx
->state
!= SSL_HdskStateClientCert
)
156 err
= SSLProcessCertificate(message
.contents
, ctx
);
157 if(ctx
->protocolSide
== SSL_ServerSide
) {
160 * Error could be from no cert (when we require one)
163 if(ctx
->peerCert
!= NULL
) {
164 ctx
->clientCertState
= kSSLClientCertRejected
;
167 else if(ctx
->peerCert
!= NULL
) {
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
174 ctx
->clientCertState
= kSSLClientCertSent
;
178 case SSL_HdskCertRequest
:
179 if (((ctx
->state
!= SSL_HdskStateHelloDone
) &&
180 (ctx
->state
!= SSL_HdskStateKeyExchange
))
181 || ctx
->certRequested
)
183 err
= SSLProcessCertificateRequest(message
.contents
, ctx
);
185 case SSL_HdskServerKeyExchange
:
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...
192 case SSL_HdskStateKeyExchange
: /* explicitly waiting for this */
193 case SSL_HdskStateHelloDone
:
198 err
= SSLProcessServerKeyExchange(message
.contents
, ctx
);
200 case SSL_HdskServerHelloDone
:
201 if (ctx
->state
!= SSL_HdskStateHelloDone
)
203 err
= SSLProcessServerHelloDone(message
.contents
, ctx
);
205 case SSL_HdskCertVerify
:
206 if (ctx
->state
!= SSL_HdskStateClientCertVerify
)
208 err
= SSLProcessCertificateVerify(message
.contents
, ctx
);
209 assert(ctx
->protocolSide
== SSL_ServerSide
);
211 ctx
->clientCertState
= kSSLClientCertRejected
;
214 case SSL_HdskClientKeyExchange
:
215 if (ctx
->state
!= SSL_HdskStateClientKeyExchange
)
217 err
= SSLProcessKeyExchange(message
.contents
, ctx
);
219 case SSL_HdskFinished
:
220 if (ctx
->state
!= SSL_HdskStateFinished
)
222 err
= SSLProcessFinished(message
.contents
, ctx
);
229 if (err
&& !ctx
->sentFatalAlert
)
230 { if (err
== errSSLProtocol
)
231 SSLFatalSessionAlert(SSL_AlertIllegalParam
, ctx
);
232 else if (err
== errSSLNegotiation
)
233 SSLFatalSessionAlert(SSL_AlertHandshakeFail
, ctx
);
235 SSLFatalSessionAlert(SSL_AlertCloseNotify
, ctx
);
240 SSLFatalSessionAlert(SSL_AlertUnexpectedMsg
, ctx
);
241 return errSSLProtocol
;
245 SSLAdvanceHandshake(SSLHandshakeType processed
, SSLContext
*ctx
)
247 SSLBuffer sessionIdentifier
;
250 { case SSL_HdskHelloRequest
:
252 * Reset the client auth state machine in case this is
255 ctx
->certRequested
= 0;
257 ctx
->certReceived
= 0;
258 ctx
->x509Requested
= 0;
259 ctx
->clientCertState
= kSSLClientCertNone
;
260 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeClientHello
, ctx
)) != 0)
262 SSLChangeHdskState(ctx
, SSL_HdskStateServerHello
);
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)
271 SSLProtocolVersion sessionProt
;
272 if ((err
= SSLRetrieveSessionID(ctx
->resumableSession
,
273 &sessionIdentifier
, ctx
)) != 0)
275 if ((err
= SSLRetrieveSessionProtocolVersion(ctx
->resumableSession
,
276 &sessionProt
, ctx
)) != 0)
277 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
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
,
288 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
291 ctx
->sessionMatch
= 1;
292 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeServerHello
,
295 if ((err
= SSLInitPendingCiphers(ctx
)) != 0 ||
296 (err
= SSLFreeBuffer(sessionIdentifier
, ctx
)) != 0)
297 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
301 SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec
,
304 /* Install new cipher spec on write side */
305 if ((err
= SSLDisposeCipherSuite(&ctx
->writeCipher
,
307 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
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
,
318 /* Finished has been sent; enable data t6ransfer on
320 ctx
->writeCipher
.ready
= 1;
321 SSLChangeHdskState(ctx
, SSL_HdskStateChangeCipherSpec
);
325 sslLogResumSessDebug(
326 "===FAILED TO RESUME SSL3 server-side session");
328 if ((err
= SSLFreeBuffer(sessionIdentifier
, ctx
)) != 0 ||
329 (err
= SSLDeleteSessionData(ctx
)) != 0)
330 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
334 if ((err
= SSLFreeBuffer(ctx
->sessionID
, ctx
)) != 0)
335 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
341 * If we get here, we're not resuming; generate a new session ID
342 * if we know our peer
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
);
350 if((err
= sslRand(ctx
, &ctx
->sessionID
)) != 0)
351 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
357 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeServerHello
, ctx
)) != 0)
359 switch (ctx
->selectedCipherSpec
->keyExchangeMethod
)
360 { case SSL_NULL_auth
:
363 case SSL_DH_anon_EXPORT
:
364 if(ctx
->clientAuth
== kAlwaysAuthenticate
) {
365 /* app requires this; abort */
366 SSLFatalSessionAlert(SSL_AlertHandshakeFail
, ctx
);
367 return errSSLNegotiation
;
369 ctx
->tryClientAuth
= false;
370 /* DH server side needs work */
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
;
380 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeCertificate
,
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.
393 bool doServerKeyExch
= false;
394 switch(ctx
->selectedCipherSpec
->keyExchangeMethod
) {
396 #if !SSL_SERVER_KEYEXCH_HACK
397 /* the "proper" way - app decides. */
400 if(ctx
->encryptPrivKeyRef
!= NULL
) {
401 doServerKeyExch
= true;
405 case SSL_DH_anon_EXPORT
:
407 case SSL_DHE_RSA_EXPORT
:
409 case SSL_DHE_DSS_EXPORT
:
410 doServerKeyExch
= true;
415 if(doServerKeyExch
) {
416 err
= SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange
, ctx
);
422 if (ctx
->tryClientAuth
)
423 { if ((err
= SSLPrepareAndQueueMessage(SSLEncodeCertificateRequest
,
426 ctx
->certRequested
= 1;
427 ctx
->clientCertState
= kSSLClientCertRequested
;
429 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeServerHelloDone
, ctx
)) != 0)
431 if (ctx
->certRequested
) {
432 SSLChangeHdskState(ctx
, SSL_HdskStateClientCert
);
435 SSLChangeHdskState(ctx
, SSL_HdskStateClientKeyExchange
);
438 case SSL_HdskServerHello
:
439 ctx
->sessionMatch
= 0;
440 if (ctx
->resumableSession
.data
!= 0 && ctx
->sessionID
.data
!= 0)
442 SSLProtocolVersion sessionProt
;
443 if ((err
= SSLRetrieveSessionID(ctx
->resumableSession
,
444 &sessionIdentifier
, ctx
)) != 0)
445 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
448 if ((err
= SSLRetrieveSessionProtocolVersion(ctx
->resumableSession
,
449 &sessionProt
, ctx
)) != 0)
450 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
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
,
461 (err
= SSLInitPendingCiphers(ctx
)) != 0 ||
462 (err
= SSLFreeBuffer(sessionIdentifier
, ctx
)) != 0)
463 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
466 ctx
->sessionMatch
= 1;
467 SSLChangeHdskState(ctx
, SSL_HdskStateChangeCipherSpec
);
471 sslLogResumSessDebug("===FAILED TO RESUME SSL3 client-side "
474 if ((err
= SSLFreeBuffer(sessionIdentifier
, ctx
)) != 0)
475 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
479 switch (ctx
->selectedCipherSpec
->keyExchangeMethod
)
481 /* these require a key exchange message */
484 case SSL_DH_anon_EXPORT
:
485 SSLChangeHdskState(ctx
, SSL_HdskStateKeyExchange
);
489 case SSL_DH_DSS_EXPORT
:
491 case SSL_DH_RSA_EXPORT
:
494 case SSL_DHE_DSS_EXPORT
:
496 case SSL_DHE_RSA_EXPORT
:
498 SSLChangeHdskState(ctx
, SSL_HdskStateCert
);
501 assert("Unknown key exchange method");
506 if (ctx
->state
== SSL_HdskStateCert
)
507 switch (ctx
->selectedCipherSpec
->keyExchangeMethod
)
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.
518 case SSL_DH_DSS_EXPORT
:
520 case SSL_DH_RSA_EXPORT
:
521 SSLChangeHdskState(ctx
, SSL_HdskStateHelloDone
);
524 case SSL_DHE_DSS_EXPORT
:
526 case SSL_DHE_RSA_EXPORT
:
528 SSLChangeHdskState(ctx
, SSL_HdskStateKeyExchange
);
531 assert("Unknown or unexpected key exchange method");
534 else if (ctx
->state
== SSL_HdskStateClientCert
)
535 { SSLChangeHdskState(ctx
, SSL_HdskStateClientKeyExchange
);
536 if (ctx
->peerCert
!= 0)
537 ctx
->certReceived
= 1;
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
;
547 ctx
->certRequested
= 1;
548 ctx
->clientCertState
= kSSLClientCertRequested
;
550 case SSL_HdskServerKeyExchange
:
551 SSLChangeHdskState(ctx
, SSL_HdskStateHelloDone
);
553 case SSL_HdskServerHelloDone
:
554 if (ctx
->certRequested
) {
556 * Server wants a client authentication cert - do
559 if (ctx
->localCert
!= 0 && ctx
->x509Requested
) {
560 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeCertificate
,
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
,
575 /* SSL3: "no cert" alert */
576 if ((err
= SSLSendAlert(SSL_AlertLevelWarning
, SSL_AlertNoCert
,
581 } /* no cert to send */
582 } /* server requested a cert */
583 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeKeyExchange
, ctx
)) != 0)
585 assert(ctx
->sslTslCalls
!= NULL
);
586 if ((err
= ctx
->sslTslCalls
->generateMasterSecret(ctx
)) != 0 ||
587 (err
= SSLInitPendingCiphers(ctx
)) != 0)
588 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
591 memset(ctx
->preMasterSecret
.data
, 0, ctx
->preMasterSecret
.length
);
592 if ((err
= SSLFreeBuffer(ctx
->preMasterSecret
, ctx
)) != 0) {
596 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeCertificateVerify
,
601 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec
,
605 /* Install new cipher spec on write side */
606 if ((err
= SSLDisposeCipherSuite(&ctx
->writeCipher
, ctx
)) != 0)
607 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
610 ctx
->writeCipher
= ctx
->writePending
;
611 /* Can't send data until Finished is sent */
612 ctx
->writeCipher
.ready
= 0;
614 /* Zero out old data */
615 memset(&ctx
->writePending
, 0, sizeof(CipherContext
));
616 ctx
->writePending
.encrypting
= 1;
617 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage
, ctx
)) != 0)
619 /* Finished has been sent; enable data transfer on write channel */
620 ctx
->writeCipher
.ready
= 1;
621 SSLChangeHdskState(ctx
, SSL_HdskStateChangeCipherSpec
);
623 case SSL_HdskCertVerify
:
624 SSLChangeHdskState(ctx
, SSL_HdskStateChangeCipherSpec
);
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
);
633 memset(ctx
->preMasterSecret
.data
, 0, ctx
->preMasterSecret
.length
);
634 if ((err
= SSLFreeBuffer(ctx
->preMasterSecret
, ctx
)) != 0)
636 if (ctx
->certReceived
) {
637 SSLChangeHdskState(ctx
, SSL_HdskStateClientCertVerify
);
640 SSLChangeHdskState(ctx
, SSL_HdskStateChangeCipherSpec
);
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;
648 if (ctx
->writePending
.ready
!= 0)
649 { if ((err
= SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec
,
653 /* Install new cipher spec on write side */
654 if ((err
= SSLDisposeCipherSuite(&ctx
->writeCipher
, ctx
)) != 0)
655 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
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
,
666 ctx
->writeCipher
.ready
= 1;
668 if (ctx
->protocolSide
== SSL_ServerSide
) {
669 SSLChangeHdskState(ctx
, SSL_HdskStateServerReady
);
672 SSLChangeHdskState(ctx
, SSL_HdskStateClientReady
);
674 if (ctx
->peerID
.data
!= 0)
675 SSLAddSessionData(ctx
);
678 assert("Unknown State");
686 SSLPrepareAndQueueMessage(EncodeMessageFunc msgFunc
, SSLContext
*ctx
)
690 if ((err
= msgFunc(rec
, ctx
)) != 0)
691 { SSLFatalSessionAlert(SSL_AlertCloseNotify
, ctx
);
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
);
701 SSLLogHdskMsg((SSLHandshakeType
)rec
.contents
.data
[0], 1);
704 assert(ctx
->sslTslCalls
!= NULL
);
705 if ((err
= ctx
->sslTslCalls
->writeRecord(rec
, ctx
)) != 0)
710 SSLFreeBuffer(rec
.contents
, ctx
);
716 SSL3ReceiveSSL2ClientHello(SSLRecord rec
, SSLContext
*ctx
)
719 if ((err
= SSLInitMessageHashes(ctx
)) != 0)
722 if ((err
= SSLHashSHA1
.update(ctx
->shaState
, rec
.contents
)) != 0 ||
723 (err
= SSLHashMD5
.update(ctx
->md5State
, rec
.contents
)) != 0)
724 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
728 if ((err
= SSLAdvanceHandshake(SSL_HdskClientHello
, ctx
)) != 0)
734 /* log changes in handshake state */
738 char *hdskStateToStr(SSLHandshakeState state
)
740 static char badStr
[100];
743 case SSL_HdskStateUninit
:
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
:
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
:
763 case SSL_HdskStateHelloDone
:
765 case SSL_HdskStateClientCert
:
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
:
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";
790 sprintf(badStr
, "Unknown state (%d(d)", state
);
795 void SSLChangeHdskState(SSLContext
*ctx
, SSLHandshakeState newState
)
797 /* FIXME - this ifndef should not be necessary */
799 sslHdskStateDebug("...hdskState = %s", hdskStateToStr(newState
));
801 ctx
->state
= newState
;
805 /* log handshake messages */
807 static char *hdskMsgToStr(SSLHandshakeType msg
)
809 static char badStr
[100];
812 case SSL_HdskHelloRequest
:
813 return "SSL_HdskHelloRequest";
814 case SSL_HdskClientHello
:
815 return "SSL_HdskClientHello";
816 case SSL_HdskServerHello
:
817 return "SSL_HdskServerHello";
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";
835 sprintf(badStr
, "Unknown state (%d(d)", msg
);
840 void SSLLogHdskMsg(SSLHandshakeType msg
, char sent
)
842 sslHdskMsgDebug("---%s handshake msg %s",
843 hdskMsgToStr(msg
), (sent
? "sent" : "recv"));