2 * Copyright (c) 1999-2001,2005-2008,2010-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@
25 * sslHandshakeHello.c - Support for client hello and server hello messages.
28 #include "sslContext.h"
29 #include "sslHandshake.h"
30 #include "sslMemory.h"
31 #include "sslSession.h"
34 #include "sslCrypto.h"
36 #include "sslDigests.h"
37 #include "sslCipherSpecs.h"
46 * Given a protocol version sent by peer, determine if we accept that version
47 * and downgrade if appropriate (which can not be done for the client side).
50 OSStatus
sslVerifyProtVersion(
52 SSLProtocolVersion peerVersion
, // sent by peer
53 SSLProtocolVersion
*negVersion
) // final negotiated version if return success
56 ? peerVersion
> ctx
->minProtocolVersion
57 : peerVersion
< ctx
->minProtocolVersion
) {
58 return errSSLNegotiation
;
61 ? peerVersion
< ctx
->maxProtocolVersion
62 : peerVersion
> ctx
->maxProtocolVersion
) {
63 if (ctx
->protocolSide
== kSSLClientSide
) {
64 return errSSLNegotiation
;
66 *negVersion
= ctx
->maxProtocolVersion
;
68 *negVersion
= peerVersion
;
75 /* IE treats null session id as valid; two consecutive sessions with NULL ID
76 * are considered a match. Workaround: when resumable sessions are disabled,
77 * send a random session ID. */
78 #define SSL_IE_NULL_RESUME_BUG 1
79 #if SSL_IE_NULL_RESUME_BUG
80 #define SSL_NULL_ID_LEN 32 /* length of bogus session ID */
84 SSLEncodeServerHello(SSLRecord
*serverHello
, SSLContext
*ctx
)
92 if (ctx
->sessionID
.data
!= 0)
93 sessionIDLen
= (UInt8
)ctx
->sessionID
.length
;
94 #if SSL_IE_NULL_RESUME_BUG
95 if(sessionIDLen
== 0) {
96 sessionIDLen
= SSL_NULL_ID_LEN
;
98 #endif /* SSL_IE_NULL_RESUME_BUG */
100 msglen
= 38 + sessionIDLen
;
102 /* this was set to a known quantity in SSLProcessClientHello */
103 check(ctx
->negProtocolVersion
!= SSL_Version_Undetermined
);
104 /* should not be here in this case */
105 check(ctx
->negProtocolVersion
!= SSL_Version_2_0
);
106 sslLogNegotiateDebug("===SSL3 server: sending version %d_%d",
107 ctx
->negProtocolVersion
>> 8, ctx
->negProtocolVersion
& 0xff);
108 sslLogNegotiateDebug("...sessionIDLen = %d", sessionIDLen
);
109 serverHello
->protocolVersion
= ctx
->negProtocolVersion
;
110 serverHello
->contentType
= SSL_RecordTypeHandshake
;
111 head
= SSLHandshakeHeaderSize(serverHello
);
112 if ((err
= SSLAllocBuffer(&serverHello
->contents
, msglen
+ head
)))
115 charPtr
= SSLEncodeHandshakeHeader(ctx
, serverHello
, SSL_HdskServerHello
, msglen
);
117 charPtr
= SSLEncodeInt(charPtr
, serverHello
->protocolVersion
, 2);
119 #if SSL_PAC_SERVER_ENABLE
120 /* serverRandom might have already been set, in SSLAdvanceHandshake() */
121 if(!ctx
->serverRandomValid
) {
122 if ((err
= SSLEncodeRandom(ctx
->serverRandom
, ctx
)) != 0) {
127 /* This is the normal production code path */
128 if ((err
= SSLEncodeRandom(ctx
->serverRandom
, ctx
)) != 0)
130 #endif /* SSL_PAC_SERVER_ENABLE */
132 memcpy(charPtr
, ctx
->serverRandom
, SSL_CLIENT_SRVR_RAND_SIZE
);
134 charPtr
+= SSL_CLIENT_SRVR_RAND_SIZE
;
135 *(charPtr
++) = (UInt8
)sessionIDLen
;
136 #if SSL_IE_NULL_RESUME_BUG
137 if(ctx
->sessionID
.data
!= NULL
) {
138 /* normal path for enabled resumable session */
139 memcpy(charPtr
, ctx
->sessionID
.data
, sessionIDLen
);
145 rb
.length
= SSL_NULL_ID_LEN
;
149 if (sessionIDLen
> 0)
150 memcpy(charPtr
, ctx
->sessionID
.data
, sessionIDLen
);
151 #endif /* SSL_IE_NULL_RESUME_BUG */
152 charPtr
+= sessionIDLen
;
153 charPtr
= SSLEncodeInt(charPtr
, ctx
->selectedCipher
, 2);
154 *(charPtr
++) = 0; /* Null compression */
156 sslLogNegotiateDebug("ssl3: server specifying cipherSuite 0x%lx",
157 (unsigned long)ctx
->selectedCipher
);
159 assert(charPtr
== serverHello
->contents
.data
+ serverHello
->contents
.length
);
161 return errSecSuccess
;
165 SSLEncodeServerHelloVerifyRequest(SSLRecord
*helloVerifyRequest
, SSLContext
*ctx
)
171 assert(ctx
->protocolSide
== kSSLServerSide
);
172 assert(ctx
->negProtocolVersion
== DTLS_Version_1_0
);
173 assert(ctx
->dtlsCookie
.length
);
175 msglen
= 3 + ctx
->dtlsCookie
.length
;
177 helloVerifyRequest
->protocolVersion
= DTLS_Version_1_0
;
178 helloVerifyRequest
->contentType
= SSL_RecordTypeHandshake
;
179 head
= SSLHandshakeHeaderSize(helloVerifyRequest
);
180 if ((err
= SSLAllocBuffer(&helloVerifyRequest
->contents
, msglen
+ head
)))
183 charPtr
= SSLEncodeHandshakeHeader(ctx
, helloVerifyRequest
, SSL_HdskHelloVerifyRequest
, msglen
);
185 charPtr
= SSLEncodeInt(charPtr
, helloVerifyRequest
->protocolVersion
, 2);
187 *charPtr
++ = ctx
->dtlsCookie
.length
;
188 memcpy(charPtr
, ctx
->dtlsCookie
.data
, ctx
->dtlsCookie
.length
);
189 charPtr
+= ctx
->dtlsCookie
.length
;
191 assert(charPtr
== (helloVerifyRequest
->contents
.data
+ helloVerifyRequest
->contents
.length
));
193 return errSecSuccess
;
198 SSLProcessServerHelloVerifyRequest(SSLBuffer message
, SSLContext
*ctx
)
200 SSLProtocolVersion protocolVersion
;
201 unsigned int cookieLen
;
204 assert(ctx
->protocolSide
== kSSLClientSide
);
206 /* TODO: those length values should not be hardcoded */
207 /* 3 bytes at least with empty cookie */
208 if (message
.length
< 3 ) {
209 sslErrorLog("SSLProcessServerHelloVerifyRequest: msg len error\n");
210 return errSSLProtocol
;
214 protocolVersion
= (SSLProtocolVersion
)SSLDecodeInt(p
, 2);
217 /* TODO: Not clear what else to do with protocol version here */
218 if(protocolVersion
!= DTLS_Version_1_0
) {
219 sslErrorLog("SSLProcessServerHelloVerifyRequest: protocol version error\n");
220 return errSSLProtocol
;
224 sslLogNegotiateDebug("cookieLen = %d, msglen=%d\n", (int)cookieLen
, (int)message
.length
);
225 /* TODO: hardcoded '15' again */
226 if (message
.length
< (3 + cookieLen
)) {
227 sslErrorLog("SSLProcessServerHelloVerifyRequest: msg len error 2\n");
228 return errSSLProtocol
;
231 err
= SSLAllocBuffer(&ctx
->dtlsCookie
, cookieLen
);
233 memcpy(ctx
->dtlsCookie
.data
, p
, cookieLen
);
239 SSLProcessServerHelloExtension_SecureRenegotiation(SSLContext
*ctx
, UInt16 extLen
, UInt8
*p
)
241 if(extLen
!= (1 + ctx
->ownVerifyData
.length
+ ctx
->peerVerifyData
.length
))
244 if(*p
!=ctx
->ownVerifyData
.length
+ ctx
->ownVerifyData
.length
)
248 if(memcmp(p
, ctx
->ownVerifyData
.data
, ctx
->ownVerifyData
.length
))
250 p
+=ctx
->ownVerifyData
.length
;
252 if(memcmp(p
, ctx
->peerVerifyData
.data
, ctx
->peerVerifyData
.length
))
255 ctx
->secure_renegotiation_received
= true;
260 SSLProcessServerHelloExtensions(SSLContext
*ctx
, UInt16 extensionsLen
, UInt8
*p
)
262 Boolean got_secure_renegotiation
= false;
265 if(extensionsLen
<2) {
266 sslErrorLog("SSLProcessHelloExtensions: need a least 2 bytes\n");
267 return errSSLProtocol
;
270 remaining
= SSLDecodeInt(p
, 2); p
+=2;
273 /* remaining = number of bytes remaining to process according to buffer data */
274 /* extensionsLen = number of bytes in the buffer */
276 if(remaining
>extensionsLen
) {
277 sslErrorLog("SSLProcessHelloExtensions: ext len error 1\n");
278 return errSSLProtocol
;
281 if(remaining
<extensionsLen
) {
282 sslErrorLog("Warning: SSLProcessServerHelloExtensions: Too many bytes\n");
290 sslErrorLog("SSLProcessHelloExtensions: ext len error\n");
291 return errSSLProtocol
;
294 extType
= SSLDecodeInt(p
, 2); p
+=2;
295 extLen
= SSLDecodeInt(p
, 2); p
+=2;
297 if (remaining
<(4+extLen
)) {
298 sslErrorLog("SSLProcessHelloExtension: ext len error 2\n");
299 return errSSLProtocol
;
301 remaining
-= (4+extLen
);
304 case SSL_HE_SecureRenegotation
:
305 if(got_secure_renegotiation
)
306 return errSSLProtocol
; /* Fail if we already processed one */
307 got_secure_renegotiation
= true;
308 SSLProcessServerHelloExtension_SecureRenegotiation(ctx
, extLen
, p
);
312 Do nothing for other extensions. Per RFC 5246, we should (MUST) error
313 if we received extensions we didnt specify in the Client Hello.
314 Client should also abort handshake if multiple extensions of the same
322 return errSecSuccess
;
328 SSLProcessServerHello(SSLBuffer message
, SSLContext
*ctx
)
330 SSLProtocolVersion protocolVersion
, negVersion
;
332 size_t extensionsLen
;
335 assert(ctx
->protocolSide
== kSSLClientSide
);
337 if (message
.length
< 38) {
338 sslErrorLog("SSLProcessServerHello: msg len error\n");
339 return errSSLProtocol
;
343 protocolVersion
= (SSLProtocolVersion
)SSLDecodeInt(p
, 2);
345 /* FIXME this should probably send appropriate alerts */
346 err
= sslVerifyProtVersion(ctx
, protocolVersion
, &negVersion
);
350 ctx
->negProtocolVersion
= negVersion
;
352 case SSL_Version_3_0
:
353 ctx
->sslTslCalls
= &Ssl3Callouts
;
355 case TLS_Version_1_0
:
356 case TLS_Version_1_1
:
357 case DTLS_Version_1_0
:
358 ctx
->sslTslCalls
= &Tls1Callouts
;
360 case TLS_Version_1_2
:
361 ctx
->sslTslCalls
= &Tls12Callouts
;
364 return errSSLNegotiation
;
366 err
= ctx
->recFuncs
->setProtocolVersion(ctx
->recCtx
, negVersion
);
371 sslLogNegotiateDebug("===SSL3 client: negVersion is %d_%d",
372 (negVersion
>> 8) & 0xff, negVersion
& 0xff);
374 memcpy(ctx
->serverRandom
, p
, 32);
378 if (message
.length
< (38 + sessionIDLen
)) {
379 sslErrorLog("SSLProcessServerHello: msg len error 2\n");
380 return errSSLProtocol
;
382 if (sessionIDLen
> 0 && ctx
->peerID
.data
!= 0)
383 { /* Don't die on error; just treat it as an uncached session */
384 if (ctx
->sessionID
.data
)
385 SSLFreeBuffer(&ctx
->sessionID
);
386 err
= SSLAllocBuffer(&ctx
->sessionID
, sessionIDLen
);
388 memcpy(ctx
->sessionID
.data
, p
, sessionIDLen
);
392 ctx
->selectedCipher
= (UInt16
)SSLDecodeInt(p
,2);
393 sslLogNegotiateDebug("===ssl3: server requests cipherKind %x",
394 (unsigned)ctx
->selectedCipher
);
396 if ((err
= FindCipherSpec(ctx
)) != 0) {
400 if (*p
++ != 0) /* Compression */
401 return errSecUnimplemented
;
403 /* Process ServerHello extensions */
404 extensionsLen
= message
.length
- (38 + sessionIDLen
);
407 err
= SSLProcessServerHelloExtensions(ctx
, extensionsLen
, p
);
412 /* RFC 5746: Make sure the renegotiation is secure */
413 if(ctx
->secure_renegotiation
&& !ctx
->secure_renegotiation_received
)
414 return errSSLNegotiation
;
416 if(ctx
->secure_renegotiation_received
)
417 ctx
->secure_renegotiation
= true;
421 * Note: the server MAY send a SSL_HE_EC_PointFormats extension if
422 * we've negotiated an ECDSA ciphersuite...but
423 * a) the provided format list MUST contain SSL_PointFormatUncompressed per
425 * b) The uncompressed format is the only one we support.
427 * Thus we drop a possible incoming SSL_HE_EC_PointFormats extension here.
428 * IF we ever support other point formats, we have to parse the extension
429 * to see what the server supports.
431 return errSecSuccess
;
435 SSLEncodeClientHello(SSLRecord
*clientHello
, SSLContext
*ctx
)
441 SSLBuffer sessionIdentifier
= { 0, NULL
};
443 size_t sessionTicketLen
= 0;
444 size_t serverNameLen
= 0;
445 size_t pointFormatLen
= 0;
446 size_t suppCurveLen
= 0;
447 size_t signatureAlgorithmsLen
= 0;
448 size_t totalExtenLen
= 0;
449 UInt16 numCipherSuites
;
452 assert(ctx
->protocolSide
== kSSLClientSide
);
454 clientHello
->contents
.length
= 0;
455 clientHello
->contents
.data
= NULL
;
458 if (ctx
->resumableSession
.data
!= 0)
459 { if ((err
= SSLRetrieveSessionID(ctx
->resumableSession
,
460 &sessionIdentifier
, ctx
)) != 0)
463 sessionIDLen
= sessionIdentifier
.length
;
467 * Since we're not in SSLv2 compatibility mode, only count non-SSLv2 ciphers.
470 numCipherSuites
= ctx
->numValidNonSSLv2Specs
;
472 numCipherSuites
= ctx
->numValidCipherSuites
;
475 /* RFC 5746 : add the fake ciphersuite unless we are including the extension */
476 if(!ctx
->secure_renegotiation
)
479 length
= 39 + 2*numCipherSuites
+ sessionIDLen
;
481 /* We always use the max enabled version in the ClientHello.client_version,
482 even in the renegotiation case. This value is saved in the context so it
483 can be used in the RSA key exchange */
484 err
= sslGetMaxProtVersion(ctx
, &ctx
->clientReqProtocol
);
486 /* we don't have a protocol enabled */
490 /* RFC 5746: If are starting a new handshake, so we didnt received this yet */
491 ctx
->secure_renegotiation_received
= false;
493 /* This is the protocol version used at the record layer, If we already
494 negotiated the protocol version previously, we should just use that,
495 otherwise we use the the minimum supported version.
496 We do not always use the minimum version because some TLS only servers
497 will reject an SSL 3 version in client_hello.
499 if(ctx
->negProtocolVersion
!= SSL_Version_Undetermined
) {
500 clientHello
->protocolVersion
= ctx
->negProtocolVersion
;
502 if(ctx
->minProtocolVersion
<TLS_Version_1_0
&& ctx
->maxProtocolVersion
>=TLS_Version_1_0
)
503 clientHello
->protocolVersion
= TLS_Version_1_0
;
505 clientHello
->protocolVersion
= ctx
->minProtocolVersion
;
509 if(clientHello
->protocolVersion
== DTLS_Version_1_0
) {
510 /* extra space for cookie */
511 /* TODO: cookie len - 0 for now */
512 length
+= 1 + ctx
->dtlsCookie
.length
;
513 sslLogNegotiateDebug("==DTLS Hello: len=%lu\n", length
);
515 /* Because of the way the version number for DTLS is encoded,
516 the following code mean that you can use extensions with DTLS... */
517 #endif /* ENABLE_DTLS */
519 /* RFC 5746: We add the extension only for renegotiation ClientHello */
520 if(ctx
->secure_renegotiation
) {
521 totalExtenLen
+= 2 + /* extension type */
522 2 + /* extension length */
523 1 + /* lenght of renegotiated_conection (client verify data) */
524 ctx
->ownVerifyData
.length
;
527 /* prepare for optional ClientHello extensions */
528 if((ctx
->clientReqProtocol
>= TLS_Version_1_0
) &&
529 (ctx
->peerDomainName
!= NULL
) &&
530 (ctx
->peerDomainNameLen
!= 0)) {
531 serverNameLen
= 2 + /* extension type */
532 2 + /* 2-byte vector length, extension_data */
533 2 + /* length of server_name_list */
534 1 + /* length of name_type */
535 2 + /* length of HostName */
536 ctx
->peerDomainNameLen
;
537 totalExtenLen
+= serverNameLen
;
539 if(ctx
->sessionTicket
.length
) {
540 sessionTicketLen
= 2 + /* extension type */
541 2 + /* 2-byte vector length, extension_data */
542 ctx
->sessionTicket
.length
;
543 totalExtenLen
+= sessionTicketLen
;
545 if((ctx
->clientReqProtocol
>= TLS_Version_1_0
) &&
546 (ctx
->ecdsaEnable
)) {
547 /* Two more extensions: point format, supported curves */
548 pointFormatLen
= 2 + /* extension type */
549 2 + /* 2-byte vector length, extension_data */
550 1 + /* length of the ec_point_format_list */
551 1; /* the single format we support */
552 suppCurveLen
= 2 + /* extension type */
553 2 + /* 2-byte vector length, extension_data */
554 2 + /* length of the elliptic_curve_list */
555 (2 * ctx
->ecdhNumCurves
); /* each curve is 2 bytes */
556 totalExtenLen
+= (pointFormatLen
+ suppCurveLen
);
559 ? ctx
->clientReqProtocol
< DTLS_Version_1_0
560 : ctx
->clientReqProtocol
>= TLS_Version_1_2
) {
561 signatureAlgorithmsLen
= 2 + /* extension type */
562 2 + /* 2-byte vector length, extension_data */
563 2 + /* length of signatureAlgorithms list */
564 2 * (ctx
->ecdsaEnable
? 5 : 3); //FIXME: 5:3 should not be hardcoded here.
565 totalExtenLen
+= signatureAlgorithmsLen
;
567 if(totalExtenLen
!= 0) {
569 * Total length extensions have to fit in a 16 bit field...
571 if(totalExtenLen
> 0xffff) {
572 sslErrorLog("Total extensions length EXCEEDED\n");
574 sessionTicketLen
= 0;
578 signatureAlgorithmsLen
= 0;
581 /* add length of total length plus lengths of extensions */
582 length
+= (totalExtenLen
+ 2);
586 clientHello
->contentType
= SSL_RecordTypeHandshake
;
587 head
= SSLHandshakeHeaderSize(clientHello
);
588 if ((err
= SSLAllocBuffer(&clientHello
->contents
, length
+ head
)))
591 p
= SSLEncodeHandshakeHeader(ctx
, clientHello
, SSL_HdskClientHello
, length
);
593 p
= SSLEncodeInt(p
, ctx
->clientReqProtocol
, 2);
595 sslLogNegotiateDebug("===SSL3 client: proclaiming max protocol "
596 "%d_%d capable ONLY",
597 ctx
->clientReqProtocol
>> 8, ctx
->clientReqProtocol
& 0xff);
598 if ((err
= SSLEncodeRandom(p
, ctx
)) != 0)
601 memcpy(ctx
->clientRandom
, p
, SSL_CLIENT_SRVR_RAND_SIZE
);
603 *p
++ = sessionIDLen
; /* 1 byte vector length */
604 if (sessionIDLen
> 0)
605 { memcpy(p
, sessionIdentifier
.data
, sessionIDLen
);
609 if (ctx
->clientReqProtocol
== DTLS_Version_1_0
) {
610 /* TODO: Add the cookie ! Currently: size=0 -> no cookie */
611 *p
++ = ctx
->dtlsCookie
.length
;
612 if(ctx
->dtlsCookie
.length
) {
613 memcpy(p
, ctx
->dtlsCookie
.data
, ctx
->dtlsCookie
.length
);
614 p
+=ctx
->dtlsCookie
.length
;
616 sslLogNegotiateDebug("==DTLS Hello: cookie len = %d\n",(int)ctx
->dtlsCookie
.length
);
621 p
= SSLEncodeInt(p
, 2*numCipherSuites
, 2);
622 /* 2 byte long vector length */
624 /* RFC 5746 : add the fake ciphersuite unless we are including the extension */
625 if(!ctx
->secure_renegotiation
)
626 p
= SSLEncodeInt(p
, TLS_EMPTY_RENEGOTIATION_INFO_SCSV
, 2);
628 for (i
= 0; i
<ctx
->numValidCipherSuites
; ++i
) {
630 if(CIPHER_SUITE_IS_SSLv2(ctx
->validCipherSuites
[i
])) {
634 sslLogNegotiateDebug("ssl3EncodeClientHello sending suite %x",
635 (unsigned)ctx
->validCipherSuites
[i
]);
636 p
= SSLEncodeInt(p
, ctx
->validCipherSuites
[i
], 2);
638 *p
++ = 1; /* 1 byte long vector */
639 *p
++ = 0; /* null compression */
642 * Append ClientHello extensions.
644 if(totalExtenLen
!= 0) {
645 /* first, total length of all extensions */
646 p
= SSLEncodeSize(p
, totalExtenLen
, 2);
648 if(ctx
->secure_renegotiation
){
649 assert(ctx
->ownVerifyData
.length
<=255);
650 p
= SSLEncodeInt(p
, SSL_HE_SecureRenegotation
, 2);
651 p
= SSLEncodeSize(p
, ctx
->ownVerifyData
.length
+1, 2);
652 p
= SSLEncodeSize(p
, ctx
->ownVerifyData
.length
, 1);
653 memcpy(p
, ctx
->ownVerifyData
.data
, ctx
->ownVerifyData
.length
);
654 p
+= ctx
->ownVerifyData
.length
;
656 if(sessionTicketLen
) {
657 sslEapDebug("Adding %lu bytes of sessionTicket to ClientHello",
658 ctx
->sessionTicket
.length
);
659 p
= SSLEncodeInt(p
, SSL_HE_SessionTicket
, 2);
660 p
= SSLEncodeSize(p
, ctx
->sessionTicket
.length
, 2);
661 memcpy(p
, ctx
->sessionTicket
.data
, ctx
->sessionTicket
.length
);
662 p
+= ctx
->sessionTicket
.length
;
665 sslEapDebug("Specifying ServerNameIndication");
666 p
= SSLEncodeInt(p
, SSL_HE_ServerName
, 2);
667 p
= SSLEncodeSize(p
, ctx
->peerDomainNameLen
+ 5, 2);
668 p
= SSLEncodeSize(p
, ctx
->peerDomainNameLen
+ 3, 2);
669 p
= SSLEncodeInt(p
, SSL_NT_HostName
, 1);
670 p
= SSLEncodeSize(p
, ctx
->peerDomainNameLen
, 2);
671 memcpy(p
, ctx
->peerDomainName
, ctx
->peerDomainNameLen
);
672 p
+= ctx
->peerDomainNameLen
;
675 UInt32 len
= 2 * ctx
->ecdhNumCurves
;
677 p
= SSLEncodeInt(p
, SSL_HE_EllipticCurves
, 2);
678 p
= SSLEncodeSize(p
, len
+2, 2); /* length of extension data */
679 p
= SSLEncodeSize(p
, len
, 2); /* length of elliptic_curve_list */
680 for(dex
=0; dex
<ctx
->ecdhNumCurves
; dex
++) {
681 sslEcdsaDebug("+++ adding supported curves %u to ClientHello",
682 (unsigned)ctx
->ecdhCurves
[dex
]);
683 p
= SSLEncodeInt(p
, ctx
->ecdhCurves
[dex
], 2);
687 sslEcdsaDebug("+++ adding point format to ClientHello");
688 p
= SSLEncodeInt(p
, SSL_HE_EC_PointFormats
, 2);
689 p
= SSLEncodeSize(p
, 2, 2); /* length of extension data */
690 p
= SSLEncodeSize(p
, 1, 1); /* length of ec_point_format_list */
691 p
= SSLEncodeInt(p
, SSL_PointFormatUncompressed
, 1);
693 if (signatureAlgorithmsLen
) {
694 sslEcdsaDebug("+++ adding signature algorithms to ClientHello");
695 /* TODO: Don't hardcode this */
696 /* We dont support SHA512 or SHA224 because we didnot implement the digest abstraction for those
697 and we dont keep a running hash for those.
698 We dont support SHA384/ECDSA because corecrypto ec does not support it with 256 bits curves */
699 UInt32 len
= 2 * (ctx
->ecdsaEnable
? 5 : 3); //FIXME: 5:3 should not be hardcoded here.
700 p
= SSLEncodeInt(p
, SSL_HE_SignatureAlgorithms
, 2);
701 p
= SSLEncodeSize(p
, len
+2, 2); /* length of extension data */
702 p
= SSLEncodeSize(p
, len
, 2); /* length of extension data */
703 // p = SSLEncodeInt(p, SSL_HashAlgorithmSHA512, 1);
704 // p = SSLEncodeInt(p, SSL_SignatureAlgorithmRSA, 1);
705 p
= SSLEncodeInt(p
, SSL_HashAlgorithmSHA384
, 1);
706 p
= SSLEncodeInt(p
, SSL_SignatureAlgorithmRSA
, 1);
707 p
= SSLEncodeInt(p
, SSL_HashAlgorithmSHA256
, 1);
708 p
= SSLEncodeInt(p
, SSL_SignatureAlgorithmRSA
, 1);
709 // p = SSLEncodeInt(p, SSL_HashAlgorithmSHA224, 1);
710 // p = SSLEncodeInt(p, SSL_SignatureAlgorithmRSA, 1);
711 p
= SSLEncodeInt(p
, SSL_HashAlgorithmSHA1
, 1);
712 p
= SSLEncodeInt(p
, SSL_SignatureAlgorithmRSA
, 1);
713 if (ctx
->ecdsaEnable
) {
714 // p = SSLEncodeInt(p, SSL_HashAlgorithmSHA512, 1);
715 // p = SSLEncodeInt(p, SSL_SignatureAlgorithmECDSA, 1);
716 // p = SSLEncodeInt(p, SSL_HashAlgorithmSHA384, 1);
717 // p = SSLEncodeInt(p, SSL_SignatureAlgorithmECDSA, 1);
718 p
= SSLEncodeInt(p
, SSL_HashAlgorithmSHA256
, 1);
719 p
= SSLEncodeInt(p
, SSL_SignatureAlgorithmECDSA
, 1);
720 // p = SSLEncodeInt(p, SSL_HashAlgorithmSHA224, 1);
721 // p = SSLEncodeInt(p, SSL_SignatureAlgorithmECDSA, 1);
722 p
= SSLEncodeInt(p
, SSL_HashAlgorithmSHA1
, 1);
723 p
= SSLEncodeInt(p
, SSL_SignatureAlgorithmECDSA
, 1);
727 sslLogNegotiateDebug("Client Hello : data=%p p=%p len=%08lx\n", clientHello
->contents
.data
, p
, (unsigned long)clientHello
->contents
.length
);
729 assert(p
== clientHello
->contents
.data
+ clientHello
->contents
.length
);
731 if ((err
= SSLInitMessageHashes(ctx
)) != 0)
736 SSLFreeBuffer(&clientHello
->contents
);
738 SSLFreeBuffer(&sessionIdentifier
);
744 SSLProcessClientHello(SSLBuffer message
, SSLContext
*ctx
)
746 SSLProtocolVersion negVersion
;
747 UInt16 cipherListLen
, cipherCount
, desiredSuite
, cipherSuite
;
748 UInt8 sessionIDLen
, compressionCount
;
751 UInt8
*eom
; /* end of message */
753 if (message
.length
< 41) {
754 sslErrorLog("SSLProcessClientHello: msg len error 1\n");
755 return errSSLProtocol
;
757 charPtr
= message
.data
;
758 eom
= charPtr
+ message
.length
;
759 ctx
->clientReqProtocol
= (SSLProtocolVersion
)SSLDecodeInt(charPtr
, 2);
761 err
= sslVerifyProtVersion(ctx
, ctx
->clientReqProtocol
, &negVersion
);
763 sslErrorLog("SSLProcessClientHello: protocol version error %04x - %04x\n", ctx
->clientReqProtocol
, negVersion
);
767 case SSL_Version_3_0
:
768 ctx
->sslTslCalls
= &Ssl3Callouts
;
770 case TLS_Version_1_0
:
771 case TLS_Version_1_1
:
772 case DTLS_Version_1_0
:
773 ctx
->sslTslCalls
= &Tls1Callouts
;
775 case TLS_Version_1_2
:
776 ctx
->sslTslCalls
= &Tls12Callouts
;
779 return errSSLNegotiation
;
781 ctx
->negProtocolVersion
= negVersion
;
782 err
= ctx
->recFuncs
->setProtocolVersion(ctx
->recCtx
, negVersion
);
786 sslLogNegotiateDebug("===SSL3 server: negVersion is %d_%d",
787 negVersion
>> 8, negVersion
& 0xff);
789 memcpy(ctx
->clientRandom
, charPtr
, SSL_CLIENT_SRVR_RAND_SIZE
);
791 sessionIDLen
= *(charPtr
++);
792 if (message
.length
< (unsigned)(41 + sessionIDLen
)) {
793 sslErrorLog("SSLProcessClientHello: msg len error 2\n");
794 return errSSLProtocol
;
796 /* FIXME peerID is never set on server side.... */
797 if (sessionIDLen
> 0 && ctx
->peerID
.data
!= 0)
798 { /* Don't die on error; just treat it as an uncacheable session */
799 err
= SSLAllocBuffer(&ctx
->sessionID
, sessionIDLen
);
801 memcpy(ctx
->sessionID
.data
, charPtr
, sessionIDLen
);
803 charPtr
+= sessionIDLen
;
806 /* TODO: actually do something with this cookie */
807 if(negVersion
==DTLS_Version_1_0
) {
808 UInt8 cookieLen
= *charPtr
++;
810 sslLogNegotiateDebug("cookieLen=%d\n", cookieLen
);
812 if((ctx
->dtlsCookie
.length
==0) || ((cookieLen
==ctx
->dtlsCookie
.length
) && (memcmp(ctx
->dtlsCookie
.data
, charPtr
, cookieLen
)==0)))
814 ctx
->cookieVerified
=true;
816 ctx
->cookieVerified
=false;
822 /* TODO: if we are about to send a HelloVerifyRequest, we probably dont need to process the cipherspecs */
825 cipherListLen
= (UInt16
)SSLDecodeInt(charPtr
, 2);
826 /* Count of cipherSuites, must be even & >= 2 */
828 if((charPtr
+ cipherListLen
) > eom
) {
829 sslErrorLog("SSLProcessClientHello: msg len error 5\n");
830 return errSSLProtocol
;
832 if ((cipherListLen
& 1) ||
833 (cipherListLen
< 2) ||
834 (message
.length
< (unsigned)(39 + sessionIDLen
+ cipherListLen
))) {
835 sslErrorLog("SSLProcessClientHello: msg len error 3\n");
836 return errSSLProtocol
;
838 cipherCount
= cipherListLen
/2;
839 cipherSuite
= 0xFFFF; /* No match marker */
840 while (cipherSuite
== 0xFFFF && cipherCount
--)
841 { desiredSuite
= (UInt16
)SSLDecodeInt(charPtr
, 2);
843 for (i
= 0; i
<ctx
->numValidCipherSuites
; i
++)
844 { if (ctx
->validCipherSuites
[i
] == desiredSuite
)
845 { cipherSuite
= desiredSuite
;
851 if (cipherSuite
== 0xFFFF)
852 return errSSLNegotiation
;
853 charPtr
+= 2 * cipherCount
; /* Advance past unchecked cipherCounts */
854 ctx
->selectedCipher
= cipherSuite
;
855 /* validate cipher later, after we get possible sessionTicket */
857 compressionCount
= *(charPtr
++);
858 if ((compressionCount
< 1) ||
860 (unsigned)(38 + sessionIDLen
+ cipherListLen
+ compressionCount
))) {
861 sslErrorLog("SSLProcessClientHello: msg len error 4\n");
862 return errSSLProtocol
;
864 /* Ignore list; we're doing null */
867 * Handle ClientHello extensions.
869 /* skip compression list */
870 charPtr
+= compressionCount
;
872 ptrdiff_t remLen
= eom
- charPtr
;
873 UInt32 totalExtensLen
;
878 * Not enough for extension type and length, but not an error...
879 * skip it and proceed.
881 sslEapDebug("SSLProcessClientHello: too small for any extension");
884 totalExtensLen
= SSLDecodeInt(charPtr
, 2);
886 if((charPtr
+ totalExtensLen
) > eom
) {
887 sslEapDebug("SSLProcessClientHello: too small for specified total_extension_length");
890 while(charPtr
< eom
) {
891 extenType
= SSLDecodeInt(charPtr
, 2);
893 extenLen
= SSLDecodeInt(charPtr
, 2);
895 if((charPtr
+ extenLen
) > eom
) {
896 sslEapDebug("SSLProcessClientHello: too small for specified extension_length");
900 #if SSL_PAC_SERVER_ENABLE
902 case SSL_HE_SessionTicket
:
903 SSLFreeBuffer(&ctx
->sessionTicket
);
904 SSLCopyBufferFromData(charPtr
, extenLen
, &ctx
->sessionTicket
);
905 sslEapDebug("Saved %lu bytes of sessionTicket from ClientHello",
906 (unsigned long)extenLen
);
909 case SSL_HE_ServerName
:
912 * This is for debug only (it's disabled for Deployment builds).
913 * Someday, I imagine we'll have a getter in the API to get this info.
916 UInt32 v
= SSLDecodeInt(cp
, 2);
918 sslEapDebug("SSL_HE_ServerName: length of server_name_list %lu",
920 v
= SSLDecodeInt(cp
, 1);
922 sslEapDebug("SSL_HE_ServerName: name_type %lu", (unsigned long)v
);
923 v
= SSLDecodeInt(cp
, 2);
925 sslEapDebug("SSL_HE_ServerName: length of HostName %lu",
927 char hostString
[v
+ 1];
928 memmove(hostString
, cp
, v
);
929 hostString
[v
] = '\0';
930 sslEapDebug("SSL_HE_ServerName: ServerName '%s'", hostString
);
933 case SSL_HE_SignatureAlgorithms
:
937 UInt8
*end
= charPtr
+ extenLen
;
939 UInt32 sigAlgsSize
= SSLDecodeInt(cp
, 2);
942 if (extenLen
!= sigAlgsSize
+ 2 || extenLen
& 1 || sigAlgsSize
& 1) {
943 sslEapDebug("SSL_HE_SignatureAlgorithms: odd length of signature algorithms list %lu %lu",
944 (unsigned long)extenLen
, (unsigned long)sigAlgsSize
);
948 ctx
->numClientSigAlgs
= sigAlgsSize
/ 2;
949 if(ctx
->clientSigAlgs
!= NULL
) {
950 sslFree(ctx
->clientSigAlgs
);
952 ctx
->clientSigAlgs
= (SSLSignatureAndHashAlgorithm
*)
953 sslMalloc((ctx
->numClientSigAlgs
) * sizeof(SSLSignatureAndHashAlgorithm
));
954 for(i
=0; i
<ctx
->numClientSigAlgs
; i
++) {
955 /* TODO: Validate hash and signature fields. */
956 ctx
->clientSigAlgs
[i
].hash
= *cp
++;
957 ctx
->clientSigAlgs
[i
].signature
= *cp
++;
958 sslLogNegotiateDebug("===Client specifies sigAlg %d %d",
959 ctx
->clientSigAlgs
[i
].hash
,
960 ctx
->clientSigAlgs
[i
].signature
);
966 sslEapDebug("SSLProcessClientHello: unknown extenType (%lu)",
967 (unsigned long)extenType
);
974 if ((err
= FindCipherSpec(ctx
)) != 0) {
977 sslLogNegotiateDebug("ssl3 server: selecting cipherKind 0x%x", (unsigned)ctx
->selectedCipher
);
978 if ((err
= SSLInitMessageHashes(ctx
)) != 0)
981 return errSecSuccess
;
985 OSStatus
sslTime(uint32_t *tim
)
990 return errSecSuccess
;
994 SSLEncodeRandom(unsigned char *p
, SSLContext
*ctx
)
995 { SSLBuffer randomData
;
999 if ((err
= sslTime(&now
)) != 0)
1001 SSLEncodeInt(p
, now
, 4);
1002 randomData
.data
= p
+4;
1003 randomData
.length
= 28;
1004 if((err
= sslRand(&randomData
)) != 0)
1006 return errSecSuccess
;
1010 SSLInitMessageHashes(SSLContext
*ctx
)
1013 if ((err
= CloseHash(&SSLHashSHA1
, &ctx
->shaState
)) != 0)
1015 if ((err
= CloseHash(&SSLHashMD5
, &ctx
->md5State
)) != 0)
1017 if ((err
= CloseHash(&SSLHashSHA256
, &ctx
->sha256State
)) != 0)
1019 if ((err
= CloseHash(&SSLHashSHA384
, &ctx
->sha512State
)) != 0)
1021 if ((err
= ReadyHash(&SSLHashSHA1
, &ctx
->shaState
)) != 0)
1023 if ((err
= ReadyHash(&SSLHashMD5
, &ctx
->md5State
)) != 0)
1025 if ((err
= ReadyHash(&SSLHashSHA256
, &ctx
->sha256State
)) != 0)
1027 if ((err
= ReadyHash(&SSLHashSHA384
, &ctx
->sha512State
)) != 0)
1029 return errSecSuccess
;