2 * Copyright (c) 1999-2001,2005-2012 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
26 * sslHandshake.c - SSL 3.0 handshake state machine.
29 #include "sslContext.h"
30 #include "sslHandshake.h"
31 #include "sslMemory.h"
32 #include "sslAlertMessage.h"
33 #include "sslSession.h"
36 #include "sslCrypto.h"
38 #include "sslDigests.h"
39 #include "cipherSpecs.h"
45 #define REQUEST_CERT_CORRECT 0
50 #define PRIstatus "ld"
53 static OSStatus
SSLProcessHandshakeMessage(SSLHandshakeMsg message
, SSLContext
*ctx
);
56 SSLUpdateHandshakeMacs(const SSLBuffer
*messageData
, SSLContext
*ctx
)
58 OSStatus err
= errSecParam
;
61 bool do_sha256
= false;
62 bool do_sha384
= false;
64 //TODO: We can stop updating the unecessary hashes once the CertVerify message is processed in case where we do Client Side Auth, or .
66 if(ctx
->negProtocolVersion
== SSL_Version_Undetermined
)
68 // we dont know yet, so we might need MD5 & SHA1 - Server should always call in with known protocol version.
69 assert(ctx
->protocolSide
==kSSLClientSide
);
70 do_md5
= do_sha1
= true;
72 ? ctx
->maxProtocolVersion
< DTLS_Version_1_0
73 : ctx
->maxProtocolVersion
>= TLS_Version_1_2
)
75 // We wil need those too, unless we are sure we wont end up doing TLS 1.2
76 do_sha256
= do_sha384
= true;
79 // we know which version we use at this point
80 if(sslVersionIsLikeTls12(ctx
)) {
81 do_sha1
= do_sha256
= do_sha384
= true;
83 do_md5
= do_sha1
= true;
88 (err
= SSLHashMD5
.update(&ctx
->md5State
, messageData
)) != 0)
91 (err
= SSLHashSHA1
.update(&ctx
->shaState
, messageData
)) != 0)
94 (err
= SSLHashSHA256
.update(&ctx
->sha256State
, messageData
)) != 0)
97 (err
= SSLHashSHA384
.update(&ctx
->sha512State
, messageData
)) != 0)
100 sslLogNegotiateDebug("%s protocol: %02X max: %02X cipher: %02X%s%s",
101 ctx
->protocolSide
== kSSLClientSide
? "client" : "server",
102 ctx
->negProtocolVersion
,
103 ctx
->maxProtocolVersion
,
105 do_md5
? " md5" : "",
106 do_sha1
? " sha1" : "",
107 do_sha256
? " sha256" : "",
108 do_sha384
? " sha384" : "");
114 SSLProcessHandshakeRecord(SSLRecord rec
, SSLContext
*ctx
)
118 UInt8
*startingP
; // top of record we're parsing
119 SSLHandshakeMsg message
= {};
120 SSLBuffer messageData
;
122 if (ctx
->fragmentedMessageCache
.data
!= 0)
124 size_t origLen
= ctx
->fragmentedMessageCache
.length
;
125 if ((err
= SSLReallocBuffer(&ctx
->fragmentedMessageCache
,
126 ctx
->fragmentedMessageCache
.length
+ rec
.contents
.length
,
128 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
131 memcpy(ctx
->fragmentedMessageCache
.data
+ origLen
,
132 rec
.contents
.data
, rec
.contents
.length
);
133 remaining
= ctx
->fragmentedMessageCache
.length
;
134 p
= ctx
->fragmentedMessageCache
.data
;
137 { remaining
= rec
.contents
.length
;
138 p
= rec
.contents
.data
;
144 while (remaining
> 0)
146 if (remaining
< head
)
147 break; /* we must have at least a header */
149 messageData
.data
= p
;
150 message
.type
= (SSLHandshakeType
)*p
++;
151 message
.contents
.length
= SSLDecodeSize(p
, 3);
156 if ((message
.contents
.length
+ head
) > remaining
)
159 message
.contents
.data
= p
;
160 p
+= message
.contents
.length
;
161 messageData
.length
= head
+ message
.contents
.length
;
162 assert(p
== messageData
.data
+ messageData
.length
);
164 /* message fragmentation */
165 remaining
-= messageData
.length
;
166 if ((err
= SSLProcessHandshakeMessage(message
, ctx
)) != 0)
169 if (message
.type
!= SSL_HdskHelloRequest
)
171 { if ((err
= SSLUpdateHandshakeMacs(&messageData
, ctx
)) != 0)
172 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
177 if ((err
= SSLAdvanceHandshake(message
.type
, ctx
)) != 0)
181 if (remaining
> 0) /* Fragmented handshake message */
182 { /* If there isn't a cache, allocate one */
183 if (ctx
->fragmentedMessageCache
.data
== 0)
184 { if ((err
= SSLAllocBuffer(&ctx
->fragmentedMessageCache
, remaining
, ctx
)) != 0)
185 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
189 if (startingP
!= ctx
->fragmentedMessageCache
.data
)
190 { memcpy(ctx
->fragmentedMessageCache
.data
, startingP
, remaining
);
191 ctx
->fragmentedMessageCache
.length
= remaining
;
194 else if (ctx
->fragmentedMessageCache
.data
!= 0)
195 { if ((err
= SSLFreeBuffer(&ctx
->fragmentedMessageCache
, ctx
)) != 0)
196 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
205 DTLSProcessHandshakeRecord(SSLRecord rec
, SSLContext
*ctx
)
206 { OSStatus err
= errSecParam
;
209 UInt8
*startingP
; // top of record we're parsing
211 const UInt32 head
= 12;
215 remaining
= rec
.contents
.length
;
216 p
= rec
.contents
.data
;
219 while (remaining
> 0)
227 if (remaining
< head
) {
228 /* flush it - record is too small */
229 sslErrorLog("DTLSProcessHandshakeRecord: remaining too small (%lu out of %lu)\n", remaining
, rec
.contents
.length
);
230 assert(0); // keep this assert until we find a test case that triggers it
234 /* Thats the 12 bytes of header : */
235 msgtype
= (SSLHandshakeType
)*p
++;
236 msglen
= SSLDecodeInt(p
, 3); p
+=3;
237 msgseq
= SSLDecodeInt(p
, 2); p
+=2;
238 fragofs
= SSLDecodeInt(p
, 3); p
+=3;
239 fraglen
= SSLDecodeInt(p
, 3); p
+=3;
243 SSLLogHdskMsg(msgtype
, 0);
244 sslHdskMsgDebug("DTLS Hdsk Record: type=%lu, len=%lu, seq=%lu (%lu), f_ofs=%lu, f_len=%lu, remaining=%lu",
245 msgtype
, msglen
, msgseq
, ctx
->hdskMessageSeqNext
, fragofs
, fraglen
, remaining
);
248 ((fraglen
+fragofs
) > msglen
)
249 || (fraglen
> remaining
)
250 || (msgseq
!=ctx
->hdskMessageSeqNext
)
251 || (fragofs
!=ctx
->hdskMessageCurrentOfs
)
252 || (fragofs
&& (msgtype
!=ctx
->hdskMessageCurrent
.type
))
253 || (fragofs
&& (msglen
!= ctx
->hdskMessageCurrent
.contents
.length
))
256 sslErrorLog("DTLSProcessHandshakeRecord: wrong fragment\n");
257 // assert(0); // keep this assert until we find a test case that triggers it
258 // This is a recoverable error, we just drop this fragment.
259 // TODO: this should probably trigger a retransmit
264 /* First fragment - allocate */
266 sslHdskMsgDebug("Allocating hdsk buf for msg type %d", msgtype
);
267 assert(ctx
->hdskMessageCurrent
.contents
.data
==NULL
);
268 assert(ctx
->hdskMessageCurrent
.contents
.length
==0);
269 if((err
=SSLAllocBuffer(&(ctx
->hdskMessageCurrent
.contents
), msglen
, ctx
))!=0) {
270 SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
273 ctx
->hdskMessageCurrent
.type
= msgtype
;
276 /* We have the next fragment, lets save it */
277 memcpy(ctx
->hdskMessageCurrent
.contents
.data
+ ctx
->hdskMessageCurrentOfs
, p
, fraglen
);
278 ctx
->hdskMessageCurrentOfs
+=fraglen
;
282 /* This was the last fragment, lets process the message */
283 if(ctx
->hdskMessageCurrentOfs
== ctx
->hdskMessageCurrent
.contents
.length
) {
284 err
= SSLProcessHandshakeMessage(ctx
->hdskMessageCurrent
, ctx
);
288 if ((msgtype
!= SSL_HdskHelloRequest
) && (msgtype
!= SSL_HdskHelloVerifyRequest
))
290 /* We need to hash a fake header as if no fragmentation */
291 uint8_t pseudo_header
[head
];
293 header
.data
=pseudo_header
;
296 pseudo_header
[0]=msgtype
;
297 SSLEncodeInt(pseudo_header
+1, msglen
, 3);
298 SSLEncodeInt(pseudo_header
+4, msgseq
, 2);
299 SSLEncodeInt(pseudo_header
+6, 0, 3);
300 SSLEncodeInt(pseudo_header
+9, msglen
, 3);
302 if ((err
= SSLHashSHA1
.update(&ctx
->shaState
, &header
)) != 0 ||
303 (err
= SSLHashMD5
.update(&ctx
->md5State
, &header
)) != 0)
305 SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
309 SSLBuffer
*messageData
=&ctx
->hdskMessageCurrent
.contents
;
310 if ((err
= SSLHashSHA1
.update(&ctx
->shaState
, messageData
)) != 0 ||
311 (err
= SSLHashMD5
.update(&ctx
->md5State
, messageData
)) != 0)
313 SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
317 sslHdskMsgDebug("Hashing %d bytes of msg seq %ld\n", messageData
->length
, msgseq
);
320 sslHdskMsgDebug("processed message of type %d", msgtype
);
322 if ((err
= SSLAdvanceHandshake(msgtype
, ctx
)) != 0)
324 sslErrorLog("AdvanceHandshake error: %"PRIstatus
"\n", err
);
328 /* Free the buffer for current message, and reset offset */
329 SSLFreeBuffer(&(ctx
->hdskMessageCurrent
.contents
), ctx
);
330 ctx
->hdskMessageCurrentOfs
=0;
332 /* If we successfully processed a message, we wait for the next one */
333 ctx
->hdskMessageSeqNext
++;
337 sslHdskMsgDebug("remaining = %ld", remaining
);
343 sslErrorLog("DTLSProcessHandshakeRecord: flusing record (err=%"PRIstatus
")\n", err
);
345 /* This will flush the current handshake message */
346 SSLFreeBuffer(&(ctx
->hdskMessageCurrent
.contents
), ctx
);
347 ctx
->hdskMessageCurrentOfs
=0;
353 DTLSRetransmit(SSLContext
*ctx
)
355 sslHdskMsgDebug("DTLSRetransmit in state %s. Last Sent = %d, Last Recv=%d, timeout=%f\n",
356 hdskStateToStr(ctx
->state
), ctx
->hdskMessageSeq
, ctx
->hdskMessageSeqNext
, ctx
->timeout_duration
);
358 /* Too many retransmits, just give up!! */
359 if(ctx
->hdskMessageRetryCount
>10)
360 return errSSLConnectionRefused
;
362 /* go back to previous cipher if retransmitting a flight including changecipherspec */
363 if(ctx
->messageQueueContainsChangeCipherSpec
) {
364 ctx
->writePending
= ctx
->writeCipher
;
365 ctx
->writeCipher
= ctx
->prevCipher
;
368 /* set timeout deadline */
369 ctx
->hdskMessageRetryCount
++;
370 ctx
->timeout_deadline
= CFAbsoluteTimeGetCurrent()+((1<<ctx
->hdskMessageRetryCount
)*ctx
->timeout_duration
);
372 /* Lets resend the last flight */
373 return SSLSendFlight(ctx
);
377 SSLProcessHandshakeMessage(SSLHandshakeMsg message
, SSLContext
*ctx
)
381 SSLLogHdskMsg(message
.type
, 0);
382 switch (message
.type
)
383 { case SSL_HdskHelloRequest
:
384 if (ctx
->protocolSide
!= kSSLClientSide
)
386 if (message
.contents
.length
> 0)
387 err
= errSSLProtocol
;
389 case SSL_HdskClientHello
:
390 if (ctx
->state
!= SSL_HdskStateServerUninit
)
392 err
= SSLProcessClientHello(message
.contents
, ctx
);
394 case SSL_HdskServerHello
:
395 if (ctx
->state
!= SSL_HdskStateServerHello
&&
396 ctx
->state
!= SSL_HdskStateServerHelloUnknownVersion
)
398 err
= SSLProcessServerHello(message
.contents
, ctx
);
401 case SSL_HdskHelloVerifyRequest
:
402 if (ctx
->protocolSide
!= kSSLClientSide
)
404 if(ctx
->state
!= SSL_HdskStateServerHello
)
406 /* TODO: Do we need to check the client state here ? */
407 err
= SSLProcessServerHelloVerifyRequest(message
.contents
, ctx
);
411 if (ctx
->state
!= SSL_HdskStateCert
&&
412 ctx
->state
!= SSL_HdskStateClientCert
)
414 err
= SSLProcessCertificate(message
.contents
, ctx
);
416 * Note that cert evaluation can now be performed asynchronously,
417 * so SSLProcessCertificate may return errSSLWouldBlock here.
420 case SSL_HdskCertRequest
:
421 if (((ctx
->state
!= SSL_HdskStateHelloDone
) &&
422 (ctx
->state
!= SSL_HdskStateKeyExchange
))
423 || ctx
->certRequested
)
425 err
= SSLProcessCertificateRequest(message
.contents
, ctx
);
426 if (ctx
->breakOnCertRequest
)
427 ctx
->signalCertRequest
= true;
429 case SSL_HdskServerKeyExchange
:
431 * Since this message is optional for some key exchange
432 * mechanisms, and completely at the server's discretion,
433 * we need to be able to handle this in one of two states...
436 case SSL_HdskStateKeyExchange
: /* explicitly waiting for this */
437 case SSL_HdskStateHelloDone
:
442 err
= SSLProcessServerKeyExchange(message
.contents
, ctx
);
444 case SSL_HdskServerHelloDone
:
445 if (ctx
->state
!= SSL_HdskStateHelloDone
)
447 err
= SSLProcessServerHelloDone(message
.contents
, ctx
);
449 case SSL_HdskCertVerify
:
450 if (ctx
->state
!= SSL_HdskStateClientCertVerify
)
452 err
= SSLProcessCertificateVerify(message
.contents
, ctx
);
453 assert(ctx
->protocolSide
== kSSLServerSide
);
455 ctx
->clientCertState
= kSSLClientCertRejected
;
458 case SSL_HdskClientKeyExchange
:
459 if (ctx
->state
!= SSL_HdskStateClientKeyExchange
)
461 err
= SSLProcessKeyExchange(message
.contents
, ctx
);
463 case SSL_HdskFinished
:
464 if (ctx
->state
!= SSL_HdskStateFinished
)
466 err
= SSLProcessFinished(message
.contents
, ctx
);
473 if (err
&& !ctx
->sentFatalAlert
)
474 { if (err
== errSSLProtocol
)
475 SSLFatalSessionAlert(SSL_AlertIllegalParam
, ctx
);
476 else if (err
== errSSLNegotiation
)
477 SSLFatalSessionAlert(SSL_AlertHandshakeFail
, ctx
);
478 else if (err
!= errSSLWouldBlock
&&
479 err
!= errSSLServerAuthCompleted
/* == errSSLClientAuthCompleted */ &&
480 err
!= errSSLClientCertRequested
)
481 SSLFatalSessionAlert(SSL_AlertCloseNotify
, ctx
);
486 SSLFatalSessionAlert(SSL_AlertUnexpectedMsg
, ctx
);
487 return errSSLProtocol
;
491 * Given a server-side SSLContext that's fully restored for a resumed session,
492 * queue up the remaining outgoing messages to finish the handshake.
499 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeServerHello
, ctx
)) != 0)
501 if ((err
= SSLInitPendingCiphers(ctx
)) != 0)
502 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
505 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec
,
509 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage
,
513 SSLChangeHdskState(ctx
, SSL_HdskStateChangeCipherSpec
);
520 SSLAdvanceHandshake(SSLHandshakeType processed
, SSLContext
*ctx
)
522 SSLBuffer sessionIdentifier
;
529 case SSL_HdskHelloVerifyRequest
:
530 /* Just fall through */
532 case SSL_HdskHelloRequest
:
534 * Reset the client auth state machine in case this is
537 ctx
->certRequested
= 0;
539 ctx
->certReceived
= 0;
540 ctx
->x509Requested
= 0;
541 ctx
->clientCertState
= kSSLClientCertNone
;
542 ctx
->readCipher
.ready
= 0;
543 ctx
->writeCipher
.ready
= 0;
544 ctx
->wroteAppData
= 0;
545 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeClientHello
, ctx
)) != 0)
547 SSLChangeHdskState(ctx
, SSL_HdskStateServerHello
);
549 case SSL_HdskClientHello
:
550 assert(ctx
->protocolSide
== kSSLServerSide
);
551 ctx
->sessionMatch
= 0;
553 if((ctx
->negProtocolVersion
==DTLS_Version_1_0
) && (ctx
->cookieVerified
==false))
554 { /* Send Hello Verify Request */
555 if((err
=SSLPrepareAndQueueMessage(SSLEncodeServerHelloVerifyRequest
, ctx
)) !=0 )
560 #if SSL_PAC_SERVER_ENABLE
561 if((ctx
->sessionTicket
.data
!= NULL
) &&
562 (ctx
->masterSecretCallback
!= NULL
)) {
564 * Client sent us a session ticket and we know how to ask
565 * the app for master secret. Go for it.
567 size_t secretLen
= SSL_MASTER_SECRET_SIZE
;
568 sslEapDebug("Server side resuming based on masterSecretCallback");
570 /* the master secret callback requires serverRandom, now... */
571 if ((err
= SSLEncodeRandom(ctx
->serverRandom
, ctx
)) != 0)
573 ctx
->serverRandomValid
= 1;
575 ctx
->masterSecretCallback(ctx
, ctx
->masterSecretArg
,
576 ctx
->masterSecret
, &secretLen
);
577 ctx
->sessionMatch
= 1;
578 /* set up selectedCipherSpec */
579 if ((err
= FindCipherSpec(ctx
)) != 0) {
582 /* queue up remaining messages to finish handshake */
583 if((err
= SSLResumeServerSide(ctx
)) != 0)
587 #endif /* SSL_PAC_SERVER_ENABLE */
588 if (ctx
->sessionID
.data
!= 0)
589 /* If session ID != 0, client is trying to resume */
590 { if (ctx
->resumableSession
.data
!= 0)
592 SSLProtocolVersion sessionProt
;
593 if ((err
= SSLRetrieveSessionID(ctx
->resumableSession
,
594 &sessionIdentifier
, ctx
)) != 0)
596 if ((err
= SSLRetrieveSessionProtocolVersion(ctx
->resumableSession
,
597 &sessionProt
, ctx
)) != 0)
598 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
601 if ((sessionIdentifier
.length
== ctx
->sessionID
.length
) &&
602 (memcmp(sessionIdentifier
.data
, ctx
->sessionID
.data
,
603 ctx
->sessionID
.length
) == 0) &&
604 (sessionProt
== ctx
->negProtocolVersion
))
605 { /* Everything matches; resume the session */
606 sslLogResumSessDebug("===RESUMING SSL3 server-side session");
607 if ((err
= SSLInstallSessionFromData(ctx
->resumableSession
,
609 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
612 ctx
->sessionMatch
= 1;
613 SSLFreeBuffer(&sessionIdentifier
, ctx
);
615 /* queue up remaining messages to finish handshake */
616 if((err
= SSLResumeServerSide(ctx
)) != 0)
621 sslLogResumSessDebug(
622 "===FAILED TO RESUME SSL3 server-side session");
624 if ((err
= SSLFreeBuffer(&sessionIdentifier
, ctx
)) != 0 ||
625 (err
= SSLDeleteSessionData(ctx
)) != 0)
626 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
630 if ((err
= SSLFreeBuffer(&ctx
->sessionID
, ctx
)) != 0)
631 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
637 * If we get here, we're not resuming; generate a new session ID
638 * if we know our peer
640 if (ctx
->peerID
.data
!= 0)
641 { /* Ignore errors; just treat as uncached session */
642 assert(ctx
->sessionID
.data
== 0);
643 err
= SSLAllocBuffer(&ctx
->sessionID
, SSL_SESSION_ID_LEN
, ctx
);
646 if((err
= sslRand(ctx
, &ctx
->sessionID
)) != 0)
647 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
653 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeServerHello
, ctx
)) != 0)
655 switch (ctx
->selectedCipherSpec
.keyExchangeMethod
)
656 { case SSL_NULL_auth
:
659 case SSL_DH_anon_EXPORT
:
660 if(ctx
->clientAuth
== kAlwaysAuthenticate
) {
661 /* app requires this; abort */
662 SSLFatalSessionAlert(SSL_AlertHandshakeFail
, ctx
);
663 return errSSLNegotiation
;
665 ctx
->tryClientAuth
= false;
666 /* DH server side needs work */
668 #endif /* APPLE_DH */
669 default: /* everything else */
670 if(ctx
->localCert
== NULL
) {
671 /* no cert but configured for, and negotiated, a
672 * ciphersuite which requires one */
673 sslErrorLog("SSLAdvanceHandshake: No server key!\n");
674 return errSSLBadConfiguration
;
676 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeCertificate
,
682 * At this point we decide whether to send a server key exchange
683 * method. For Apple servers, I think we'll ALWAYS do this, because
684 * of key usage restrictions (can't decrypt and sign with the same
685 * private key), but conceptually in this code, we do it if
686 * enabled by the presence of encryptPrivKey.
689 bool doServerKeyExch
= false;
690 switch(ctx
->selectedCipherSpec
.keyExchangeMethod
) {
692 #if !SSL_SERVER_KEYEXCH_HACK
693 /* the "proper" way - app decides. */
696 if(ctx
->encryptPrivKeyRef
!= NULL
) {
697 doServerKeyExch
= true;
701 case SSL_DH_anon_EXPORT
:
703 case SSL_DHE_RSA_EXPORT
:
705 case SSL_DHE_DSS_EXPORT
:
706 doServerKeyExch
= true;
711 if(doServerKeyExch
) {
712 err
= SSLPrepareAndQueueMessage(SSLEncodeServerKeyExchange
, ctx
);
718 if (ctx
->tryClientAuth
)
719 { if ((err
= SSLPrepareAndQueueMessage(SSLEncodeCertificateRequest
,
722 ctx
->certRequested
= 1;
723 ctx
->clientCertState
= kSSLClientCertRequested
;
725 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeServerHelloDone
, ctx
)) != 0)
727 if (ctx
->certRequested
) {
728 SSLChangeHdskState(ctx
, SSL_HdskStateClientCert
);
731 SSLChangeHdskState(ctx
, SSL_HdskStateClientKeyExchange
);
734 case SSL_HdskServerHello
:
735 ctx
->sessionMatch
= 0;
736 if (ctx
->resumableSession
.data
!= 0 && ctx
->sessionID
.data
!= 0)
738 SSLProtocolVersion sessionProt
;
739 if ((err
= SSLRetrieveSessionID(ctx
->resumableSession
,
740 &sessionIdentifier
, ctx
)) != 0)
741 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
744 if ((err
= SSLRetrieveSessionProtocolVersion(ctx
->resumableSession
,
745 &sessionProt
, ctx
)) != 0)
746 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
749 if ((sessionIdentifier
.length
== ctx
->sessionID
.length
) &&
750 (memcmp(sessionIdentifier
.data
, ctx
->sessionID
.data
,
751 ctx
->sessionID
.length
) == 0) &&
752 (sessionProt
== ctx
->negProtocolVersion
))
753 { /* Everything matches; resume the session */
754 sslLogResumSessDebug("===RESUMING SSL3 client-side session");
755 if ((err
= SSLInstallSessionFromData(ctx
->resumableSession
,
757 (err
= SSLInitPendingCiphers(ctx
)) != 0 ||
758 (err
= SSLFreeBuffer(&sessionIdentifier
, ctx
)) != 0)
759 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
762 ctx
->sessionMatch
= 1;
763 SSLChangeHdskState(ctx
, SSL_HdskStateChangeCipherSpec
);
767 sslLogResumSessDebug("===FAILED TO RESUME SSL3 client-side "
770 if ((err
= SSLFreeBuffer(&sessionIdentifier
, ctx
)) != 0)
771 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
775 switch (ctx
->selectedCipherSpec
.keyExchangeMethod
)
777 /* these require a key exchange message */
780 case SSL_DH_anon_EXPORT
:
781 SSLChangeHdskState(ctx
, SSL_HdskStateKeyExchange
);
785 case SSL_DH_DSS_EXPORT
:
787 case SSL_DH_RSA_EXPORT
:
790 case SSL_DHE_DSS_EXPORT
:
792 case SSL_DHE_RSA_EXPORT
:
795 case SSL_ECDHE_ECDSA
:
798 SSLChangeHdskState(ctx
, SSL_HdskStateCert
);
801 assert("Unknown key exchange method");
806 if (ctx
->state
== SSL_HdskStateCert
)
807 switch (ctx
->selectedCipherSpec
.keyExchangeMethod
)
810 * I really think the two RSA cases should be
811 * handled the same here - the server key exchange is
812 * optional, and is up to the server.
813 * Note this isn't the same as SSL_SERVER_KEYEXCH_HACK;
814 * we're a client here.
818 case SSL_DH_DSS_EXPORT
:
820 case SSL_DH_RSA_EXPORT
:
823 SSLChangeHdskState(ctx
, SSL_HdskStateHelloDone
);
826 case SSL_DHE_DSS_EXPORT
:
828 case SSL_DHE_RSA_EXPORT
:
830 case SSL_ECDHE_ECDSA
:
832 SSLChangeHdskState(ctx
, SSL_HdskStateKeyExchange
);
835 assert("Unknown or unexpected key exchange method");
838 else if (ctx
->state
== SSL_HdskStateClientCert
)
839 { SSLChangeHdskState(ctx
, SSL_HdskStateClientKeyExchange
);
840 if (ctx
->peerCert
!= 0)
841 ctx
->certReceived
= 1;
844 case SSL_HdskCertRequest
:
845 /* state stays in SSL_HdskStateHelloDone; distinction is in
846 * ctx->certRequested */
847 if (ctx
->peerCert
== 0)
848 { SSLFatalSessionAlert(SSL_AlertHandshakeFail
, ctx
);
849 return errSSLProtocol
;
851 assert(ctx
->protocolSide
== kSSLClientSide
);
852 ctx
->certRequested
= 1;
853 ctx
->clientCertState
= kSSLClientCertRequested
;
855 case SSL_HdskServerKeyExchange
:
856 SSLChangeHdskState(ctx
, SSL_HdskStateHelloDone
);
858 case SSL_HdskServerHelloDone
:
860 * Waiting until server has sent hello done to interrupt and allow
861 * setting client cert, so we can send certificate, keyexchange and
862 * cert verify message together
864 if (ctx
->state
!= SSL_HdskStateClientCert
) {
865 if (ctx
->signalServerAuth
) {
866 ctx
->signalServerAuth
= false;
867 SSLChangeHdskState(ctx
, SSL_HdskStateClientCert
);
868 return errSSLServerAuthCompleted
;
869 } else if (ctx
->signalCertRequest
) {
870 ctx
->signalCertRequest
= false;
871 SSLChangeHdskState(ctx
, SSL_HdskStateClientCert
);
872 return errSSLClientCertRequested
;
873 } else if (ctx
->signalClientAuth
) {
874 ctx
->signalClientAuth
= false;
875 return errSSLClientAuthCompleted
;
879 if (ctx
->clientCertState
== kSSLClientCertRequested
) {
881 * Server wants a client authentication cert - do
884 if (ctx
->localCert
!= 0 && ctx
->x509Requested
) {
885 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeCertificate
,
891 /* response for no cert depends on protocol version */
892 if(ctx
->negProtocolVersion
>= TLS_Version_1_0
) {
893 /* TLS: send empty cert msg */
894 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeCertificate
,
900 /* SSL3: "no cert" alert */
901 if ((err
= SSLSendAlert(SSL_AlertLevelWarning
, SSL_AlertNoCert_RESERVED
,
906 } /* no cert to send */
907 } /* server requested a cert */
908 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeKeyExchange
, ctx
)) != 0)
910 assert(ctx
->sslTslCalls
!= NULL
);
911 if ((err
= ctx
->sslTslCalls
->generateMasterSecret(ctx
)) != 0 ||
912 (err
= SSLInitPendingCiphers(ctx
)) != 0)
913 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
916 memset(ctx
->preMasterSecret
.data
, 0, ctx
->preMasterSecret
.length
);
917 if ((err
= SSLFreeBuffer(&ctx
->preMasterSecret
, ctx
)) != 0) {
921 /* Not all client auth mechanisms require a cert verify message */
922 switch(ctx
->negAuthType
) {
923 case SSLClientAuth_RSASign
:
924 case SSLClientAuth_ECDSASign
:
925 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeCertificateVerify
,
934 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec
,
938 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage
, ctx
)) != 0)
940 SSLChangeHdskState(ctx
, SSL_HdskStateChangeCipherSpec
);
942 case SSL_HdskCertVerify
:
943 SSLChangeHdskState(ctx
, SSL_HdskStateChangeCipherSpec
);
945 case SSL_HdskClientKeyExchange
:
946 assert(ctx
->sslTslCalls
!= NULL
);
947 if ((err
= ctx
->sslTslCalls
->generateMasterSecret(ctx
)) != 0 ||
948 (err
= SSLInitPendingCiphers(ctx
)) != 0)
949 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
952 memset(ctx
->preMasterSecret
.data
, 0, ctx
->preMasterSecret
.length
);
953 if ((err
= SSLFreeBuffer(&ctx
->preMasterSecret
, ctx
)) != 0)
955 if (ctx
->certReceived
) {
956 SSLChangeHdskState(ctx
, SSL_HdskStateClientCertVerify
);
959 SSLChangeHdskState(ctx
, SSL_HdskStateChangeCipherSpec
);
962 case SSL_HdskFinished
:
963 /* Handshake is over; enable data transfer on read channel */
964 ctx
->readCipher
.ready
= 1;
965 /* If writePending is set, we haven't yet sent a finished message;
967 if (ctx
->writePending
.ready
!= 0)
968 { if ((err
= SSLPrepareAndQueueMessage(SSLEncodeChangeCipherSpec
,
971 if ((err
= SSLPrepareAndQueueMessage(SSLEncodeFinishedMessage
,
975 if (ctx
->protocolSide
== kSSLServerSide
) {
976 SSLChangeHdskState(ctx
, SSL_HdskStateServerReady
);
979 SSLChangeHdskState(ctx
, SSL_HdskStateClientReady
);
981 if ((ctx
->peerID
.data
!= 0) && (ctx
->sessionTicket
.data
== NULL
)) {
982 /* note we avoid caching session data for PAC-style resumption */
983 SSLAddSessionData(ctx
);
991 /* We should have a full flight when we reach here, sending it for the first time */
992 ctx
->hdskMessageRetryCount
= 0;
993 ctx
->timeout_deadline
= CFAbsoluteTimeGetCurrent() + ctx
->timeout_duration
;
994 return SSLSendFlight(ctx
);
998 SSLPrepareAndQueueMessage(EncodeMessageFunc msgFunc
, SSLContext
*ctx
)
1000 SSLRecord rec
= {0, 0, {0, NULL
}};
1001 WaitingMessage
*out
;
1002 WaitingMessage
*queue
;
1004 if ((err
= msgFunc(&rec
, ctx
)) != 0)
1005 { SSLFatalSessionAlert(SSL_AlertCloseNotify
, ctx
);
1009 if (rec
.contentType
== SSL_RecordTypeHandshake
)
1011 if ((err
= SSLUpdateHandshakeMacs(&rec
.contents
, ctx
)) != 0)
1012 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
1015 SSLLogHdskMsg((SSLHandshakeType
)rec
.contents
.data
[0], 1);
1016 ctx
->hdskMessageSeq
++;
1020 out
= (WaitingMessage
*)sslMalloc(sizeof(WaitingMessage
));
1021 if(out
==NULL
) goto fail
;
1026 queue
=ctx
->messageWriteQueue
;
1027 if (queue
== NULL
) {
1028 sslHdskMsgDebug("Queuing first message in flight\n");
1029 ctx
->messageWriteQueue
= out
;
1032 while (queue
->next
!= 0) {
1033 queue
= queue
->next
;
1036 sslHdskMsgDebug("Queuing message %d in flight\n", n
);
1042 SSLFreeBuffer(&rec
.contents
, ctx
);
1047 OSStatus
SSLSendMessage(SSLRecord rec
, SSLContext
*ctx
)
1051 assert(ctx
->sslTslCalls
!= NULL
);
1053 if ((err
= ctx
->sslTslCalls
->writeRecord(rec
, ctx
)) != 0)
1055 if(rec
.contentType
== SSL_RecordTypeChangeCipher
) {
1056 /* Install new cipher spec on write side */
1057 if ((err
= SSLDisposeCipherSuite(&ctx
->writeCipher
, ctx
)) != 0)
1058 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
1061 ctx
->prevCipher
= ctx
->writeCipher
;
1062 ctx
->writeCipher
= ctx
->writePending
;
1063 /* Can't send data until Finished is sent */
1064 ctx
->writeCipher
.ready
= 0;
1065 ctx
->wroteAppData
= 0;
1067 /* Zero out old data */
1068 memset(&ctx
->writePending
, 0, sizeof(CipherContext
));
1069 ctx
->writePending
.encrypting
= 1;
1071 /* TODO: that should only happen after Finished message is sent. <rdar://problem/9682471> */
1072 ctx
->writeCipher
.ready
= 1;
1079 OSStatus
DTLSSendMessage(SSLRecord rec
, SSLContext
*ctx
)
1083 assert(ctx
->sslTslCalls
!= NULL
);
1085 if(rec
.contentType
!= SSL_RecordTypeHandshake
) {
1086 sslHdskMsgDebug("Not fragmenting message type=%d len=%d\n", rec
.contentType
, rec
.contents
.length
);
1087 if ((err
= ctx
->sslTslCalls
->writeRecord(rec
, ctx
)) != 0)
1089 if(rec
.contentType
== SSL_RecordTypeChangeCipher
) {
1090 /* Install new cipher spec on write side */
1091 if ((err
= SSLDisposeCipherSuite(&ctx
->writeCipher
, ctx
)) != 0)
1092 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
1095 ctx
->prevCipher
= ctx
->writeCipher
;
1096 ctx
->writeCipher
= ctx
->writePending
;
1097 /* Can't send data until Finished is sent */
1098 ctx
->writeCipher
.ready
= 0;
1099 ctx
->wroteAppData
= 0;
1101 /* Zero out old data */
1102 memset(&ctx
->writePending
, 0, sizeof(CipherContext
));
1103 ctx
->writePending
.encrypting
= 1;
1105 /* TODO: that should only happen after Finished message is sent. See <rdar://problem/9682471> */
1106 ctx
->writeCipher
.ready
= 1;
1113 int msghead
= 12; /* size of message header in DTLS */
1115 size_t len
= rec
.contents
.length
-msghead
;
1116 UInt32 seq
= SSLDecodeInt(rec
.contents
.data
+4, 2);
1117 (void) seq
; // Suppress warnings
1120 sslHdskMsgDebug("Fragmenting msg seq %ld (rl=%d, ml=%d)", seq
, rec
.contents
.length
,
1121 SSLDecodeInt(rec
.contents
.data
+1, 3));
1124 SSLGetDatagramWriteSize(ctx
, &fraglen
);
1127 fragrec
.contentType
= rec
.contentType
;
1128 fragrec
.protocolVersion
= rec
.protocolVersion
;
1129 if((err
=SSLAllocBuffer(&fragrec
.contents
, fraglen
+ msghead
, ctx
))!=0)
1132 /* copy the constant part of the header */
1133 memcpy(fragrec
.contents
.data
,rec
.contents
.data
, 6);
1135 while(len
>fraglen
) {
1137 sslHdskMsgDebug("Fragmenting msg seq %ld (o=%d,l=%d)", seq
, ofs
, fraglen
);
1139 /* fragment offset and fragment length */
1140 SSLEncodeSize(fragrec
.contents
.data
+6, ofs
, 3);
1141 SSLEncodeSize(fragrec
.contents
.data
+9, fraglen
, 3);
1142 /* copy the payload */
1143 memcpy(fragrec
.contents
.data
+msghead
, rec
.contents
.data
+msghead
+ofs
, fraglen
);
1144 if ((err
= ctx
->sslTslCalls
->writeRecord(fragrec
, ctx
)) != 0)
1150 sslHdskMsgDebug("Fragmenting msg seq %ld - Last Fragment (o=%d,l=%d)", seq
, ofs
, len
);
1153 /* fragment offset and fragment length */
1154 SSLEncodeSize(fragrec
.contents
.data
+6, ofs
, 3);
1155 SSLEncodeSize(fragrec
.contents
.data
+9, len
, 3);
1156 /* copy the payload */
1157 memcpy(fragrec
.contents
.data
+msghead
, rec
.contents
.data
+msghead
+ofs
, len
);
1158 fragrec
.contents
.length
=len
+msghead
;
1159 err
= ctx
->sslTslCalls
->writeRecord(fragrec
, ctx
);
1162 /* Free the allocated fragment buffer */
1163 SSLFreeBuffer(&fragrec
.contents
, ctx
);
1171 OSStatus
SSLResetFlight(SSLContext
*ctx
)
1174 WaitingMessage
*queue
;
1175 WaitingMessage
*next
;
1178 assert(ctx
->sslTslCalls
!= NULL
);
1180 queue
=ctx
->messageWriteQueue
;
1181 ctx
->messageQueueContainsChangeCipherSpec
=false;
1185 err
= SSLFreeBuffer(&queue
->rec
.contents
, ctx
);
1193 ctx
->messageWriteQueue
=NULL
;
1202 OSStatus
SSLSendFlight(SSLContext
*ctx
)
1205 WaitingMessage
*queue
;
1208 assert(ctx
->sslTslCalls
!= NULL
);
1210 queue
=ctx
->messageWriteQueue
;
1214 err
=DTLSSendMessage(queue
->rec
, ctx
);
1216 err
=SSLSendMessage(queue
->rec
, ctx
);
1231 SSL3ReceiveSSL2ClientHello(SSLRecord rec
, SSLContext
*ctx
)
1234 if ((err
= SSLInitMessageHashes(ctx
)) != 0)
1237 if ((err
= SSLHashSHA1
.update(&ctx
->shaState
, &rec
.contents
)) != 0 ||
1238 (err
= SSLHashMD5
.update(&ctx
->md5State
, &rec
.contents
)) != 0)
1239 { SSLFatalSessionAlert(SSL_AlertInternalError
, ctx
);
1243 if ((err
= SSLAdvanceHandshake(SSL_HdskClientHello
, ctx
)) != 0)
1249 /* log changes in handshake state */
1253 char *hdskStateToStr(SSLHandshakeState state
)
1255 static char badStr
[100];
1258 case SSL_HdskStateUninit
:
1260 case SSL_HdskStateServerUninit
:
1261 return "ServerUninit";
1262 case SSL_HdskStateClientUninit
:
1263 return "ClientUninit";
1264 case SSL_HdskStateGracefulClose
:
1265 return "GracefulClose";
1266 case SSL_HdskStateErrorClose
:
1267 return "ErrorClose";
1268 case SSL_HdskStateNoNotifyClose
:
1269 return "NoNotifyClose";
1270 case SSL_HdskStateServerHello
:
1271 return "ServerHello";
1272 case SSL_HdskStateServerHelloUnknownVersion
:
1273 return "ServerHelloUnknownVersion";
1274 case SSL_HdskStateKeyExchange
:
1275 return "KeyExchange";
1276 case SSL_HdskStateCert
:
1278 case SSL_HdskStateHelloDone
:
1280 case SSL_HdskStateClientCert
:
1281 return "ClientCert";
1282 case SSL_HdskStateClientKeyExchange
:
1283 return "ClientKeyExchange";
1284 case SSL_HdskStateClientCertVerify
:
1285 return "ClientCertVerify";
1286 case SSL_HdskStateChangeCipherSpec
:
1287 return "ChangeCipherSpec";
1288 case SSL_HdskStateFinished
:
1290 case SSL2_HdskStateClientMasterKey
:
1291 return "SSL2_ClientMasterKey";
1292 case SSL2_HdskStateClientFinished
:
1293 return "SSL2_ClientFinished";
1294 case SSL2_HdskStateServerHello
:
1295 return "SSL2_ServerHello";
1296 case SSL2_HdskStateServerVerify
:
1297 return "SSL2_ServerVerify";
1298 case SSL2_HdskStateServerFinished
:
1299 return "SSL2_ServerFinished";
1300 case SSL_HdskStateServerReady
:
1301 return "SSL_ServerReady";
1302 case SSL_HdskStateClientReady
:
1303 return "SSL_ClientReady";
1305 sprintf(badStr
, "Unknown state (%d(d)", state
);
1310 void SSLChangeHdskState(SSLContext
*ctx
, SSLHandshakeState newState
)
1312 /* FIXME - this ifndef should not be necessary */
1314 sslHdskStateDebug("...hdskState = %s", hdskStateToStr(newState
));
1316 ctx
->state
= newState
;
1320 /* log handshake messages */
1322 static char *hdskMsgToStr(SSLHandshakeType msg
)
1324 static char badStr
[100];
1327 case SSL_HdskHelloRequest
:
1328 return "SSL_HdskHelloRequest";
1329 case SSL_HdskClientHello
:
1330 return "SSL_HdskClientHello";
1331 case SSL_HdskServerHello
:
1332 return "SSL_HdskServerHello";
1333 case SSL_HdskHelloVerifyRequest
:
1334 return "SSL_HdskHelloVerifyRequest";
1336 return "SSL_HdskCert";
1337 case SSL_HdskServerKeyExchange
:
1338 return "SSL_HdskServerKeyExchange";
1339 case SSL_HdskCertRequest
:
1340 return "SSL_HdskCertRequest";
1341 case SSL_HdskServerHelloDone
:
1342 return "SSL_HdskServerHelloDone";
1343 case SSL_HdskCertVerify
:
1344 return "SSL_HdskCertVerify";
1345 case SSL_HdskClientKeyExchange
:
1346 return "SSL_HdskClientKeyExchange";
1347 case SSL_HdskFinished
:
1348 return "SSL_HdskFinished";
1350 sprintf(badStr
, "Unknown msg (%d(d))", msg
);
1355 void SSLLogHdskMsg(SSLHandshakeType msg
, char sent
)
1357 sslHdskMsgDebug("---%s handshake msg %s",
1358 hdskMsgToStr(msg
), (sent
? "sent" : "recv"));