2 * Copyright (c) 2013-2014 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 #include "tlsCallbacks.h"
27 #include "sslContext.h"
28 #include "sslCrypto.h"
30 #include "sslMemory.h"
31 #include <Security/SecCertificate.h>
32 #include <Security/SecCertificatePriv.h>
33 #include "utilities/SecCFRelease.h"
35 #include <tls_helpers.h>
36 #include <tls_cache.h>
39 int tls_handshake_write_callback(tls_handshake_ctx_t ctx
, const SSLBuffer data
, uint8_t content_type
)
41 SSLContext
*myCtx
= (SSLContext
*)ctx
;
42 sslDebugLog("%p (rec.len=%zd, ct=%d, d[0]=%d)\n", myCtx
, data
.length
, content_type
, data
.data
[0]);
47 rec
.contentType
=content_type
;
49 return myCtx
->recFuncs
->write(myCtx
->recCtx
,rec
);
54 tls_handshake_message_callback(tls_handshake_ctx_t ctx
, tls_handshake_message_t event
)
56 SSLContext
*myCtx
= (SSLContext
*)ctx
;
57 const tls_buffer
*npn_data
;
58 const tls_buffer
*alpn_data
;
61 sslDebugLog("%p, message = %d\n", ctx
, event
);
64 case tls_handshake_message_certificate_request
:
65 assert(myCtx
->protocolSide
== kSSLClientSide
);
66 // Need to call this here, in case SetCertificate was already called.
67 myCtx
->clientCertState
= kSSLClientCertRequested
;
68 myCtx
->clientAuthTypes
= tls_handshake_get_peer_acceptable_client_auth_type(myCtx
->hdsk
, &myCtx
->numAuthTypes
);
69 if (myCtx
->breakOnCertRequest
&& (myCtx
->localCertArray
==NULL
)) {
70 myCtx
->signalCertRequest
= true;
71 err
= errSSLClientCertRequested
;
74 case tls_handshake_message_client_hello
:
75 myCtx
->peerSigAlgs
= tls_handshake_get_peer_signature_algorithms(myCtx
->hdsk
, &myCtx
->numPeerSigAlgs
);
76 if (myCtx
->breakOnClientHello
) {
77 err
= errSSLClientHelloReceived
;
80 case tls_handshake_message_server_hello
:
81 myCtx
->serverHelloReceived
= true;
82 alpn_data
= tls_handshake_get_peer_alpn_data(myCtx
->hdsk
);
84 myCtx
->alpnFunc(myCtx
, myCtx
->alpnFuncInfo
, alpn_data
->data
, alpn_data
->length
);
86 npn_data
= tls_handshake_get_peer_npn_data(myCtx
->hdsk
);
88 myCtx
->npnFunc(myCtx
, myCtx
->npnFuncInfo
, npn_data
->data
, npn_data
->length
);
91 myCtx
->peerSigAlgs
= tls_handshake_get_peer_signature_algorithms(myCtx
->hdsk
, &myCtx
->numPeerSigAlgs
);
93 case tls_handshake_message_certificate
:
94 /* For clients, we only check the cert when we receive the ServerHelloDone message.
95 For servers, we check the client's cert right here. For both we set the public key */
96 err
= tls_helper_set_peer_pubkey(myCtx
->hdsk
);
97 if(!err
&& (myCtx
->protocolSide
== kSSLServerSide
)) {
98 err
= tls_verify_peer_cert(myCtx
);
101 case tls_handshake_message_server_hello_done
:
102 err
= tls_verify_peer_cert(myCtx
);
104 case tls_handshake_message_NPN_encrypted_extension
:
105 npn_data
= tls_handshake_get_peer_npn_data(myCtx
->hdsk
);
107 myCtx
->npnFunc(myCtx
, myCtx
->npnFuncInfo
, npn_data
->data
, npn_data
->length
);
109 case tls_handshake_message_certificate_status
:
119 tls_handshake_ready_callback(tls_handshake_ctx_t ctx
, bool write
, bool ready
)
121 SSLContext
*myCtx
= (SSLContext
*)ctx
;
123 sslDebugLog("%p %s ready=%d\n", myCtx
, write
?"write":"read", ready
);
126 myCtx
->writeCipher_ready
=ready
?1:0;
128 myCtx
->readCipher_ready
=ready
?1:0;
130 SSLChangeHdskState(myCtx
, SSL_HdskStateReady
);
132 SSLChangeHdskState(myCtx
, SSL_HdskStatePending
);
138 tls_handshake_set_retransmit_timer_callback(tls_handshake_ctx_t ctx
, int attempt
)
140 SSLContext
*myCtx
= (SSLContext
*)ctx
;
142 sslDebugLog("%p attempt=%d\n", ctx
, attempt
);
145 myCtx
->timeout_deadline
= CFAbsoluteTimeGetCurrent()+((1<<(attempt
-1))*myCtx
->timeout_duration
);
147 myCtx
->timeout_deadline
= 0; // cancel the timeout
153 tls_handshake_init_pending_cipher_callback(tls_handshake_ctx_t ctx
,
154 uint16_t selectedCipher
,
158 sslDebugLog("%p, cipher=%04x, server=%d\n", ctx
, selectedCipher
, server
);
159 SSLContext
*myCtx
= (SSLContext
*)ctx
;
160 return myCtx
->recFuncs
->initPendingCiphers(myCtx
->recCtx
, selectedCipher
, server
, key
);
164 tls_handshake_advance_write_callback(tls_handshake_ctx_t ctx
)
166 SSLContext
*myCtx
= (SSLContext
*)ctx
;
167 sslDebugLog("%p\n", myCtx
);
168 //FIXME: need to filter on cipher too - require missing coretls ciphersuite header */
169 bool split
= (myCtx
->oneByteRecordEnable
&& (myCtx
->negProtocolVersion
<=TLS_Version_1_0
));
170 myCtx
->recFuncs
->setOption(myCtx
->recCtx
, kSSLRecordOptionSendOneByteRecord
, split
);
171 return myCtx
->recFuncs
->advanceWriteCipher(myCtx
->recCtx
);
175 int tls_handshake_rollback_write_callback(tls_handshake_ctx_t ctx
)
177 SSLContext
*myCtx
= (SSLContext
*)ctx
;
178 sslDebugLog("%p\n", myCtx
);
179 return myCtx
->recFuncs
->rollbackWriteCipher(myCtx
->recCtx
);
183 int tls_handshake_advance_read_cipher_callback(tls_handshake_ctx_t ctx
)
185 SSLContext
*myCtx
= (SSLContext
*)ctx
;
186 sslDebugLog("%p\n", myCtx
);
187 return myCtx
->recFuncs
->advanceReadCipher(myCtx
->recCtx
);
191 int tls_handshake_set_protocol_version_callback(tls_handshake_ctx_t ctx
,
192 tls_protocol_version protocolVersion
)
194 SSLContext
*myCtx
= (SSLContext
*)ctx
;
195 myCtx
->negProtocolVersion
= protocolVersion
;
196 return myCtx
->recFuncs
->setProtocolVersion(myCtx
->recCtx
, protocolVersion
);
200 tls_handshake_save_session_data_callback(tls_handshake_ctx_t ctx
, SSLBuffer sessionKey
, SSLBuffer sessionData
)
202 int err
= errSSLSessionNotFound
;
203 SSLContext
*myCtx
= (SSLContext
*)ctx
;
205 sslDebugLog("%s: %p, key len=%zd, k[0]=%02x, data len=%zd\n", __FUNCTION__
, myCtx
, sessionKey
.length
, sessionKey
.data
[0], sessionData
.length
);
208 err
= tls_cache_save_session_data(myCtx
->cache
, &sessionKey
, &sessionData
, myCtx
->sessionCacheTimeout
);
214 tls_handshake_load_session_data_callback(tls_handshake_ctx_t ctx
, SSLBuffer sessionKey
, SSLBuffer
*sessionData
)
216 SSLContext
*myCtx
= (SSLContext
*)ctx
;
217 int err
= errSSLSessionNotFound
;
219 SSLFreeBuffer(&myCtx
->resumableSession
);
221 err
= tls_cache_load_session_data(myCtx
->cache
, &sessionKey
, &myCtx
->resumableSession
);
223 sslDebugLog("%p, key len=%zd, data len=%zd, err=%d\n", ctx
, sessionKey
.length
, sessionData
->length
, err
);
224 *sessionData
= myCtx
->resumableSession
;
230 tls_handshake_delete_session_data_callback(tls_handshake_ctx_t ctx
, SSLBuffer sessionKey
)
232 int err
= errSSLSessionNotFound
;
233 SSLContext
*myCtx
= (SSLContext
*)ctx
;
235 sslDebugLog("%p, key len=%zd k[0]=%02x\n", ctx
, sessionKey
.length
, sessionKey
.data
[0]);
237 err
= tls_cache_delete_session_data(myCtx
->cache
, &sessionKey
);
243 tls_handshake_delete_all_sessions_callback(tls_handshake_ctx_t ctx
)
245 SSLContext
*myCtx
= (SSLContext
*)ctx
;
246 sslDebugLog("%p\n", ctx
);
249 tls_cache_empty(myCtx
->cache
);
254 tls_handshake_callbacks_t tls_handshake_callbacks
= {
255 .write
= tls_handshake_write_callback
,
256 .message
= tls_handshake_message_callback
,
257 .ready
= tls_handshake_ready_callback
,
258 .set_retransmit_timer
= tls_handshake_set_retransmit_timer_callback
,
259 .save_session_data
= tls_handshake_save_session_data_callback
,
260 .load_session_data
= tls_handshake_load_session_data_callback
,
261 .delete_session_data
= tls_handshake_delete_session_data_callback
,
262 .delete_all_sessions
= tls_handshake_delete_all_sessions_callback
,
263 .init_pending_cipher
= tls_handshake_init_pending_cipher_callback
,
264 .advance_write_cipher
= tls_handshake_advance_write_callback
,
265 .rollback_write_cipher
= tls_handshake_rollback_write_callback
,
266 .advance_read_cipher
= tls_handshake_advance_read_cipher_callback
,
267 .set_protocol_version
= tls_handshake_set_protocol_version_callback
,