1//
2//  ssl-43-ciphers.c
3//  regressions
4//
5//  Created by Fabrice Gautier on 6/7/11.
6//  Copyright 2011 Apple, Inc. All rights reserved.
7//
8
9#include <stdbool.h>
10#include <pthread.h>
11#include <fcntl.h>
12#include <sys/mman.h>
13#include <unistd.h>
14#include <sys/types.h>
15#include <netinet/in.h>
16#include <sys/socket.h>
17#include <netdb.h>
18#include <arpa/inet.h>
19#include <CoreFoundation/CoreFoundation.h>
20
21#include <AssertMacros.h>
22#include <Security/SecureTransportPriv.h> /* SSLSetOption */
23#include <Security/SecureTransport.h>
24#include <Security/SecPolicy.h>
25#include <Security/SecTrust.h>
26#include <Security/SecIdentity.h>
27#include <Security/SecIdentityPriv.h>
28#include <Security/SecCertificatePriv.h>
29#include <Security/SecKeyPriv.h>
30#include <Security/SecItem.h>
31#include <Security/SecRandom.h>
32
33#include <utilities/array_size.h>
34#include <utilities/SecIOFormat.h>
35
36#include <string.h>
37#include <sys/types.h>
38#include <sys/socket.h>
39#include <errno.h>
40#include <stdlib.h>
41#include <mach/mach_time.h>
42
43
44#include "ssl_regressions.h"
45#include "ssl-utils.h"
46
47/*
48 SSL CipherSuite tests
49
50 Below are all the ciphers that are individually tested.  The first element
51 is the SecureTransport/RFC name; the second is what openssl calls it, which
52 can be looked up in ciphers(1).
53
54 All SSL_DH_* and TLS_DH_* are disabled because neither openssl nor
55 securetranport support them:
56 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_DSS_WITH_DES_CBC_SHA,
57 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
58 SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
59 TLS_DH_DSS_WITH_AES_128_CBC_SHA, TLS_DH_RSA_WITH_AES_128_CBC_SHA,
60 TLS_DH_DSS_WITH_AES_256_CBC_SHA, TLS_DH_RSA_WITH_AES_256_CBC_SHA,
61
62 DSS is unimplemented by securetransport on the phone:
63 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA,
64 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
65 TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
66
67 SSLv2 ciphersuites disabled by securetransport on phone:
68 SSL_RSA_WITH_RC2_CBC_MD5, SSL_RSA_WITH_IDEA_CBC_MD5,
69 SSL_RSA_WITH_DES_CBC_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5,
70
71 SSLv3 ciphersuites disabled by securetransport on phone:
72 SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
73
74 */
75
76#define OPENSSL_SERVER "ariadne.apple.com"
77#define GNUTLS_SERVER "ariadne.apple.com"
78
79static struct {
80    const char *host;
81    int base_port;
82    int cs_index;
83    bool client_auth;
84} servers[] = {
85    { OPENSSL_SERVER, 4000, 0, false}, //openssl s_server w/o client side auth
86    { GNUTLS_SERVER, 5000, 1, false}, // gnutls-serv w/o client side auth
87    { "www.mikestoolbox.org", 442, 2, false}, // mike's  w/o client side auth
88//    { "tls.secg.org", 40022, 3, false}, // secg ecc server w/o client side auth - This server generate DH params we dont support.
89
90    { OPENSSL_SERVER, 4010, 0, true}, //openssl s_server w/ client side auth
91    { GNUTLS_SERVER, 5010, 1, true}, // gnutls-serv w/ client side auth
92    { "www.mikestoolbox.net", 442, 2, true}, // mike's  w/ client side auth
93//    { "tls.secg.org", 8442, 3}, //secg ecc server w/ client side auth
94};
95int nservers = sizeof(servers)/sizeof(servers[0]);
96
97int protos[]={ kSSLProtocol3, kTLSProtocol1, kTLSProtocol11, kTLSProtocol12 };
98int nprotos = sizeof(protos)/sizeof(protos[0]);
99
100typedef struct _CipherSuiteName {
101    int prot;
102    SSLCipherSuite cipher;
103    const char *name;
104    int portoffset[4]; // 0=not supported , else = port offset for this ciphersuite
105    bool dh_anonymous;
106} CipherSuiteName;
107
108/* prot: 0 = SSL3, 1=TLSv1.0, 2=TLSv1.1, 3=TLSv1.2 */
109#define CIPHER(prot, cipher, offsets...) { prot, cipher, #cipher, offsets},
110
111const CipherSuiteName ciphers[] = {
112    //SSL_NULL_WITH_NULL_NULL, unsupported
113#if 1
114    /* RSA cipher suites */
115    CIPHER(0, SSL_RSA_WITH_NULL_MD5,    {1, 1, 0, 1}, false)
116    CIPHER(0, SSL_RSA_WITH_NULL_SHA,    {1, 1, 0, 1}, false)
117    CIPHER(3, TLS_RSA_WITH_NULL_SHA256, {0, 1, 0, 0}, false)
118#endif
119
120#if 1
121    CIPHER(0, SSL_RSA_WITH_RC4_128_MD5,         {1, 1, 1, 1}, false)
122    CIPHER(0, SSL_RSA_WITH_RC4_128_SHA,         {1, 1, 1, 1}, false)
123    CIPHER(0, SSL_RSA_WITH_3DES_EDE_CBC_SHA,    {1, 1, 1, 1}, false)
124    CIPHER(0, TLS_RSA_WITH_AES_128_CBC_SHA,     {1, 1, 1, 1}, false)
125    CIPHER(3, TLS_RSA_WITH_AES_128_CBC_SHA256,  {0, 1, 1, 0}, false)
126    CIPHER(0, TLS_RSA_WITH_AES_256_CBC_SHA,     {1, 1, 1, 1}, false)
127    CIPHER(3, TLS_RSA_WITH_AES_256_CBC_SHA256,  {0, 1, 1, 0}, false)
128#endif
129
130#if 1
131    /* DHE_RSA ciphers suites */
132    CIPHER(0, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,    {1, 1, 1, 1}, false)
133    CIPHER(0, TLS_DHE_RSA_WITH_AES_128_CBC_SHA,     {1, 1, 1, 1}, false)
134    CIPHER(3, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,  {0, 1, 1, 0}, false)
135    CIPHER(0, TLS_DHE_RSA_WITH_AES_256_CBC_SHA,     {1, 1, 1, 1}, false)
136    CIPHER(3, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,  {0, 1, 1, 0}, false)
137#endif
138
139
140#if 1
141    /* DH_anon cipher suites */
142    CIPHER(0, SSL_DH_anon_WITH_RC4_128_MD5,         {1, 1, 0, 1}, true)
143    CIPHER(0, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,    {1, 1, 0, 1}, true)
144    CIPHER(0, TLS_DH_anon_WITH_AES_128_CBC_SHA,     {1, 1, 0, 1}, true)
145    CIPHER(3, TLS_DH_anon_WITH_AES_128_CBC_SHA256,  {0, 1, 0, 1}, true)
146    CIPHER(0, TLS_DH_anon_WITH_AES_256_CBC_SHA,     {1, 1, 0, 1}, true)
147    CIPHER(3, TLS_DH_anon_WITH_AES_256_CBC_SHA256,  {0, 1, 0, 1}, true)
148#endif
149
150#if 1
151    /* ECDHE_ECDSA cipher suites */
152    CIPHER(1, TLS_ECDHE_ECDSA_WITH_NULL_SHA,            {4, 4, 0, 1}, false)
153    CIPHER(1, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,         {4, 0, 0, 1}, false)
154    CIPHER(1, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,    {4, 4, 0, 1}, false)
155    CIPHER(1, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,     {4, 4, 0, 1}, false)
156    CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,  {0, 4, 0, 1}, false)
157    CIPHER(1, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,     {4, 4, 0, 1}, false)
158    CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,  {0, 4, 0, 1}, false)
159#endif
160
161#if 1
162    /* ECDHE_RSA cipher suites */
163    CIPHER(1, TLS_ECDHE_RSA_WITH_RC4_128_SHA,           {1, 0, 0, 1}, false)
164    CIPHER(1, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,      {1, 1, 0, 1}, false)
165    CIPHER(1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,       {1, 1, 0, 1}, false)
166    CIPHER(3, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,    {0, 1, 0, 0}, false)
167    CIPHER(1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,       {1, 1, 0, 1}, false)
168    CIPHER(3, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,    {0, 0, 0, 0}, false) // Not supported by either gnutls or openssl
169#endif
170
171#if 1
172    /* ECDH_ECDSA cipher suites */
173    CIPHER(1, TLS_ECDH_ECDSA_WITH_RC4_128_SHA,          {4, 0, 0, 1}, false)
174    CIPHER(1, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,     {4, 0, 0, 1}, false)
175    CIPHER(1, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,      {4, 0, 0, 1}, false)
176    CIPHER(3, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,   {0, 0, 0, 1}, false)
177    CIPHER(1, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,      {4, 0, 0, 1}, false)
178    CIPHER(3, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,   {0, 0, 0, 1}, false)
179#endif
180
181#if 1
182    /* ECDH_RSA cipher suites */
183    CIPHER(1, TLS_ECDH_RSA_WITH_RC4_128_SHA,            {3, 0, 0, 1}, false)
184    CIPHER(1, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,       {3, 0, 0, 1}, false)
185    CIPHER(1, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,        {3, 0, 0, 1}, false)
186    CIPHER(3, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,     {0, 0, 0, 1}, false)
187    CIPHER(1, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,        {3, 0, 0, 1}, false)
188    CIPHER(3, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,     {0, 0, 0, 1}, false)
189#endif
190
191#if 0
192    CIPHER(1, TLS_PSK_WITH_RC4_128_SHA,                 {1, 1, 0, 0}, true)
193    CIPHER(1, TLS_PSK_WITH_3DES_EDE_CBC_SHA,            {1, 1, 0, 0}, true)
194    CIPHER(1, TLS_PSK_WITH_AES_128_CBC_SHA,             {1, 1, 0, 0}, true)
195    CIPHER(1, TLS_PSK_WITH_AES_256_CBC_SHA,             {1, 1, 0, 0}, true)
196    CIPHER(3, TLS_PSK_WITH_AES_128_CBC_SHA256,          {0, 1, 0, 0}, true)
197    CIPHER(3, TLS_PSK_WITH_AES_256_CBC_SHA384,          {0, 0, 0, 0}, true)
198    CIPHER(1, TLS_PSK_WITH_NULL_SHA,                    {0, 0, 0, 0}, true)
199    CIPHER(3, TLS_PSK_WITH_NULL_SHA256,                 {0, 1, 0, 0}, true)
200    CIPHER(3, TLS_PSK_WITH_NULL_SHA384,                 {0, 0, 0, 0}, true)
201#endif
202
203#if 0
204    CIPHER(3, TLS_RSA_WITH_AES_128_GCM_SHA256,          {0, 1, 0, 0}, false)
205    CIPHER(3, TLS_RSA_WITH_AES_256_GCM_SHA384,          {0, 0, 0, 0}, false)
206
207    CIPHER(3, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,      {0, 1, 0, 0}, false)
208    CIPHER(3, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,      {0, 0, 0, 0}, false)
209
210    CIPHER(3, TLS_DH_anon_WITH_AES_128_GCM_SHA256,      {0, 1, 0, 0}, false)
211    CIPHER(3, TLS_DH_anon_WITH_AES_256_GCM_SHA384,      {0, 0, 0, 0}, false)
212
213    CIPHER(3, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,     {0, 0, 0, 0}, false)
214    CIPHER(3, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,     {0, 0, 0, 0}, false)
215
216    CIPHER(3, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,   {0, 0, 0, 0}, false)
217    CIPHER(3, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,   {0, 0, 0, 0}, false)
218
219    CIPHER(3, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,    {0, 1, 0, 0}, false)
220    CIPHER(3, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,    {0, 0, 0, 0}, false)
221
222    CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,  {0, 1, 0, 0}, false)
223    CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,  {0, 0, 0, 0}, false)
224#endif
225
226
227
228#if 0
229    CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5, true, false, true,false)
230    CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, true, false, true, false)
231    CIPHER(SSL_RSA_WITH_DES_CBC_SHA, true, false, true, false)
232    CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, true, false, true, false)
233    CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA, true, false, true, false)
234    CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, true, false, true, true)
235    CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, true, false, true, true)
236    CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA, true, false, true, true)
237#endif
238
239
240    /* "Any" cipher suite - test the default configuration */
241    {0, SSL_NO_SUCH_CIPHERSUITE, "Any cipher 1", {1, 1, 1, 1}, false},
242    {0, SSL_NO_SUCH_CIPHERSUITE, "Any cipher 2", {2, 2, 0, 0}, false},
243
244    // Those servers wont talk SSL3.0 because they have EC certs
245    {1, SSL_NO_SUCH_CIPHERSUITE, "Any cipher 3", {3, 3, 0, 0}, false},
246    {1, SSL_NO_SUCH_CIPHERSUITE, "Any cipher 4", {4, 4, 0, 0}, false},
247
248
249    { -1, -1, NULL, }
250};
251
252static int ciphers_len = array_size(ciphers);
253
254
255
256#if 0 // currently unused
257static SSLCipherSuite sslcipher_atoi(const char *name)
258{
259    const CipherSuiteName *a = ciphers;
260    while(a->name) {
261        if (0 == strcmp(a->name, name)) break;
262        a++;
263    }
264    return a->cipher;
265}
266
267static const char * sslcipher_itoa(SSLCipherSuite num)
268{
269    const CipherSuiteName *a = ciphers;
270    while(a->cipher >= 0) {
271        if (num == a->cipher) break;
272        a++;
273    }
274    return a->name;
275}
276#endif // currently unused
277
278unsigned char dh_param_512_bytes[] = {
279    0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64,
280    0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0,
281    0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd,
282    0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b,
283    0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb,
284    0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02
285};
286unsigned char *dh_param_512_der = dh_param_512_bytes;
287unsigned int dh_param_512_der_len = 72;
288
289typedef struct {
290    uint32_t session_id;
291    bool is_session_resume;
292    SSLContextRef st;
293    bool is_server;
294    bool client_side_auth;
295    bool dh_anonymous;
296    int comm;
297    CFArrayRef certs;
298} ssl_test_handle;
299
300
301
302
303#if 0
304static void hexdump(const uint8_t *bytes, size_t len) {
305	size_t ix;
306    printf("socket write(%p, %lu)\n", bytes, len);
307	for (ix = 0; ix < len; ++ix) {
308        if (!(ix % 16))
309            printf("\n");
310		printf("%02X ", bytes[ix]);
311	}
312	printf("\n");
313}
314#else
315#define hexdump(bytes, len)
316#endif
317
318static int SocketConnect(const char *hostName, int port)
319{
320    struct sockaddr_in  addr;
321    struct in_addr      host;
322	int					sock;
323    int                 err;
324    struct hostent      *ent;
325
326    if (hostName[0] >= '0' && hostName[0] <= '9')
327    {
328        host.s_addr = inet_addr(hostName);
329    }
330    else {
331		unsigned dex;
332#define GETHOST_RETRIES 5
333		/* seeing a lot of soft failures here that I really don't want to track down */
334		for(dex=0; dex<GETHOST_RETRIES; dex++) {
335			if(dex != 0) {
336				printf("\n...retrying gethostbyname(%s)", hostName);
337			}
338			ent = gethostbyname(hostName);
339			if(ent != NULL) {
340				break;
341			}
342		}
343        if(ent == NULL) {
344			printf("\n***gethostbyname(%s) returned: %s\n", hostName, hstrerror(h_errno));
345            return -1;
346        }
347        memcpy(&host, ent->h_addr, sizeof(struct in_addr));
348    }
349
350    sock = socket(AF_INET, SOCK_STREAM, 0);
351    addr.sin_addr = host;
352    addr.sin_port = htons((u_short)port);
353
354    addr.sin_family = AF_INET;
355    err = connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in));
356
357    if(err!=0)
358    {
359        perror("connect failed");
360        return err;
361    }
362
363    return sock;
364}
365
366
367static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
368{
369	size_t len = *length;
370	uint8_t *ptr = (uint8_t *)data;
371
372    do {
373        ssize_t ret;
374        do {
375            hexdump(ptr, len);
376            ret = write((int)conn, ptr, len);
377            if (ret < 0)
378                perror("send");
379        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
380        if (ret > 0) {
381            len -= ret;
382            ptr += ret;
383        }
384        else
385            return -36;
386    } while (len > 0);
387
388    *length = *length - len;
389    return errSecSuccess;
390}
391
392static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
393{
394	size_t len = *length;
395	uint8_t *ptr = (uint8_t *)data;
396
397    do {
398        ssize_t ret;
399        do {
400            ret = read((int)conn, ptr, len);
401            if (ret < 0)
402                perror("send");
403        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
404        if (ret > 0) {
405            len -= ret;
406            ptr += ret;
407        }
408        else
409            return -36;
410    } while (len > 0);
411
412    *length = *length - len;
413    return errSecSuccess;
414}
415
416unsigned char dn[] = {
417    0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
418    0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
419    0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
420    0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
421    0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
422    0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
423    0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
424    0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
425};
426unsigned int dn_len = 96;
427
428static SSLContextRef make_ssl_ref(bool server, bool client_side_auth, bool dh_anonymous,
429                                  bool dtls, int sock, CFArrayRef certs, SSLProtocol prot)
430{
431    SSLContextRef ctx = NULL;
432    if(dtls)
433        require_noerr(SSLNewDatagramContext(server, &ctx), out);
434    else
435        require_noerr(SSLNewContext(server, &ctx), out);
436    require_noerr(SSLSetProtocolVersionMax(ctx, prot), out);
437    require_noerr(SSLSetIOFuncs(ctx,
438                                (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
439    require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out);
440    //    static const char *peer_domain_name = "localhost";
441    // require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
442    //                                   strlen(peer_domain_name)), out);
443
444
445    if (!dh_anonymous) {
446        if (server)
447            require_noerr(SSLSetCertificate(ctx, certs), out);
448        if (client_side_auth && server) {
449            require_noerr(SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate), out);
450            require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out);
451        }
452#if 0 /* Setting client certificate in advance */
453        if (client_side_auth && !server)
454            require_noerr(SSLSetCertificate(ctx, certs), out);
455#endif
456        if (client_side_auth && !server) /* enable break from SSLHandshake */
457            require_noerr(SSLSetSessionOption(ctx,
458                                              kSSLSessionOptionBreakOnCertRequested, true), out);
459        require_noerr(SSLSetSessionOption(ctx,
460                                          kSSLSessionOptionBreakOnServerAuth, true), out);
461    }
462
463    /* Tell SecureTransport to not check certs itself: it will break out of the
464     handshake to let us take care of it instead. */
465    require_noerr(SSLSetEnableCertVerify(ctx, false), out);
466
467    require_noerr(SSLSetPSKIdentity(ctx, "Client_identity", 15), out);
468    require_noerr(SSLSetPSKSharedSecret(ctx, "123456789", 9), out);
469
470
471    if (server) {
472        require_noerr(SSLSetDiffieHellmanParams(ctx,
473                                                 dh_param_512_der, dh_param_512_der_len), out);
474    }
475    else /* if client */ {
476    }
477
478    return ctx;
479out:
480    if (ctx)
481        SSLDisposeContext(ctx);
482    return NULL;
483}
484
485static OSStatus securetransport(ssl_test_handle * ssl)
486{
487    OSStatus ortn;
488    SSLContextRef ctx = ssl->st;
489    SecTrustRef trust = NULL;
490    bool got_server_auth = false, got_client_cert_req = false;
491
492    //uint64_t start = mach_absolute_time();
493    do {
494        ortn = SSLHandshake(ctx);
495
496        if (ortn == errSSLServerAuthCompleted)
497        {
498            require_string(!got_server_auth, out, "second server auth");
499            require_string(!got_client_cert_req, out, "got client cert req before server auth");
500            got_server_auth = true;
501            require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
502            /* verify peer cert chain */
503            require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
504            SecTrustResultType trust_result = 0;
505            /* this won't verify without setting up a trusted anchor */
506            require_noerr(SecTrustEvaluate(trust, &trust_result), out);
507
508            CFIndex n_certs = SecTrustGetCertificateCount(trust);
509            /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
510
511            CFMutableArrayRef peer_cert_array = CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks);
512            CFMutableArrayRef orig_peer_cert_array = CFArrayCreateMutableCopy(NULL, n_certs, ssl->certs);
513            while (n_certs--)
514                CFArrayInsertValueAtIndex(peer_cert_array, 0,
515                                          SecTrustGetCertificateAtIndex(trust, n_certs));
516
517            SecIdentityRef ident = (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0);
518            SecCertificateRef peer_cert = NULL;
519            require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out);
520            CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert);
521            CFRelease(peer_cert);
522
523#if 0
524            require(CFEqual(orig_peer_cert_array, peer_cert_array), out);
525#endif
526            CFRelease(orig_peer_cert_array);
527            CFRelease(peer_cert_array);
528
529            /*
530             CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
531             char cert_name_buffer[1024];
532             require(CFStringGetFileSystemRepresentation(cert_name,
533             cert_name_buffer, sizeof(cert_name_buffer)), out);
534             fprintf(stderr, "cert name: %s\n", cert_name_buffer);
535             CFRelease(trust);
536             */
537        } else if (ortn == errSSLClientCertRequested) {
538            require_string(!got_client_cert_req, out, "second client cert req");
539            require_string(got_server_auth, out, "didn't get server auth first");
540            got_client_cert_req = true;
541
542            /* set client cert */
543            require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server");
544            require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH");
545/*
546            CFArrayRef DNs = NULL;
547            require_noerr(SSLCopyDistinguishedNames	(ctx, &DNs), out);
548            require(DNs, out);
549            CFRelease(DNs);
550*/
551            require_string(ssl->client_side_auth, out, "errSSLClientCertRequested in run not testing that");
552            require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
553        }
554    } while (ortn == errSSLWouldBlock
555             || ortn == errSSLServerAuthCompleted
556             || ortn == errSSLClientCertRequested);
557    require_noerr_action_quiet(ortn, out,
558                               fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
559
560    if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) {
561        require_action_string(got_server_auth, out, ortn=-1, "never got server auth.");
562        if (ssl->client_side_auth)
563            require_string(got_client_cert_req, out, "never got client cert req");
564    }
565    //uint64_t elapsed = mach_absolute_time() - start;
566    //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
567
568    /*
569     SSLProtocol proto = kSSLProtocolUnknown;
570     require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
571
572    SSLCipherSuite cipherSuite;
573    require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
574    //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
575
576	Boolean	sessionWasResumed = false;
577    uint8_t session_id_data[MAX_SESSION_ID_LENGTH];
578    size_t session_id_length = sizeof(session_id_data);
579    require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out);
580    require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1);
581    // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
582    //hexdump(session_id_data, session_id_length);
583
584#if 1
585    char *req="GET / HTTP/1.0\r\n\r\n";
586    char ibuf[4096];
587    size_t len;
588    if (!ssl->is_server) {
589        require_noerr_quiet(ortn = SSLWrite(ctx, req, strlen(req), &len), out);
590        require_action_quiet(len == strlen(req), out, ortn = -1);
591        require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out);
592        ibuf[len]=0;
593//        printf(">>>\n%s<<<\n", ibuf);
594    }
595#endif
596
597out:
598    SSLClose(ctx);
599    SSLDisposeContext(ctx);
600    if (trust) CFRelease(trust);
601
602    return ortn;
603}
604
605
606
607static ssl_test_handle *
608ssl_test_handle_create(uint32_t session_id, bool resume, bool server, bool client_side_auth, bool dh_anonymous, bool dtls,
609                       int comm, CFArrayRef certs, SSLProtocol prot)
610{
611    ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
612    if (handle) {
613        handle->session_id = session_id;
614        handle->is_session_resume = resume;
615        handle->is_server = server;
616        handle->client_side_auth = client_side_auth;
617        handle->dh_anonymous = dh_anonymous;
618        handle->comm = comm;
619        handle->certs = certs;
620        handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, prot);
621    }
622    return handle;
623}
624
625static void
626tests(void)
627{
628    CFArrayRef client_certs = client_chain();
629    ok(client_certs, "got client certs");
630
631    int i;
632    int p, pr;
633
634    for (p=0; p<nservers;p++) {
635    for (pr=0; pr<nprotos; pr++) {
636
637        for (i=0; ciphers[i].name != NULL; i++) {
638
639            ssl_test_handle *client;
640            SSLProtocol proto = protos[pr];
641            int port;
642
643            int s;
644
645            SKIP: {
646                skip("This ciphersuite is not supported for this protocol version", 2, ciphers[i].prot<=pr);
647                skip("This server doesn't support this ciphersuite", 2, ciphers[i].portoffset[servers[p].cs_index]);
648
649                port=servers[p].base_port + ciphers[i].portoffset[servers[p].cs_index];
650                uint32_t session_id = (pr<<16) | (port<<8) | (i+1);
651
652                s=SocketConnect(servers[p].host, port);
653
654                ok(s,
655                   "Connect failed: %40s to %s:%d proto=%d", ciphers[i].name, servers[p].host, port, pr);
656
657                skip("Could not connect to the server", 1, s);
658
659                //fprintf(stderr, "session_id: %d\n", session_id);
660                client = ssl_test_handle_create(session_id, false, false/*client*/,
661                                                servers[p].client_auth, ciphers[i].dh_anonymous, 0,
662                                                s, client_certs, proto);
663
664                /* set fixed cipher on client and server */
665                if(ciphers[i].cipher != SSL_NO_SUCH_CIPHERSUITE) {
666                    if(SSLSetEnabledCiphers(client->st, &ciphers[i].cipher, 1)!=0)
667                        printf("Invalid cipher %04x (i=%d, p=%d, pr=%d)\n", ciphers[i].cipher, i, p, pr);
668                }
669
670                ok(!securetransport(client),
671                   "Handshake failed: %40s to %s:%d proto=%d", ciphers[i].name, servers[p].host, port, pr);
672
673                close(s);
674
675            } /* SKIP block */
676        }
677    } /* all ciphers */
678    } /* all servers */
679
680    CFReleaseNull(client_certs);
681}
682
683int ssl_43_ciphers(int argc, char *const *argv)
684{
685        plan_tests(1 + 2*nservers*nprotos*(ciphers_len-1));
686
687        tests();
688
689        return 0;
690}
691
692/*
693 TODO: count errSSLWouldBlock
694 TODO: skip tests that don't matter: client_auth and anonymous dh
695 TODO: we seem to only be negotiating tls - force a round of sslv3
696 TODO: allow secure transport to also defer client side auth to client
697 TODO: make sure anonymous dh is never selected if not expicitly enabled
698 TODO: make sure DHE is not available if not explicitly enabled and no parameters
699 are set
700 TODO: resumable sessions
701 */
702