]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/lib/tlsCallbacks.c
Security-58286.200.222.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 static
39 int tls_handshake_write_callback(tls_handshake_ctx_t ctx, const SSLBuffer data, uint8_t content_type)
40 {
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]);
43
44 SSLRecord rec;
45
46 rec.contents=data;
47 rec.contentType=content_type;
48
49 return myCtx->recFuncs->write(myCtx->recCtx,rec);
50 }
51
52
53 static int
54 tls_handshake_message_callback(tls_handshake_ctx_t ctx, tls_handshake_message_t event)
55 {
56 SSLContext *myCtx = (SSLContext *)ctx;
57 const tls_buffer *npn_data;
58 const tls_buffer *alpn_data;
59 int err = 0;
60
61 sslDebugLog("%p, message = %d\n", ctx, event);
62
63 switch(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;
72 }
73 break;
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;
78 }
79 break;
80 case tls_handshake_message_server_hello:
81 myCtx->serverHelloReceived = true;
82 alpn_data = tls_handshake_get_peer_alpn_data(myCtx->hdsk);
83 if (alpn_data && myCtx->alpnFunc != NULL) {
84 myCtx->alpnFunc(myCtx, myCtx->alpnFuncInfo, alpn_data->data, alpn_data->length);
85 } else {
86 npn_data = tls_handshake_get_peer_npn_data(myCtx->hdsk);
87 if(npn_data) {
88 myCtx->npnFunc(myCtx, myCtx->npnFuncInfo, npn_data->data, npn_data->length);
89 }
90 }
91 myCtx->peerSigAlgs = tls_handshake_get_peer_signature_algorithms(myCtx->hdsk, &myCtx->numPeerSigAlgs);
92 break;
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);
99 }
100 break;
101 case tls_handshake_message_server_hello_done:
102 err = tls_verify_peer_cert(myCtx);
103 break;
104 case tls_handshake_message_NPN_encrypted_extension:
105 npn_data = tls_handshake_get_peer_npn_data(myCtx->hdsk);
106 if(npn_data)
107 myCtx->npnFunc(myCtx, myCtx->npnFuncInfo, npn_data->data, npn_data->length);
108 break;
109 case tls_handshake_message_certificate_status:
110 break;
111 default:
112 break;
113 }
114
115 return err;
116 }
117
118 static void
119 tls_handshake_ready_callback(tls_handshake_ctx_t ctx, bool write, bool ready)
120 {
121 SSLContext *myCtx = (SSLContext *)ctx;
122
123 sslDebugLog("%p %s ready=%d\n", myCtx, write?"write":"read", ready);
124
125 if(write) {
126 myCtx->writeCipher_ready=ready?1:0;
127 } else {
128 myCtx->readCipher_ready=ready?1:0;
129 if(ready) {
130 SSLChangeHdskState(myCtx, SSL_HdskStateReady);
131 } else {
132 SSLChangeHdskState(myCtx, SSL_HdskStatePending);
133 }
134 }
135 }
136
137 static int
138 tls_handshake_set_retransmit_timer_callback(tls_handshake_ctx_t ctx, int attempt)
139 {
140 SSLContext *myCtx = (SSLContext *)ctx;
141
142 sslDebugLog("%p attempt=%d\n", ctx, attempt);
143
144 if(attempt) {
145 myCtx->timeout_deadline = CFAbsoluteTimeGetCurrent()+((1<<(attempt-1))*myCtx->timeout_duration);
146 } else {
147 myCtx->timeout_deadline = 0; // cancel the timeout
148 }
149 return 0;
150 }
151
152 static int
153 tls_handshake_init_pending_cipher_callback(tls_handshake_ctx_t ctx,
154 uint16_t selectedCipher,
155 bool server,
156 SSLBuffer key)
157 {
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);
161 }
162
163 static int
164 tls_handshake_advance_write_callback(tls_handshake_ctx_t ctx)
165 {
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);
172 }
173
174 static
175 int tls_handshake_rollback_write_callback(tls_handshake_ctx_t ctx)
176 {
177 SSLContext *myCtx = (SSLContext *)ctx;
178 sslDebugLog("%p\n", myCtx);
179 return myCtx->recFuncs->rollbackWriteCipher(myCtx->recCtx);
180 }
181
182 static
183 int tls_handshake_advance_read_cipher_callback(tls_handshake_ctx_t ctx)
184 {
185 SSLContext *myCtx = (SSLContext *)ctx;
186 sslDebugLog("%p\n", myCtx);
187 return myCtx->recFuncs->advanceReadCipher(myCtx->recCtx);
188 }
189
190 static
191 int tls_handshake_set_protocol_version_callback(tls_handshake_ctx_t ctx,
192 tls_protocol_version protocolVersion)
193 {
194 SSLContext *myCtx = (SSLContext *)ctx;
195 myCtx->negProtocolVersion = protocolVersion;
196 return myCtx->recFuncs->setProtocolVersion(myCtx->recCtx, protocolVersion);
197 }
198
199 static int
200 _buildConfigurationSpecificSessionCacheKey(SSLContext *myCtx, SSLBuffer *sessionKey, SSLBuffer *outputBuffer)
201 {
202 SSLBuffer configurationBuffer;
203 configurationBuffer.data = NULL;
204 configurationBuffer.length = 0;
205 int err = SSLGetSessionConfigurationIdentifier(myCtx, &configurationBuffer);
206 if (err != errSecSuccess) {
207 return err;
208 }
209
210 outputBuffer->length = configurationBuffer.length + sessionKey->length;
211 outputBuffer->data = (uint8_t *) malloc(outputBuffer->length);
212 if (outputBuffer->data == NULL) {
213 free(configurationBuffer.data);
214 return errSecAllocate;
215 }
216
217 memcpy(outputBuffer->data, configurationBuffer.data, configurationBuffer.length);
218 memcpy(outputBuffer->data + configurationBuffer.length, sessionKey->data, sessionKey->length);
219
220 free(configurationBuffer.data);
221
222 return errSecSuccess;
223 }
224
225 static int
226 tls_handshake_save_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey, SSLBuffer sessionData)
227 {
228 int err = errSSLSessionNotFound;
229 SSLContext *myCtx = (SSLContext *)ctx;
230
231 if (myCtx->cache == NULL) {
232 return errSSLSessionNotFound;
233 }
234
235 SSLBuffer configurationSpecificKey;
236 configurationSpecificKey.data = NULL;
237 configurationSpecificKey.length = 0;
238 err = _buildConfigurationSpecificSessionCacheKey(myCtx, &sessionKey, &configurationSpecificKey);
239 if (err != errSecSuccess) {
240 return err;
241 }
242
243 sslDebugLog("%s: %p, key len=%zd, k[0]=%02x, data len=%zd\n", __FUNCTION__, myCtx, configurationSpecificKey.length, configurationSpecificKey.data[0], sessionData.length);
244
245 err = tls_cache_save_session_data(myCtx->cache, &configurationSpecificKey, &sessionData, myCtx->sessionCacheTimeout);
246
247 free(configurationSpecificKey.data);
248
249 return err;
250 }
251
252 static int
253 tls_handshake_load_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey, SSLBuffer *sessionData)
254 {
255 SSLContext *myCtx = (SSLContext *)ctx;
256 int err = errSSLSessionNotFound;
257
258 SSLFreeBuffer(&myCtx->resumableSession);
259 if (myCtx->cache == NULL) {
260 return errSSLSessionNotFound;
261 }
262
263 SSLBuffer configurationSpecificKey;
264 configurationSpecificKey.data = NULL;
265 configurationSpecificKey.length = 0;
266 err = _buildConfigurationSpecificSessionCacheKey(myCtx, &sessionKey, &configurationSpecificKey);
267 if (err != errSecSuccess) {
268 return err;
269 }
270
271 err = tls_cache_load_session_data(myCtx->cache, &configurationSpecificKey, &myCtx->resumableSession);
272 sslDebugLog("%p, key len=%zd, data len=%zd, err=%d\n", ctx, configurationSpecificKey.length, sessionData->length, err);
273 *sessionData = myCtx->resumableSession;
274
275 free(configurationSpecificKey.data);
276
277 return err;
278 }
279
280 static int
281 tls_handshake_delete_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey)
282 {
283 int err = errSSLSessionNotFound;
284 SSLContext *myCtx = (SSLContext *)ctx;
285
286 sslDebugLog("%p, key len=%zd k[0]=%02x\n", ctx, sessionKey.length, sessionKey.data[0]);
287 if(myCtx->cache) {
288 err = tls_cache_delete_session_data(myCtx->cache, &sessionKey);
289 }
290 return err;
291 }
292
293 static int
294 tls_handshake_delete_all_sessions_callback(tls_handshake_ctx_t ctx)
295 {
296 SSLContext *myCtx = (SSLContext *)ctx;
297 sslDebugLog("%p\n", ctx);
298
299 if(myCtx->cache) {
300 tls_cache_empty(myCtx->cache);
301 }
302 return 0;
303 }
304
305 tls_handshake_callbacks_t tls_handshake_callbacks = {
306 .write = tls_handshake_write_callback,
307 .message = tls_handshake_message_callback,
308 .ready = tls_handshake_ready_callback,
309 .set_retransmit_timer = tls_handshake_set_retransmit_timer_callback,
310 .save_session_data = tls_handshake_save_session_data_callback,
311 .load_session_data = tls_handshake_load_session_data_callback,
312 .delete_session_data = tls_handshake_delete_session_data_callback,
313 .delete_all_sessions = tls_handshake_delete_all_sessions_callback,
314 .init_pending_cipher = tls_handshake_init_pending_cipher_callback,
315 .advance_write_cipher = tls_handshake_advance_write_callback,
316 .rollback_write_cipher = tls_handshake_rollback_write_callback,
317 .advance_read_cipher = tls_handshake_advance_read_cipher_callback,
318 .set_protocol_version = tls_handshake_set_protocol_version_callback,
319 };