]> git.saurik.com Git - apple/security.git/blob - libsecurity_ssl/regressions/ssl-42-ciphers.c
Security-55471.14.tar.gz
[apple/security.git] / libsecurity_ssl / regressions / ssl-42-ciphers.c
1
2 #include <stdbool.h>
3 #include <pthread.h>
4 #include <fcntl.h>
5 #include <sys/mman.h>
6 #include <unistd.h>
7
8 #include <CoreFoundation/CoreFoundation.h>
9
10 #include <AssertMacros.h>
11 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
12 #include <Security/SecureTransport.h>
13 #include <Security/SecPolicy.h>
14 #include <Security/SecTrust.h>
15 #include <Security/SecIdentity.h>
16 #include <Security/SecIdentityPriv.h>
17 #include <Security/SecCertificatePriv.h>
18 #include <Security/SecKeyPriv.h>
19 #include <Security/SecItem.h>
20 #include <Security/SecRandom.h>
21
22 #include <utilities/array_size.h>
23 #include <string.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <errno.h>
27 #include <stdlib.h>
28 #include <mach/mach_time.h>
29
30 #if TARGET_OS_IPHONE
31 #include <Security/SecRSAKey.h>
32 #endif
33
34 #include "ssl_regressions.h"
35 #include "ssl-utils.h"
36
37 /*
38 SSL CipherSuite tests
39
40 Below are all the ciphers that are individually tested. The first element
41 is the SecureTransport/RFC name; the second is what openssl calls it, which
42 can be looked up in ciphers(1).
43
44 All SSL_DH_* and TLS_DH_* are disabled because neither openssl nor
45 securetranport support them:
46 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_DSS_WITH_DES_CBC_SHA,
47 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
48 SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
49 TLS_DH_DSS_WITH_AES_128_CBC_SHA, TLS_DH_RSA_WITH_AES_128_CBC_SHA,
50 TLS_DH_DSS_WITH_AES_256_CBC_SHA, TLS_DH_RSA_WITH_AES_256_CBC_SHA,
51
52 DSS is unimplemented by securetransport on the phone:
53 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA,
54 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
55 TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
56
57 SSLv2 ciphersuites disabled by securetransport on phone:
58 SSL_RSA_WITH_RC2_CBC_MD5, SSL_RSA_WITH_IDEA_CBC_MD5,
59 SSL_RSA_WITH_DES_CBC_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5,
60
61 SSLv3 ciphersuites disabled by securetransport on phone:
62 SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
63
64 Export ciphersuites disabled on iOS 5.0:
65 SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
66 SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
67 SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,
68 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA
69
70 */
71
72 typedef struct _CipherSuiteName {
73 SSLCipherSuite cipher;
74 const char *name;
75 bool dh_anonymous;
76 } CipherSuiteName;
77
78 #define CIPHER(cipher, dh_anonymous) { cipher, #cipher, dh_anonymous },
79
80 static const CipherSuiteName ciphers[] = {
81 //SSL_NULL_WITH_NULL_NULL, unsupported
82 CIPHER(SSL_RSA_WITH_NULL_SHA, false)
83 CIPHER(SSL_RSA_WITH_NULL_MD5, false)
84 CIPHER(TLS_RSA_WITH_NULL_SHA256, false)
85
86 CIPHER(SSL_RSA_WITH_RC4_128_MD5, false)
87 CIPHER(SSL_RSA_WITH_RC4_128_SHA, false)
88 CIPHER(SSL_RSA_WITH_3DES_EDE_CBC_SHA, false)
89
90 CIPHER(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, false)
91 CIPHER(SSL_DH_anon_WITH_RC4_128_MD5, true)
92 CIPHER(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, true)
93 CIPHER(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, false)
94 CIPHER(TLS_DH_anon_WITH_AES_128_CBC_SHA, true)
95 CIPHER(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, false)
96 CIPHER(TLS_DH_anon_WITH_AES_256_CBC_SHA, true)
97
98 CIPHER(TLS_RSA_WITH_AES_128_CBC_SHA, false)
99 CIPHER(TLS_RSA_WITH_AES_256_CBC_SHA, false)
100
101
102 CIPHER(TLS_PSK_WITH_AES_128_CBC_SHA, true)
103 CIPHER(TLS_PSK_WITH_AES_256_CBC_SHA384, true)
104 CIPHER(TLS_PSK_WITH_AES_128_CBC_SHA256, true)
105 CIPHER(TLS_PSK_WITH_AES_256_CBC_SHA, true)
106 CIPHER(TLS_PSK_WITH_AES_128_CBC_SHA, true)
107 CIPHER(TLS_PSK_WITH_RC4_128_SHA, true)
108 CIPHER(TLS_PSK_WITH_3DES_EDE_CBC_SHA, true)
109 CIPHER(TLS_PSK_WITH_NULL_SHA384, true)
110 CIPHER(TLS_PSK_WITH_NULL_SHA256, true)
111 CIPHER(TLS_PSK_WITH_NULL_SHA, true)
112
113
114 #if 0
115 CIPHER(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, false)
116 CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, false)
117
118 CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, false)
119 CIPHER(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, false)
120
121 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, false)
122 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, false)
123
124 CIPHER(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, true)
125 CIPHER(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, true)
126
127 CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, false)
128 CIPHER(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, false)
129 CIPHER(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, false)
130 CIPHER(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, false)
131 #endif
132
133 #if 0
134 CIPHER(TLS_RSA_WITH_AES_256_GCM_SHA384, false)
135 CIPHER(TLS_RSA_WITH_AES_128_GCM_SHA256, false)
136 #endif
137
138 /* Export ciphers are disabled */
139 #if 0
140 CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5, false)
141 CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, false)
142 CIPHER(SSL_RSA_WITH_DES_CBC_SHA, false)
143 CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, false)
144 CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA, false)
145 CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, true)
146 CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, true)
147 CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA, true)
148 #endif
149
150 { -1 }
151 };
152
153 static int ciphers_len = array_size(ciphers);
154
155
156 static int protos[]={kTLSProtocol1, kTLSProtocol11, kTLSProtocol12 };
157 static int nprotos = sizeof(protos)/sizeof(protos[0]);
158
159
160 #if 0 // currently unused
161 static SSLCipherSuite sslcipher_atoi(const char *name)
162 {
163 const CipherSuiteName *a = ciphers;
164 while(a->name) {
165 if (0 == strcmp(a->name, name)) break;
166 a++;
167 }
168 return a->cipher;
169 }
170
171 static const char * sslcipher_itoa(SSLCipherSuite num)
172 {
173 const CipherSuiteName *a = ciphers;
174 while(a->cipher >= 0) {
175 if (num == a->cipher) break;
176 a++;
177 }
178 return a->name;
179 }
180 #endif // currently unused
181
182 static unsigned char dh_param_512_bytes[] = {
183 0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64,
184 0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0,
185 0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd,
186 0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b,
187 0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb,
188 0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02
189 };
190 static unsigned char *dh_param_512_der = dh_param_512_bytes;
191 static unsigned int dh_param_512_der_len = 72;
192
193
194 typedef struct {
195 uint32_t session_id;
196 bool is_session_resume;
197 SSLContextRef st;
198 bool is_server;
199 bool is_dtls;
200 bool client_side_auth;
201 bool dh_anonymous;
202 int comm;
203 CFArrayRef certs;
204 SSLProtocol proto;
205 } ssl_test_handle;
206
207 #if 0 // currently unused
208 static CFArrayRef SecIdentityCopySSLClientAuthenticationChain(SecIdentityRef identity)
209 {
210 CFMutableArrayRef chain = NULL;
211 SecPolicyRef policy = NULL;
212 SecTrustRef trust = NULL;
213 SecTrustResultType trust_result;
214
215 do {
216 policy = SecPolicyCreateSSL(false, NULL);
217 if (!policy)
218 break;
219
220 SecCertificateRef cert = NULL;
221 if (SecIdentityCopyCertificate(identity, &cert))
222 break;
223
224 CFArrayRef certs = CFArrayCreate(NULL, (const void **)&cert,
225 1, &kCFTypeArrayCallBacks);
226 CFRelease(cert);
227 if (!certs)
228 break;
229
230 if (SecTrustCreateWithCertificates(certs, policy, &trust))
231 break;
232 CFRelease(certs);
233 CFRelease(policy);
234 if (SecTrustEvaluate(trust, &trust_result))
235 break;
236
237 int i, count = SecTrustGetCertificateCount(trust);
238 chain = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks);
239 CFArrayAppendValue(chain, identity);
240 for (i = 1; i < count; i++) {
241 if ((i+1 == count) && (trust_result == kSecTrustResultUnspecified))
242 continue; /* skip anchor if chain is complete */
243 SecCertificateRef s = SecTrustGetCertificateAtIndex(trust, i);
244 CFArrayAppendValue(chain, s);
245 }
246 } while (0);
247 if (trust)
248 CFRelease(trust);
249 if (policy)
250 CFRelease(policy);
251 return chain;
252 }
253 #endif // currently unused
254
255 // MARK: -
256 // MARK: SecureTransport support
257
258 #if 0
259 static void hexdump(const uint8_t *bytes, size_t len) {
260 size_t ix;
261 printf("socket write(%p, %lu)\n", bytes, len);
262 for (ix = 0; ix < len; ++ix) {
263 if (!(ix % 16))
264 printf("\n");
265 printf("%02X ", bytes[ix]);
266 }
267 printf("\n");
268 }
269 #else
270 #define hexdump(bytes, len)
271 #endif
272
273 static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
274 {
275 size_t len = *length;
276 uint8_t *ptr = (uint8_t *)data;
277
278 do {
279 ssize_t ret;
280 do {
281 hexdump(ptr, len);
282 ret = write((int)conn, ptr, len);
283 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
284 if (ret > 0) {
285 len -= ret;
286 ptr += ret;
287 }
288 else
289 return -36;
290 } while (len > 0);
291
292 *length = *length - len;
293 return errSecSuccess;
294 }
295
296 static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
297 {
298 size_t len = *length;
299 uint8_t *ptr = (uint8_t *)data;
300
301 do {
302 ssize_t ret;
303 do {
304 ret = read((int)conn, ptr, len);
305 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
306 if (ret > 0) {
307 len -= ret;
308 ptr += ret;
309 }
310 else
311 return -36;
312 } while (len > 0);
313
314 *length = *length - len;
315 return errSecSuccess;
316 }
317
318 static unsigned char dn[] = {
319 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
320 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
321 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
322 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
323 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
324 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
325 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
326 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
327 };
328 static unsigned int dn_len = 96;
329
330 static SSLContextRef make_ssl_ref(bool server, bool client_side_auth, bool dh_anonymous,
331 bool dtls, int sock, CFArrayRef certs, SSLProtocol proto)
332 {
333 SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, dtls?kSSLDatagramType:kSSLStreamType);
334 require(ctx, out);
335
336 if(dtls) {
337 size_t mtu;
338 require_noerr(SSLSetMaxDatagramRecordSize(ctx, 400), out);
339 require_noerr(SSLGetMaxDatagramRecordSize(ctx, &mtu), out);
340 } else {
341 require_noerr(SSLSetProtocolVersionMax(ctx, proto), out);
342 }
343 require_noerr(SSLSetIOFuncs(ctx,
344 (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
345 require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out);
346 static const char *peer_domain_name = "localhost";
347 require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
348 strlen(peer_domain_name)), out);
349
350
351 if (!dh_anonymous) {
352 if (server)
353 require_noerr(SSLSetCertificate(ctx, certs), out);
354 if (client_side_auth && server) {
355 SSLAuthenticate auth;
356 require_noerr(SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate), out);
357 require_noerr(SSLGetClientSideAuthenticate(ctx, &auth), out);
358 require(auth==kAlwaysAuthenticate, out);
359 require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out);
360 }
361 #if 0 /* Setting client certificate in advance */
362 if (client_side_auth && !server)
363 require_noerr(SSLSetCertificate(ctx, certs), out);
364 #endif
365 if (client_side_auth && !server) /* enable break from SSLHandshake */
366 require_noerr(SSLSetSessionOption(ctx,
367 kSSLSessionOptionBreakOnCertRequested, true), out);
368 require_noerr(SSLSetSessionOption(ctx,
369 kSSLSessionOptionBreakOnServerAuth, true), out);
370 }
371
372 /* Tell SecureTransport to not check certs itself: it will break out of the
373 handshake to let us take care of it instead. */
374 require_noerr(SSLSetEnableCertVerify(ctx, false), out);
375
376 if (server) {
377 require_noerr(SSLSetDiffieHellmanParams(ctx,
378 dh_param_512_der, dh_param_512_der_len), out);
379 }
380 else /* if client */ {
381 }
382
383 return ctx;
384 out:
385 if (ctx)
386 CFRelease(ctx);
387 return NULL;
388 }
389
390 static void *securetransport_ssl_thread(void *arg)
391 {
392 OSStatus ortn;
393 ssl_test_handle * ssl = (ssl_test_handle *)arg;
394 SSLContextRef ctx = ssl->st;
395 SecTrustRef trust = NULL;
396 bool got_server_auth = false, got_client_cert_req = false;
397
398 pthread_setname_np(ssl->is_server?"server thread":"client thread");
399
400 //uint64_t start = mach_absolute_time();
401 do {
402 ortn = SSLHandshake(ctx);
403
404 if (ortn == errSSLPeerAuthCompleted)
405 {
406 require_string(!got_server_auth, out, "second server auth");
407 require_string(!got_client_cert_req, out, "got client cert req before server auth");
408 got_server_auth = true;
409 require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
410 /* verify peer cert chain */
411 require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
412 SecTrustResultType trust_result = 0;
413 /* this won't verify without setting up a trusted anchor */
414 require_noerr(SecTrustEvaluate(trust, &trust_result), out);
415
416 CFIndex n_certs = SecTrustGetCertificateCount(trust);
417 /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
418
419 CFMutableArrayRef peer_cert_array =
420 CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks);
421 CFMutableArrayRef orig_peer_cert_array =
422 CFArrayCreateMutableCopy(NULL, n_certs, ssl->certs);
423 while (n_certs--)
424 CFArrayInsertValueAtIndex(peer_cert_array, 0,
425 SecTrustGetCertificateAtIndex(trust, n_certs));
426
427 SecIdentityRef ident =
428 (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0);
429 SecCertificateRef peer_cert = NULL;
430 require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out);
431 CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert);
432 CFRelease(peer_cert);
433
434 require(CFEqual(orig_peer_cert_array, peer_cert_array), out);
435 CFRelease(orig_peer_cert_array);
436 CFRelease(peer_cert_array);
437
438 /*
439 CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
440 char cert_name_buffer[1024];
441 require(CFStringGetFileSystemRepresentation(cert_name,
442 cert_name_buffer, sizeof(cert_name_buffer)), out);
443 fprintf(stderr, "cert name: %s\n", cert_name_buffer);
444 CFRelease(trust);
445 */
446 } else if (ortn == errSSLClientCertRequested) {
447 require_string(!got_client_cert_req, out, "second client cert req");
448 require_string(got_server_auth, out, "didn't get server auth first");
449 got_client_cert_req = true;
450
451 /* set client cert */
452 require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server");
453 require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH");
454
455 CFArrayRef DNs = NULL;
456 require_noerr(SSLCopyDistinguishedNames (ctx, &DNs), out);
457 require(DNs, out);
458 CFRelease(DNs);
459
460 require_string(ssl->client_side_auth, out, "errSSLClientCertRequested in run not testing that");
461 require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
462 }
463 } while (ortn == errSSLWouldBlock
464 || ortn == errSSLServerAuthCompleted
465 || ortn == errSSLClientCertRequested);
466 require_noerr_action_quiet(ortn, out,
467 fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
468
469 if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) {
470 require_string(got_server_auth, out, "never got server auth");
471 if (ssl->client_side_auth)
472 require_string(got_client_cert_req, out, "never got client cert req");
473 }
474 //uint64_t elapsed = mach_absolute_time() - start;
475 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
476
477 /*
478 SSLProtocol proto = kSSLProtocolUnknown;
479 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
480
481 SSLCipherSuite cipherSuite;
482 require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
483 //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
484
485 if(ssl->is_dtls) {
486 size_t sz;
487 SSLGetDatagramWriteSize(ctx, &sz);
488 //fprintf(stderr, "Max Write Size = %ld\n", sz);
489 }
490
491 Boolean sessionWasResumed = false;
492 uint8_t session_id_data[MAX_SESSION_ID_LENGTH];
493 size_t session_id_length = sizeof(session_id_data);
494 require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out);
495 require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1);
496 // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
497 //hexdump(session_id_data, session_id_length);
498
499 unsigned char ibuf[4096], obuf[4096];
500 size_t len;
501 if (ssl->is_server) {
502 SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf);
503 require_noerr_quiet(ortn = SSLWrite(ctx, obuf, sizeof(obuf), &len), out);
504 require_action_quiet(len == sizeof(obuf), out, ortn = -1);
505 }
506 require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out);
507 require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
508
509 if (ssl->is_server) {
510 require_noerr(memcmp(ibuf, obuf, sizeof(ibuf)), out);
511 } else {
512 require_noerr_quiet(ortn = SSLWrite(ctx, ibuf, sizeof(ibuf), &len), out);
513 require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
514 }
515
516 out:
517 SSLClose(ctx);
518 CFRelease(ctx);
519 if (trust) CFRelease(trust);
520 close(ssl->comm);
521 pthread_exit((void *)(intptr_t)ortn);
522 return NULL;
523 }
524
525
526
527 static ssl_test_handle *
528 ssl_test_handle_create(uint32_t session_id, bool resume, bool server, bool client_side_auth, bool dh_anonymous, bool dtls,
529 int comm, CFArrayRef certs, SSLProtocol proto)
530 {
531 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
532 if (handle) {
533 handle->session_id = session_id;
534 handle->is_session_resume = resume;
535 handle->is_server = server;
536 handle->is_dtls = dtls;
537 handle->client_side_auth = client_side_auth;
538 handle->dh_anonymous = dh_anonymous;
539 handle->comm = comm;
540 handle->certs = certs;
541 handle->proto = proto;
542 handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, proto);
543 }
544 return handle;
545 }
546
547 static void
548 tests(void)
549 {
550 pthread_t client_thread, server_thread;
551 CFArrayRef server_certs = server_chain();
552 ok(server_certs, "got server certs");
553
554 /* Enable this if you want to test a specific d/i/k/l combination */
555 #if 0
556 int d=0, i=0, l=0, k=0; { {
557 #else
558 int d,i,k,l,p;
559
560 for (p=0; p<nprotos; p++)
561 for (d=0;d<2; d++) /* dtls or not dtls */
562 for (k=0; k<2; k++)
563 {
564 for (i=0; ciphers[i].cipher != (SSLCipherSuite)(-1); i++)
565 for (l = 0; l<2; l++) {
566 #endif
567 SKIP:{
568 //skip("Session resumption tests do not work at this point", 1, l != 1);
569
570 int sp[2];
571 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
572 fcntl(sp[0], F_SETNOSIGPIPE, 1);
573 fcntl(sp[1], F_SETNOSIGPIPE, 1);
574
575 ssl_test_handle *server, *client;
576
577 bool client_side_auth = (k);
578
579 uint32_t session_id = (k+1) << 16 | (i+1);
580 //fprintf(stderr, "session_id: %d\n", session_id);
581 server = ssl_test_handle_create(session_id, (l == 1), true /*server*/,
582 client_side_auth, ciphers[i].dh_anonymous, d,
583 sp[0], server_certs, protos[p]);
584 client = ssl_test_handle_create(session_id, (l == 1), false/*client*/,
585 client_side_auth, ciphers[i].dh_anonymous, d,
586 sp[1], server_certs, protos[p]);
587
588 require_noerr(SSLSetPeerID(server->st, &session_id, sizeof(session_id)), out);
589 require_noerr(SSLSetPeerID(client->st, &session_id, sizeof(session_id)), out);
590
591 /* set fixed cipher on client and server */
592 require_noerr(SSLSetEnabledCiphers(client->st, &ciphers[i].cipher, 1), out);
593 require_noerr(SSLSetEnabledCiphers(server->st, &ciphers[i].cipher, 1), out);
594
595 require_noerr(SSLSetPSKSharedSecret(client->st, "123456789", 9), out);
596 require_noerr(SSLSetPSKSharedSecret(server->st, "123456789", 9), out);
597
598
599 pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
600 pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
601
602 int server_err, client_err;
603 pthread_join(client_thread, (void*)&client_err);
604 pthread_join(server_thread, (void*)&server_err);
605
606
607 ok(!server_err && !client_err,
608 "%40s ADH:%d CSA:%d DTLS:%d RESUME:%d PROTO:%d",
609 ciphers[i].name,
610 server->dh_anonymous,
611 server->client_side_auth,
612 d, l, p);
613 out:
614 free(client);
615 free(server);
616
617 }
618 } /* all ciphers */
619 } /* all configs */
620
621 CFRelease(server_certs);
622 }
623
624 int ssl_42_ciphers(int argc, char *const *argv)
625 {
626
627 plan_tests(2 * 2 * 2 * nprotos * (ciphers_len-1)/* client auth on/off * #configs * #ciphers */
628 + 1 /*cert*/);
629
630
631 tests();
632
633 return 0;
634 }
635
636 /*
637 TODO: count errSSLWouldBlock
638 TODO: skip tests that don't matter: client_auth and anonymous dh
639 TODO: we seem to only be negotiating tls - force a round of sslv3
640 TODO: allow secure transport to also defer client side auth to client
641 TODO: make sure anonymous dh is never selected if not expicitly enabled
642 TODO: make sure DHE is not available if not explicitly enabled and no parameters
643 are set
644 TODO: resumable sessions
645 */