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