1
2#if TARGET_OS_IPHONE
3// Currently only supported for iOS
4
5#include <stdbool.h>
6#include <pthread.h>
7#include <fcntl.h>
8#include <sys/mman.h>
9#include <unistd.h>
10
11#include <CoreFoundation/CoreFoundation.h>
12
13#include <AssertMacros.h>
14#include <Security/SecureTransportPriv.h> /* SSLSetOption */
15#include <Security/SecureTransport.h>
16#include <Security/SecPolicy.h>
17#include <Security/SecTrust.h>
18#include <Security/SecIdentity.h>
19#include <Security/SecIdentityPriv.h>
20#include <Security/SecCertificatePriv.h>
21#include <Security/SecKeyPriv.h>
22#include <Security/SecItem.h>
23#include <Security/SecRandom.h>
24
25#include <string.h>
26#include <sys/types.h>
27#include <sys/socket.h>
28#include <errno.h>
29#include <stdlib.h>
30#include <mach/mach_time.h>
31
32#include <Security/SecRSAKey.h>
33
34#include "testlist.h"
35
36/*
37    SSL CipherSuite tests
38
39    Below are all the ciphers that are individually tested.  The first element
40    is the SecureTransport/RFC name; the second is what openssl calls it, which
41    can be looked up in ciphers(1).
42
43    All SSL_DH_* and TLS_DH_* are disabled because neither openssl nor
44    securetranport support them:
45    SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_DSS_WITH_DES_CBC_SHA,
46    SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
47    SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
48    TLS_DH_DSS_WITH_AES_128_CBC_SHA, TLS_DH_RSA_WITH_AES_128_CBC_SHA,
49    TLS_DH_DSS_WITH_AES_256_CBC_SHA, TLS_DH_RSA_WITH_AES_256_CBC_SHA,
50
51    DSS is unimplemented by securetransport on the phone:
52    SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA,
53    SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
54    TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
55
56    SSLv2 ciphersuites disabled by securetransport on phone:
57    SSL_RSA_WITH_RC2_CBC_MD5, SSL_RSA_WITH_IDEA_CBC_MD5,
58    SSL_RSA_WITH_DES_CBC_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5,
59
60    SSLv3 ciphersuites disabled by securetransport on phone:
61    SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
62
63*/
64
65typedef struct _CipherSuiteName {
66        SSLCipherSuite cipher;
67        const char *name;
68        bool dh_anonymous;
69} CipherSuiteName;
70
71#define CIPHER(cipher, dh_anonymous) { cipher, #cipher, dh_anonymous }
72
73static const CipherSuiteName ciphers[] = {
74#if 0
75    /* TODO: Generate an ecdsa private key and certificate for the tests. */
76    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, false),
77    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, false),
78    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, false),
79    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, false),
80    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, false),
81    CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, false),
82    CIPHER(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, false),
83    CIPHER(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, false),
84    CIPHER(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, false),
85    CIPHER(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, false),
86    CIPHER(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, false),
87    CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, false),
88    CIPHER(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, false),
89    CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, false),
90    CIPHER(TLS_ECDHE_RSA_WITH_RC4_128_SHA, false),
91    CIPHER(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, false),
92    CIPHER(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, false),
93    CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, false),
94    CIPHER(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, false),
95    CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, false),
96    CIPHER(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, false),
97    CIPHER(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, false),
98    CIPHER(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, false),
99    CIPHER(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, false),
100    CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, false),
101    CIPHER(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, false),
102    CIPHER(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, false),
103    CIPHER(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, false),
104    CIPHER(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, false),
105    CIPHER(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, false),
106    CIPHER(TLS_ECDH_RSA_WITH_RC4_128_SHA, false),
107    CIPHER(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, false),
108#endif
109    CIPHER(TLS_RSA_WITH_AES_256_GCM_SHA384, false),
110    CIPHER(TLS_RSA_WITH_AES_128_GCM_SHA256, false),
111    CIPHER(TLS_RSA_WITH_AES_256_CBC_SHA256, false),
112    CIPHER(TLS_RSA_WITH_AES_128_CBC_SHA256, false),
113    CIPHER(TLS_RSA_WITH_AES_128_CBC_SHA, false),
114    CIPHER(SSL_RSA_WITH_RC4_128_SHA, false),
115    CIPHER(SSL_RSA_WITH_RC4_128_MD5, false),
116    CIPHER(TLS_RSA_WITH_AES_256_CBC_SHA, false),
117    CIPHER(SSL_RSA_WITH_3DES_EDE_CBC_SHA, false),
118    CIPHER(SSL_RSA_WITH_3DES_EDE_CBC_MD5, false),
119    CIPHER(SSL_RSA_WITH_DES_CBC_SHA, false),
120    CIPHER(SSL_RSA_WITH_DES_CBC_MD5, false),
121    CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5, false),
122    CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, false),
123    CIPHER(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, false),
124    CIPHER(SSL_RSA_WITH_RC2_CBC_MD5, false),
125    CIPHER(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, false),
126    CIPHER(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, false),
127    CIPHER(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, false),
128    CIPHER(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, false),
129    CIPHER(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, false),
130    CIPHER(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, false),
131    CIPHER(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, false),
132    CIPHER(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, false),
133    CIPHER(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, false),
134    CIPHER(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, false),
135    CIPHER(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, false),
136    CIPHER(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, false),
137    CIPHER(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, false),
138    CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA, false),
139    CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, false),
140    CIPHER(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, false),
141    CIPHER(SSL_DHE_DSS_WITH_DES_CBC_SHA, false),
142    CIPHER(SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, false),
143    CIPHER(TLS_DH_anon_WITH_AES_256_GCM_SHA384, true),
144    CIPHER(TLS_DH_anon_WITH_AES_128_GCM_SHA256, true),
145    CIPHER(TLS_DH_anon_WITH_AES_128_CBC_SHA256, true),
146    CIPHER(TLS_DH_anon_WITH_AES_256_CBC_SHA256, true),
147    CIPHER(TLS_DH_anon_WITH_AES_128_CBC_SHA, true),
148    CIPHER(TLS_DH_anon_WITH_AES_256_CBC_SHA, true),
149    CIPHER(SSL_DH_anon_WITH_RC4_128_MD5, true),
150    CIPHER(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, true),
151    CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA, true),
152    CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, true),
153    CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, true),
154#if 0
155	CIPHER(TLS_ECDHE_ECDSA_WITH_NULL_SHA, false),
156	CIPHER(TLS_ECDHE_RSA_WITH_NULL_SHA, false),
157    CIPHER(TLS_ECDH_ECDSA_WITH_NULL_SHA, false),
158	CIPHER(TLS_ECDH_RSA_WITH_NULL_SHA, false),
159#endif
160    CIPHER(TLS_RSA_WITH_NULL_SHA256, false),
161    CIPHER(SSL_RSA_WITH_NULL_SHA, false),
162    CIPHER(SSL_RSA_WITH_NULL_MD5, false),
163#if 0
164    /* We don't support these yet. */
165    CIPHER(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, false),
166    CIPHER(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, false),
167    CIPHER(TLS_RSA_WITH_RC4_128_SHA, false),
168    CIPHER(TLS_RSA_WITH_3DES_EDE_CBC_SHA, false),
169    CIPHER(TLS_RSA_WITH_RC4_128_MD5, false),
170    CIPHER(TLS_DH_DSS_WITH_AES_256_GCM_SHA384, false),
171    CIPHER(TLS_DH_DSS_WITH_AES_128_GCM_SHA256, false),
172    CIPHER(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, false),
173    CIPHER(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, false),
174    CIPHER(TLS_DH_DSS_WITH_AES_256_CBC_SHA256, false),
175    CIPHER(TLS_DH_RSA_WITH_AES_256_CBC_SHA256, false),
176    CIPHER(TLS_DH_DSS_WITH_AES_128_CBC_SHA256, false),
177    CIPHER(TLS_DH_RSA_WITH_AES_128_CBC_SHA256, false),
178    CIPHER(TLS_DH_DSS_WITH_AES_256_CBC_SHA, false),
179    CIPHER(TLS_DH_RSA_WITH_AES_256_CBC_SHA, false),
180	CIPHER(TLS_DH_DSS_WITH_AES_128_CBC_SHA, false),
181    CIPHER(TLS_DH_RSA_WITH_AES_128_CBC_SHA, false),
182    CIPHER(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, false),
183    CIPHER(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, false),
184    CIPHER(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, false),
185	CIPHER(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, false),
186    CIPHER(TLS_ECDH_anon_WITH_RC4_128_SHA, false),
187    CIPHER(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, false),
188    CIPHER(TLS_ECDH_anon_WITH_NULL_SHA, false),
189#endif
190
191    { -1, NULL }
192};
193
194static int ciphers_len = array_size(ciphers);
195
196#if 0 // currently unused
197static SSLCipherSuite sslcipher_atoi(const char *name)
198{
199       const CipherSuiteName *a = ciphers;
200       while(a->name) {
201           if (0 == strcmp(a->name, name)) break;
202           a++;
203       }
204       return a->cipher;
205}
206
207static const char * sslcipher_itoa(SSLCipherSuite num)
208{
209       const CipherSuiteName *a = ciphers;
210       while(a->cipher >= 0) {
211           if (num == a->cipher) break;
212           a++;
213       }
214       return a->name;
215}
216#endif // currently unused
217
218static unsigned char dh_param_512_bytes[] = {
219  0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64,
220  0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0,
221  0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd,
222  0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b,
223  0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb,
224  0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02
225};
226static unsigned char *dh_param_512_der = dh_param_512_bytes;
227static unsigned int dh_param_512_der_len = 72;
228
229/* openssl req -newkey rsa:512 -sha1 -days 365  -subj "/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=localhost" -x509 -nodes -outform DER -keyout privkey.der -outform der -out cert.der */
230static unsigned char pkey_der[] = {
231  0x30, 0x82, 0x01, 0x3b, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xc0, 0x80,
232  0x43, 0xf1, 0x4d, 0xdc, 0x9a, 0x24, 0xe7, 0x25, 0x7c, 0x8b, 0x8b, 0x65,
233  0x87, 0x97, 0xed, 0x3f, 0xfa, 0xfe, 0xbe, 0xcb, 0x12, 0x43, 0x1f, 0x0c,
234  0xb5, 0xbf, 0x6b, 0x81, 0xee, 0x1b, 0x46, 0x6a, 0x02, 0x86, 0x92, 0xec,
235  0x8a, 0xb3, 0x65, 0x77, 0x15, 0xd0, 0x49, 0xb4, 0x22, 0x84, 0xf4, 0x85,
236  0x56, 0x53, 0xf5, 0x5a, 0x3b, 0xad, 0x23, 0xa8, 0x0c, 0x24, 0xb7, 0xf5,
237  0xf4, 0xa1, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x41, 0x00, 0xb8, 0x7f,
238  0xf7, 0x1e, 0xa7, 0x0e, 0xc1, 0x9a, 0x8f, 0x04, 0x49, 0xcb, 0x81, 0x4e,
239  0x4d, 0x58, 0x5a, 0xe7, 0x10, 0x8c, 0xea, 0x96, 0xbd, 0xa9, 0x21, 0x70,
240  0x50, 0x1d, 0xe8, 0x4f, 0x7e, 0xc2, 0x71, 0xff, 0x55, 0xc5, 0xa7, 0x28,
241  0xc8, 0xf2, 0xc7, 0x19, 0xd1, 0x2c, 0x10, 0x40, 0x39, 0xa8, 0xe1, 0x5b,
242  0xbd, 0x97, 0x04, 0xff, 0xd3, 0x27, 0x9b, 0xce, 0x5e, 0x8d, 0x2f, 0x0e,
243  0xd9, 0xf1, 0x02, 0x21, 0x00, 0xde, 0xfc, 0x18, 0x88, 0xa4, 0xef, 0x3b,
244  0x18, 0xca, 0x54, 0x3f, 0xa8, 0x14, 0x96, 0x9a, 0xd7, 0x67, 0x57, 0x55,
245  0xdc, 0x6b, 0xd4, 0x8e, 0x7d, 0xb4, 0x32, 0x00, 0x63, 0x67, 0x6a, 0x57,
246  0x65, 0x02, 0x21, 0x00, 0xdd, 0x00, 0xba, 0xdc, 0xa1, 0xe2, 0x5c, 0xda,
247  0xfe, 0xfc, 0x50, 0x1e, 0x9b, 0x95, 0x28, 0x34, 0xf2, 0x52, 0x31, 0x7a,
248  0x15, 0x00, 0x6f, 0xcc, 0x08, 0x2c, 0x6d, 0x55, 0xb0, 0x24, 0x6a, 0x8d,
249  0x02, 0x20, 0x14, 0xf5, 0x7d, 0x18, 0xda, 0xe7, 0xe1, 0x96, 0x22, 0xee,
250  0x68, 0x4d, 0x54, 0x22, 0x13, 0xcb, 0xcb, 0x5a, 0xda, 0x27, 0x2d, 0xbb,
251  0x7c, 0xe9, 0x33, 0xd6, 0xbf, 0x52, 0x98, 0x95, 0xd6, 0x41, 0x02, 0x21,
252  0x00, 0xaa, 0x58, 0x8c, 0xaf, 0xd1, 0x6b, 0xdc, 0x6c, 0xc4, 0xcc, 0x10,
253  0xa9, 0x76, 0xfc, 0xc2, 0x50, 0x05, 0x53, 0xcb, 0x65, 0x31, 0x58, 0xf3,
254  0xd3, 0x4d, 0x9d, 0x88, 0xec, 0xda, 0x67, 0x47, 0x65, 0x02, 0x20, 0x53,
255  0xf2, 0x49, 0x77, 0x7e, 0x10, 0xc1, 0xc4, 0xed, 0xc0, 0xaf, 0x99, 0x79,
256  0xab, 0x7b, 0x25, 0x0e, 0x70, 0x36, 0xd2, 0xd1, 0xa3, 0x81, 0x0d, 0x83,
257  0x4f, 0x6b, 0x1b, 0x48, 0xec, 0x87, 0x90
258};
259static unsigned int pkey_der_len = 319;
260
261static unsigned char cert_der[] = {
262  0x30, 0x82, 0x02, 0x79, 0x30, 0x82, 0x02, 0x23, 0xa0, 0x03, 0x02, 0x01,
263  0x02, 0x02, 0x09, 0x00, 0xc2, 0xa8, 0x3b, 0xaa, 0x40, 0xa4, 0x29, 0x2b,
264  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
265  0x05, 0x05, 0x00, 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
266  0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
267  0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
268  0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b,
269  0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
270  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
271  0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06,
272  0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68,
273  0x6f, 0x73, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x39, 0x31,
274  0x35, 0x32, 0x31, 0x35, 0x30, 0x35, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x39,
275  0x30, 0x39, 0x31, 0x35, 0x32, 0x31, 0x35, 0x30, 0x35, 0x36, 0x5a, 0x30,
276  0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
277  0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
278  0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
279  0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
280  0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
281  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
282  0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03,
283  0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30,
284  0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
285  0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00,
286  0xc0, 0x80, 0x43, 0xf1, 0x4d, 0xdc, 0x9a, 0x24, 0xe7, 0x25, 0x7c, 0x8b,
287  0x8b, 0x65, 0x87, 0x97, 0xed, 0x3f, 0xfa, 0xfe, 0xbe, 0xcb, 0x12, 0x43,
288  0x1f, 0x0c, 0xb5, 0xbf, 0x6b, 0x81, 0xee, 0x1b, 0x46, 0x6a, 0x02, 0x86,
289  0x92, 0xec, 0x8a, 0xb3, 0x65, 0x77, 0x15, 0xd0, 0x49, 0xb4, 0x22, 0x84,
290  0xf4, 0x85, 0x56, 0x53, 0xf5, 0x5a, 0x3b, 0xad, 0x23, 0xa8, 0x0c, 0x24,
291  0xb7, 0xf5, 0xf4, 0xa1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xc3,
292  0x30, 0x81, 0xc0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
293  0x04, 0x14, 0xe3, 0x58, 0xab, 0x35, 0xc0, 0x58, 0xb8, 0x65, 0x40, 0xca,
294  0x9b, 0x6c, 0xeb, 0x2f, 0xf5, 0xbf, 0xbd, 0x0b, 0xf3, 0xa6, 0x30, 0x81,
295  0x90, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0x88, 0x30, 0x81, 0x85,
296  0x80, 0x14, 0xe3, 0x58, 0xab, 0x35, 0xc0, 0x58, 0xb8, 0x65, 0x40, 0xca,
297  0x9b, 0x6c, 0xeb, 0x2f, 0xf5, 0xbf, 0xbd, 0x0b, 0xf3, 0xa6, 0xa1, 0x62,
298  0xa4, 0x60, 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
299  0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
300  0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e,
301  0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
302  0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
303  0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
304  0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
305  0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
306  0x73, 0x74, 0x82, 0x09, 0x00, 0xc2, 0xa8, 0x3b, 0xaa, 0x40, 0xa4, 0x29,
307  0x2b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03,
308  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
309  0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x41, 0x40, 0x07,
310  0xde, 0x1f, 0xd0, 0x00, 0x62, 0x75, 0x36, 0xb3, 0x94, 0xa8, 0xac, 0x3b,
311  0x98, 0xbb, 0x28, 0x56, 0xf6, 0x9f, 0xe3, 0x87, 0xd4, 0xa1, 0x7a, 0x85,
312  0xce, 0x40, 0x8a, 0xfd, 0x12, 0xb4, 0x99, 0x8c, 0x1d, 0x05, 0x61, 0xdb,
313  0x35, 0xb8, 0x04, 0x7c, 0xfb, 0xe4, 0x97, 0x88, 0x66, 0xa0, 0x54, 0x7b,
314  0x1c, 0xce, 0x99, 0xd8, 0xd3, 0x99, 0x80, 0x40, 0x9b, 0xa2, 0x73, 0x8b,
315  0xfd
316};
317static unsigned int cert_der_len = 637;
318
319typedef struct {
320    uint32_t session_id;
321    bool is_session_resume;
322    SSLContextRef handle;
323    bool is_st;
324    bool is_server;
325    bool client_side_auth;
326    bool dh_anonymous;
327    int comm;
328    CFArrayRef certs;
329} ssl_test_handle;
330
331#if 0 // currently unused
332static CFArrayRef SecIdentityCopySSLClientAuthenticationChain(SecIdentityRef identity)
333{
334   CFMutableArrayRef chain = NULL;
335   SecPolicyRef policy = NULL;
336   SecTrustRef trust = NULL;
337   SecTrustResultType trust_result;
338
339   do {
340       policy = SecPolicyCreateSSL(false, NULL);
341       if (!policy)
342           break;
343
344       SecCertificateRef cert = NULL;
345       if (SecIdentityCopyCertificate(identity, &cert))
346           break;
347
348       CFArrayRef certs = CFArrayCreate(NULL, (const void **)&cert,
349                 1, &kCFTypeArrayCallBacks);
350       CFRelease(cert);
351       if (!certs)
352           break;
353
354       if (SecTrustCreateWithCertificates(certs, policy, &trust))
355           break;
356       CFRelease(certs);
357       CFRelease(policy);
358       if (SecTrustEvaluate(trust, &trust_result))
359           break;
360
361       int i, count = SecTrustGetCertificateCount(trust);
362       chain = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks);
363       CFArrayAppendValue(chain, identity);
364       for (i = 1; i < count; i++) {
365           if ((i+1 == count) && (trust_result == kSecTrustResultUnspecified))
366               continue; /* skip anchor if chain is complete */
367           SecCertificateRef s = SecTrustGetCertificateAtIndex(trust, i);
368           CFArrayAppendValue(chain, s);
369       }
370   } while (0);
371   if (trust)
372       CFRelease(trust);
373   if (policy)
374       CFRelease(policy);
375   return chain;
376}
377#endif // currently unused
378
379static CFArrayRef server_chain()
380{
381    SecKeyRef pkey = SecKeyCreateRSAPrivateKey(kCFAllocatorDefault,
382        pkey_der, pkey_der_len, kSecKeyEncodingPkcs1);
383    SecCertificateRef cert = SecCertificateCreateWithBytes(kCFAllocatorDefault,
384        cert_der, cert_der_len);
385    SecIdentityRef ident = SecIdentityCreate(kCFAllocatorDefault, cert, pkey);
386    CFRelease(pkey);
387    CFRelease(cert);
388    CFArrayRef items = CFArrayCreate(kCFAllocatorDefault,
389        (const void **)&ident, 1, &kCFTypeArrayCallBacks);
390    CFRelease(ident);
391    return items;
392}
393
394// MARK: -
395// MARK: SecureTransport support
396
397#if 0
398static void hexdump(const uint8_t *bytes, size_t len) {
399	size_t ix;
400    printf("socket write(%p, %lu)\n", bytes, len);
401	for (ix = 0; ix < len; ++ix) {
402        if (!(ix % 16))
403            printf("\n");
404		printf("%02X ", bytes[ix]);
405	}
406	printf("\n");
407}
408#else
409#define hexdump(bytes, len)
410#endif
411
412static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
413{
414	size_t len = *length;
415	uint8_t *ptr = (uint8_t *)data;
416
417    do {
418        ssize_t ret;
419        do {
420            hexdump(ptr, len);
421            ret = write((int)conn, ptr, len);
422            if (ret < 0)
423                perror("send");
424        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
425        if (ret > 0) {
426            len -= ret;
427            ptr += ret;
428        }
429        else
430            return -36;
431    } while (len > 0);
432
433    *length = *length - len;
434    return errSecSuccess;
435}
436
437static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
438{
439	size_t len = *length;
440	uint8_t *ptr = (uint8_t *)data;
441
442    do {
443        ssize_t ret;
444        do {
445            ret = read((int)conn, ptr, len);
446            if (ret < 0)
447                perror("send");
448        } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
449        if (ret > 0) {
450            len -= ret;
451            ptr += ret;
452        }
453        else
454            return -36;
455    } while (len > 0);
456
457    *length = *length - len;
458    return errSecSuccess;
459}
460
461static unsigned char dn[] = {
462  0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
463  0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
464  0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
465  0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
466  0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
467  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
468  0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
469  0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
470};
471static unsigned int dn_len = 96;
472
473static SSLContextRef make_ssl_ref(bool server, bool client_side_auth, bool dh_anonymous,
474    bool dtls, int sock, CFArrayRef certs)
475{
476    SSLContextRef ctx = NULL;
477    if(dtls)
478        require_noerr(SSLNewDatagramContext(server, &ctx), out);
479    else
480        require_noerr(SSLNewContext(server, &ctx), out);
481    require_noerr(SSLSetIOFuncs(ctx,
482        (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
483    require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)sock), out);
484    static const char *peer_domain_name = "localhost";
485    require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
486        strlen(peer_domain_name)), out);
487
488    if (!dh_anonymous) {
489        if (server)
490            require_noerr(SSLSetCertificate(ctx, certs), out);
491        if (client_side_auth && server) {
492            require_noerr(SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate), out);
493            require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out);
494        }
495#if 0 /* Setting client certificate in advance */
496        if (client_side_auth && !server)
497            require_noerr(SSLSetCertificate(ctx, certs), out);
498#endif
499        if (client_side_auth && !server) /* enable break from SSLHandshake */
500            require_noerr(SSLSetSessionOption(ctx,
501                kSSLSessionOptionBreakOnCertRequested, true), out);
502        require_noerr(SSLSetSessionOption(ctx,
503            kSSLSessionOptionBreakOnServerAuth, true), out);
504    }
505
506    /* Tell SecureTransport to not check certs itself: it will break out of the
507       handshake to let us take care of it instead. */
508    require_noerr(SSLSetEnableCertVerify(ctx, false), out);
509
510    if (server) {
511        require_noerr(SSLSetDiffieHellmanParams(ctx,
512            dh_param_512_der, dh_param_512_der_len), out);
513    }
514    else /* if client */ {
515    }
516
517    return ctx;
518out:
519    if (ctx)
520        SSLDisposeContext(ctx);
521    return NULL;
522}
523
524static void *securetransport_ssl_thread(void *arg)
525{
526    OSStatus ortn;
527    ssl_test_handle * ssl = (ssl_test_handle *)arg;
528    SSLContextRef ctx = ssl->handle;
529    SecTrustRef trust = NULL;
530    bool got_server_auth = false, got_client_cert_req = false;
531
532    //uint64_t start = mach_absolute_time();
533    do {
534        ortn = SSLHandshake(ctx);
535
536        if (ortn == errSSLServerAuthCompleted)
537        {
538            require_string(!got_server_auth, out, "second server auth");
539            require_string(!got_client_cert_req, out, "got client cert req before server auth");
540            got_server_auth = true;
541            require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
542            /* verify peer cert chain */
543            require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
544            SecTrustResultType trust_result = 0;
545            /* this won't verify without setting up a trusted anchor */
546            require_noerr(SecTrustEvaluate(trust, &trust_result), out);
547
548            CFIndex n_certs = SecTrustGetCertificateCount(trust);
549            /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
550
551            CFMutableArrayRef peer_cert_array =
552                CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks);
553            CFMutableArrayRef orig_peer_cert_array =
554                CFArrayCreateMutableCopy(NULL, n_certs, ssl->certs);
555            while (n_certs--)
556                CFArrayInsertValueAtIndex(peer_cert_array, 0,
557                    SecTrustGetCertificateAtIndex(trust, n_certs));
558
559            SecIdentityRef ident =
560                (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0);
561            SecCertificateRef peer_cert = NULL;
562            require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out);
563            CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert);
564            CFRelease(peer_cert);
565
566            require(CFEqual(orig_peer_cert_array, peer_cert_array), out);
567            CFRelease(orig_peer_cert_array);
568            CFRelease(peer_cert_array);
569
570            /*
571            CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
572            char cert_name_buffer[1024];
573            require(CFStringGetFileSystemRepresentation(cert_name,
574                cert_name_buffer, sizeof(cert_name_buffer)), out);
575            fprintf(stderr, "cert name: %s\n", cert_name_buffer);
576            CFRelease(trust);
577            */
578        } else if (ortn == errSSLClientCertRequested) {
579            require_string(!got_client_cert_req, out, "second client cert req");
580            require_string(got_server_auth, out, "didn't get server auth first");
581            got_client_cert_req = true;
582
583            /* set client cert */
584            require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server");
585            require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH");
586
587            CFArrayRef DNs = NULL;
588            require_noerr(SSLCopyDistinguishedNames	(ctx, &DNs), out);
589            require(DNs, out);
590            CFRelease(DNs);
591
592            require_string(ssl->client_side_auth, out, "errSSLClientCertRequested in run not testing that");
593            require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
594        }
595    } while (ortn == errSSLWouldBlock
596        || ortn == errSSLServerAuthCompleted
597        || ortn == errSSLClientCertRequested);
598    require_noerr_action_quiet(ortn, out,
599        fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
600
601    if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) {
602        require_string(got_server_auth, out, "never got server auth");
603        if (ssl->client_side_auth)
604            require_string(got_client_cert_req, out, "never got client cert req");
605    }
606    //uint64_t elapsed = mach_absolute_time() - start;
607    //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
608
609    /*
610    SSLProtocol proto = kSSLProtocolUnknown;
611    require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
612
613    SSLCipherSuite cipherSuite;
614    require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
615    //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
616
617	Boolean	sessionWasResumed = false;
618    uint8_t session_id_data[MAX_SESSION_ID_LENGTH];
619    size_t session_id_length = sizeof(session_id_data);
620    require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out);
621    require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1);
622    // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
623    //hexdump(session_id_data, session_id_length);
624
625    unsigned char ibuf[4096], obuf[4096];
626    size_t len;
627    if (ssl->is_server) {
628        SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf);
629        require_noerr_quiet(ortn = SSLWrite(ctx, obuf, sizeof(obuf), &len), out);
630        require_action_quiet(len == sizeof(obuf), out, ortn = -1);
631    }
632    require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out);
633    require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
634
635    if (ssl->is_server) {
636        require_noerr(memcmp(ibuf, obuf, sizeof(ibuf)), out);
637    } else {
638        require_noerr_quiet(ortn = SSLWrite(ctx, ibuf, sizeof(ibuf), &len), out);
639        require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
640    }
641
642out:
643    SSLClose(ctx);
644    SSLDisposeContext(ctx);
645    if (trust) CFRelease(trust);
646
647    pthread_exit((void *)(intptr_t)ortn);
648    return NULL;
649}
650
651
652
653static ssl_test_handle *
654ssl_test_handle_create(uint32_t session_id, bool resume, bool server, bool client_side_auth, bool dh_anonymous, bool dtls,
655    int comm, CFArrayRef certs)
656{
657    ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
658    if (handle) {
659        handle->session_id = session_id;
660        handle->is_session_resume = resume;
661        handle->is_server = server;
662        handle->client_side_auth = client_side_auth;
663        handle->dh_anonymous = dh_anonymous;
664        handle->comm = comm;
665        handle->certs = certs;
666        handle->handle = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs);
667    }
668    return handle;
669}
670
671static void
672tests(void)
673{
674    pthread_t client_thread, server_thread;
675    CFArrayRef server_certs = server_chain();
676    ok(server_certs, "got server certs");
677
678#if 0
679    int i=0, j=1, k=1; {
680#else
681    int d,i,k,l;
682    for (d=0;d<2; d++)  /* dtls or not dtls */
683    for (k=0; k<2; k++)
684    for (i=0; ciphers[i].cipher != (SSLCipherSuite)(-1); i++)
685    for (l = 0; l<2; l++) {
686#endif
687        SKIP: {
688            skip("ST doesn't support resumption", 1, l != 1);
689
690            int sp[2];
691            if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
692
693            ssl_test_handle *server, *client;
694
695            bool client_side_auth = (k);
696
697            uint32_t session_id = (k+1) << 16 | 1 << 8 | (i+1);
698            //fprintf(stderr, "session_id: %d\n", session_id);
699            server = ssl_test_handle_create(session_id, (l == 1), true /*server*/,
700                client_side_auth, ciphers[i].dh_anonymous, d,
701                sp[0], server_certs);
702            client = ssl_test_handle_create(session_id, (l == 1), false/*client*/,
703                client_side_auth, ciphers[i].dh_anonymous, d,
704                sp[1], server_certs);
705
706            require_noerr(SSLSetPeerID(server->handle, &session_id, sizeof(session_id)), out);
707            require_noerr(SSLSetPeerID(client->handle, &session_id, sizeof(session_id)), out);
708
709            /* set fixed cipher on client and server */
710            require_noerr(SSLSetEnabledCiphers(client->handle, &ciphers[i].cipher, 1), out);
711            require_noerr(SSLSetEnabledCiphers(server->handle, &ciphers[i].cipher, 1), out);
712
713            char test_description[1024];
714            snprintf(test_description, sizeof(test_description),
715                     "%40s ADH:%d CSA:%d DTLS:%d",
716                     ciphers[i].name,
717                     server->dh_anonymous,
718                     server->client_side_auth,
719                     d);
720
721            printf("Echo test: %s\n", test_description);
722
723            pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
724            pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
725
726            int server_err, client_err;
727            pthread_join(client_thread, (void*)&client_err);
728            pthread_join(server_thread, (void*)&server_err);
729
730            ok(!server_err && !client_err, "%40s ADH:%d CSA:%d DTLS:%d",
731               ciphers[i].name,
732               server->dh_anonymous,
733               server->client_side_auth,
734               d);
735        out:
736            close(sp[0]);
737            close(sp[1]);
738        }
739    } /* all configs */
740
741    CFRelease(server_certs);
742
743}
744
745int ssl_39_echo(int argc, char *const *argv)
746{
747    plan_tests(2 * 2 * 2 * 3 * (ciphers_len-1)/* client auth on/off * #configs * #ciphers */
748                + 1 /*cert*/);
749
750
751    tests();
752
753    return 0;
754}
755
756#endif
757
758/*
759TODO: count errSSLWouldBlock
760TODO: skip tests that don't matter: client_auth and anonymous dh
761TODO: we seem to only be negotiating tls - force a round of sslv3
762TODO: allow secure transport to also defer client side auth to client
763TODO: make sure anonymous dh is never selected if not expicitly enabled
764TODO: make sure DHE is not available if not explicitly enabled and no parameters
765      are set
766TODO: resumable sessions
767*/
768