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
102typedef 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
110static 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
171static int protos[]={kTLSProtocol1, kTLSProtocol11, kTLSProtocol12 };
172
173#if 0 // currently unused
174static 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
184static 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
195static 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};
203static unsigned char *dh_param_512_der = dh_param_512_bytes;
204static unsigned int dh_param_512_der_len = 72;
205
206
207typedef 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
225static 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
242static unsigned char readBuffer[MTU];
243static unsigned int  readOff=0;
244static size_t        readLeft=0;
245
246static
247OSStatus 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
297static
298OSStatus 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
347static 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};
357static unsigned int dn_len = 96;
358
359
360static 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;
427out:
428    if (ctx)
429        CFRelease(ctx);
430    return NULL;
431}
432
433static 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
582out:
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
593static ssl_test_handle *
594ssl_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
615static 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
667int st_test(void);
668int 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
760