]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/regressions/ssl-42-ciphers.c
Security-57740.51.3.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 /* fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
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 /*
377 CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
378 char cert_name_buffer[1024];
379 require(CFStringGetFileSystemRepresentation(cert_name,
380 cert_name_buffer, sizeof(cert_name_buffer)), out);
381 fprintf(stderr, "cert name: %s\n", cert_name_buffer);
382 CFRelease(trust);
383 */
384 return true;
385 out:
386 CFReleaseNull(orig_peer_cert_array);
387 CFReleaseNull(peer_cert_array);
388 return false;
389 }
390
391
392 #include <mach/mach_time.h>
393
394 #define perf_start() uint64_t _perf_time = mach_absolute_time();
395 #define perf_scale_factor() ({struct mach_timebase_info info; mach_timebase_info(&info); ((double)info.numer) / (1000000.0 * info.denom);})
396 #define perf_time() ((mach_absolute_time() - _perf_time) * perf_scale_factor())
397
398
399 static void *securetransport_ssl_thread(void *arg)
400 {
401 OSStatus ortn;
402 ssl_test_handle * ssl = (ssl_test_handle *)arg;
403 SSLContextRef ctx = ssl->st;
404 SecTrustRef trust = NULL;
405 bool got_server_auth = false, got_client_cert_req = false;
406 SSLSessionState ssl_state;
407
408 perf_start();
409
410 pthread_setname_np(ssl->is_server?"server thread":"client thread");
411
412 require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out);
413 require_action(ssl_state==kSSLIdle, out, ortn = -1);
414
415 //uint64_t start = mach_absolute_time();
416 do {
417 ortn = SSLHandshake(ctx);
418 require_noerr(SSLGetSessionState(ctx,&ssl_state), out);
419
420 if (ortn == errSSLPeerAuthCompleted)
421 {
422 require_action(ssl_state==kSSLHandshake, out, ortn = -1);
423 require_string(!got_server_auth, out, "second server auth");
424 require_string(!ssl->dh_anonymous, out, "server auth with anon cipher");
425 // Note: Previously, the implementation always returned errSSLPeerAuthCompleted before
426 // errSSLClientCertRequested. Due to OCSP stappling implementation, this is no longer guaranteed.
427 // This behavior change should not be an issue, but it's possible that some applications will
428 // have issue with this new behavior. If we do find out that this is causing an issue, then
429 // the following require statement should be re-enabled, and the implementation changed
430 // to implement the former behavior.
431 //require_string(!got_client_cert_req, out, "got client cert req before server auth");
432 got_server_auth = true;
433 require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
434 require_string(check_peer_cert(ctx, ssl, &trust), out, "Certificate check failed");
435 } else if (ortn == errSSLClientCertRequested) {
436 require_action(ssl_state==kSSLHandshake, out, ortn = -1);
437 require_string(!got_client_cert_req, out, "second client cert req");
438 // Note: see Note above.
439 //require_string(got_server_auth, out, "didn't get server auth first");
440 got_client_cert_req = true;
441
442 /* set client cert */
443 require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server");
444 require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH");
445
446 CFArrayRef DNs = NULL;
447 require_noerr(SSLCopyDistinguishedNames (ctx, &DNs), out);
448 require(DNs, out);
449 CFRelease(DNs);
450
451 require_string(ssl->client_side_auth != kNeverAuthenticate, out, "errSSLClientCertRequested in run not testing that");
452 if(ssl->client_side_auth == kAlwaysAuthenticate) { // Only set a client cert in mode 1.
453 require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
454 }
455 } else if (ortn == errSSLWouldBlock) {
456 require_action(ssl_state==kSSLHandshake, out, ortn = -1);
457 }
458 } while (ortn == errSSLWouldBlock
459 || ortn == errSSLServerAuthCompleted
460 || ortn == errSSLClientCertRequested);
461 require_noerr_action_quiet(ortn, out,
462 fprintf(stderr, "Fell out of SSLHandshake with error: %d (%s)\n", (int)ortn, ssl->is_server?"server":"client"));
463
464 require_action(ssl_state==kSSLConnected, out, ortn = -1);
465
466 if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) {
467 require_string(got_server_auth, out, "never got server auth");
468 if (ssl->client_side_auth != kNeverAuthenticate)
469 require_string(got_client_cert_req, out, "never got client cert req");
470 }
471
472 if (!ssl->is_server && !ssl->dh_anonymous && ssl->is_session_resume) {
473 require_string(!got_server_auth, out, "got server auth during resumption??");
474 require_string(check_peer_cert(ctx, ssl, &trust), out, "Certificate check failed (resumption case)");
475 }
476 //uint64_t elapsed = mach_absolute_time() - start;
477 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
478
479 /*
480 SSLProtocol proto = kSSLProtocolUnknown;
481 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
482
483 SSLCipherSuite cipherSuite;
484 require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
485 //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
486
487 if(ssl->is_dtls) {
488 size_t sz;
489 SSLGetDatagramWriteSize(ctx, &sz);
490 //fprintf(stderr, "Max Write Size = %ld\n", sz);
491 }
492
493 Boolean sessionWasResumed = false;
494 uint8_t session_id_data[MAX_SESSION_ID_LENGTH];
495 size_t session_id_length = sizeof(session_id_data);
496 require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out);
497 require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1);
498 // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
499 //hexdump(session_id_data, session_id_length);
500
501 #define BUFSIZE (8*1024)
502 unsigned char ibuf[BUFSIZE], obuf[BUFSIZE];
503
504 for(int i=0; i<10; i++) {
505 size_t len;
506 if (ssl->is_server) {
507 memset(obuf, i, BUFSIZE);
508 // SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf);
509 require_noerr(ortn = SSLWrite(ctx, obuf, BUFSIZE, &len), out);
510 require_action(len == BUFSIZE, out, ortn = -1);
511
512 require_noerr(ortn = SSLWrite(ctx, obuf, 0, &len), out);
513 require_action(len == 0, out, ortn = -1);
514 }
515
516 len=0;
517 while(len<BUFSIZE) {
518 size_t l=len;
519 ortn = SSLRead(ctx, ibuf+len, BUFSIZE-len, &l);
520 len+=l;
521 //printf("SSLRead [%p] %d, l=%zd len=%zd\n", ctx, (int)ortn, l, len);
522 }
523
524 //printf("SSLRead [%p] done\n", ctx);
525
526 require_noerr(ortn, out);
527 require_action(len == BUFSIZE, out, ortn = -1);
528
529 if (ssl->is_server) {
530 require_noerr(memcmp(ibuf, obuf, BUFSIZE), out);
531 } else {
532 require_noerr(ortn = SSLWrite(ctx, ibuf, BUFSIZE, &len), out);
533 require_action(len == BUFSIZE, out, ortn = -1);
534 }
535 }
536
537 out:
538 SSLClose(ctx);
539 CFRelease(ctx);
540 if (trust) CFRelease(trust);
541 close(ssl->comm);
542
543 ssl->time = perf_time();
544
545 pthread_exit((void *)(intptr_t)ortn);
546 return NULL;
547 }
548
549
550
551 static ssl_test_handle *
552 ssl_test_handle_create(uint32_t session_id, bool resume, bool server, SSLAuthenticate client_side_auth, bool dh_anonymous, bool dtls,
553 int comm, CFArrayRef certs, CFArrayRef peer_certs, SSLProtocol proto)
554 {
555 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
556 if (handle) {
557 handle->session_id = session_id;
558 handle->is_session_resume = resume;
559 handle->is_server = server;
560 handle->is_dtls = dtls;
561 handle->client_side_auth = client_side_auth;
562 handle->dh_anonymous = dh_anonymous;
563 handle->comm = comm;
564 handle->certs = certs;
565 handle->peer_certs = peer_certs;
566 handle->proto = proto;
567 handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, proto);
568 }
569 return handle;
570 }
571
572 static void
573 tests(void)
574 {
575 pthread_t client_thread, server_thread;
576
577 CFArrayRef server_rsa_certs = server_chain();
578 CFArrayRef server_ec_certs = server_ec_chain();
579 CFArrayRef client_certs = trusted_client_chain();
580 ok(server_rsa_certs, "got rsa server cert chain");
581 ok(server_ec_certs, "got ec server cert chain");
582 ok(client_certs, "got rsa client cert chain");
583
584 /* Enable this if you want to test a specific d/i/k/l/m/p combination */
585 #if 0
586 int i=0, l=0, k=0, p=0; { {
587 #else
588 int i,k,l, p;
589
590 for (p=0; p<nprotos; p++)
591 for (k=0; k<3; k++) /* client side auth mode:
592 0 (kSSLNeverAuthenticate): server doesn't request ,
593 1 (kSSLAlwaysAuthenticate): server request, client provide,
594 2 (kSSLTryAuthenticate): server request, client does not provide */
595 {
596
597 for (i=0; i<SupportedCipherSuitesCount; i++)
598 for (l = 0; l<2; l++) { /* resumption or not */
599 #endif
600 uint16_t cs = (uint16_t)(SupportedCipherSuites[i]);
601 KeyExchangeMethod kem = sslCipherSuiteGetKeyExchangeMethod(cs);
602 SSL_CipherAlgorithm cipher = sslCipherSuiteGetSymmetricCipherAlgorithm(cs);
603 tls_protocol_version min_version = sslCipherSuiteGetMinSupportedTLSVersion(cs);
604
605 CFArrayRef server_certs;
606
607 if(kem == SSL_ECDHE_ECDSA) {
608 server_certs = server_ec_certs;
609 } else {
610 server_certs = server_rsa_certs;
611 }
612
613
614 SKIP:{
615 bool dtls = (protos[p] == kDTLSProtocol1);
616 bool server_ok = ((kem != SSL_ECDH_ECDSA) && (kem != SSL_ECDH_RSA) && (kem != SSL_ECDH_anon));
617 bool dh_anonymous = ((kem == SSL_DH_anon) || (kem == TLS_PSK));
618 bool version_ok;
619
620 switch(protos[p]) {
621 case kDTLSProtocol1:
622 version_ok = cipher != SSL_CipherAlgorithmRC4_128 && (min_version != tls_protocol_version_TLS_1_2);
623 break;
624 case kSSLProtocol3:
625 version_ok = (min_version == tls_protocol_version_SSL_3);
626 break;
627 case kTLSProtocol1:
628 case kTLSProtocol11:
629 version_ok = (min_version != tls_protocol_version_TLS_1_2);
630 break;
631 case kTLSProtocol12:
632 version_ok = true;
633 break;
634 default:
635 version_ok = false;
636
637 }
638
639 skip("This ciphersuite is not supported by Server", 1, server_ok);
640 skip("This ciphersuite is not supported for this protocol version", 1, version_ok);
641
642 int sp[2];
643 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
644 fcntl(sp[0], F_SETNOSIGPIPE, 1);
645 fcntl(sp[1], F_SETNOSIGPIPE, 1);
646
647 ssl_test_handle *server, *client;
648 size_t num_supported_ciphers = 0;
649 SSLCipherSuite *supported_ciphers = NULL;
650
651 SSLAuthenticate client_side_auth = k;
652
653 uint32_t session_id = (p<<24) | (k<<16) | (i+1);
654 //fprintf(stderr, "session_id: %d\n", session_id);
655 server = ssl_test_handle_create(session_id, (l == 1), true /*server*/,
656 client_side_auth, dh_anonymous, dtls,
657 sp[0], server_certs, client_certs, protos[p]);
658 client = ssl_test_handle_create(session_id, (l == 1), false /*client*/,
659 client_side_auth, dh_anonymous, dtls,
660 sp[1], client_certs, server_certs, protos[p]);
661
662 require_noerr(SSLSetPeerID(server->st, &session_id, sizeof(session_id)), out);
663 require_noerr(SSLSetPeerID(client->st, &session_id, sizeof(session_id)), out);
664
665 /* set single cipher on client, default ciphers on server */
666 num_supported_ciphers = 0;
667 require_noerr(SSLSetEnabledCiphers(client->st, &(SupportedCipherSuites[i]), 1), out);
668 require_noerr(SSLGetNumberSupportedCiphers(server->st, &num_supported_ciphers), out);
669 require(supported_ciphers=malloc(num_supported_ciphers*sizeof(SSLCipherSuite)), out);
670 require_noerr(SSLGetSupportedCiphers(server->st, supported_ciphers, &num_supported_ciphers), out);
671 require_noerr(SSLSetEnabledCiphers(server->st, supported_ciphers, num_supported_ciphers), out);
672
673 require_noerr(SSLSetPSKSharedSecret(client->st, "123456789", 9), out);
674 require_noerr(SSLSetPSKSharedSecret(server->st, "123456789", 9), out);
675
676 pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
677 pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
678
679 int server_err, client_err;
680 pthread_join(client_thread, (void*)&client_err);
681 pthread_join(server_thread, (void*)&server_err);
682
683 #if 0
684 // If you want to print an approximate time for each handshake.
685 printf("%4llu - %40s CSA:%d RESUME:%d PROTO:0x%04x\n",
686 client->time,
687 ciphersuite_name(SupportedCipherSuites[i]),
688 server->client_side_auth,
689 l, protos[p]);
690 #endif
691
692 ok(!server_err && !client_err,
693 "%40s CSA:%d RESUME:%d PROTO:0x%04x",
694 ciphersuite_name(SupportedCipherSuites[i]),
695 server->client_side_auth,
696 l, protos[p]);
697 out:
698 free(client);
699 free(server);
700 free(supported_ciphers);
701 }
702 } /* all ciphers */
703 } /* all configs */
704
705
706 CFReleaseSafe(server_ec_certs);
707 CFReleaseSafe(server_rsa_certs);
708 CFReleaseSafe(client_certs);
709
710 }
711
712 int ssl_42_ciphers(int argc, char *const *argv)
713 {
714
715 plan_tests(3 * 2 * nprotos * SupportedCipherSuitesCount /* client auth 0/1/2 * #resumptions * #protos * #ciphers */
716 + 3 /*cert*/);
717
718 tests();
719
720 return 0;
721 }
722
723 /*
724 TODO: count errSSLWouldBlock
725 TODO: skip tests that don't matter: client_auth and anonymous dh
726 TODO: we seem to only be negotiating tls - force a round of sslv3
727 TODO: allow secure transport to also defer client side auth to client
728 TODO: make sure anonymous dh is never selected if not expicitly enabled
729 TODO: make sure DHE is not available if not explicitly enabled and no parameters
730 are set
731 TODO: resumable sessions
732 */