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