]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/lib/tlsCallbacks.c
Security-59754.41.1.tar.gz
[apple/security.git] / OSX / libsecurity_ssl / lib / tlsCallbacks.c
1 /*
2 * Copyright (c) 2013-2014 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 #include <stdio.h>
26 #include "tlsCallbacks.h"
27 #include "sslContext.h"
28 #include "sslCrypto.h"
29 #include "sslDebug.h"
30 #include "sslMemory.h"
31 #include <Security/SecCertificate.h>
32 #include <Security/SecCertificatePriv.h>
33 #include "utilities/SecCFRelease.h"
34
35 #include <tls_helpers.h>
36 #include <tls_cache.h>
37
38 #include "utilities/simulatecrash_assert.h"
39
40 static
41 int tls_handshake_write_callback(tls_handshake_ctx_t ctx, const SSLBuffer data, uint8_t content_type)
42 {
43 SSLContext *myCtx = (SSLContext *)ctx;
44 sslDebugLog("%p (rec.len=%zd, ct=%d, d[0]=%d)\n", myCtx, data.length, content_type, data.data[0]);
45
46 SSLRecord rec;
47
48 rec.contents=data;
49 rec.contentType=content_type;
50
51 return myCtx->recFuncs->write(myCtx->recCtx,rec);
52 }
53
54
55 static int
56 tls_handshake_message_callback(tls_handshake_ctx_t ctx, tls_handshake_message_t event)
57 {
58 SSLContext *myCtx = (SSLContext *)ctx;
59 const tls_buffer *npn_data;
60 const tls_buffer *alpn_data;
61 int err = 0;
62
63 sslDebugLog("%p, message = %d\n", ctx, event);
64
65 switch(event) {
66 case tls_handshake_message_certificate_request:
67 assert(myCtx->protocolSide == kSSLClientSide);
68 // Need to call this here, in case SetCertificate was already called.
69 myCtx->clientCertState = kSSLClientCertRequested;
70 myCtx->clientAuthTypes = tls_handshake_get_peer_acceptable_client_auth_type(myCtx->hdsk, &myCtx->numAuthTypes);
71 if (myCtx->breakOnCertRequest && (myCtx->localCertArray==NULL)) {
72 myCtx->signalCertRequest = true;
73 err = errSSLClientCertRequested;
74 }
75 break;
76 case tls_handshake_message_client_hello:
77 myCtx->peerSigAlgs = tls_handshake_get_peer_signature_algorithms(myCtx->hdsk, &myCtx->numPeerSigAlgs);
78 if (myCtx->breakOnClientHello) {
79 err = errSSLClientHelloReceived;
80 }
81 break;
82 case tls_handshake_message_server_hello:
83 myCtx->serverHelloReceived = true;
84 alpn_data = tls_handshake_get_peer_alpn_data(myCtx->hdsk);
85 if (alpn_data && myCtx->alpnFunc != NULL) {
86 myCtx->alpnFunc(myCtx, myCtx->alpnFuncInfo, alpn_data->data, alpn_data->length);
87 } else {
88 npn_data = tls_handshake_get_peer_npn_data(myCtx->hdsk);
89 if(npn_data) {
90 myCtx->npnFunc(myCtx, myCtx->npnFuncInfo, npn_data->data, npn_data->length);
91 }
92 }
93 myCtx->peerSigAlgs = tls_handshake_get_peer_signature_algorithms(myCtx->hdsk, &myCtx->numPeerSigAlgs);
94 break;
95 case tls_handshake_message_certificate:
96 /* For clients, we only check the cert when we receive the ServerHelloDone message.
97 For servers, we check the client's cert right here. For both we set the public key */
98 err = tls_helper_set_peer_pubkey(myCtx->hdsk);
99 if(!err && (myCtx->protocolSide == kSSLServerSide)) {
100 err = tls_verify_peer_cert(myCtx);
101 }
102 break;
103 case tls_handshake_message_server_hello_done:
104 err = tls_verify_peer_cert(myCtx);
105 break;
106 case tls_handshake_message_NPN_encrypted_extension:
107 npn_data = tls_handshake_get_peer_npn_data(myCtx->hdsk);
108 if(npn_data)
109 myCtx->npnFunc(myCtx, myCtx->npnFuncInfo, npn_data->data, npn_data->length);
110 break;
111 case tls_handshake_message_certificate_status:
112 break;
113 default:
114 break;
115 }
116
117 return err;
118 }
119
120 static void
121 tls_handshake_ready_callback(tls_handshake_ctx_t ctx, bool write, bool ready)
122 {
123 SSLContext *myCtx = (SSLContext *)ctx;
124
125 sslDebugLog("%p %s ready=%d\n", myCtx, write?"write":"read", ready);
126
127 if(write) {
128 myCtx->writeCipher_ready=ready?1:0;
129 } else {
130 myCtx->readCipher_ready=ready?1:0;
131 if(ready) {
132 SSLChangeHdskState(myCtx, SSL_HdskStateReady);
133 } else {
134 SSLChangeHdskState(myCtx, SSL_HdskStatePending);
135 }
136 }
137 }
138
139 static int
140 tls_handshake_set_retransmit_timer_callback(tls_handshake_ctx_t ctx, int attempt)
141 {
142 SSLContext *myCtx = (SSLContext *)ctx;
143
144 sslDebugLog("%p attempt=%d\n", ctx, attempt);
145
146 if(attempt) {
147 myCtx->timeout_deadline = CFAbsoluteTimeGetCurrent()+((1<<(attempt-1))*myCtx->timeout_duration);
148 } else {
149 myCtx->timeout_deadline = 0; // cancel the timeout
150 }
151 return 0;
152 }
153
154 static int
155 tls_handshake_init_pending_cipher_callback(tls_handshake_ctx_t ctx,
156 uint16_t selectedCipher,
157 bool server,
158 SSLBuffer key)
159 {
160 sslDebugLog("%p, cipher=%04x, server=%d\n", ctx, selectedCipher, server);
161 SSLContext *myCtx = (SSLContext *)ctx;
162 return myCtx->recFuncs->initPendingCiphers(myCtx->recCtx, selectedCipher, server, key);
163 }
164
165 static int
166 tls_handshake_advance_write_callback(tls_handshake_ctx_t ctx)
167 {
168 SSLContext *myCtx = (SSLContext *)ctx;
169 sslDebugLog("%p\n", myCtx);
170 //FIXME: need to filter on cipher too - require missing coretls ciphersuite header */
171 bool split = (myCtx->oneByteRecordEnable && (myCtx->negProtocolVersion<=TLS_Version_1_0));
172 myCtx->recFuncs->setOption(myCtx->recCtx, kSSLRecordOptionSendOneByteRecord, split);
173 return myCtx->recFuncs->advanceWriteCipher(myCtx->recCtx);
174 }
175
176 static
177 int tls_handshake_rollback_write_callback(tls_handshake_ctx_t ctx)
178 {
179 SSLContext *myCtx = (SSLContext *)ctx;
180 sslDebugLog("%p\n", myCtx);
181 return myCtx->recFuncs->rollbackWriteCipher(myCtx->recCtx);
182 }
183
184 static
185 int tls_handshake_advance_read_cipher_callback(tls_handshake_ctx_t ctx)
186 {
187 SSLContext *myCtx = (SSLContext *)ctx;
188 sslDebugLog("%p\n", myCtx);
189 return myCtx->recFuncs->advanceReadCipher(myCtx->recCtx);
190 }
191
192 static
193 int tls_handshake_set_protocol_version_callback(tls_handshake_ctx_t ctx,
194 tls_protocol_version protocolVersion)
195 {
196 SSLContext *myCtx = (SSLContext *)ctx;
197 myCtx->negProtocolVersion = protocolVersion;
198 return myCtx->recFuncs->setProtocolVersion(myCtx->recCtx, protocolVersion);
199 }
200
201 static int
202 _buildConfigurationSpecificSessionCacheKey(SSLContext *myCtx, SSLBuffer *sessionKey, SSLBuffer *outputBuffer)
203 {
204 SSLBuffer configurationBuffer;
205 configurationBuffer.data = NULL;
206 configurationBuffer.length = 0;
207 int err = SSLGetSessionConfigurationIdentifier(myCtx, &configurationBuffer);
208 if (err != errSecSuccess) {
209 return err;
210 }
211
212 outputBuffer->length = configurationBuffer.length + sessionKey->length;
213 outputBuffer->data = (uint8_t *) malloc(outputBuffer->length);
214 if (outputBuffer->data == NULL) {
215 free(configurationBuffer.data);
216 return errSecAllocate;
217 }
218
219 memcpy(outputBuffer->data, configurationBuffer.data, configurationBuffer.length);
220 memcpy(outputBuffer->data + configurationBuffer.length, sessionKey->data, sessionKey->length);
221
222 free(configurationBuffer.data);
223
224 return errSecSuccess;
225 }
226
227 static int
228 tls_handshake_save_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey, SSLBuffer sessionData)
229 {
230 int err = errSSLSessionNotFound;
231 SSLContext *myCtx = (SSLContext *)ctx;
232
233 if (myCtx->cache == NULL) {
234 return errSSLSessionNotFound;
235 }
236
237 SSLBuffer configurationSpecificKey;
238 configurationSpecificKey.data = NULL;
239 configurationSpecificKey.length = 0;
240 err = _buildConfigurationSpecificSessionCacheKey(myCtx, &sessionKey, &configurationSpecificKey);
241 if (err != errSecSuccess) {
242 return err;
243 }
244
245 sslDebugLog("%s: %p, key len=%zd, k[0]=%02x, data len=%zd\n", __FUNCTION__, myCtx, configurationSpecificKey.length, configurationSpecificKey.data[0], sessionData.length);
246
247 err = tls_cache_save_session_data(myCtx->cache, &configurationSpecificKey, &sessionData, myCtx->sessionCacheTimeout);
248
249 free(configurationSpecificKey.data);
250
251 return err;
252 }
253
254 static int
255 tls_handshake_load_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey, SSLBuffer *sessionData)
256 {
257 SSLContext *myCtx = (SSLContext *)ctx;
258 int err = errSSLSessionNotFound;
259
260 SSLFreeBuffer(&myCtx->resumableSession);
261 if (myCtx->cache == NULL) {
262 return errSSLSessionNotFound;
263 }
264
265 SSLBuffer configurationSpecificKey;
266 configurationSpecificKey.data = NULL;
267 configurationSpecificKey.length = 0;
268 err = _buildConfigurationSpecificSessionCacheKey(myCtx, &sessionKey, &configurationSpecificKey);
269 if (err != errSecSuccess) {
270 return err;
271 }
272
273 err = tls_cache_load_session_data(myCtx->cache, &configurationSpecificKey, &myCtx->resumableSession);
274 sslDebugLog("%p, key len=%zd, data len=%zd, err=%d\n", ctx, configurationSpecificKey.length, sessionData->length, err);
275 *sessionData = myCtx->resumableSession;
276
277 free(configurationSpecificKey.data);
278
279 return err;
280 }
281
282 static int
283 tls_handshake_delete_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey)
284 {
285 int err = errSSLSessionNotFound;
286 SSLContext *myCtx = (SSLContext *)ctx;
287
288 sslDebugLog("%p, key len=%zd k[0]=%02x\n", ctx, sessionKey.length, sessionKey.data[0]);
289 if(myCtx->cache) {
290 err = tls_cache_delete_session_data(myCtx->cache, &sessionKey);
291 }
292 return err;
293 }
294
295 static int
296 tls_handshake_delete_all_sessions_callback(tls_handshake_ctx_t ctx)
297 {
298 SSLContext *myCtx = (SSLContext *)ctx;
299 sslDebugLog("%p\n", ctx);
300
301 if(myCtx->cache) {
302 tls_cache_empty(myCtx->cache);
303 }
304 return 0;
305 }
306
307 tls_handshake_callbacks_t tls_handshake_callbacks = {
308 .write = tls_handshake_write_callback,
309 .message = tls_handshake_message_callback,
310 .ready = tls_handshake_ready_callback,
311 .set_retransmit_timer = tls_handshake_set_retransmit_timer_callback,
312 .save_session_data = tls_handshake_save_session_data_callback,
313 .load_session_data = tls_handshake_load_session_data_callback,
314 .delete_session_data = tls_handshake_delete_session_data_callback,
315 .delete_all_sessions = tls_handshake_delete_all_sessions_callback,
316 .init_pending_cipher = tls_handshake_init_pending_cipher_callback,
317 .advance_write_cipher = tls_handshake_advance_write_callback,
318 .rollback_write_cipher = tls_handshake_rollback_write_callback,
319 .advance_read_cipher = tls_handshake_advance_read_cipher_callback,
320 .set_protocol_version = tls_handshake_set_protocol_version_callback,
321 };