1/*
2 * Copyright (c) 1999-2001,2005-2012 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25/*
26 * sslHandshake.c - SSL 3.0 handshake state machine.
27 */
28
29#include "sslContext.h"
30#include "sslHandshake.h"
31#include "sslMemory.h"
32#include "sslAlertMessage.h"
33#include "sslSession.h"
34#include "sslUtils.h"
35#include "sslDebug.h"
36#include "sslCrypto.h"
37#include "sslRand.h"
38#include "sslDigests.h"
39#include "sslCipherSpecs.h"
40#include "cipherSpecs.h"
41
42#include <utilities/SecIOFormat.h>
43
44#include <AssertMacros.h>
45#include <string.h>
46#include <assert.h>
47#include <inttypes.h>
48
49#define REQUEST_CERT_CORRECT        0
50
51#if __LP64__
52#define PRIstatus "d"
53#else
54#define PRIstatus "ld"
55#endif
56
57
58uint8_t *
59SSLEncodeHandshakeHeader(SSLContext *ctx, SSLRecord *rec, SSLHandshakeType type, size_t msglen)
60{
61    uint8_t *charPtr;
62
63    charPtr = rec->contents.data;
64    *charPtr++ = type;
65    charPtr = SSLEncodeSize(charPtr, msglen, 3);
66
67    if(rec->protocolVersion == DTLS_Version_1_0) {
68        charPtr = SSLEncodeInt(charPtr, ctx->hdskMessageSeq, 2);
69        /* fragmentation -- we encode header as if unfragmented,
70         actual fragmentation happens at lower layer. */
71        charPtr = SSLEncodeInt(charPtr, 0, 3);
72        charPtr = SSLEncodeSize(charPtr, msglen, 3);
73    }
74
75    return charPtr;
76}
77
78static OSStatus SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx);
79
80static OSStatus
81SSLUpdateHandshakeMacs(const SSLBuffer *messageData, SSLContext *ctx)
82{
83    OSStatus err = errSSLInternal;
84    bool do_md5 = false;
85    bool do_sha1 = false;
86    bool do_sha256 = false;
87    bool do_sha384 = false;
88
89    //TODO: We can stop updating the unecessary hashes once the CertVerify message is processed in case where we do Client Side Auth, or .
90
91    if(ctx->negProtocolVersion == SSL_Version_Undetermined)
92    {
93        // we dont know yet, so we might need MD5 & SHA1 - Server should always call in with known protocol version.
94        assert(ctx->protocolSide==kSSLClientSide);
95        do_md5 = do_sha1 = true;
96        if(ctx->isDTLS
97           ? ctx->maxProtocolVersion < DTLS_Version_1_0
98           : ctx->maxProtocolVersion >= TLS_Version_1_2)
99        {
100            // We wil need those too, unless we are sure we wont end up doing TLS 1.2
101            do_sha256 = do_sha384 = true;
102        }
103    } else {
104        // we know which version we use at this point
105        if(sslVersionIsLikeTls12(ctx)) {
106            do_sha1 = do_sha256 = do_sha384 = true;
107        } else {
108            do_md5 = do_sha1 = true;
109        }
110    }
111
112    if (do_md5 &&
113        (err = SSLHashMD5.update(&ctx->md5State, messageData)) != 0)
114        goto done;
115    if (do_sha1 &&
116        (err = SSLHashSHA1.update(&ctx->shaState, messageData)) != 0)
117        goto done;
118    if (do_sha256 &&
119        (err = SSLHashSHA256.update(&ctx->sha256State, messageData)) != 0)
120        goto done;
121    if (do_sha384 &&
122        (err = SSLHashSHA384.update(&ctx->sha512State, messageData)) != 0)
123        goto done;
124
125    sslLogNegotiateDebug("%s protocol: %02X max: %02X cipher: %02X%s%s%s%s",
126                         ctx->protocolSide == kSSLClientSide ? "client" : "server",
127                         ctx->negProtocolVersion,
128                         ctx->maxProtocolVersion,
129                         ctx->selectedCipher,
130                         do_md5 ? " md5" : "",
131                         do_sha1 ? " sha1" : "",
132                         do_sha256 ? " sha256" : "",
133                         do_sha384 ? " sha384" : "");
134done:
135    return err;
136}
137
138OSStatus
139SSLProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
140{   OSStatus        err;
141    size_t          remaining;
142    UInt8           *p;
143	UInt8			*startingP;		// top of record we're parsing
144    SSLHandshakeMsg message = {};
145    SSLBuffer       messageData;
146
147    if (ctx->fragmentedMessageCache.data != 0)
148    {
149		size_t origLen = ctx->fragmentedMessageCache.length;
150		if ((err = SSLReallocBuffer(&ctx->fragmentedMessageCache,
151                    ctx->fragmentedMessageCache.length + rec.contents.length)) != 0)
152        {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
153            return err;
154        }
155        memcpy(ctx->fragmentedMessageCache.data + origLen,
156            rec.contents.data, rec.contents.length);
157        remaining = ctx->fragmentedMessageCache.length;
158        p = ctx->fragmentedMessageCache.data;
159    }
160    else
161    {   remaining = rec.contents.length;
162        p = rec.contents.data;
163    }
164	startingP = p;
165
166    size_t head = 4;
167
168    while (remaining > 0)
169    {
170        if (remaining < head)
171            break;  /* we must have at least a header */
172
173        messageData.data = p;
174        message.type = (SSLHandshakeType)*p++;
175        message.contents.length = SSLDecodeSize(p, 3);
176
177
178        p += 3;
179
180        if ((message.contents.length + head) > remaining)
181            break;
182
183        message.contents.data = p;
184        p += message.contents.length;
185        messageData.length = head + message.contents.length;
186        assert(p == messageData.data + messageData.length);
187
188        /* message fragmentation */
189        remaining -= messageData.length;
190        if ((err = SSLProcessHandshakeMessage(message, ctx)) != 0)
191            return err;
192
193        if (message.type != SSL_HdskHelloRequest)
194
195        {   if ((err = SSLUpdateHandshakeMacs(&messageData, ctx)) != 0)
196            {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
197                return err;
198            }
199        }
200
201        if ((err = SSLAdvanceHandshake(message.type, ctx)) != 0)
202            return err;
203    }
204
205    if (remaining > 0)      /* Fragmented handshake message */
206    {   /* If there isn't a cache, allocate one */
207        if (ctx->fragmentedMessageCache.data == 0)
208        {   if ((err = SSLAllocBuffer(&ctx->fragmentedMessageCache, remaining)))
209            {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
210                return err;
211            }
212        }
213        if (startingP != ctx->fragmentedMessageCache.data)
214        {   memcpy(ctx->fragmentedMessageCache.data, startingP, remaining);
215            ctx->fragmentedMessageCache.length = remaining;
216        }
217    }
218    else if (ctx->fragmentedMessageCache.data != 0)
219    {   if ((err = SSLFreeBuffer(&ctx->fragmentedMessageCache)))
220        {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
221            return err;
222        }
223    }
224
225    return errSecSuccess;
226}
227
228OSStatus
229DTLSProcessHandshakeRecord(SSLRecord rec, SSLContext *ctx)
230{   OSStatus        err = errSecParam;
231    size_t          remaining;
232    UInt8           *p;
233	UInt8			*startingP;		// top of record we're parsing
234
235    const UInt32 head = 12;
236
237    assert(ctx->isDTLS);
238
239    remaining = rec.contents.length;
240    p = rec.contents.data;
241	startingP = p;
242
243    while (remaining > 0)
244    {
245        UInt8 msgtype;
246        UInt32 msglen;
247        UInt32 msgseq;
248        UInt32 fraglen;
249        UInt32 fragofs;
250
251        if (remaining < head) {
252            /* flush it - record is too small */
253            sslErrorLog("DTLSProcessHandshakeRecord: remaining too small (%lu out of %lu)\n", remaining, rec.contents.length);
254            assert(0); // keep this assert until we find a test case that triggers it
255            err = errSSLProtocol;
256            goto flushit;
257        }
258
259        /* Thats the 12 bytes of header : */
260        msgtype = (SSLHandshakeType)*p++;
261        msglen = SSLDecodeInt(p, 3); p+=3;
262        msgseq = SSLDecodeInt(p, 2); p+=2;
263        fragofs = SSLDecodeInt(p, 3); p+=3;
264        fraglen = SSLDecodeInt(p, 3); p+=3;
265
266        remaining -= head;
267
268        SSLLogHdskMsg(msgtype, 0);
269        sslHdskMsgDebug("DTLS Hdsk Record: type=%u, len=%u, seq=%u (%u), f_ofs=%u, f_len=%u, remaining=%u",
270                             msgtype, (int)msglen, (int)msgseq, (int)ctx->hdskMessageSeqNext, (int)fragofs, (int)fraglen, (int)remaining);
271
272        if(
273           ((fraglen+fragofs) > msglen)
274           || (fraglen > remaining)
275           || (msgseq!=ctx->hdskMessageSeqNext)
276           || (fragofs!=ctx->hdskMessageCurrentOfs)
277           || (fragofs && (msgtype!=ctx->hdskMessageCurrent.type))
278           || (fragofs && (msglen != ctx->hdskMessageCurrent.contents.length))
279           )
280        {
281            sslErrorLog("DTLSProcessHandshakeRecord: wrong fragment\n");
282            // assert(0); // keep this assert until we find a test case that triggers it
283            // This is a recoverable error, we just drop this fragment.
284            // TODO: this should probably trigger a retransmit
285            err = errSecSuccess;
286            goto flushit;
287        }
288
289        /* First fragment - allocate */
290        if(fragofs==0) {
291            sslHdskMsgDebug("Allocating hdsk buf for msg type %d", msgtype);
292            assert(ctx->hdskMessageCurrent.contents.data==NULL);
293            assert(ctx->hdskMessageCurrent.contents.length==0);
294            if((err=SSLAllocBuffer(&(ctx->hdskMessageCurrent.contents), msglen))) {
295                SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
296                return err;
297            }
298            ctx->hdskMessageCurrent.type = msgtype;
299        }
300
301        /* We have the next fragment, lets save it */
302        memcpy(ctx->hdskMessageCurrent.contents.data + ctx->hdskMessageCurrentOfs, p, fraglen);
303        ctx->hdskMessageCurrentOfs+=fraglen;
304        p+=fraglen;
305        remaining-=fraglen;
306
307        /* This was the last fragment, lets process the message */
308        if(ctx->hdskMessageCurrentOfs == ctx->hdskMessageCurrent.contents.length) {
309            err = SSLProcessHandshakeMessage(ctx->hdskMessageCurrent, ctx);
310            if(err)
311                goto flushit;
312
313            if ((msgtype != SSL_HdskHelloRequest) && (msgtype != SSL_HdskHelloVerifyRequest))
314            {
315                /* We need to hash a fake header as if no fragmentation */
316                uint8_t pseudo_header[head];
317                SSLBuffer header;
318                header.data=pseudo_header;
319                header.length=head;
320
321                pseudo_header[0]=msgtype;
322                SSLEncodeInt(pseudo_header+1, msglen, 3);
323                SSLEncodeInt(pseudo_header+4, msgseq, 2);
324                SSLEncodeInt(pseudo_header+6, 0, 3);
325                SSLEncodeInt(pseudo_header+9, msglen, 3);
326
327                if ((err = SSLHashSHA1.update(&ctx->shaState, &header)) != 0 ||
328                    (err = SSLHashMD5.update(&ctx->md5State, &header)) != 0)
329                {
330                    SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
331                    goto flushit;
332                }
333
334                SSLBuffer *messageData=&ctx->hdskMessageCurrent.contents;
335                if ((err = SSLHashSHA1.update(&ctx->shaState, messageData)) != 0 ||
336                    (err = SSLHashMD5.update(&ctx->md5State, messageData)) != 0)
337                {
338                    SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
339                    goto flushit;
340                }
341
342                sslHdskMsgDebug("Hashing %d bytes of msg seq %d\n", (int)messageData->length, (int)msgseq);
343            }
344
345            sslHdskMsgDebug("processed message of type %d", msgtype);
346
347            if ((err = SSLAdvanceHandshake(msgtype, ctx)) != 0)
348            {
349                sslErrorLog("AdvanceHandshake error: %" PRIdOSStatus "\n", err);
350                goto flushit;
351            }
352
353            /* Free the buffer for current message, and reset offset */
354            SSLFreeBuffer(&(ctx->hdskMessageCurrent.contents));
355            ctx->hdskMessageCurrentOfs=0;
356
357            /* If we successfully processed a message, we wait for the next one */
358            ctx->hdskMessageSeqNext++;
359
360        }
361
362        sslHdskMsgDebug("remaining = %ld", remaining);
363    }
364
365    return errSecSuccess;
366
367flushit:
368    sslErrorLog("DTLSProcessHandshakeRecord: flusing record (err=%"PRIstatus")\n", err);
369
370    /* This will flush the current handshake message */
371    SSLFreeBuffer(&(ctx->hdskMessageCurrent.contents));
372    ctx->hdskMessageCurrentOfs=0;
373
374    return err;
375}
376
377OSStatus
378DTLSRetransmit(SSLContext *ctx)
379{
380    sslHdskMsgDebug("DTLSRetransmit in state %s. Last Sent = %d, Last Recv=%d, timeout=%f\n",
381                hdskStateToStr(ctx->state), ctx->hdskMessageSeq, ctx->hdskMessageSeqNext, ctx->timeout_duration);
382
383    /* Too many retransmits, just give up!! */
384    if(ctx->hdskMessageRetryCount>10)
385        return errSSLConnectionRefused;
386
387    /* go back to previous cipher if retransmitting a flight including changecipherspec */
388    if(ctx->messageQueueContainsChangeCipherSpec) {
389        OSStatus err;
390        err = ctx->recFuncs->rollbackWriteCipher(ctx->recCtx);
391        if(err)
392            return err;
393    }
394
395    /* set timeout deadline */
396    ctx->hdskMessageRetryCount++;
397    ctx->timeout_deadline = CFAbsoluteTimeGetCurrent()+((1<<ctx->hdskMessageRetryCount)*ctx->timeout_duration);
398
399    /* Lets resend the last flight */
400    return SSLSendFlight(ctx);
401}
402
403static OSStatus
404SSLProcessHandshakeMessage(SSLHandshakeMsg message, SSLContext *ctx)
405{   OSStatus      err;
406
407    err = errSecSuccess;
408    SSLLogHdskMsg(message.type, 0);
409    switch (message.type)
410    {   case SSL_HdskHelloRequest:
411            if (ctx->protocolSide != kSSLClientSide)
412                goto wrongMessage;
413            if (message.contents.length > 0)
414                err = errSSLProtocol;
415            break;
416        case SSL_HdskClientHello:
417            if (ctx->state != SSL_HdskStateServerUninit)
418                goto wrongMessage;
419            err = SSLProcessClientHello(message.contents, ctx);
420            break;
421        case SSL_HdskServerHello:
422            if (ctx->state != SSL_HdskStateServerHello)
423                goto wrongMessage;
424            err = SSLProcessServerHello(message.contents, ctx);
425            break;
426#if ENABLE_DTLS
427        case SSL_HdskHelloVerifyRequest:
428            if (ctx->protocolSide != kSSLClientSide)
429                goto wrongMessage;
430            if(ctx->state != SSL_HdskStateServerHello)
431                goto wrongMessage;
432            /* TODO: Do we need to check the client state here ? */
433            err = SSLProcessServerHelloVerifyRequest(message.contents, ctx);
434            break;
435#endif
436        case SSL_HdskCert:
437            if (ctx->state != SSL_HdskStateCert &&
438                ctx->state != SSL_HdskStateClientCert)
439                goto wrongMessage;
440			err = SSLProcessCertificate(message.contents, ctx);
441			/*
442			 * Note that cert evaluation can now be performed asynchronously,
443			 * so SSLProcessCertificate may return errSSLWouldBlock here.
444			 */
445            break;
446        case SSL_HdskCertRequest:
447            if (((ctx->state != SSL_HdskStateHelloDone) &&
448			     (ctx->state != SSL_HdskStateKeyExchange))
449                 || ctx->certRequested)
450                goto wrongMessage;
451            err = SSLProcessCertificateRequest(message.contents, ctx);
452            if (ctx->breakOnCertRequest)
453                ctx->signalCertRequest = true;
454            break;
455        case SSL_HdskServerKeyExchange:
456       		/*
457		 * Since this message is optional for some key exchange
458			 * mechanisms, and completely at the server's discretion,
459			 * we need to be able to handle this in one of two states...
460        	 */
461        	switch(ctx->state) {
462        		case SSL_HdskStateKeyExchange:	/* explicitly waiting for this */
463        		case SSL_HdskStateHelloDone:
464        			break;
465        		default:
466                	goto wrongMessage;
467        	}
468            err = SSLProcessServerKeyExchange(message.contents, ctx);
469            break;
470        case SSL_HdskServerHelloDone:
471            if (ctx->state != SSL_HdskStateHelloDone)
472                goto wrongMessage;
473            err = SSLProcessServerHelloDone(message.contents, ctx);
474            break;
475        case SSL_HdskCertVerify:
476            if (ctx->state != SSL_HdskStateClientCertVerify)
477                goto wrongMessage;
478            err = SSLProcessCertificateVerify(message.contents, ctx);
479			assert(ctx->protocolSide == kSSLServerSide);
480			if(err) {
481				ctx->clientCertState = kSSLClientCertRejected;
482			}
483            break;
484        case SSL_HdskClientKeyExchange:
485            if (ctx->state != SSL_HdskStateClientKeyExchange)
486                goto wrongMessage;
487            err = SSLProcessKeyExchange(message.contents, ctx);
488            break;
489        case SSL_HdskFinished:
490            if (ctx->state != SSL_HdskStateFinished)
491                goto wrongMessage;
492            err = SSLProcessFinished(message.contents, ctx);
493            break;
494        default:
495            goto wrongMessage;
496            break;
497    }
498
499    if (err && !ctx->sentFatalAlert)
500    {   if (err == errSSLProtocol)
501            SSLFatalSessionAlert(SSL_AlertIllegalParam, ctx);
502        else if (err == errSSLNegotiation)
503            SSLFatalSessionAlert(SSL_AlertHandshakeFail, ctx);
504        else if (err != errSSLWouldBlock &&
505				 err != errSSLServerAuthCompleted /* == errSSLClientAuthCompleted */ &&
506				 err != errSSLClientCertRequested)
507            SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
508    }
509    return err;
510
511wrongMessage:
512    SSLFatalSessionAlert(SSL_AlertUnexpectedMsg, ctx);
513    return errSSLProtocol;
514}
515
516/*
517 * Given a server-side SSLContext that's fully restored for a resumed session,
518 * queue up the remaining outgoing messages to finish the handshake.
519 */
520static OSStatus
521SSLResumeServerSide(
522	SSLContext *ctx)
523{
524	OSStatus err;
525	if ((err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
526		return err;
527	if ((err = SSLInitPendingCiphers(ctx)) != 0)
528	{   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
529		return err;
530	}
531	if ((err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec,
532				ctx)) != 0)
533		return err;
534
535	if ((err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage,
536			ctx)) != 0)
537		return err;
538
539	SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
540
541	return errSecSuccess;
542
543}
544
545OSStatus
546SSLAdvanceHandshake(SSLHandshakeType processed, SSLContext *ctx)
547{   OSStatus        err;
548    SSLBuffer       sessionIdentifier;
549
550    SSLResetFlight(ctx);
551
552    switch (processed)
553    {
554#if ENABLE_DTLS
555        case SSL_HdskHelloVerifyRequest:
556            /* Just fall through */
557#endif
558        case SSL_HdskHelloRequest:
559			/*
560			 * Reset the client auth state machine in case this is
561			 * a renegotiation.
562			 */
563			ctx->certRequested = 0;
564			ctx->certSent = 0;
565			ctx->certReceived = 0;
566			ctx->x509Requested = 0;
567			ctx->clientCertState = kSSLClientCertNone;
568			ctx->readCipher_ready = 0;
569			ctx->writeCipher_ready = 0;
570            if ((err = SSLPrepareAndQueueMessage(SSLEncodeClientHello, ctx)) != 0)
571                return err;
572            SSLChangeHdskState(ctx, SSL_HdskStateServerHello);
573            break;
574        case SSL_HdskClientHello:
575            assert(ctx->protocolSide == kSSLServerSide);
576			ctx->sessionMatch = 0;
577
578            if((ctx->negProtocolVersion==DTLS_Version_1_0) && (ctx->cookieVerified==false))
579            {   /* Send Hello Verify Request */
580                if((err=SSLPrepareAndQueueMessage(SSLEncodeServerHelloVerifyRequest, ctx)) !=0 )
581                    return err;
582                break;
583            }
584
585			#if 	SSL_PAC_SERVER_ENABLE
586			if((ctx->sessionTicket.data != NULL) &&
587			   (ctx->masterSecretCallback != NULL)) {
588				/*
589				 * Client sent us a session ticket and we know how to ask
590				 * the app for master secret. Go for it.
591				 */
592				size_t secretLen = SSL_MASTER_SECRET_SIZE;
593				sslEapDebug("Server side resuming based on masterSecretCallback");
594
595				/* the master secret callback requires serverRandom, now... */
596			    if ((err = SSLEncodeRandom(ctx->serverRandom, ctx)) != 0)
597       				 return err;
598				ctx->serverRandomValid = 1;
599
600				ctx->masterSecretCallback(ctx, ctx->masterSecretArg,
601					ctx->masterSecret, &secretLen);
602				ctx->sessionMatch = 1;
603				/* set up selectedCipherSpec */
604				if ((err = FindCipherSpec(ctx)) != 0) {
605					return err;
606				}
607				/* queue up remaining messages to finish handshake */
608				if((err = SSLResumeServerSide(ctx)) != 0)
609					return err;
610				break;
611			}
612			#endif	/* SSL_PAC_SERVER_ENABLE */
613            if (ctx->sessionID.data != 0)
614			/* If session ID != 0, client is trying to resume */
615            {   if (ctx->resumableSession.data != 0)
616                {
617					SSLProtocolVersion sessionProt;
618					if ((err = SSLRetrieveSessionID(ctx->resumableSession,
619								&sessionIdentifier, ctx)) != 0)
620                        return err;
621					if ((err = SSLRetrieveSessionProtocolVersion(ctx->resumableSession,
622							&sessionProt, ctx)) != 0)
623					{   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
624						return err;
625					}
626					if ((sessionIdentifier.length == ctx->sessionID.length) &&
627                        (memcmp(sessionIdentifier.data, ctx->sessionID.data,
628							ctx->sessionID.length) == 0) &&
629					    (sessionProt == ctx->negProtocolVersion))
630                    {   /* Everything matches; resume the session */
631						sslLogResumSessDebug("===RESUMING SSL3 server-side session");
632                        if ((err = SSLInstallSessionFromData(ctx->resumableSession,
633								ctx)) != 0)
634                        {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
635                            return err;
636                        }
637						ctx->sessionMatch = 1;
638						SSLFreeBuffer(&sessionIdentifier);
639
640						/* queue up remaining messages to finish handshake */
641						if((err = SSLResumeServerSide(ctx)) != 0)
642							return err;
643                        break;
644                    }
645					else {
646						sslLogResumSessDebug(
647							"===FAILED TO RESUME SSL3 server-side session");
648					}
649                    if ((err = SSLFreeBuffer(&sessionIdentifier)) != 0 ||
650                        (err = SSLDeleteSessionData(ctx)) != 0)
651                    {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
652                        return err;
653                    }
654                }
655                if ((err = SSLFreeBuffer(&ctx->sessionID)) != 0)
656                {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
657                    return err;
658                }
659            }
660
661            /*
662			 * If we get here, we're not resuming; generate a new session ID
663			 * if we know our peer
664			 */
665            if (ctx->peerID.data != 0)
666            {   /* Ignore errors; just treat as uncached session */
667                assert(ctx->sessionID.data == 0);
668                err = SSLAllocBuffer(&ctx->sessionID, SSL_SESSION_ID_LEN);
669                if (err == 0)
670                {
671                    if((err = sslRand(&ctx->sessionID)) != 0)
672                    {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
673                        return err;
674                    }
675                }
676            }
677
678            if ((err = SSLPrepareAndQueueMessage(SSLEncodeServerHello, ctx)) != 0)
679                return err;
680            switch (ctx->selectedCipherSpecParams.keyExchangeMethod)
681            {   case SSL_NULL_auth:
682            	#if		APPLE_DH
683                case SSL_DH_anon:
684                case SSL_ECDH_anon:
685                	if(ctx->clientAuth == kAlwaysAuthenticate) {
686                		/* app requires this; abort */
687                		SSLFatalSessionAlert(SSL_AlertHandshakeFail, ctx);
688                		return errSSLNegotiation;
689                	}
690                	ctx->tryClientAuth = false;
691					/* DH server side needs work */
692                    break;
693                #endif	/* APPLE_DH */
694                case TLS_PSK:
695                    /* skip the cert */
696                    break;
697
698                case SSL_RSA:
699                case SSL_DH_DSS:
700                case SSL_DH_RSA:
701                case SSL_DHE_DSS:
702                case SSL_DHE_RSA:
703                case SSL_ECDH_ECDSA:
704                case SSL_ECDHE_ECDSA:
705                case SSL_ECDH_RSA:
706                case SSL_ECDHE_RSA:
707					if(ctx->localCert == NULL) {
708						/* no cert but configured for, and negotiated, a
709						 * ciphersuite which requires one */
710						sslErrorLog("SSLAdvanceHandshake: No server key!\n");
711						return errSSLBadConfiguration;
712					}
713                    if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificate,
714							ctx)) != 0)
715                        return err;
716                    break;
717
718                default:        /* everything else */
719                    sslErrorLog("SSLAdvanceHandshake: Unsupported KEM!\n");
720                    return errSSLInternal;
721            }
722			/*
723			 * At this point we decide whether to send a server key exchange
724			 * method. For Apple servers, I think we'll ALWAYS do this, because
725			 * of key usage restrictions (can't decrypt and sign with the same
726			 * private key), but conceptually in this code, we do it if
727			 * enabled by the presence of encryptPrivKey.
728			 */
729			{
730				bool doServerKeyExch = false;
731				switch(ctx->selectedCipherSpecParams.keyExchangeMethod) {
732					case SSL_RSA:
733						if(ctx->encryptPrivKeyRef != NULL) {
734							doServerKeyExch = true;
735						}
736						break;
737					case SSL_DH_anon:
738					case SSL_DHE_RSA:
739					case SSL_DHE_DSS:
740						doServerKeyExch = true;
741						break;
742					default: /* In all other cases, we don't send a ServerkeyExchange message */
743						break;
744				}
745				if(doServerKeyExch) {
746					err = SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange, ctx);
747					if(err) {
748						return err;
749					}
750				}
751			}
752            if (ctx->tryClientAuth)
753            {   if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificateRequest,
754						ctx)) != 0)
755                    return err;
756                ctx->certRequested = 1;
757				ctx->clientCertState = kSSLClientCertRequested;
758            }
759            if ((err = SSLPrepareAndQueueMessage(SSLEncodeServerHelloDone, ctx)) != 0)
760                return err;
761            if (ctx->certRequested) {
762                SSLChangeHdskState(ctx, SSL_HdskStateClientCert);
763            }
764            else {
765                SSLChangeHdskState(ctx, SSL_HdskStateClientKeyExchange);
766            }
767            break;
768        case SSL_HdskServerHello:
769			ctx->sessionMatch = 0;
770            if (ctx->resumableSession.data != 0 && ctx->sessionID.data != 0)
771            {
772				SSLProtocolVersion sessionProt;
773				if ((err = SSLRetrieveSessionID(ctx->resumableSession,
774						&sessionIdentifier, ctx)) != 0)
775                {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
776                    return err;
777                }
778				if ((err = SSLRetrieveSessionProtocolVersion(ctx->resumableSession,
779						&sessionProt, ctx)) != 0)
780                {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
781                    return err;
782                }
783                if ((sessionIdentifier.length == ctx->sessionID.length) &&
784                    (memcmp(sessionIdentifier.data, ctx->sessionID.data,
785							ctx->sessionID.length) == 0) &&
786					(sessionProt == ctx->negProtocolVersion))
787                {   /* Everything matches; resume the session */
788					sslLogResumSessDebug("===RESUMING SSL3 client-side session");
789                    if ((err = SSLInstallSessionFromData(ctx->resumableSession,
790							ctx)) != 0 ||
791                        (err = SSLInitPendingCiphers(ctx)) != 0 ||
792                        (err = SSLFreeBuffer(&sessionIdentifier)) != 0)
793                    {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
794                        return err;
795                    }
796					ctx->sessionMatch = 1;
797                    SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
798                    break;
799                }
800				else {
801					sslLogResumSessDebug("===FAILED TO RESUME SSL3 client-side "
802							"session");
803				}
804                if ((err = SSLFreeBuffer(&sessionIdentifier)) != 0)
805                {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
806                    return err;
807                }
808            }
809            switch (ctx->selectedCipherSpecParams.keyExchangeMethod)
810            {
811            	/* these require a key exchange message */
812            	case SSL_NULL_auth:
813                case SSL_DH_anon:
814                    SSLChangeHdskState(ctx, SSL_HdskStateKeyExchange);
815                    break;
816                case SSL_RSA:
817                case SSL_DH_DSS:
818                case SSL_DH_RSA:
819                case SSL_RSA_EXPORT:
820                case SSL_DHE_DSS:
821                case SSL_DHE_RSA:
822                case SSL_Fortezza:
823				case SSL_ECDH_ECDSA:
824				case SSL_ECDHE_ECDSA:
825				case SSL_ECDH_RSA:
826				case SSL_ECDHE_RSA:
827                    SSLChangeHdskState(ctx, SSL_HdskStateCert);
828                    break;
829                case TLS_PSK:
830                    SSLChangeHdskState(ctx, SSL_HdskStateHelloDone);
831                    break;
832                default:
833                    assert("Unknown key exchange method");
834                    break;
835            }
836            break;
837        case SSL_HdskCert:
838            if (ctx->state == SSL_HdskStateCert)
839                switch (ctx->selectedCipherSpecParams.keyExchangeMethod)
840                {   case SSL_RSA:
841                 	/*
842                	 * I really think the two RSA cases should be
843                	 * handled the same here - the server key exchange is
844                	 * optional, and is up to the server.
845                	 * Note this isn't the same as SSL_SERVER_KEYEXCH_HACK;
846                	 * we're a client here.
847                	 */
848                    case SSL_DH_DSS:
849                    case SSL_DH_RSA:
850					case SSL_ECDH_ECDSA:
851					case SSL_ECDH_RSA:
852                        SSLChangeHdskState(ctx, SSL_HdskStateHelloDone);
853                        break;
854                    case SSL_DHE_DSS:
855                    case SSL_DHE_RSA:
856                    case SSL_Fortezza:
857					case SSL_ECDHE_ECDSA:
858					case SSL_ECDHE_RSA:
859                        SSLChangeHdskState(ctx, SSL_HdskStateKeyExchange);
860                        break;
861                    default:
862                        assert("Unknown or unexpected key exchange method");
863                        break;
864                }
865            else if (ctx->state == SSL_HdskStateClientCert)
866            {   SSLChangeHdskState(ctx, SSL_HdskStateClientKeyExchange);
867                if (ctx->peerCert != 0)
868                    ctx->certReceived = 1;
869            }
870            break;
871        case SSL_HdskCertRequest:
872			/* state stays in SSL_HdskStateHelloDone; distinction is in
873			 *  ctx->certRequested */
874            if (ctx->peerCert == 0)
875            {   SSLFatalSessionAlert(SSL_AlertHandshakeFail, ctx);
876                return errSSLProtocol;
877            }
878            assert(ctx->protocolSide == kSSLClientSide);
879            ctx->certRequested = 1;
880            ctx->clientCertState = kSSLClientCertRequested;
881            break;
882        case SSL_HdskServerKeyExchange:
883            SSLChangeHdskState(ctx, SSL_HdskStateHelloDone);
884            break;
885        case SSL_HdskServerHelloDone:
886			/*
887             * Waiting until server has sent hello done to interrupt and allow
888             * setting client cert, so we can send certificate, keyexchange and
889             * cert verify message together
890			 */
891            if (ctx->state != SSL_HdskStateClientCert) {
892                if (ctx->signalServerAuth) {
893                    ctx->signalServerAuth = false;
894                    SSLChangeHdskState(ctx, SSL_HdskStateClientCert);
895                    return errSSLServerAuthCompleted;
896                } else if (ctx->signalCertRequest) {
897                    ctx->signalCertRequest = false;
898                    SSLChangeHdskState(ctx, SSL_HdskStateClientCert);
899                    return errSSLClientCertRequested;
900                } else if (ctx->signalClientAuth) {
901                    ctx->signalClientAuth = false;
902                    return errSSLClientAuthCompleted;
903                }
904            }
905
906			if (ctx->clientCertState == kSSLClientCertRequested) {
907				/*
908				 * Server wants a client authentication cert - do
909				 * we have one?
910				 */
911                if (ctx->localCert != 0 && ctx->x509Requested) {
912					if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificate,
913							ctx)) != 0) {
914						return err;
915					}
916                }
917                else {
918					/* response for no cert depends on protocol version */
919					if(ctx->negProtocolVersion >= TLS_Version_1_0) {
920						/* TLS: send empty cert msg */
921						if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificate,
922								ctx)) != 0) {
923							return err;
924						}
925					}
926					else {
927						/* SSL3: "no cert" alert */
928						if ((err = SSLSendAlert(SSL_AlertLevelWarning, SSL_AlertNoCert_RESERVED,
929								ctx)) != 0) {
930							return err;
931						}
932					}
933                }	/* no cert to send */
934            }	/* server requested a cert */
935            if ((err = SSLPrepareAndQueueMessage(SSLEncodeKeyExchange, ctx)) != 0)
936                return err;
937			assert(ctx->sslTslCalls != NULL);
938            if ((err = ctx->sslTslCalls->generateMasterSecret(ctx)) != 0 ||
939                (err = SSLInitPendingCiphers(ctx)) != 0)
940            {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
941                return err;
942            }
943			memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
944            if ((err = SSLFreeBuffer(&ctx->preMasterSecret))) {
945                return err;
946			}
947            if (ctx->certSent) {
948				/* Not all client auth mechanisms require a cert verify message */
949				switch(ctx->negAuthType) {
950					case SSLClientAuth_RSASign:
951					case SSLClientAuth_ECDSASign:
952						if ((err = SSLPrepareAndQueueMessage(SSLEncodeCertificateVerify,
953								ctx)) != 0) {
954							return err;
955						}
956						break;
957					default:
958						break;
959				}
960			}
961            if ((err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec,
962					ctx)) != 0) {
963                return err;
964			}
965            if ((err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage, ctx)) != 0)
966                return err;
967            SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
968            break;
969        case SSL_HdskCertVerify:
970            SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
971            break;
972        case SSL_HdskClientKeyExchange:
973 			assert(ctx->sslTslCalls != NULL);
974			if ((err = ctx->sslTslCalls->generateMasterSecret(ctx)) != 0 ||
975                (err = SSLInitPendingCiphers(ctx)) != 0)
976            {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
977                return err;
978            }
979			memset(ctx->preMasterSecret.data, 0, ctx->preMasterSecret.length);
980            if ((err = SSLFreeBuffer(&ctx->preMasterSecret)))
981                return err;
982            if (ctx->certReceived) {
983                SSLChangeHdskState(ctx, SSL_HdskStateClientCertVerify);
984            }
985            else {
986                SSLChangeHdskState(ctx, SSL_HdskStateChangeCipherSpec);
987            }
988            break;
989        case SSL_HdskFinished:
990            /* Handshake is over; enable data transfer on read channel */
991            ctx->readCipher_ready = 1;
992            /* If writePending is set, we haven't yet sent a finished message;
993			 * send it */
994            /* Note: If using session resumption, the client will hit this, otherwise the server will */
995            if (ctx->writePending_ready != 0)
996            {   if ((err = SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec,
997						ctx)) != 0)
998                    return err;
999                if ((err = SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage,
1000							ctx)) != 0)
1001                    return err;
1002            }
1003            if (ctx->protocolSide == kSSLServerSide) {
1004                SSLChangeHdskState(ctx, SSL_HdskStateServerReady);
1005            }
1006            else {
1007                SSLChangeHdskState(ctx, SSL_HdskStateClientReady);
1008            }
1009            if ((ctx->peerID.data != 0) && (ctx->sessionTicket.data == NULL)) {
1010				/* note we avoid caching session data for PAC-style resumption */
1011                SSLAddSessionData(ctx);
1012			}
1013            break;
1014        default:
1015            assert(0);
1016            break;
1017    }
1018
1019    /* We should have a full flight when we reach here, sending it for the first time */
1020    ctx->hdskMessageRetryCount = 0;
1021    ctx->timeout_deadline = CFAbsoluteTimeGetCurrent() + ctx->timeout_duration;
1022    return SSLSendFlight(ctx);
1023}
1024
1025OSStatus
1026SSLPrepareAndQueueMessage(EncodeMessageFunc msgFunc, SSLContext *ctx)
1027{   OSStatus        err;
1028    SSLRecord       rec = {0, 0, {0, NULL}};
1029    WaitingMessage  *out;
1030    WaitingMessage  *queue;
1031
1032    if ((err = msgFunc(&rec, ctx)) != 0)
1033    {   SSLFatalSessionAlert(SSL_AlertCloseNotify, ctx);
1034        goto fail;
1035    }
1036
1037    if (rec.contentType == SSL_RecordTypeHandshake)
1038    {
1039        if ((err = SSLUpdateHandshakeMacs(&rec.contents, ctx)) != 0)
1040        {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
1041            goto fail;
1042        }
1043        SSLLogHdskMsg((SSLHandshakeType)rec.contents.data[0], 1);
1044        ctx->hdskMessageSeq++;
1045    }
1046
1047    err=errSSLInternal;
1048    out = (WaitingMessage *)sslMalloc(sizeof(WaitingMessage));
1049    if(out==NULL) goto fail;
1050
1051    out->next = NULL;
1052	out->rec = rec;
1053
1054    queue=ctx->messageWriteQueue;
1055    if (queue == NULL) {
1056        sslHdskMsgDebug("Queuing first message in flight\n");
1057        ctx->messageWriteQueue = out;
1058    } else {
1059        int n=1;
1060        while (queue->next != 0) {
1061            queue = queue->next;
1062            n++;
1063        }
1064        sslHdskMsgDebug("Queuing message %d in flight\n", n);
1065        queue->next = out;
1066    }
1067
1068    return errSecSuccess;
1069fail:
1070    SSLFreeBuffer(&rec.contents);
1071    return err;
1072}
1073
1074static
1075OSStatus SSLSendMessage(SSLRecord rec, SSLContext *ctx)
1076{
1077    OSStatus err;
1078
1079
1080    if ((err = SSLWriteRecord(rec, ctx)) != 0)
1081        return err;
1082    if(rec.contentType == SSL_RecordTypeChangeCipher) {
1083        /* Install new cipher spec on write side */
1084        /* Can't send data until Finished is sent */
1085        ctx->writeCipher_ready = 0;
1086	ctx->wroteAppData = 0;
1087
1088        if ((err = ctx->recFuncs->advanceWriteCipher(ctx->recCtx)) != 0)
1089        {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
1090            return err;
1091        }
1092
1093        /* pending cipher is invalid now - this is currently used to figure out if we need
1094           to send out the last flight */
1095        ctx->writePending_ready = 0;
1096
1097        /* TODO: that should only happen after Finished message is sent. <rdar://problem/9682471> */
1098        ctx->writeCipher_ready = 1;
1099    }
1100
1101    return errSecSuccess;
1102}
1103
1104static
1105OSStatus DTLSSendMessage(SSLRecord rec, SSLContext *ctx)
1106{
1107    OSStatus err=errSecSuccess;
1108
1109    if(rec.contentType != SSL_RecordTypeHandshake) {
1110        sslHdskMsgDebug("Not fragmenting message type=%d len=%d\n", (int)rec.contentType, (int)rec.contents.length);
1111        if ((err = SSLWriteRecord(rec, ctx)) != 0)
1112            return err;
1113        if(rec.contentType == SSL_RecordTypeChangeCipher) {
1114			/* Can't send data until Finished is sent */
1115            ctx->writeCipher_ready = 0;
1116            ctx->wroteAppData = 0;
1117
1118            /* Install new cipher spec on write side */
1119            if ((err = ctx->recFuncs->advanceWriteCipher(ctx->recCtx)) != 0)
1120            {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
1121                return err;
1122            }
1123
1124            /* pending cipher is invalid now - this is currently used to figure out if we need
1125             to send out the last flight */
1126            ctx->writePending_ready = 0;
1127
1128            /* TODO: that should only happen after Finished message is sent. See <rdar://problem/9682471> */
1129            ctx->writeCipher_ready = 1;
1130
1131        }
1132    } else {
1133    /* fragmenting */
1134        SSLRecord fragrec;
1135
1136        int msghead = 12;  /* size of message header in DTLS */
1137        size_t fraglen;
1138        size_t len = rec.contents.length-msghead;
1139        UInt32 seq = SSLDecodeInt(rec.contents.data+4, 2);
1140        (void) seq; // Suppress warnings
1141        size_t ofs = 0;
1142
1143        sslHdskMsgDebug("Fragmenting msg seq %d (rl=%d, ml=%d)", (int)seq, (int)rec.contents.length,
1144                        SSLDecodeInt(rec.contents.data+1, 3));
1145
1146
1147        SSLGetDatagramWriteSize(ctx, &fraglen);
1148        fraglen -=  msghead;
1149
1150        fragrec.contentType = rec.contentType;
1151        fragrec.protocolVersion = rec.protocolVersion;
1152        if((err=SSLAllocBuffer(&fragrec.contents, fraglen + msghead)))
1153            return err;
1154
1155        /* copy the constant part of the header */
1156        memcpy(fragrec.contents.data,rec.contents.data, 6);
1157
1158        while(len>fraglen) {
1159
1160            sslHdskMsgDebug("Fragmenting msg seq %d (o=%d,l=%d)", (int)seq, (int)ofs, (int)fraglen);
1161
1162            /* fragment offset and fragment length */
1163            SSLEncodeSize(fragrec.contents.data+6, ofs, 3);
1164            SSLEncodeSize(fragrec.contents.data+9, fraglen, 3);
1165            /* copy the payload */
1166            memcpy(fragrec.contents.data+msghead, rec.contents.data+msghead+ofs, fraglen);
1167            if ((err = SSLWriteRecord(fragrec, ctx)) != 0)
1168                goto cleanup;
1169            len-=fraglen;
1170            ofs+=fraglen;
1171        }
1172
1173        sslHdskMsgDebug("Fragmenting msg seq %d - Last Fragment (o=%d,l=%d)", (int)seq, (int)ofs, (int)len);
1174
1175        /* last fragment */
1176        /* fragment offset and fragment length */
1177        SSLEncodeSize(fragrec.contents.data+6, ofs, 3);
1178        SSLEncodeSize(fragrec.contents.data+9, len, 3);
1179        /* copy the payload */
1180        memcpy(fragrec.contents.data+msghead, rec.contents.data+msghead+ofs, len);
1181        fragrec.contents.length=len+msghead;
1182        err = SSLWriteRecord(fragrec, ctx);
1183
1184    cleanup:
1185        /* Free the allocated fragment buffer */
1186        SSLFreeBuffer(&fragrec.contents);
1187
1188    }
1189
1190    return err;
1191}
1192
1193
1194OSStatus SSLResetFlight(SSLContext *ctx)
1195{
1196    OSStatus err;
1197    WaitingMessage *queue;
1198    WaitingMessage *next;
1199    int n=0;
1200
1201    queue=ctx->messageWriteQueue;
1202    ctx->messageQueueContainsChangeCipherSpec=false;
1203
1204    while(queue) {
1205        n++;
1206        err = SSLFreeBuffer(&queue->rec.contents);
1207        if (err != 0)
1208            goto fail;
1209        next=queue->next;
1210        sslFree(queue);
1211        queue=next;
1212    }
1213
1214    ctx->messageWriteQueue=NULL;
1215
1216    return errSecSuccess;
1217fail:
1218    check_noerr(err);
1219    return err;
1220}
1221
1222OSStatus SSLSendFlight(SSLContext *ctx)
1223{
1224    OSStatus err;
1225    WaitingMessage  *queue;
1226    int n=0;
1227
1228    queue=ctx->messageWriteQueue;
1229
1230    while(queue) {
1231        if (ctx->isDTLS) {
1232            err=DTLSSendMessage(queue->rec, ctx);
1233        } else {
1234            err=SSLSendMessage(queue->rec, ctx);
1235        }
1236        if (err != 0)
1237            goto fail;
1238        queue=queue->next;
1239        n++;
1240    }
1241
1242    return errSecSuccess;
1243fail:
1244    check_noerr(err);
1245    return err;
1246}
1247
1248OSStatus
1249SSL3ReceiveSSL2ClientHello(SSLRecord rec, SSLContext *ctx)
1250{   OSStatus      err;
1251
1252    if ((err = SSLInitMessageHashes(ctx)) != 0)
1253        return err;
1254
1255    if ((err = SSLHashSHA1.update(&ctx->shaState, &rec.contents)) != 0 ||
1256        (err = SSLHashMD5.update(&ctx->md5State, &rec.contents)) != 0)
1257    {   SSLFatalSessionAlert(SSL_AlertInternalError, ctx);
1258        return err;
1259    }
1260
1261    if ((err = SSLAdvanceHandshake(SSL_HdskClientHello, ctx)) != 0)
1262        return err;
1263
1264    return errSecSuccess;
1265}
1266
1267/*
1268 * Determine max enabled protocol, i.e., the one we try to negotiate for.
1269 * Only returns an error (errSecParam) if NO protocols are enabled, which can
1270 * in fact happen by malicious or ignorant use of SSLSetProtocolVersionEnabled().
1271 */
1272OSStatus sslGetMaxProtVersion(
1273                              SSLContext 			*ctx,
1274                              SSLProtocolVersion	*version)	// RETURNED
1275{
1276    /* This check is here until SSLSetProtocolVersionEnabled() is gone .*/
1277    if (ctx->maxProtocolVersion == SSL_Version_Undetermined)
1278        return errSecBadReq;
1279
1280    *version = ctx->maxProtocolVersion;
1281    return errSecSuccess;
1282}
1283
1284
1285/* log changes in handshake state */
1286#ifndef	NDEBUG
1287#include <stdio.h>
1288
1289char *hdskStateToStr(SSLHandshakeState state)
1290{
1291	static char badStr[100];
1292
1293	switch(state) {
1294		case SSL_HdskStateUninit:
1295			return "Uninit";
1296		case SSL_HdskStateServerUninit:
1297			return "ServerUninit";
1298		case SSL_HdskStateClientUninit:
1299			return "ClientUninit";
1300		case SSL_HdskStateGracefulClose:
1301			return "GracefulClose";
1302		case SSL_HdskStateErrorClose:
1303			return "ErrorClose";
1304		case SSL_HdskStateNoNotifyClose:
1305			return "NoNotifyClose";
1306		case SSL_HdskStateServerHello:
1307			return "ServerHello";
1308		case SSL_HdskStateKeyExchange:
1309			return "KeyExchange";
1310		case SSL_HdskStateCert:
1311			return "Cert";
1312		case SSL_HdskStateHelloDone:
1313			return "HelloDone";
1314		case SSL_HdskStateClientCert:
1315			return "ClientCert";
1316		case SSL_HdskStateClientKeyExchange:
1317			return "ClientKeyExchange";
1318		case SSL_HdskStateClientCertVerify:
1319			return "ClientCertVerify";
1320		case SSL_HdskStateChangeCipherSpec:
1321			return "ChangeCipherSpec";
1322		case SSL_HdskStateFinished:
1323			return "Finished";
1324		case SSL_HdskStateServerReady:
1325			return "SSL_ServerReady";
1326		case SSL_HdskStateClientReady:
1327			return "SSL_ClientReady";
1328		default:
1329			sprintf(badStr, "Unknown state (%d(d)", state);
1330			return badStr;
1331	}
1332}
1333
1334/* This is a macro in Release mode */
1335void SSLChangeHdskState(SSLContext *ctx, SSLHandshakeState newState)
1336{
1337	sslHdskStateDebug("...hdskState = %s", hdskStateToStr(newState));
1338	ctx->state = newState;
1339}
1340
1341/* log handshake messages */
1342
1343static char *hdskMsgToStr(SSLHandshakeType msg)
1344{
1345	static char badStr[100];
1346
1347	switch(msg) {
1348		case SSL_HdskHelloRequest:
1349			return "SSL_HdskHelloRequest";
1350		case SSL_HdskClientHello:
1351			return "SSL_HdskClientHello";
1352		case SSL_HdskServerHello:
1353			return "SSL_HdskServerHello";
1354        case SSL_HdskHelloVerifyRequest:
1355			return "SSL_HdskHelloVerifyRequest";
1356		case SSL_HdskCert:
1357			return "SSL_HdskCert";
1358		case SSL_HdskServerKeyExchange:
1359			return "SSL_HdskServerKeyExchange";
1360		case SSL_HdskCertRequest:
1361			return "SSL_HdskCertRequest";
1362		case SSL_HdskServerHelloDone:
1363			return "SSL_HdskServerHelloDone";
1364		case SSL_HdskCertVerify:
1365			return "SSL_HdskCertVerify";
1366		case SSL_HdskClientKeyExchange:
1367			return "SSL_HdskClientKeyExchange";
1368		case SSL_HdskFinished:
1369			return "SSL_HdskFinished";
1370		default:
1371			sprintf(badStr, "Unknown msg (%d(d))", msg);
1372			return badStr;
1373	}
1374}
1375
1376void SSLLogHdskMsg(SSLHandshakeType msg, char sent)
1377{
1378	sslHdskMsgDebug("---%s handshake msg %s",
1379		hdskMsgToStr(msg), (sent ? "sent" : "recv"));
1380}
1381
1382#endif	/* NDEBUG */
1383
1384