]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/lib/tlsCallbacks.c
Security-57740.31.2.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) {
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 tls_handshake_save_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey, SSLBuffer sessionData)
201 {
202 int err = errSSLSessionNotFound;
203 SSLContext *myCtx = (SSLContext *)ctx;
204
205 sslDebugLog("%s: %p, key len=%zd, k[0]=%02x, data len=%zd\n", __FUNCTION__, myCtx, sessionKey.length, sessionKey.data[0], sessionData.length);
206
207 if(myCtx->cache) {
208 err = tls_cache_save_session_data(myCtx->cache, &sessionKey, &sessionData, myCtx->sessionCacheTimeout);
209 }
210 return err;
211 }
212
213 static int
214 tls_handshake_load_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey, SSLBuffer *sessionData)
215 {
216 SSLContext *myCtx = (SSLContext *)ctx;
217 int err = errSSLSessionNotFound;
218
219 SSLFreeBuffer(&myCtx->resumableSession);
220 if(myCtx->cache) {
221 err = tls_cache_load_session_data(myCtx->cache, &sessionKey, &myCtx->resumableSession);
222 }
223 sslDebugLog("%p, key len=%zd, data len=%zd, err=%d\n", ctx, sessionKey.length, sessionData->length, err);
224 *sessionData = myCtx->resumableSession;
225
226 return err;
227 }
228
229 static int
230 tls_handshake_delete_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey)
231 {
232 int err = errSSLSessionNotFound;
233 SSLContext *myCtx = (SSLContext *)ctx;
234
235 sslDebugLog("%p, key len=%zd k[0]=%02x\n", ctx, sessionKey.length, sessionKey.data[0]);
236 if(myCtx->cache) {
237 err = tls_cache_delete_session_data(myCtx->cache, &sessionKey);
238 }
239 return err;
240 }
241
242 static int
243 tls_handshake_delete_all_sessions_callback(tls_handshake_ctx_t ctx)
244 {
245 SSLContext *myCtx = (SSLContext *)ctx;
246 sslDebugLog("%p\n", ctx);
247
248 if(myCtx->cache) {
249 tls_cache_empty(myCtx->cache);
250 }
251 return 0;
252 }
253
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,
268 };