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