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