]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/lib/tlsCallbacks.c
Security-57336.10.29.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 "appleSession.h"
32 #include <Security/SecCertificate.h>
33 #include <Security/SecCertificatePriv.h>
34 #include "utilities/SecCFRelease.h"
35
36
37 static
38 int tls_handshake_write_callback(tls_handshake_ctx_t ctx, const SSLBuffer data, uint8_t content_type)
39 {
40 SSLContext *myCtx = (SSLContext *)ctx;
41 sslDebugLog("%p (rec.len=%zd, ct=%d, d[0]=%d)\n", myCtx, data.length, content_type, data.data[0]);
42
43 SSLRecord rec;
44
45 rec.contents=data;
46 rec.contentType=content_type;
47
48 return myCtx->recFuncs->write(myCtx->recCtx,rec);
49 }
50
51
52 static int
53 tls_handshake_message_callback(tls_handshake_ctx_t ctx, tls_handshake_message_t event)
54 {
55 SSLContext *myCtx = (SSLContext *)ctx;
56 const tls_buffer *npn_data;
57 const tls_buffer *alpn_data;
58 int err = 0;
59
60 sslDebugLog("%p, message = %d\n", ctx, event);
61
62 switch(event) {
63 case tls_handshake_message_certificate_request:
64 assert(myCtx->protocolSide == kSSLClientSide);
65 // Need to call this here, in case SetCertificate was already called.
66 myCtx->clientCertState = kSSLClientCertRequested;
67 myCtx->clientAuthTypes = tls_handshake_get_peer_acceptable_client_auth_type(myCtx->hdsk, &myCtx->numAuthTypes);
68 SSLUpdateNegotiatedClientAuthType(myCtx);
69 if (myCtx->breakOnCertRequest && (myCtx->localCert==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_set_peer_pubkey(myCtx);
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 SSLContext *myCtx = (SSLContext *)ctx;
203 sslDebugLog("%s: %p, key len=%zd, k[0]=%02x, data len=%zd\n", __FUNCTION__, myCtx, sessionKey.length, sessionKey.data[0], sessionData.length);
204 return sslAddSession(sessionKey, sessionData, myCtx->sessionCacheTimeout);
205 }
206
207 static int
208 tls_handshake_load_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey, SSLBuffer *sessionData)
209 {
210 SSLContext *myCtx = (SSLContext *)ctx;
211 int err;
212
213 SSLFreeBuffer(&myCtx->resumableSession);
214 err = sslCopySession(sessionKey, &myCtx->resumableSession);
215
216 sslDebugLog("%p, key len=%zd, data len=%zd, err=%d\n", ctx, sessionKey.length, sessionData->length, err);
217
218 *sessionData = myCtx->resumableSession;
219
220 return err;
221 }
222
223 static int
224 tls_handshake_delete_session_data_callback(tls_handshake_ctx_t ctx, SSLBuffer sessionKey)
225 {
226 sslDebugLog("%p, key len=%zd k[0]=%02x\n", ctx, sessionKey.length, sessionKey.data[0]);
227 return sslDeleteSession(sessionKey);
228 }
229
230 static int
231 tls_handshake_delete_all_sessions_callback(tls_handshake_ctx_t ctx)
232 {
233 sslDebugLog("%p\n", ctx);
234
235 return sslCleanupSession();
236 }
237
238 tls_handshake_callbacks_t tls_handshake_callbacks = {
239 .write = tls_handshake_write_callback,
240 .message = tls_handshake_message_callback,
241 .ready = tls_handshake_ready_callback,
242 .set_retransmit_timer = tls_handshake_set_retransmit_timer_callback,
243 .save_session_data = tls_handshake_save_session_data_callback,
244 .load_session_data = tls_handshake_load_session_data_callback,
245 .delete_session_data = tls_handshake_delete_session_data_callback,
246 .delete_all_sessions = tls_handshake_delete_all_sessions_callback,
247 .init_pending_cipher = tls_handshake_init_pending_cipher_callback,
248 .advance_write_cipher = tls_handshake_advance_write_callback,
249 .rollback_write_cipher = tls_handshake_rollback_write_callback,
250 .advance_read_cipher = tls_handshake_advance_read_cipher_callback,
251 .set_protocol_version = tls_handshake_set_protocol_version_callback,
252 };
253
254