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
86typedef 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
94static 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
155static int protos[]={kTLSProtocol1, kTLSProtocol11, kTLSProtocol12 };
156
157#if 0 // currently unused
158static 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
168static 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
179static 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};
187static unsigned char *dh_param_512_der = dh_param_512_bytes;
188static unsigned int dh_param_512_der_len = 72;
189
190
191typedef 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
209static 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
226static unsigned char readBuffer[MTU];
227static unsigned int  readOff=0;
228static size_t        readLeft=0;
229
230static
231OSStatus 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
281static
282OSStatus 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
331static 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};
341static unsigned int dn_len = 96;
342
343
344static 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;
411out:
412    if (ctx)
413        CFRelease(ctx);
414    return NULL;
415}
416
417static 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
566out:
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
577static ssl_test_handle *
578ssl_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
599static 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
651int st_test(void);
652int 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
744