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