]> git.saurik.com Git - apple/security.git/blob - libsecurity_ssl/regressions/ssl-43-ciphers.c
Security-55471.14.tar.gz
[apple/security.git] / libsecurity_ssl / regressions / ssl-43-ciphers.c
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
79 static 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
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 };
95 int nservers = sizeof(servers)/sizeof(servers[0]);
96
97 int protos[]={ kSSLProtocol3, kTLSProtocol1, kTLSProtocol11, kTLSProtocol12 };
98 int nprotos = sizeof(protos)/sizeof(protos[0]);
99
100 typedef 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
111 const 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
252 static int ciphers_len = array_size(ciphers);
253
254
255
256 #if 0 // currently unused
257 static 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
267 static 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
278 unsigned 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 };
286 unsigned char *dh_param_512_der = dh_param_512_bytes;
287 unsigned int dh_param_512_der_len = 72;
288
289 typedef 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
304 static 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
318 static 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
367 static 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
392 static 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
416 unsigned 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 };
426 unsigned int dn_len = 96;
427
428 static 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;
479 out:
480 if (ctx)
481 SSLDisposeContext(ctx);
482 return NULL;
483 }
484
485 static 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
597 out:
598 SSLClose(ctx);
599 SSLDisposeContext(ctx);
600 if (trust) CFRelease(trust);
601
602 return ortn;
603 }
604
605
606
607 static ssl_test_handle *
608 ssl_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
625 static void
626 tests(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
683 int 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 */