]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/regressions/ssl-42-ciphers.c
Security-59306.11.20.tar.gz
[apple/security.git] / OSX / 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 <utilities/SecCFRelease.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <errno.h>
28 #include <stdlib.h>
29 #include <mach/mach_time.h>
30
31 #include <tls_ciphersuites.h>
32
33 #if TARGET_OS_IPHONE
34 #include <Security/SecRSAKey.h>
35 #endif
36
37 #include "ssl_regressions.h"
38 #include "ssl-utils.h"
39
40 /*
41 SSL CipherSuite tests
42 */
43
44 static const SSLCipherSuite SupportedCipherSuites[] = {
45
46 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
47 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
48 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
49 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
50 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
51 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
52 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
53
54 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
55 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
56 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
57 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
58 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
59 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
60 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
61
62 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
63 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
64 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
65 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
66 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
67 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
68 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
69
70 TLS_RSA_WITH_AES_256_GCM_SHA384,
71 TLS_RSA_WITH_AES_128_GCM_SHA256,
72 TLS_RSA_WITH_AES_256_CBC_SHA256,
73 TLS_RSA_WITH_AES_128_CBC_SHA256,
74 TLS_RSA_WITH_AES_256_CBC_SHA,
75 TLS_RSA_WITH_AES_128_CBC_SHA,
76 SSL_RSA_WITH_3DES_EDE_CBC_SHA,
77
78 /* RC4 */
79 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
80 TLS_ECDHE_RSA_WITH_RC4_128_SHA,
81 SSL_RSA_WITH_RC4_128_SHA,
82 SSL_RSA_WITH_RC4_128_MD5,
83
84 /* Unsafe ciphersuites */
85
86 TLS_DH_anon_WITH_AES_256_GCM_SHA384,
87 TLS_DH_anon_WITH_AES_128_GCM_SHA256,
88 TLS_DH_anon_WITH_AES_128_CBC_SHA256,
89 TLS_DH_anon_WITH_AES_256_CBC_SHA256,
90 TLS_DH_anon_WITH_AES_128_CBC_SHA,
91 TLS_DH_anon_WITH_AES_256_CBC_SHA,
92 SSL_DH_anon_WITH_RC4_128_MD5,
93 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,
94
95 TLS_ECDH_anon_WITH_NULL_SHA,
96 TLS_ECDH_anon_WITH_RC4_128_SHA,
97 TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
98 TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
99 TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
100
101 TLS_ECDHE_ECDSA_WITH_NULL_SHA,
102 TLS_ECDHE_RSA_WITH_NULL_SHA,
103
104 TLS_PSK_WITH_AES_256_CBC_SHA384,
105 TLS_PSK_WITH_AES_128_CBC_SHA256,
106 TLS_PSK_WITH_AES_256_CBC_SHA,
107 TLS_PSK_WITH_AES_128_CBC_SHA,
108 TLS_PSK_WITH_RC4_128_SHA,
109 TLS_PSK_WITH_3DES_EDE_CBC_SHA,
110 TLS_PSK_WITH_NULL_SHA384,
111 TLS_PSK_WITH_NULL_SHA256,
112 TLS_PSK_WITH_NULL_SHA,
113
114 TLS_RSA_WITH_NULL_SHA256,
115 SSL_RSA_WITH_NULL_SHA,
116 SSL_RSA_WITH_NULL_MD5
117
118 };
119
120 static const unsigned SupportedCipherSuitesCount = sizeof(SupportedCipherSuites)/sizeof(SupportedCipherSuites[0]);
121
122
123 static int protos[]={kTLSProtocol1, kTLSProtocol11, kTLSProtocol12, kDTLSProtocol1 };
124 static int nprotos = sizeof(protos)/sizeof(protos[0]);
125
126
127 static unsigned char dh_param_1024_bytes[] = {
128 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0xf2, 0x56, 0xb9, 0x41, 0x74,
129 0x8c, 0x54, 0x22, 0xad, 0x94, 0x2b, 0xed, 0x83, 0xb9, 0xa0, 0x2f, 0x40,
130 0xce, 0xf8, 0xec, 0x96, 0xed, 0xcd, 0x8e, 0xfc, 0xf8, 0xdd, 0x06, 0x15,
131 0xbc, 0x68, 0x0d, 0x0e, 0x2c, 0xef, 0x00, 0x71, 0x28, 0x3d, 0x27, 0x6d,
132 0x5e, 0x42, 0x8c, 0xbd, 0x0f, 0x07, 0x23, 0x9d, 0x07, 0x8e, 0x52, 0x47,
133 0xa2, 0x5d, 0xf8, 0xd9, 0x9a, 0x7b, 0xb4, 0xab, 0xd2, 0xa3, 0x39, 0xe9,
134 0x2c, 0x3b, 0x9b, 0xaa, 0xbe, 0x4e, 0x01, 0x36, 0x16, 0xc2, 0x9e, 0x7b,
135 0x38, 0x78, 0x82, 0xd0, 0xed, 0x8e, 0x1e, 0xce, 0xa6, 0x23, 0x95, 0xae,
136 0x31, 0x66, 0x58, 0x60, 0x44, 0xdf, 0x1f, 0x9c, 0x68, 0xbf, 0x8b, 0xf1,
137 0xb4, 0xa8, 0xe7, 0xb2, 0x43, 0x8b, 0xa9, 0x3d, 0xa1, 0xb7, 0x1a, 0x11,
138 0xcf, 0xf4, 0x5e, 0xf7, 0x08, 0xf6, 0x84, 0x1c, 0xd7, 0xfa, 0x40, 0x10,
139 0xdc, 0x64, 0x83, 0x02, 0x01, 0x02
140 };
141 static unsigned char *dh_param_der = dh_param_1024_bytes;
142 static unsigned int dh_param_der_len = sizeof(dh_param_1024_bytes);
143
144
145 typedef struct {
146 uint32_t session_id;
147 bool is_session_resume;
148 SSLContextRef st;
149 bool is_server;
150 bool is_dtls;
151 SSLAuthenticate client_side_auth;
152 bool dh_anonymous;
153 int comm;
154 CFArrayRef certs;
155 CFArrayRef peer_certs;
156 SSLProtocol proto;
157 uint64_t time; // output
158 } ssl_test_handle;
159
160 #if 0 // currently unused
161 static CFArrayRef SecIdentityCopySSLClientAuthenticationChain(SecIdentityRef identity)
162 {
163 CFMutableArrayRef chain = NULL;
164 SecPolicyRef policy = NULL;
165 SecTrustRef trust = NULL;
166 SecTrustResultType trust_result;
167
168 do {
169 policy = SecPolicyCreateSSL(false, NULL);
170 if (!policy)
171 break;
172
173 SecCertificateRef cert = NULL;
174 if (SecIdentityCopyCertificate(identity, &cert))
175 break;
176
177 CFArrayRef certs = CFArrayCreate(NULL, (const void **)&cert,
178 1, &kCFTypeArrayCallBacks);
179 CFRelease(cert);
180 if (!certs)
181 break;
182
183 if (SecTrustCreateWithCertificates(certs, policy, &trust))
184 break;
185 CFRelease(certs);
186 CFRelease(policy);
187 if (SecTrustEvaluate(trust, &trust_result))
188 break;
189
190 int i, count = SecTrustGetCertificateCount(trust);
191 chain = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks);
192 CFArrayAppendValue(chain, identity);
193 for (i = 1; i < count; i++) {
194 if ((i+1 == count) && (trust_result == kSecTrustResultUnspecified))
195 continue; /* skip anchor if chain is complete */
196 SecCertificateRef s = SecTrustGetCertificateAtIndex(trust, i);
197 CFArrayAppendValue(chain, s);
198 }
199 } while (0);
200 if (trust)
201 CFRelease(trust);
202 if (policy)
203 CFRelease(policy);
204 return chain;
205 }
206 #endif // currently unused
207
208 // MARK: -
209 // MARK: SecureTransport support
210
211 #if 0
212 static void hexdump(const uint8_t *bytes, size_t len) {
213 size_t ix;
214 printf("socket write(%p, %lu)\n", bytes, len);
215 for (ix = 0; ix < len; ++ix) {
216 if (!(ix % 16))
217 printf("\n");
218 printf("%02X ", bytes[ix]);
219 }
220 printf("\n");
221 }
222 #else
223 #define hexdump(bytes, len)
224 #endif
225
226 static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
227 {
228 size_t len = *length;
229 uint8_t *ptr = (uint8_t *)data;
230
231 do {
232 ssize_t ret;
233 do {
234 hexdump(ptr, len);
235 ret = write((int)conn, ptr, len);
236 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
237 if (ret > 0) {
238 len -= ret;
239 ptr += ret;
240 }
241 else
242 return -36;
243 } while (len > 0);
244
245 *length = *length - len;
246 return errSecSuccess;
247 }
248
249 static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
250 {
251 size_t len = *length;
252 uint8_t *ptr = (uint8_t *)data;
253
254 do {
255 ssize_t ret;
256 do {
257 ret = read((int)conn, ptr, len);
258 } while ((ret < 0) && (errno == EINPROGRESS || errno == EAGAIN || errno == EINTR));
259 if (ret > 0) {
260 len -= ret;
261 ptr += ret;
262 } else {
263 printf("read error(%d): ret=%zd, errno=%d\n", (int)conn, ret, errno);
264 return -errno;
265 }
266 } while (len > 0);
267
268 *length = *length - len;
269 return errSecSuccess;
270 }
271
272 static unsigned char dn[] = {
273 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
274 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
275 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
276 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
277 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
278 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
279 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
280 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
281 };
282 static unsigned int dn_len = 96;
283
284 static SSLContextRef make_ssl_ref(bool server, SSLAuthenticate client_side_auth, bool dh_anonymous,
285 bool dtls, int sock, CFArrayRef certs, SSLProtocol proto)
286 {
287 SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, dtls?kSSLDatagramType:kSSLStreamType);
288 require(ctx, out);
289
290 if(dtls) {
291 size_t mtu;
292 require_noerr(SSLSetMaxDatagramRecordSize(ctx, 400), out);
293 require_noerr(SSLGetMaxDatagramRecordSize(ctx, &mtu), out);
294 }
295 require_noerr(SSLSetProtocolVersionMax(ctx, proto), out);
296
297 require_noerr(SSLSetIOFuncs(ctx,
298 (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
299 require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out);
300 static const char *peer_domain_name = "localhost";
301 require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
302 strlen(peer_domain_name)), out);
303
304 require_noerr(SSLSetMinimumDHGroupSize(ctx, 512), out);
305
306 if (!dh_anonymous) {
307 if (server)
308 require_noerr(SSLSetCertificate(ctx, certs), out);
309 if ((client_side_auth != kNeverAuthenticate) && server) {
310 SSLAuthenticate auth;
311 require_noerr(SSLSetClientSideAuthenticate(ctx, client_side_auth), out);
312 require_noerr(SSLGetClientSideAuthenticate(ctx, &auth), out);
313 require(auth==client_side_auth, out);
314 require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out);
315 }
316 #if 0 /* Setting client certificate in advance */
317 if ((client_side_auth == kAlwaysAuthenticate) && !server)
318 require_noerr(SSLSetCertificate(ctx, certs), out);
319 #endif
320 if ((client_side_auth != kNeverAuthenticate) && !server) /* enable break from SSLHandshake */
321 require_noerr(SSLSetSessionOption(ctx,
322 kSSLSessionOptionBreakOnCertRequested, true), out);
323 }
324
325 /* Set this option, even if doing anonDH or PSK - it should NOT break out in those case */
326 require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnServerAuth, true), out);
327
328 /* Tell SecureTransport to not check certs itself: it will break out of the
329 handshake to let us take care of it instead. */
330 require_noerr(SSLSetEnableCertVerify(ctx, false), out);
331
332 if (server) {
333 require_noerr(SSLSetDiffieHellmanParams(ctx,
334 dh_param_der, dh_param_der_len), out);
335 }
336 else /* if client */ {
337 }
338
339 return ctx;
340 out:
341 if (ctx)
342 CFRelease(ctx);
343 return NULL;
344 }
345
346 static bool check_peer_cert(SSLContextRef ctx, const ssl_test_handle *ssl, SecTrustRef *trust)
347 {
348 CFMutableArrayRef peer_cert_array = NULL;
349 CFMutableArrayRef orig_peer_cert_array = NULL;
350
351 /* verify peer cert chain */
352 require_noerr(SSLCopyPeerTrust(ctx, trust), out);
353 SecTrustResultType trust_result = 0;
354 /* this won't verify without setting up a trusted anchor */
355 require_noerr(SecTrustEvaluate(*trust, &trust_result), out);
356
357 CFIndex n_certs = SecTrustGetCertificateCount(*trust);
358
359 peer_cert_array = CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks);
360 orig_peer_cert_array = CFArrayCreateMutableCopy(NULL, n_certs, ssl->peer_certs);
361 while (n_certs--)
362 CFArrayInsertValueAtIndex(peer_cert_array, 0,
363 SecTrustGetCertificateAtIndex(*trust, n_certs));
364
365 SecIdentityRef ident =
366 (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0);
367 SecCertificateRef peer_cert = NULL;
368 require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out);
369 CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert);
370 CFRelease(peer_cert);
371
372 require(CFEqual(orig_peer_cert_array, peer_cert_array), out);
373 CFReleaseNull(orig_peer_cert_array);
374 CFReleaseNull(peer_cert_array);
375
376 return true;
377 out:
378 CFReleaseNull(orig_peer_cert_array);
379 CFReleaseNull(peer_cert_array);
380 return false;
381 }
382
383
384 #include <mach/mach_time.h>
385
386 #define perf_start() uint64_t _perf_time = mach_absolute_time();
387 #define perf_scale_factor() ({struct mach_timebase_info info; mach_timebase_info(&info); ((double)info.numer) / (1000000.0 * info.denom);})
388 #define perf_time() ((mach_absolute_time() - _perf_time) * perf_scale_factor())
389
390
391 static void *securetransport_ssl_thread(void *arg)
392 {
393 OSStatus ortn;
394 ssl_test_handle * ssl = (ssl_test_handle *)arg;
395 SSLContextRef ctx = ssl->st;
396 SecTrustRef trust = NULL;
397 bool got_server_auth = false, got_client_cert_req = false;
398 SSLSessionState ssl_state;
399
400 perf_start();
401
402 pthread_setname_np(ssl->is_server?"server thread":"client thread");
403
404 require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out);
405 require_action(ssl_state==kSSLIdle, out, ortn = -1);
406
407 do {
408 ortn = SSLHandshake(ctx);
409 require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
410
411 if (ortn == errSSLPeerAuthCompleted)
412 {
413 require_action(ssl_state==kSSLHandshake, out, ortn = -1);
414 require_string(!got_server_auth, out, "second server auth");
415 require_string(!ssl->dh_anonymous, out, "server auth with anon cipher");
416 // Note: Previously, the implementation always returned errSSLPeerAuthCompleted before
417 // errSSLClientCertRequested. Due to OCSP stappling implementation, this is no longer guaranteed.
418 // This behavior change should not be an issue, but it's possible that some applications will
419 // have issue with this new behavior. If we do find out that this is causing an issue, then
420 // the following require statement should be re-enabled, and the implementation changed
421 // to implement the former behavior.
422 //require_string(!got_client_cert_req, out, "got client cert req before server auth");
423 got_server_auth = true;
424 require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
425 require_string(check_peer_cert(ctx, ssl, &trust), out, "Certificate check failed");
426 } else if (ortn == errSSLClientCertRequested) {
427 require_action(ssl_state==kSSLHandshake, out, ortn = -1);
428 require_string(!got_client_cert_req, out, "second client cert req");
429 // Note: see Note above.
430 //require_string(got_server_auth, out, "didn't get server auth first");
431 got_client_cert_req = true;
432
433 /* set client cert */
434 require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server");
435 require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH");
436
437 CFArrayRef DNs = NULL;
438 require_noerr(SSLCopyDistinguishedNames (ctx, &DNs), out);
439 require(DNs, out);
440 CFRelease(DNs);
441
442 require_string(ssl->client_side_auth != kNeverAuthenticate, out, "errSSLClientCertRequested in run not testing that");
443 if(ssl->client_side_auth == kAlwaysAuthenticate) { // Only set a client cert in mode 1.
444 require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
445 }
446 } else if (ortn == errSSLWouldBlock) {
447 require_action(ssl_state==kSSLHandshake, out, ortn = -1);
448 }
449 } while (ortn == errSSLWouldBlock
450 || ortn == errSSLServerAuthCompleted
451 || ortn == errSSLClientCertRequested);
452 require_noerr_action_quiet(ortn, out,
453 fprintf(stderr, "Fell out of SSLHandshake with error: %d (%s)\n", (int)ortn, ssl->is_server?"server":"client"));
454
455 require_action(ssl_state==kSSLConnected, out, ortn = -1);
456
457 if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) {
458 require_string(got_server_auth, out, "never got server auth");
459 if (ssl->client_side_auth != kNeverAuthenticate)
460 require_string(got_client_cert_req, out, "never got client cert req");
461 }
462
463 if (!ssl->is_server && !ssl->dh_anonymous && ssl->is_session_resume) {
464 require_string(!got_server_auth, out, "got server auth during resumption??");
465 require_string(check_peer_cert(ctx, ssl, &trust), out, "Certificate check failed (resumption case)");
466 }
467
468 SSLCipherSuite cipherSuite;
469 require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
470
471 if(ssl->is_dtls) {
472 size_t sz;
473 SSLGetDatagramWriteSize(ctx, &sz);
474 }
475
476 Boolean sessionWasResumed = false;
477 uint8_t session_id_data[MAX_SESSION_ID_LENGTH];
478 size_t session_id_length = sizeof(session_id_data);
479 require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out);
480 require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1);
481
482 #define BUFSIZE (8*1024)
483 unsigned char ibuf[BUFSIZE], obuf[BUFSIZE];
484
485 for(int i=0; i<10; i++) {
486 size_t len;
487 if (ssl->is_server) {
488 memset(obuf, i, BUFSIZE);
489 require_noerr(ortn = SSLWrite(ctx, obuf, BUFSIZE, &len), out);
490 require_action(len == BUFSIZE, out, ortn = -1);
491
492 require_noerr(ortn = SSLWrite(ctx, obuf, 0, &len), out);
493 require_action(len == 0, out, ortn = -1);
494 }
495
496 len=0;
497 while(len<BUFSIZE) {
498 size_t l=len;
499 ortn = SSLRead(ctx, ibuf+len, BUFSIZE-len, &l);
500 len+=l;
501 }
502
503 require_noerr(ortn, out);
504 require_action(len == BUFSIZE, out, ortn = -1);
505
506 if (ssl->is_server) {
507 require_noerr(memcmp(ibuf, obuf, BUFSIZE), out);
508 } else {
509 require_noerr(ortn = SSLWrite(ctx, ibuf, BUFSIZE, &len), out);
510 require_action(len == BUFSIZE, out, ortn = -1);
511 }
512 }
513
514 out:
515 SSLClose(ctx);
516 CFRelease(ctx);
517 if (trust) CFRelease(trust);
518 close(ssl->comm);
519
520 ssl->time = perf_time();
521
522 pthread_exit((void *)(intptr_t)ortn);
523 return NULL;
524 }
525
526
527
528 static ssl_test_handle *
529 ssl_test_handle_create(uint32_t session_id, bool resume, bool server, SSLAuthenticate client_side_auth, bool dh_anonymous, bool dtls,
530 int comm, CFArrayRef certs, CFArrayRef peer_certs, SSLProtocol proto)
531 {
532 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
533 if (handle) {
534 handle->session_id = session_id;
535 handle->is_session_resume = resume;
536 handle->is_server = server;
537 handle->is_dtls = dtls;
538 handle->client_side_auth = client_side_auth;
539 handle->dh_anonymous = dh_anonymous;
540 handle->comm = comm;
541 handle->certs = certs;
542 handle->peer_certs = peer_certs;
543 handle->proto = proto;
544 handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, proto);
545 }
546 return handle;
547 }
548
549 static void
550 tests(void)
551 {
552 pthread_t client_thread, server_thread;
553
554 CFArrayRef server_rsa_certs = server_chain();
555 CFArrayRef server_ec_certs = server_ec_chain();
556 CFArrayRef client_certs = trusted_client_chain();
557 require(server_rsa_certs != NULL, end);
558 require(server_ec_certs != NULL, end);
559 require(client_certs != NULL, end);
560
561 int i,k,l, p;
562
563 for (p=0; p<nprotos; p++)
564 for (k=0; k<3; k++) /* client side auth mode:
565 0 (kSSLNeverAuthenticate): server doesn't request ,
566 1 (kSSLAlwaysAuthenticate): server request, client provide,
567 2 (kSSLTryAuthenticate): server request, client does not provide */
568 {
569
570 for (i=0; i<SupportedCipherSuitesCount; i++)
571 for (l = 0; l<2; l++) { /* resumption or not */
572 uint16_t cs = (uint16_t)(SupportedCipherSuites[i]);
573 KeyExchangeMethod kem = sslCipherSuiteGetKeyExchangeMethod(cs);
574 SSL_CipherAlgorithm cipher = sslCipherSuiteGetSymmetricCipherAlgorithm(cs);
575 tls_protocol_version min_version = sslCipherSuiteGetMinSupportedTLSVersion(cs);
576
577 CFArrayRef server_certs;
578
579 if(kem == SSL_ECDHE_ECDSA) {
580 server_certs = server_ec_certs;
581 } else {
582 server_certs = server_rsa_certs;
583 }
584
585
586 SKIP:{
587 bool dtls = (protos[p] == kDTLSProtocol1);
588 bool server_ok = ((kem != SSL_ECDH_ECDSA) && (kem != SSL_ECDH_RSA) && (kem != SSL_ECDH_anon));
589 bool dh_anonymous = ((kem == SSL_DH_anon) || (kem == TLS_PSK));
590 bool version_ok;
591
592 switch(protos[p]) {
593 case kDTLSProtocol1:
594 version_ok = cipher != SSL_CipherAlgorithmRC4_128 && (min_version != tls_protocol_version_TLS_1_2);
595 break;
596 case kSSLProtocol3:
597 version_ok = (min_version == tls_protocol_version_SSL_3);
598 break;
599 case kTLSProtocol1:
600 case kTLSProtocol11:
601 version_ok = (min_version != tls_protocol_version_TLS_1_2);
602 break;
603 case kTLSProtocol12:
604 version_ok = true;
605 break;
606 default:
607 version_ok = false;
608
609 }
610
611 skip("This ciphersuite is not supported by Server", 1, server_ok);
612 skip("This ciphersuite is not supported for this protocol version", 1, version_ok);
613
614 int sp[2];
615 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) {
616 exit(errno);
617 }
618 fcntl(sp[0], F_SETNOSIGPIPE, 1);
619 fcntl(sp[1], F_SETNOSIGPIPE, 1);
620
621 ssl_test_handle *server, *client;
622 size_t num_supported_ciphers = 0;
623 SSLCipherSuite *supported_ciphers = NULL;
624
625 SSLAuthenticate client_side_auth = k;
626
627 uint32_t session_id = (p<<24) | (k<<16) | (i+1);
628 server = ssl_test_handle_create(session_id, (l == 1), true /*server*/,
629 client_side_auth, dh_anonymous, dtls,
630 sp[0], server_certs, client_certs, protos[p]);
631 client = ssl_test_handle_create(session_id, (l == 1), false /*client*/,
632 client_side_auth, dh_anonymous, dtls,
633 sp[1], client_certs, server_certs, protos[p]);
634
635 require_noerr(SSLSetPeerID(server->st, &session_id, sizeof(session_id)), out);
636 require_noerr(SSLSetPeerID(client->st, &session_id, sizeof(session_id)), out);
637
638 /* set single cipher on client, default ciphers on server */
639 num_supported_ciphers = 0;
640 require_noerr(SSLSetEnabledCiphers(client->st, &(SupportedCipherSuites[i]), 1), out);
641 require_noerr(SSLGetNumberSupportedCiphers(server->st, &num_supported_ciphers), out);
642 require(supported_ciphers=malloc(num_supported_ciphers*sizeof(SSLCipherSuite)), out);
643 require_noerr(SSLGetSupportedCiphers(server->st, supported_ciphers, &num_supported_ciphers), out);
644 require_noerr(SSLSetEnabledCiphers(server->st, supported_ciphers, num_supported_ciphers), out);
645
646 require_noerr(SSLSetPSKSharedSecret(client->st, "123456789", 9), out);
647 require_noerr(SSLSetPSKSharedSecret(server->st, "123456789", 9), out);
648
649 pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
650 pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
651
652 intptr_t server_err, client_err;
653 pthread_join(client_thread, (void*)&client_err);
654 pthread_join(server_thread, (void*)&server_err);
655
656 #if 0
657 // If you want to print an approximate time for each handshake.
658 printf("%4llu - %40s CSA:%d RESUME:%d PROTO:0x%04x\n",
659 client->time,
660 ciphersuite_name(SupportedCipherSuites[i]),
661 server->client_side_auth,
662 l, protos[p]);
663 #endif
664
665 ok(!server_err && !client_err,
666 "%40s CSA:%d RESUME:%d PROTO:0x%04x",
667 ciphersuite_name(SupportedCipherSuites[i]),
668 server->client_side_auth,
669 l, protos[p]);
670 out:
671 free(client);
672 free(server);
673 free(supported_ciphers);
674 }
675 } /* all ciphers */
676 } /* all configs */
677
678
679 end:
680 CFReleaseSafe(client_certs);
681 CFReleaseSafe(server_ec_certs);
682 CFReleaseSafe(server_rsa_certs);
683 }
684
685 int ssl_42_ciphers(int argc, char *const *argv)
686 {
687
688 plan_tests(3 * 2 * nprotos * SupportedCipherSuitesCount /* client auth 0/1/2 * #resumptions * #protos * #ciphers */);
689
690 tests();
691
692 return 0;
693 }
694
695 /*
696 TODO: count errSSLWouldBlock
697 TODO: skip tests that don't matter: client_auth and anonymous dh
698 TODO: we seem to only be negotiating tls - force a round of sslv3
699 TODO: allow secure transport to also defer client side auth to client
700 TODO: make sure anonymous dh is never selected if not expicitly enabled
701 TODO: make sure DHE is not available if not explicitly enabled and no parameters
702 are set
703 TODO: resumable sessions
704 */