]> git.saurik.com Git - apple/security.git/blob - tlsnke/tlsnketest/st_test.c
Security-55471.14.tar.gz
[apple/security.git] / tlsnke / tlsnketest / st_test.c
1 //
2 // st_test.c
3 // tlsnke
4 //
5 // Created by Fabrice Gautier on 1/13/12.
6 // Copyright (c) 2012 Apple, Inc. All rights reserved.
7 //
8
9
10 #include <CoreFoundation/CoreFoundation.h>
11 #include <Security/Security.h>
12 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
13 #include <Security/SecRandom.h>
14
15 #include <AssertMacros.h>
16
17 #include "ssl-utils.h"
18
19 #if 0
20 #include <Security/SecPolicy.h>
21 #include <Security/SecTrust.h>
22 #include <Security/SecIdentity.h>
23 #include <Security/SecIdentityPriv.h>
24 #include <Security/SecCertificatePriv.h>
25 #include <Security/SecKeyPriv.h>
26 #if TARGET_OS_IPHONE
27 #include <Security/SecRSAKey.h>
28 #endif
29 #include <Security/SecItem.h>
30 #include <Security/SecRandom.h>
31 #endif
32
33 #include <string.h>
34 #include <errno.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <stdbool.h>
38 #include <pthread.h>
39 #include <fcntl.h>
40 #include <unistd.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <sys/mman.h>
44 #include <mach/mach_time.h>
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
47 #include <netdb.h>
48
49 #include "tlssocket.h"
50
51 /*
52 SSL CipherSuite tests
53
54 Below are all the ciphers that are individually tested. The first element
55 is the SecureTransport/RFC name; the second is what openssl calls it, which
56 can be looked up in ciphers(1).
57
58 All SSL_DH_* and TLS_DH_* are disabled because neither openssl nor
59 securetranport support them:
60 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_DSS_WITH_DES_CBC_SHA,
61 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
62 SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
63 TLS_DH_DSS_WITH_AES_128_CBC_SHA, TLS_DH_RSA_WITH_AES_128_CBC_SHA,
64 TLS_DH_DSS_WITH_AES_256_CBC_SHA, TLS_DH_RSA_WITH_AES_256_CBC_SHA,
65
66 DSS is unimplemented by securetransport on the phone:
67 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA,
68 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
69 TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
70
71 SSLv2 ciphersuites disabled by securetransport on phone:
72 SSL_RSA_WITH_RC2_CBC_MD5, SSL_RSA_WITH_IDEA_CBC_MD5,
73 SSL_RSA_WITH_DES_CBC_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5,
74
75 SSLv3 ciphersuites disabled by securetransport on phone:
76 SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
77
78 Export ciphersuites disabled on iOS 5.0:
79 SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
80 SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
81 SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,
82 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA
83
84 */
85
86 typedef struct _CipherSuiteName {
87 SSLCipherSuite cipher;
88 const char *name;
89 bool dh_anonymous;
90 } CipherSuiteName;
91
92 #define CIPHER(cipher, dh_anonymous) { cipher, #cipher, dh_anonymous },
93
94 static const CipherSuiteName ciphers[] = {
95 //SSL_NULL_WITH_NULL_NULL, unsupported
96 CIPHER(SSL_RSA_WITH_NULL_SHA, false)
97 CIPHER(SSL_RSA_WITH_NULL_MD5, false)
98 CIPHER(TLS_RSA_WITH_NULL_SHA256, false)
99
100 // CIPHER(SSL_RSA_WITH_RC4_128_MD5, false)
101 //CIPHER(SSL_RSA_WITH_RC4_128_SHA, false)
102 CIPHER(SSL_RSA_WITH_3DES_EDE_CBC_SHA, false)
103
104 CIPHER(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, false)
105 //CIPHER(SSL_DH_anon_WITH_RC4_128_MD5, true)
106 CIPHER(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, true)
107 CIPHER(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, false)
108 CIPHER(TLS_DH_anon_WITH_AES_128_CBC_SHA, true)
109 CIPHER(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, false)
110 CIPHER(TLS_DH_anon_WITH_AES_256_CBC_SHA, true)
111
112 CIPHER(TLS_RSA_WITH_AES_128_CBC_SHA, false)
113 CIPHER(TLS_RSA_WITH_AES_256_CBC_SHA, false)
114
115
116 #if 0
117 CIPHER(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, false)
118 CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, false)
119
120 CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, false)
121 CIPHER(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, false)
122
123 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, false)
124 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, false)
125
126 CIPHER(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, true)
127 CIPHER(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, true)
128
129 CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, false)
130 CIPHER(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, false)
131 CIPHER(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, false)
132 CIPHER(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, false)
133 #endif
134
135 #if 0
136 CIPHER(TLS_RSA_WITH_AES_256_GCM_SHA384, false)
137 CIPHER(TLS_RSA_WITH_AES_128_GCM_SHA256, false)
138 #endif
139
140 /* Export ciphers are disabled */
141 #if 0
142 CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5, false)
143 CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, false)
144 CIPHER(SSL_RSA_WITH_DES_CBC_SHA, false)
145 CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, false)
146 CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA, false)
147 CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, true)
148 CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, true)
149 CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA, true)
150 #endif
151
152 { -1 }
153 };
154
155 static int protos[]={kTLSProtocol1, kTLSProtocol11, kTLSProtocol12 };
156
157 #if 0 // currently unused
158 static SSLCipherSuite sslcipher_atoi(const char *name)
159 {
160 const CipherSuiteName *a = ciphers;
161 while(a->name) {
162 if (0 == strcmp(a->name, name)) break;
163 a++;
164 }
165 return a->cipher;
166 }
167
168 static const char * sslcipher_itoa(SSLCipherSuite num)
169 {
170 const CipherSuiteName *a = ciphers;
171 while(a->cipher >= 0) {
172 if (num == a->cipher) break;
173 a++;
174 }
175 return a->name;
176 }
177 #endif // currently unused
178
179 static unsigned char dh_param_512_bytes[] = {
180 0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64,
181 0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0,
182 0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd,
183 0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b,
184 0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb,
185 0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02
186 };
187 static unsigned char *dh_param_512_der = dh_param_512_bytes;
188 static unsigned int dh_param_512_der_len = 72;
189
190
191 typedef struct {
192 uint32_t session_id;
193 bool is_session_resume;
194 SSLContextRef st;
195 bool is_server;
196 bool is_dtls;
197 bool client_side_auth;
198 bool dh_anonymous;
199 int comm;
200 CFArrayRef certs;
201 SSLProtocol proto;
202 } ssl_test_handle;
203
204
205 // MARK: -
206 // MARK: SecureTransport support
207
208 #if 0
209 static void hexdump(const uint8_t *bytes, size_t len) {
210 size_t ix;
211 printf("socket write(%p, %lu)\n", bytes, len);
212 for (ix = 0; ix < len; ++ix) {
213 if (!(ix % 16))
214 printf("\n");
215 printf("%02X ", bytes[ix]);
216 }
217 printf("\n");
218 }
219 #else
220 #define hexdump(bytes, len)
221 #endif
222
223
224 /* 2K should be enough for everybody */
225 #define MTU 8000
226 static unsigned char readBuffer[MTU];
227 static unsigned int readOff=0;
228 static size_t readLeft=0;
229
230 static
231 OSStatus SocketRead(
232 SSLConnectionRef connection,
233 void *data,
234 size_t *dataLength)
235 {
236 int fd = (int)connection;
237 ssize_t len;
238
239 if(readLeft==0)
240 {
241 // printf("SocketRead(%d): waiting for data %ld\n", fd, *dataLength);
242
243 len = read(fd, readBuffer, MTU);
244
245 if(len>0) {
246 readOff=0;
247 readLeft=(size_t) len;
248 //printf("SocketRead(%d): %ld bytes... epoch: %02x seq=%02x%02x\n",
249 // fd, len, d[4], d[9], d[10]);
250
251 } else {
252 int theErr = errno;
253 switch(theErr) {
254 case EAGAIN:
255 printf("SocketRead(%d): WouldBlock\n", fd);
256 *dataLength=0;
257 /* nonblocking, no data */
258 return errSSLWouldBlock;
259 default:
260 perror("SocketRead");
261 return -36;
262 }
263 }
264 }
265
266 if(readLeft<*dataLength) {
267 *dataLength=readLeft;
268 }
269
270
271 memcpy(data, readBuffer+readOff, *dataLength);
272 readLeft-=*dataLength;
273 readOff+=*dataLength;
274
275 // printf("%s: returning %ld bytes, left %ld\n", __FUNCTION__, *dataLength, readLeft);
276
277 return errSecSuccess;
278
279 }
280
281 static
282 OSStatus SocketWrite(
283 SSLConnectionRef connection,
284 const void *data,
285 size_t *dataLength) /* IN/OUT */
286 {
287 int fd = (int)connection;
288 ssize_t len;
289 OSStatus err = errSecSuccess;
290
291 #if 0
292 const uint8_t *d=data;
293
294 if((rand()&3)==1) {
295
296 /* drop 1/8th packets */
297 printf("SocketWrite: Drop %ld bytes... epoch: %02x seq=%02x%02x\n",
298 *dataLength, d[4], d[9], d[10]);
299 return errSecSuccess;
300
301 }
302 #endif
303
304 // printf("SocketWrite(%d): Sending %ld bytes... epoch: %02x seq=%02x%02x\n",
305 // fd, *dataLength, d[4], d[9], d[10]);
306
307 len = send(fd, data, *dataLength, 0);
308 if(len>0) {
309 *dataLength=(size_t)len;
310 return err;
311 }
312
313 int theErr = errno;
314 switch(theErr) {
315 case EAGAIN:
316 /* nonblocking, no data */
317 printf("SocketWrite(%d): WouldBlock\n", fd);
318 err = errSSLWouldBlock;
319 break;
320 default:
321 perror("SocketWrite");
322 err = -36;
323 break;
324 }
325
326 return err;
327
328 }
329
330
331 static unsigned char dn[] = {
332 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
333 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
334 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
335 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
336 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
337 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
338 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
339 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
340 };
341 static unsigned int dn_len = 96;
342
343
344 static SSLContextRef make_ssl_ref(bool server, bool client_side_auth, bool dh_anonymous,
345 bool dtls, int sock, CFArrayRef certs, SSLProtocol proto, bool kernel)
346 {
347 SSLContextRef ctx;
348
349 if(kernel) {
350 require(dtls, out);
351 ctx = SSLCreateContextWithRecordFuncs(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, dtls?kSSLDatagramType:kSSLStreamType, &TLSSocket_Funcs);
352 require(ctx, out);
353 printf("Attaching filter\n");
354 require_noerr(TLSSocket_Attach(sock), out);
355 require_noerr(SSLSetRecordContext(ctx, (intptr_t) sock), out);
356 } else {
357 ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, dtls?kSSLDatagramType:kSSLStreamType);
358 require(ctx, out);
359 require_noerr(SSLSetIOFuncs(ctx,
360 (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
361 require_noerr(SSLSetConnection(ctx, (intptr_t)sock), out);
362 }
363 require(ctx, out);
364
365 if(dtls) {
366 size_t mtu;
367 require_noerr(SSLSetMaxDatagramRecordSize(ctx, 400), out);
368 require_noerr(SSLGetMaxDatagramRecordSize(ctx, &mtu), out);
369 } else {
370 require_noerr(SSLSetProtocolVersionMax(ctx, proto), out);
371 kernel = false; // not available for tls, only dtls currently.
372 }
373
374 static const char *peer_domain_name = "localhost";
375 require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
376 strlen(peer_domain_name)), out);
377
378 if (!dh_anonymous) {
379 if (server)
380 require_noerr(SSLSetCertificate(ctx, certs), out);
381 if (client_side_auth && server) {
382 SSLAuthenticate auth;
383 require_noerr(SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate), out);
384 require_noerr(SSLGetClientSideAuthenticate(ctx, &auth), out);
385 require(auth==kAlwaysAuthenticate, out);
386 require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out);
387 }
388 #if 0 /* Setting client certificate in advance */
389 if (client_side_auth && !server)
390 require_noerr(SSLSetCertificate(ctx, certs), out);
391 #endif
392 if (client_side_auth && !server) /* enable break from SSLHandshake */
393 require_noerr(SSLSetSessionOption(ctx,
394 kSSLSessionOptionBreakOnCertRequested, true), out);
395 require_noerr(SSLSetSessionOption(ctx,
396 kSSLSessionOptionBreakOnServerAuth, true), out);
397 }
398
399 /* Tell SecureTransport to not check certs itself: it will break out of the
400 handshake to let us take care of it instead. */
401 require_noerr(SSLSetEnableCertVerify(ctx, false), out);
402
403 if (server) {
404 require_noerr(SSLSetDiffieHellmanParams(ctx,
405 dh_param_512_der, dh_param_512_der_len), out);
406 }
407 else /* if client */ {
408 }
409
410 return ctx;
411 out:
412 if (ctx)
413 CFRelease(ctx);
414 return NULL;
415 }
416
417 static void *securetransport_ssl_thread(void *arg)
418 {
419 OSStatus ortn;
420 ssl_test_handle * ssl = (ssl_test_handle *)arg;
421 SSLContextRef ctx = ssl->st;
422 SecTrustRef trust = NULL;
423 bool got_server_auth = false, got_client_cert_req = false;
424
425
426 if(ssl->is_server) {
427 struct sockaddr_in ca; /* client address for connect */
428 ssize_t l;
429 int fd = ssl->comm;
430
431 printf("Server waiting for first packet...\n");
432 /* PEEK only... */
433 socklen_t slen=sizeof(ca);
434 char b;
435 if((l=recvfrom(fd, &b, 1, MSG_PEEK, (struct sockaddr *)&ca, &slen))==-1)
436 {
437 perror("recvfrom");
438 return NULL;
439 }
440
441 printf("Received packet from %s:%d (%ld), connecting...\n", inet_ntoa(ca.sin_addr), ca.sin_port, l);
442
443 if(connect(fd, (struct sockaddr *)&ca, sizeof(ca))==-1)
444 {
445 perror("connect");
446 return NULL;
447 }
448 }
449
450 //uint64_t start = mach_absolute_time();
451 do {
452 ortn = SSLHandshake(ctx);
453
454 if (ortn == errSSLServerAuthCompleted)
455 {
456 require_string(!got_server_auth, out, "second server auth");
457 require_string(!got_client_cert_req, out, "got client cert req before server auth");
458 got_server_auth = true;
459 require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
460 /* verify peer cert chain */
461 require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
462 SecTrustResultType trust_result = 0;
463 /* this won't verify without setting up a trusted anchor */
464 require_noerr(SecTrustEvaluate(trust, &trust_result), out);
465
466 CFIndex n_certs = SecTrustGetCertificateCount(trust);
467 /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
468
469 CFMutableArrayRef peer_cert_array =
470 CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks);
471 CFMutableArrayRef orig_peer_cert_array =
472 CFArrayCreateMutableCopy(NULL, n_certs, ssl->certs);
473 while (n_certs--)
474 CFArrayInsertValueAtIndex(peer_cert_array, 0,
475 SecTrustGetCertificateAtIndex(trust, n_certs));
476
477 SecIdentityRef ident =
478 (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0);
479 SecCertificateRef peer_cert = NULL;
480 require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out);
481 CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert);
482 CFRelease(peer_cert);
483
484 require(CFEqual(orig_peer_cert_array, peer_cert_array), out);
485 CFRelease(orig_peer_cert_array);
486 CFRelease(peer_cert_array);
487
488 /*
489 CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
490 char cert_name_buffer[1024];
491 require(CFStringGetFileSystemRepresentation(cert_name,
492 cert_name_buffer, sizeof(cert_name_buffer)), out);
493 fprintf(stderr, "cert name: %s\n", cert_name_buffer);
494 CFRelease(trust);
495 */
496 } else if (ortn == errSSLClientCertRequested) {
497 require_string(!got_client_cert_req, out, "second client cert req");
498 require_string(got_server_auth, out, "didn't get server auth first");
499 got_client_cert_req = true;
500
501 /* set client cert */
502 require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server");
503 require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH");
504
505 CFArrayRef DNs = NULL;
506 require_noerr(SSLCopyDistinguishedNames (ctx, &DNs), out);
507 require(DNs, out);
508 CFRelease(DNs);
509
510 require_string(ssl->client_side_auth, out, "errSSLClientCertRequested in run not testing that");
511 require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
512 }
513 } while (ortn == errSSLWouldBlock
514 || ortn == errSSLServerAuthCompleted
515 || ortn == errSSLClientCertRequested);
516 require_noerr_action_quiet(ortn, out,
517 fprintf(stderr, "Fell out of SSLHandshake with error: %ld\n", (long)ortn));
518
519 if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) {
520 require_string(got_server_auth, out, "never got server auth");
521 if (ssl->client_side_auth)
522 require_string(got_client_cert_req, out, "never got client cert req");
523 }
524 //uint64_t elapsed = mach_absolute_time() - start;
525 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
526
527 /*
528 SSLProtocol proto = kSSLProtocolUnknown;
529 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
530
531 SSLCipherSuite cipherSuite;
532 require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
533 //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
534
535 if(ssl->is_dtls) {
536 size_t sz;
537 SSLGetDatagramWriteSize(ctx, &sz);
538 // fprintf(stderr, "Max Write Size = %ld\n", sz);
539 }
540
541 Boolean sessionWasResumed = false;
542 uint8_t session_id_data[MAX_SESSION_ID_LENGTH];
543 size_t session_id_length = sizeof(session_id_data);
544 require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out);
545 require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1);
546 // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
547 //hexdump(session_id_data, session_id_length);
548
549 unsigned char ibuf[300], obuf[300];
550 size_t len;
551 if (ssl->is_server) {
552 SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf);
553 require_noerr_quiet(ortn = SSLWrite(ctx, obuf, sizeof(obuf), &len), out);
554 require_action_quiet(len == sizeof(obuf), out, ortn = -1);
555 }
556 require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out);
557 require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
558
559 if (ssl->is_server) {
560 require_noerr(memcmp(ibuf, obuf, sizeof(ibuf)), out);
561 } else {
562 require_noerr_quiet(ortn = SSLWrite(ctx, ibuf, sizeof(ibuf), &len), out);
563 require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
564 }
565
566 out:
567 SSLClose(ctx);
568 CFRelease(ctx);
569 if (trust) CFRelease(trust);
570 close(ssl->comm);
571 pthread_exit((void *)(intptr_t)ortn);
572 return NULL;
573 }
574
575
576
577 static ssl_test_handle *
578 ssl_test_handle_create(uint32_t session_id, bool resume, bool server, bool client_side_auth, bool dh_anonymous, bool dtls,
579 int comm, CFArrayRef certs, SSLProtocol proto, bool kernel)
580 {
581 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
582 if (handle) {
583 handle->session_id = session_id;
584 handle->is_session_resume = resume;
585 handle->is_server = server;
586 handle->is_dtls = dtls;
587 handle->client_side_auth = client_side_auth;
588 handle->dh_anonymous = dh_anonymous;
589 handle->comm = comm;
590 handle->certs = certs;
591 handle->proto = proto;
592 handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, proto, kernel);
593 }
594 return handle;
595 }
596
597
598
599 static void createsockets(int sp[2])
600 {
601
602
603 int sock;
604 struct sockaddr_in server_addr;
605 struct hostent *host;
606 int err;
607
608 host = gethostbyname("localhost");
609
610 server_addr.sin_family = AF_INET;
611 server_addr.sin_port = htons(5000);
612 server_addr.sin_addr = *((struct in_addr *)host->h_addr);
613 bzero(&(server_addr.sin_zero),8);
614 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
615 perror("server socket");
616 exit(1);
617 }
618
619 if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))
620 == -1) {
621 perror("Unable to bind");
622 exit(1);
623 }
624
625 printf("Server Waiting for client on port 5000\n");
626
627 sp[0]=sock;
628
629 printf("Create client socket\n");
630 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
631 if(sock<0) {
632 perror("client socket");
633 exit(1);
634 }
635
636 err = connect(sock, (struct sockaddr *)&server_addr,
637 sizeof(struct sockaddr));
638 if(err)
639 {
640 perror("connect");
641 exit(1);
642 }
643
644 sp[1]=sock;
645
646 printf("Connected\n");
647
648
649 }
650
651 int st_test(void);
652 int st_test(void)
653 {
654 pthread_t client_thread, server_thread;
655 CFArrayRef server_certs = server_chain();
656 check(server_certs);
657
658 char msg[128];
659
660 /* Enable this if you want to test a specific d/i/k/l/p/ combination */
661 #if 0
662 int d=0, i=0, l=0, c=0, k=0; { {
663 #else
664 int d,i,c,k,l,p;
665
666 p=0;
667 //for (p=0; p<nprotos; p++)
668 d=1;
669 //for (d=0;d<2; d++) /* dtls or not dtls */
670 //for (c=0; c<2; k++) /* csa or not */
671 for (k=1; k<2; k++) /* kernel or not */
672 {
673 for (i=0; ciphers[i].cipher != (SSLCipherSuite)(-1); i++) {
674 l=0;
675 //for (l = 0; l<2; l++) {
676 #endif
677 SKIP:{
678 //skip("Session resumption tests do not work at this point", 1, l != 1);
679 int sp[2];
680
681 #if 0
682 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
683 fcntl(sp[0], F_SETNOSIGPIPE, 1);
684 fcntl(sp[1], F_SETNOSIGPIPE, 1);
685 #else
686 createsockets(sp);
687 #endif
688 ssl_test_handle *server, *client;
689
690 bool client_side_auth = (c);
691 bool kernel = (k);
692 uint32_t session_id = (c+1) << 16 | (i+1);
693 //fprintf(stderr, "session_id: %d\n", session_id);
694 server = ssl_test_handle_create(session_id, (l == 1), true /*server*/,
695 client_side_auth, ciphers[i].dh_anonymous, d,
696 sp[0], server_certs, protos[p], false);
697 client = ssl_test_handle_create(session_id, (l == 1), false/*client*/,
698 client_side_auth, ciphers[i].dh_anonymous, d,
699 sp[1], server_certs, protos[p], kernel);
700
701 require_noerr(SSLSetPeerID(server->st, &session_id, sizeof(session_id)), out);
702 require_noerr(SSLSetPeerID(client->st, &session_id, sizeof(session_id)), out);
703
704 /* set fixed cipher on client and server */
705 require_noerr(SSLSetEnabledCiphers(client->st, &ciphers[i].cipher, 1), out);
706 require_noerr(SSLSetEnabledCiphers(server->st, &ciphers[i].cipher, 1), out);
707
708
709 snprintf(msg, sizeof(msg),
710 "%40s ADH:%d CSA:%d DTLS:%d RESUME:%d PROTO:%d KERNEL:%d",
711 ciphers[i].name,
712 server->dh_anonymous,
713 server->client_side_auth,
714 d, l, p, k);
715
716 printf("%s\n", msg);
717
718 pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
719 pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
720
721 int server_err, client_err;
722 pthread_join(client_thread, (void*)&client_err);
723 pthread_join(server_thread, (void*)&server_err);
724
725
726 __Check_String(!server_err && !client_err, msg);
727
728 out:
729 free(client);
730 free(server);
731
732 printf("\n\n");
733 sleep(2);
734 }
735 } /* all ciphers */
736 } /* all configs */
737
738 CFRelease(server_certs);
739
740 return 0;
741 }
742
743