]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/regressions/ssl-51-state.c
Security-59306.61.1.tar.gz
[apple/security.git] / OSX / libsecurity_ssl / regressions / ssl-51-state.c
1 //
2 // ssl-51-state.c
3 // libsecurity_ssl
4 //
5
6 #include <stdbool.h>
7 #include <pthread.h>
8 #include <fcntl.h>
9 #include <sys/mman.h>
10 #include <unistd.h>
11
12 #include <CoreFoundation/CoreFoundation.h>
13
14 #include <AssertMacros.h>
15 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
16 #include <Security/SecureTransport.h>
17 #include <Security/SecPolicy.h>
18 #include <Security/SecTrust.h>
19 #include <Security/SecIdentity.h>
20 #include <Security/SecIdentityPriv.h>
21 #include <Security/SecCertificatePriv.h>
22 #include <Security/SecKeyPriv.h>
23 #include <Security/SecItem.h>
24 #include <Security/SecRandom.h>
25
26 #include <string.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <errno.h>
30 #include <stdlib.h>
31 #include <mach/mach_time.h>
32
33 #if TARGET_OS_IPHONE
34 #include <Security/SecRSAKey.h>
35 #endif
36
37 #include "ssl_regressions.h"
38 #include "ssl-utils.h"
39
40 #include <tls_stream_parser.h>
41 #include <tls_handshake.h>
42 #include <tls_record.h>
43
44 #include <sys/queue.h>
45
46
47 #define test_printf(x...)
48
49 /* extern struct ccrng_state *ccDRBGGetRngState(); */
50 #include <CommonCrypto/CommonRandomSPI.h>
51 #define CCRNGSTATE ccDRBGGetRngState()
52
53 struct RecQueueItem {
54 STAILQ_ENTRY(RecQueueItem) next; /* link to next queued entry or NULL */
55 tls_buffer record;
56 size_t offset; /* byte reads from this one */
57 };
58
59 typedef struct {
60 SSLContextRef st;
61 tls_stream_parser_t parser;
62 tls_record_t record;
63 tls_handshake_t hdsk;
64 STAILQ_HEAD(, RecQueueItem) rec_queue; // coretls server queue packet in this queue
65 int ready_count;
66 } ssl_test_handle;
67
68
69 static
70 int tls_buffer_alloc(tls_buffer *buf, size_t length)
71 {
72 buf->data = malloc(length);
73 if(!buf->data) return -ENOMEM;
74 buf->length = length;
75 return 0;
76 }
77
78 static
79 int tls_buffer_free(tls_buffer *buf)
80 {
81 free(buf->data);
82 buf->data = NULL;
83 buf->length = 0;
84 return 0;
85 }
86
87 #pragma mark -
88 #pragma mark SecureTransport support
89
90 #if 0
91 static void hexdump(const char *s, const uint8_t *bytes, size_t len) {
92 size_t ix;
93 printf("socket %s(%p, %lu)\n", s, bytes, len);
94 for (ix = 0; ix < len; ++ix) {
95 if (!(ix % 16))
96 printf("\n");
97 printf("%02X ", bytes[ix]);
98 }
99 printf("\n");
100 }
101 #else
102 #define hexdump(string, bytes, len)
103 #endif
104
105 static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length)
106 {
107 ssl_test_handle *handle =(ssl_test_handle *)h;
108
109 size_t len = *length;
110 uint8_t *ptr = (uint8_t *)data;
111
112 tls_buffer buffer;
113 buffer.data = ptr;
114 buffer.length = len;
115 return tls_stream_parser_parse(handle->parser, buffer);
116 }
117
118 static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length)
119 {
120 ssl_test_handle *handle =(ssl_test_handle *)h;
121
122 test_printf("%s: %p requesting len=%zd\n", __FUNCTION__, h, *length);
123
124 struct RecQueueItem *item = STAILQ_FIRST(&handle->rec_queue);
125
126 if(item==NULL) {
127 test_printf("%s: %p no data available\n", __FUNCTION__, h);
128 return errSSLWouldBlock;
129 }
130
131 size_t avail = item->record.length - item->offset;
132
133 test_printf("%s: %p %zd bytes available in %p\n", __FUNCTION__, h, avail, item);
134
135 if(avail > *length) {
136 memcpy(data, item->record.data+item->offset, *length);
137 item->offset += *length;
138 } else {
139 memcpy(data, item->record.data+item->offset, avail);
140 *length = avail;
141 STAILQ_REMOVE_HEAD(&handle->rec_queue, next);
142 tls_buffer_free(&item->record);
143 free(item);
144 }
145
146 test_printf("%s: %p %zd bytes read\n", __FUNCTION__, h, *length);
147
148
149 return 0;
150 }
151
152 static int process(tls_stream_parser_ctx_t ctx, tls_buffer record)
153 {
154 ssl_test_handle *h = (ssl_test_handle *)ctx;
155 tls_buffer decrypted;
156 uint8_t ct;
157 int err;
158
159 test_printf("%s: %p processing %zd bytes\n", __FUNCTION__, ctx, record.length);
160
161
162 decrypted.length = tls_record_decrypted_size(h->record, record.length);
163 decrypted.data = malloc(decrypted.length);
164
165 require_action(decrypted.data, errOut, err=-ENOMEM);
166 require_noerr((err=tls_record_decrypt(h->record, record, &decrypted, &ct)), errOut);
167
168 test_printf("%s: %p decrypted %zd bytes, ct=%d\n", __FUNCTION__, ctx, decrypted.length, ct);
169
170 err=tls_handshake_process(h->hdsk, decrypted, ct);
171
172 test_printf("%s: %p processed, err=%d\n", __FUNCTION__, ctx, err);
173
174 errOut:
175 free(decrypted.data);
176 return err;
177 }
178
179 static int
180 tls_handshake_write_callback(tls_handshake_ctx_t ctx, const tls_buffer data, uint8_t content_type)
181 {
182 int err = 0;
183 ssl_test_handle *handle = (ssl_test_handle *)ctx;
184
185 test_printf("%s: %p writing data ct=%d, len=%zd\n", __FUNCTION__, ctx, content_type, data.length);
186
187 struct RecQueueItem *item = malloc(sizeof(struct RecQueueItem));
188 require_action(item, errOut, err=-ENOMEM);
189
190 err=tls_buffer_alloc(&item->record, tls_record_encrypted_size(handle->record, content_type, data.length));
191 require_noerr(err, errOut);
192
193 err=tls_record_encrypt(handle->record, data, content_type, &item->record);
194 require_noerr(err, errOut);
195
196 item->offset = 0;
197
198 test_printf("%s: %p queing %zd encrypted bytes, item=%p\n", __FUNCTION__, ctx, item->record.length, item);
199
200 STAILQ_INSERT_TAIL(&handle->rec_queue, item, next);
201
202 return 0;
203
204 errOut:
205 if(item) {
206 tls_buffer_free(&item->record);
207 free(item);
208 }
209 return err;
210 }
211
212
213 static int
214 tls_handshake_message_callback(tls_handshake_ctx_t ctx, tls_handshake_message_t event)
215 {
216 ssl_test_handle __unused *handle = (ssl_test_handle *)ctx;
217
218 test_printf("%s: %p event = %d\n", __FUNCTION__, handle, event);
219
220 int err = 0;
221
222 return err;
223 }
224
225
226
227 static uint8_t appdata[] = "appdata";
228
229 tls_buffer appdata_buffer = {
230 .data = appdata,
231 .length = sizeof(appdata),
232 };
233
234
235 static void
236 tls_handshake_ready_callback(tls_handshake_ctx_t ctx, bool write, bool ready)
237 {
238 ssl_test_handle *handle = (ssl_test_handle *)ctx;
239
240 test_printf("%s: %p %s ready=%d\n", __FUNCTION__, handle, write?"write":"read", ready);
241
242 if(ready) {
243 if(write) {
244 if(handle->ready_count == 0) {
245 tls_handshake_request_renegotiation(handle->hdsk);
246 } else {
247 tls_handshake_write_callback(ctx, appdata_buffer, tls_record_type_AppData);
248 }
249 handle->ready_count++;;
250 }
251 }
252 }
253
254 static int
255 tls_handshake_set_retransmit_timer_callback(tls_handshake_ctx_t ctx, int attempt)
256 {
257 ssl_test_handle __unused *handle = (ssl_test_handle *)ctx;
258
259 test_printf("%s: %p attempt = %d\n", __FUNCTION__, handle, attempt);
260
261 return -1;
262 }
263
264 static
265 int mySSLRecordInitPendingCiphersFunc(tls_handshake_ctx_t ref,
266 uint16_t selectedCipher,
267 bool server,
268 tls_buffer key)
269 {
270 ssl_test_handle *handle = (ssl_test_handle *)ref;
271
272 test_printf("%s: %p, cipher=%04x, server=%d\n", __FUNCTION__, ref, selectedCipher, server);
273 return tls_record_init_pending_ciphers(handle->record, selectedCipher, server, key);
274 }
275
276 static
277 int mySSLRecordAdvanceWriteCipherFunc(tls_handshake_ctx_t ref)
278 {
279 ssl_test_handle *handle = (ssl_test_handle *)ref;
280 test_printf("%s: %p\n", __FUNCTION__, ref);
281 return tls_record_advance_write_cipher(handle->record);
282 }
283
284 static
285 int mySSLRecordRollbackWriteCipherFunc(tls_handshake_ctx_t ref)
286 {
287 ssl_test_handle *handle = (ssl_test_handle *)ref;
288 test_printf("%s: %p\n", __FUNCTION__, ref);
289 return tls_record_rollback_write_cipher(handle->record);
290 }
291
292 static
293 int mySSLRecordAdvanceReadCipherFunc(tls_handshake_ctx_t ref)
294 {
295 ssl_test_handle *handle = (ssl_test_handle *)ref;
296 test_printf("%s: %p\n", __FUNCTION__, ref);
297 return tls_record_advance_read_cipher(handle->record);
298 }
299
300 static
301 int mySSLRecordSetProtocolVersionFunc(tls_handshake_ctx_t ref,
302 tls_protocol_version protocolVersion)
303 {
304 ssl_test_handle *handle = (ssl_test_handle *)ref;
305 test_printf("%s: %p, version=%04x\n", __FUNCTION__, ref, protocolVersion);
306 return tls_record_set_protocol_version(handle->record, protocolVersion);
307 }
308
309
310 static int
311 tls_handshake_save_session_data_callback(tls_handshake_ctx_t ctx, tls_buffer sessionKey, tls_buffer sessionData)
312 {
313 ssl_test_handle __unused *handle = (ssl_test_handle *)ctx;
314
315 test_printf("%s: %p\n", __FUNCTION__, handle);
316
317 return -1;
318 }
319
320 static int
321 tls_handshake_load_session_data_callback(tls_handshake_ctx_t ctx, tls_buffer sessionKey, tls_buffer *sessionData)
322 {
323 ssl_test_handle __unused *handle = (ssl_test_handle *)ctx;
324
325 test_printf("%s: %p\n", __FUNCTION__, handle);
326
327 return -1;
328 }
329
330 static int
331 tls_handshake_delete_session_data_callback(tls_handshake_ctx_t ctx, tls_buffer sessionKey)
332 {
333 ssl_test_handle __unused *handle = (ssl_test_handle *)ctx;
334
335 test_printf("%s: %p\n", __FUNCTION__, handle);
336
337 return -1;
338 }
339
340 static int
341 tls_handshake_delete_all_sessions_callback(tls_handshake_ctx_t ctx)
342 {
343 ssl_test_handle __unused *handle = (ssl_test_handle *)ctx;
344
345 test_printf("%s: %p\n", __FUNCTION__, handle);
346
347 return -1;
348 }
349
350 /* TLS callbacks */
351 tls_handshake_callbacks_t tls_handshake_callbacks = {
352 .write = tls_handshake_write_callback,
353 .message = tls_handshake_message_callback,
354 .ready = tls_handshake_ready_callback,
355 .set_retransmit_timer = tls_handshake_set_retransmit_timer_callback,
356 .init_pending_cipher = mySSLRecordInitPendingCiphersFunc,
357 .advance_write_cipher = mySSLRecordAdvanceWriteCipherFunc,
358 .rollback_write_cipher = mySSLRecordRollbackWriteCipherFunc,
359 .advance_read_cipher = mySSLRecordAdvanceReadCipherFunc,
360 .set_protocol_version = mySSLRecordSetProtocolVersionFunc,
361 .load_session_data = tls_handshake_load_session_data_callback,
362 .save_session_data = tls_handshake_save_session_data_callback,
363 .delete_session_data = tls_handshake_delete_session_data_callback,
364 .delete_all_sessions = tls_handshake_delete_all_sessions_callback,
365 };
366
367
368 static void
369 ssl_test_handle_destroy(ssl_test_handle *handle)
370 {
371 if(handle) {
372 if(handle->parser) tls_stream_parser_destroy(handle->parser);
373 if(handle->record) tls_record_destroy(handle->record);
374 if(handle->hdsk) tls_handshake_destroy(handle->hdsk);
375 if(handle->st) CFRelease(handle->st);
376 free(handle);
377 }
378 }
379
380 static uint16_t ciphers[] = {
381 TLS_PSK_WITH_AES_128_CBC_SHA,
382 };
383 static int nciphers = sizeof(ciphers)/sizeof(ciphers[0]);
384
385 static SSLCipherSuite ciphersuites[] = {
386 TLS_PSK_WITH_AES_128_CBC_SHA,
387 };
388 static int nciphersuites = sizeof(ciphersuites)/sizeof(ciphersuites[0]);
389
390
391
392 static uint8_t shared_secret[] = "secret";
393
394 tls_buffer psk_secret = {
395 .data = shared_secret,
396 .length = sizeof(shared_secret),
397 };
398
399 static ssl_test_handle *
400 ssl_test_handle_create(bool server)
401 {
402 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
403 SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType);
404
405 require(handle, out);
406 require(ctx, out);
407
408 require_noerr(SSLSetIOFuncs(ctx, (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
409 require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)handle), out);
410 require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnServerAuth, true), out);
411 require_noerr(SSLSetEnabledCiphers(ctx, ciphersuites, nciphersuites), out);
412 require_noerr(SSLSetPSKSharedSecret(ctx, shared_secret, sizeof(shared_secret)), out);
413
414 handle->st = ctx;
415 handle->parser = tls_stream_parser_create(handle, process);
416 handle->record = tls_record_create(false, CCRNGSTATE);
417 handle->hdsk = tls_handshake_create(false, true); // server.
418
419 require_noerr(tls_handshake_set_ciphersuites(handle->hdsk, ciphers, nciphers), out);
420 require_noerr(tls_handshake_set_callbacks(handle->hdsk, &tls_handshake_callbacks, handle), out);
421 require_noerr(tls_handshake_set_psk_secret(handle->hdsk, &psk_secret), out);
422 require_noerr(tls_handshake_set_renegotiation(handle->hdsk, true), out);
423
424 // Initialize the record queue
425 STAILQ_INIT(&handle->rec_queue);
426
427 return handle;
428
429 out:
430 if (handle) free(handle);
431 if (ctx) CFRelease(ctx);
432 return NULL;
433 }
434
435 static void
436 tests(void)
437 {
438 OSStatus ortn;
439
440 ssl_test_handle *client;
441 SSLSessionState state;
442
443 client = ssl_test_handle_create(false);
444
445 require_action(client, out, ortn = -1);
446
447 ortn = SSLGetSessionState(client->st, &state);
448 require_noerr(ortn, out);
449 is(state, kSSLIdle, "State should be Idle");
450
451 do {
452 ortn = SSLHandshake(client->st);
453 test_printf("SSLHandshake returned err=%d\n", (int)ortn);
454
455 require_noerr(SSLGetSessionState(client->st, &state), out);
456
457 if (ortn == errSSLPeerAuthCompleted || ortn == errSSLWouldBlock)
458 {
459 require_action(state==kSSLHandshake, out, ortn = -1);
460 }
461
462 } while(ortn==errSSLWouldBlock ||
463 ortn==errSSLPeerAuthCompleted);
464
465
466 is(ortn, 0, "Unexpected SSLHandshake exit code");
467 is(state, kSSLConnected, "State should be Connected");
468
469 uint8_t buffer[128];
470 size_t available = 0;
471
472 test_printf("Initial handshake done\n");
473
474 do {
475 ortn = SSLRead(client->st, buffer, sizeof(buffer), &available);
476 test_printf("SSLRead returned err=%d, avail=%zd\n", (int)ortn, available);
477 require_noerr(SSLGetSessionState(client->st, &state), out);
478
479 if (ortn == errSSLPeerAuthCompleted)
480 {
481 require_action(state==kSSLHandshake, out, ortn = -1);
482 }
483
484 } while(available==0);
485
486 is(ortn, 0, "Unexpected SSLRead exit code");
487 is(state, kSSLConnected, "State should be Connected");
488
489
490 out:
491 is(ortn, 0, "Final result is non zero");
492 ssl_test_handle_destroy(client);
493
494 }
495
496 int ssl_51_state(int argc, char *const *argv)
497 {
498
499 plan_tests(6);
500
501 tests();
502
503 return 0;
504 }