]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/regressions/ssl-48-split.c
Security-59306.11.20.tar.gz
[apple/security.git] / OSX / libsecurity_ssl / regressions / ssl-48-split.c
1 //
2 // ssl-48-crashes.c
3 // libsecurity_ssl
4 //
5 //
6
7
8 #include <stdbool.h>
9 #include <pthread.h>
10 #include <fcntl.h>
11 #include <sys/mman.h>
12 #include <unistd.h>
13
14 #include <CoreFoundation/CoreFoundation.h>
15
16 #include <AssertMacros.h>
17 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
18 #include <Security/SecureTransport.h>
19 #include <Security/SecPolicy.h>
20 #include <Security/SecTrust.h>
21 #include <Security/SecIdentity.h>
22 #include <Security/SecIdentityPriv.h>
23 #include <Security/SecCertificatePriv.h>
24 #include <Security/SecKeyPriv.h>
25 #include <Security/SecItem.h>
26 #include <Security/SecRandom.h>
27
28 #include <utilities/SecCFRelease.h>
29 #include <string.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <errno.h>
33 #include <stdlib.h>
34 #include <mach/mach_time.h>
35
36 #if TARGET_OS_IPHONE
37 #include <Security/SecRSAKey.h>
38 #endif
39
40 #include "ssl_regressions.h"
41 #include "ssl-utils.h"
42
43 #include <tls_stream_parser.h>
44
45
46 typedef struct {
47 SSLContextRef st;
48 bool is_server;
49 int comm;
50 CFArrayRef certs;
51 int write_counter;
52 tls_stream_parser_t parser;
53 size_t write_size;
54 } ssl_test_handle;
55
56
57 #pragma mark -
58 #pragma mark SecureTransport support
59
60 #if 0
61 static void hexdump(const char *s, const uint8_t *bytes, size_t len) {
62 size_t ix;
63 printf("socket %s(%p, %lu)\n", s, bytes, len);
64 for (ix = 0; ix < len; ++ix) {
65 if (!(ix % 16))
66 printf("\n");
67 printf("%02X ", bytes[ix]);
68 }
69 printf("\n");
70 }
71 #else
72 #define hexdump(string, bytes, len)
73 #endif
74
75 static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length)
76 {
77 ssl_test_handle *handle =(ssl_test_handle *)h;
78 int conn = handle->comm;
79 size_t len = *length;
80 uint8_t *ptr = (uint8_t *)data;
81
82 if(handle->is_server) {
83 //printf("SocketWrite: server write len=%zd\n", len);
84
85 tls_buffer buffer;
86 buffer.data = ptr;
87 buffer.length = len;
88 tls_stream_parser_parse(handle->parser, buffer);
89 }
90
91 do {
92 ssize_t ret;
93 do {
94 hexdump("write", ptr, len);
95 ret = write((int)conn, ptr, len);
96 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
97 if (ret > 0) {
98 len -= ret;
99 ptr += ret;
100 }
101 else
102 return -36;
103 } while (len > 0);
104
105 *length = *length - len;
106 return errSecSuccess;
107 }
108
109 static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length)
110 {
111 const ssl_test_handle *handle=h;
112 int conn = handle->comm;
113 size_t len = *length;
114 uint8_t *ptr = (uint8_t *)data;
115
116
117 do {
118 ssize_t ret;
119 do {
120 ret = read((int)conn, ptr, len);
121 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
122 if (ret > 0) {
123 len -= ret;
124 ptr += ret;
125 }
126 else
127 return -36;
128 } while (len > 0);
129
130 if(len!=0)
131 printf("Something went wrong here... len=%d\n", (int)len);
132
133 *length = *length - len;
134 return errSecSuccess;
135 }
136
137 static int process(tls_stream_parser_ctx_t ctx, tls_buffer record)
138 {
139 ssl_test_handle *handle = (ssl_test_handle *)ctx;
140
141 // printf("processing record len=%zd, type=%d\n", record.length, record.data[0]);
142 if(record.data[0]==tls_record_type_AppData) {
143 handle->write_counter++;
144 // printf("record count = %d\n", handle->write_counter);
145 }
146
147 return 0;
148 }
149
150
151 static void *securetransport_ssl_thread(void *arg)
152 {
153 OSStatus ortn;
154 ssl_test_handle * ssl = (ssl_test_handle *)arg;
155 SSLContextRef ctx = ssl->st;
156 bool got_server_auth = false;
157
158 //uint64_t start = mach_absolute_time();
159 do {
160 ortn = SSLHandshake(ctx);
161
162 if (ortn == errSSLServerAuthCompleted)
163 {
164 require_string(!got_server_auth, out, "second server auth");
165 got_server_auth = true;
166 }
167 } while (ortn == errSSLWouldBlock
168 || ortn == errSSLServerAuthCompleted);
169
170 require_noerr_action_quiet(ortn, out,
171 fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
172
173 unsigned char ibuf[90000], obuf[45000];
174
175 if (ssl->is_server) {
176 size_t len;
177 require_action(errSecSuccess==SecRandomCopyBytes(kSecRandomDefault, ssl->write_size, obuf), out, ortn = -1);
178 require_noerr(ortn = SSLWrite(ctx, obuf, ssl->write_size, &len), out);
179 require_action(len == ssl->write_size, out, ortn = -1);
180 require_noerr(ortn = SSLWrite(ctx, obuf, ssl->write_size, &len), out);
181 require_action(len == ssl->write_size, out, ortn = -1);
182 } else {
183 size_t len = ssl->write_size*2;
184 size_t olen;
185 unsigned char *p = ibuf;
186 while (len) {
187 require_noerr(ortn = SSLRead(ctx, p, len, &olen), out);
188 len -= olen;
189 p += olen;
190 }
191 }
192
193 out:
194 SSLClose(ctx);
195 CFRelease(ctx);
196 close(ssl->comm);
197 pthread_exit((void *)(intptr_t)ortn);
198 return NULL;
199 }
200
201 static void
202 ssl_test_handle_destroy(ssl_test_handle *handle)
203 {
204 if(handle) {
205 if(handle->parser) tls_stream_parser_destroy(handle->parser);
206 free(handle);
207 }
208 }
209
210 static ssl_test_handle *
211 ssl_test_handle_create(bool server, int comm, CFArrayRef certs)
212 {
213 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
214 SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType);
215
216 require(handle, out);
217 require(ctx, out);
218
219 require_noerr(SSLSetIOFuncs(ctx,
220 (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
221 require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)handle), out);
222
223 if (server)
224 require_noerr(SSLSetCertificate(ctx, certs), out);
225
226 require_noerr(SSLSetSessionOption(ctx,
227 kSSLSessionOptionBreakOnServerAuth, true), out);
228
229 /* Tell SecureTransport to not check certs itself: it will break out of the
230 handshake to let us take care of it instead. */
231 require_noerr(SSLSetEnableCertVerify(ctx, false), out);
232
233 handle->is_server = server;
234 handle->comm = comm;
235 handle->certs = certs;
236 handle->st = ctx;
237 handle->write_counter = 0;
238 handle->parser = tls_stream_parser_create(handle, process);
239
240 return handle;
241
242 out:
243 if (handle) free(handle);
244 if (ctx) CFRelease(ctx);
245 return NULL;
246 }
247
248 static SSLCipherSuite ciphers[] = {
249 TLS_RSA_WITH_AES_128_CBC_SHA,
250 //FIXME: re-enable this test when its fixed.
251 //TLS_RSA_WITH_RC4_128_SHA,
252 };
253 static int nciphers = sizeof(ciphers)/sizeof(ciphers[0]);
254
255 static SSLProtocol versions[] = {
256 kSSLProtocol3,
257 kTLSProtocol1,
258 kTLSProtocol11,
259 kTLSProtocol12,
260 };
261 static int nversions = sizeof(versions)/sizeof(versions[0]);
262
263 // { write size, expected count when nosplit, expected count when split }
264 static size_t wsizes[][3] = {
265 { 1, 2, 2 },
266 { 2, 2, 3 },
267 { 3, 2, 3 },
268 { 4, 2, 3 },
269 { 16384, 2, 3 },
270 { 16385, 4, 4 },
271 { 16386, 4, 5 },
272 { 16387, 4, 5 },
273 { 16388, 4, 5 },
274 { 32768, 4, 5 },
275 { 32769, 6, 6 },
276 { 32770, 6, 7 },
277 { 32771, 6, 7 },
278 { 32772, 6, 7 },
279 };
280 static int nwsizes = sizeof(wsizes)/sizeof(wsizes[0]);
281
282 static void
283 tests(void)
284 {
285 pthread_t client_thread, server_thread;
286 CFArrayRef server_certs = server_chain();
287 ok(server_certs, "got server certs");
288
289 int i,j,k,s;
290
291 for(i=0; i<nciphers; i++)
292 for(j=0; j<nversions; j++)
293 for(k=0; k<nwsizes; k++)
294 for(s=0; s<3; s++)
295 {
296 int sp[2];
297 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
298 fcntl(sp[0], F_SETNOSIGPIPE, 1);
299 fcntl(sp[1], F_SETNOSIGPIPE, 1);
300
301 ssl_test_handle *server, *client;
302
303 server = ssl_test_handle_create(true /*server*/, sp[0], server_certs);
304 client = ssl_test_handle_create(false/*client*/, sp[1], NULL);
305
306 server->write_size = wsizes[k][0];
307 client->write_size = wsizes[k][0];
308
309 require(client, out);
310 require(server, out);
311
312 require_noerr(SSLSetProtocolVersionMin(server->st, kSSLProtocol3), out); // We need this server to do SSL3.
313 require_noerr(SSLSetProtocolVersionMax(client->st, versions[j]), out);
314 require_noerr(SSLSetEnabledCiphers(client->st, &ciphers[i], 1), out);
315 if(s) {
316 // s=0: default (should be enabled)
317 // s=1: explicit enable
318 // s=2: expliciti disable
319 require_noerr(SSLSetSessionOption(server->st, kSSLSessionOptionSendOneByteRecord, (s==1)?true:false), out);
320 }
321 // printf("**** Test Case: i=%d, j=%d, k=%d (%zd), s=%d ****\n", i, j, k, wsizes[k][0], s);
322
323 pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
324 pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
325
326 intptr_t server_err, client_err;
327 pthread_join(client_thread, (void*)&client_err);
328 pthread_join(server_thread, (void*)&server_err);
329
330 ok(!server_err, "Server error = %ld", server_err);
331 ok(!client_err, "Client error = %ld", client_err);
332
333 /* one byte split is expected only for AES when using TLS 1.0 or lower, and when not disabled */
334 bool expected_split = (i==0) && (s!=2) && (versions[j]<=kTLSProtocol1);
335 int expected_count = (int)(expected_split ? wsizes[k][2]: wsizes[k][1]);
336
337 is(server->write_counter, expected_count, "wrong number of data records");
338
339 // fprintf(stderr, "Server write counter = %d, expected %d\n", server->write_counter, expected_count);
340
341 out:
342 ssl_test_handle_destroy(client);
343 ssl_test_handle_destroy(server);
344
345 }
346 CFReleaseNull(server_certs);
347 }
348
349 int ssl_48_split(int argc, char *const *argv)
350 {
351
352 plan_tests(1 + nciphers*nversions*nwsizes*3 * 3);
353
354
355 tests();
356
357 return 0;
358 }