]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_ssl/regressions/ssl-42-ciphers.c
Security-57031.40.6.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 int 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, int 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 require_noerr(SSLSetMinimumDHGroupSize(ctx, 512), out);
346
347 if (!dh_anonymous) {
348 if (server)
349 require_noerr(SSLSetCertificate(ctx, certs), out);
350 if (client_side_auth && server) {
351 SSLAuthenticate auth;
352 require_noerr(SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate), out);
353 require_noerr(SSLGetClientSideAuthenticate(ctx, &auth), out);
354 require(auth==kAlwaysAuthenticate, out);
355 require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out);
356 }
357 #if 0 /* Setting client certificate in advance */
358 if (client_side_auth && !server)
359 require_noerr(SSLSetCertificate(ctx, certs), out);
360 #endif
361 if (client_side_auth && !server) /* enable break from SSLHandshake */
362 require_noerr(SSLSetSessionOption(ctx,
363 kSSLSessionOptionBreakOnCertRequested, true), out);
364 require_noerr(SSLSetSessionOption(ctx,
365 kSSLSessionOptionBreakOnServerAuth, true), out);
366 }
367
368 /* Tell SecureTransport to not check certs itself: it will break out of the
369 handshake to let us take care of it instead. */
370 require_noerr(SSLSetEnableCertVerify(ctx, false), out);
371
372 if (server) {
373 require_noerr(SSLSetDiffieHellmanParams(ctx,
374 dh_param_512_der, dh_param_512_der_len), out);
375 }
376 else /* if client */ {
377 }
378
379 return ctx;
380 out:
381 if (ctx)
382 CFRelease(ctx);
383 return NULL;
384 }
385
386 static bool check_peer_cert(SSLContextRef ctx, const ssl_test_handle *ssl, SecTrustRef *trust)
387 {
388 /* verify peer cert chain */
389 require_noerr(SSLCopyPeerTrust(ctx, trust), out);
390 SecTrustResultType trust_result = 0;
391 /* this won't verify without setting up a trusted anchor */
392 require_noerr(SecTrustEvaluate(*trust, &trust_result), out);
393
394 CFIndex n_certs = SecTrustGetCertificateCount(*trust);
395 /* fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
396
397 CFMutableArrayRef peer_cert_array =
398 CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks);
399 CFMutableArrayRef orig_peer_cert_array =
400 CFArrayCreateMutableCopy(NULL, n_certs, ssl->certs);
401 while (n_certs--)
402 CFArrayInsertValueAtIndex(peer_cert_array, 0,
403 SecTrustGetCertificateAtIndex(*trust, n_certs));
404
405 SecIdentityRef ident =
406 (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0);
407 SecCertificateRef peer_cert = NULL;
408 require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out);
409 CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert);
410 CFRelease(peer_cert);
411
412 require(CFEqual(orig_peer_cert_array, peer_cert_array), out);
413 CFRelease(orig_peer_cert_array);
414 CFRelease(peer_cert_array);
415
416 /*
417 CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
418 char cert_name_buffer[1024];
419 require(CFStringGetFileSystemRepresentation(cert_name,
420 cert_name_buffer, sizeof(cert_name_buffer)), out);
421 fprintf(stderr, "cert name: %s\n", cert_name_buffer);
422 CFRelease(trust);
423 */
424 return true;
425 out:
426 return false;
427 }
428
429 static void *securetransport_ssl_thread(void *arg)
430 {
431 OSStatus ortn;
432 ssl_test_handle * ssl = (ssl_test_handle *)arg;
433 SSLContextRef ctx = ssl->st;
434 SecTrustRef trust = NULL;
435 bool got_server_auth = false, got_client_cert_req = false;
436 SSLSessionState ssl_state;
437
438 pthread_setname_np(ssl->is_server?"server thread":"client thread");
439
440 require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out);
441 require_action(ssl_state==kSSLIdle, out, ortn = -1);
442
443 //uint64_t start = mach_absolute_time();
444 do {
445 ortn = SSLHandshake(ctx);
446 require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
447
448 if (ortn == errSSLPeerAuthCompleted)
449 {
450 require_action(ssl_state==kSSLHandshake, out, ortn = -1);
451 require_string(!got_server_auth, out, "second server auth");
452 require_string(!got_client_cert_req, out, "got client cert req before server auth");
453 got_server_auth = true;
454 require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
455 require_string(check_peer_cert(ctx, ssl, &trust), out, "Certificate check failed");
456 } else if (ortn == errSSLClientCertRequested) {
457 require_action(ssl_state==kSSLHandshake, out, ortn = -1);
458 require_string(!got_client_cert_req, out, "second client cert req");
459 require_string(got_server_auth, out, "didn't get server auth first");
460 got_client_cert_req = true;
461
462 /* set client cert */
463 require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server");
464 require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH");
465
466 CFArrayRef DNs = NULL;
467 require_noerr(SSLCopyDistinguishedNames (ctx, &DNs), out);
468 require(DNs, out);
469 CFRelease(DNs);
470
471 require_string(ssl->client_side_auth, out, "errSSLClientCertRequested in run not testing that");
472 if(ssl->client_side_auth==1) { // Don't set a client cert in mode 2.
473 require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
474 }
475 } else if (ortn == errSSLWouldBlock) {
476 require_action(ssl_state==kSSLHandshake, out, ortn = -1);
477 }
478 } while (ortn == errSSLWouldBlock
479 || ortn == errSSLServerAuthCompleted
480 || ortn == errSSLClientCertRequested);
481 require_noerr_action_quiet(ortn, out,
482 fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
483
484 require_action(ssl_state==kSSLConnected, out, ortn = -1);
485
486 if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) {
487 require_string(got_server_auth, out, "never got server auth");
488 if (ssl->client_side_auth)
489 require_string(got_client_cert_req, out, "never got client cert req");
490 }
491
492 if (!ssl->is_server && !ssl->dh_anonymous && ssl->is_session_resume) {
493 require_string(!got_server_auth, out, "got server auth during resumption??");
494 require_string(check_peer_cert(ctx, ssl, &trust), out, "Certificate check failed (resumption case)");
495 }
496 //uint64_t elapsed = mach_absolute_time() - start;
497 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
498
499 /*
500 SSLProtocol proto = kSSLProtocolUnknown;
501 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
502
503 SSLCipherSuite cipherSuite;
504 require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
505 //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
506
507 if(ssl->is_dtls) {
508 size_t sz;
509 SSLGetDatagramWriteSize(ctx, &sz);
510 //fprintf(stderr, "Max Write Size = %ld\n", sz);
511 }
512
513 Boolean sessionWasResumed = false;
514 uint8_t session_id_data[MAX_SESSION_ID_LENGTH];
515 size_t session_id_length = sizeof(session_id_data);
516 require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out);
517 require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1);
518 // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
519 //hexdump(session_id_data, session_id_length);
520
521 #define BUFSIZE (8*1024)
522 unsigned char ibuf[BUFSIZE], obuf[BUFSIZE];
523
524 for(int i=0; i<10; i++) {
525 size_t len;
526 if (ssl->is_server) {
527 memset(obuf, i, BUFSIZE);
528 // SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf);
529 require_noerr(ortn = SSLWrite(ctx, obuf, BUFSIZE, &len), out);
530 require_action(len == BUFSIZE, out, ortn = -1);
531
532 require_noerr(ortn = SSLWrite(ctx, obuf, 0, &len), out);
533 require_action(len == 0, out, ortn = -1);
534 }
535
536 len=0;
537 while(len<BUFSIZE) {
538 size_t l=len;
539 ortn = SSLRead(ctx, ibuf+len, BUFSIZE-len, &l);
540 len+=l;
541 //printf("SSLRead [%p] %d, l=%zd len=%zd\n", ctx, (int)ortn, l, len);
542 }
543
544 //printf("SSLRead [%p] done\n", ctx);
545
546 require_noerr(ortn, out);
547 require_action(len == BUFSIZE, out, ortn = -1);
548
549 if (ssl->is_server) {
550 require_noerr(memcmp(ibuf, obuf, BUFSIZE), out);
551 } else {
552 require_noerr(ortn = SSLWrite(ctx, ibuf, BUFSIZE, &len), out);
553 require_action(len == BUFSIZE, out, ortn = -1);
554 }
555 }
556
557 out:
558 SSLClose(ctx);
559 CFRelease(ctx);
560 if (trust) CFRelease(trust);
561 close(ssl->comm);
562 pthread_exit((void *)(intptr_t)ortn);
563 return NULL;
564 }
565
566
567
568 static ssl_test_handle *
569 ssl_test_handle_create(uint32_t session_id, bool resume, bool server, int client_side_auth, bool dh_anonymous, bool dtls,
570 int comm, CFArrayRef certs, SSLProtocol proto)
571 {
572 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
573 if (handle) {
574 handle->session_id = session_id;
575 handle->is_session_resume = resume;
576 handle->is_server = server;
577 handle->is_dtls = dtls;
578 handle->client_side_auth = client_side_auth;
579 handle->dh_anonymous = dh_anonymous;
580 handle->comm = comm;
581 handle->certs = certs;
582 handle->proto = proto;
583 handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, proto);
584 }
585 return handle;
586 }
587
588 static void
589 tests(void)
590 {
591 pthread_t client_thread, server_thread;
592 CFArrayRef server_certs = server_chain();
593 ok(server_certs, "got server certs");
594
595 /* Enable this if you want to test a specific d/i/k/l combination */
596 #if 0
597 int d=0, i=0, l=0, k=0; { {
598 #else
599 int d,i,k,l,p;
600
601 for (p=0; p<nprotos; p++)
602 for (d=0;d<2; d++) /* dtls or not dtls */
603 for (k=0; k<3; k++) /* client side auth mode: 0: server doesn't request , 1: server request, client provide, 2: server request, client does not provide */
604 {
605 for (i=0; ciphers[i].cipher != (SSLCipherSuite)(-1); i++)
606 for (l = 0; l<2; l++) {
607 #endif
608 SKIP:{
609 skip("This ciphersuite is not supported for DTLS", 1, !d || ciphers[i].dtls);
610
611 int sp[2];
612 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
613 fcntl(sp[0], F_SETNOSIGPIPE, 1);
614 fcntl(sp[1], F_SETNOSIGPIPE, 1);
615
616 ssl_test_handle *server, *client;
617
618 int client_side_auth = (k);
619
620 uint32_t session_id = (k+1) << 16 | (i+1);
621 //fprintf(stderr, "session_id: %d\n", session_id);
622 server = ssl_test_handle_create(session_id, (l == 1), true /*server*/,
623 client_side_auth, ciphers[i].dh_anonymous, d,
624 sp[0], server_certs, protos[p]);
625 client = ssl_test_handle_create(session_id, (l == 1), false/*client*/,
626 client_side_auth, ciphers[i].dh_anonymous, d,
627 sp[1], server_certs, protos[p]);
628
629 require_noerr(SSLSetPeerID(server->st, &session_id, sizeof(session_id)), out);
630 require_noerr(SSLSetPeerID(client->st, &session_id, sizeof(session_id)), out);
631
632 /* set fixed cipher on client and server */
633 require_noerr(SSLSetEnabledCiphers(client->st, &ciphers[i].cipher, 1), out);
634 require_noerr(SSLSetEnabledCiphers(server->st, &ciphers[i].cipher, 1), out);
635
636 require_noerr(SSLSetPSKSharedSecret(client->st, "123456789", 9), out);
637 require_noerr(SSLSetPSKSharedSecret(server->st, "123456789", 9), out);
638
639
640 pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
641 pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
642
643 int server_err, client_err;
644 pthread_join(client_thread, (void*)&client_err);
645 pthread_join(server_thread, (void*)&server_err);
646
647
648 ok(!server_err && !client_err,
649 "%40s ADH:%d CSA:%d DTLS:%d RESUME:%d PROTO:%d",
650 ciphers[i].name,
651 server->dh_anonymous,
652 server->client_side_auth,
653 d, l, p);
654 out:
655 free(client);
656 free(server);
657
658 }
659 } /* all ciphers */
660 } /* all configs */
661
662 CFRelease(server_certs);
663 }
664
665 int ssl_42_ciphers(int argc, char *const *argv)
666 {
667
668 plan_tests(3 * 2 * 2 * nprotos * (ciphers_len-1)/* client auth 0/1/2 * #configs * protos * #ciphers */
669 + 1 /*cert*/);
670
671
672 tests();
673
674 return 0;
675 }
676
677 /*
678 TODO: count errSSLWouldBlock
679 TODO: skip tests that don't matter: client_auth and anonymous dh
680 TODO: we seem to only be negotiating tls - force a round of sslv3
681 TODO: allow secure transport to also defer client side auth to client
682 TODO: make sure anonymous dh is never selected if not expicitly enabled
683 TODO: make sure DHE is not available if not explicitly enabled and no parameters
684 are set
685 TODO: resumable sessions
686 */