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