8 #include <CoreFoundation/CoreFoundation.h>
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>
22 #include <utilities/array_size.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
28 #include <mach/mach_time.h>
30 #include <tls_ciphersuites.h>
33 #include <Security/SecRSAKey.h>
36 #include "ssl_regressions.h"
37 #include "ssl-utils.h"
43 static const SSLCipherSuite SupportedCipherSuites
[] = {
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
,
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
,
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
,
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
,
77 // TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
78 TLS_ECDHE_RSA_WITH_RC4_128_SHA
,
79 SSL_RSA_WITH_RC4_128_SHA
,
80 SSL_RSA_WITH_RC4_128_MD5
,
82 /* Unsafe ciphersuites */
84 TLS_DH_anon_WITH_AES_256_GCM_SHA384
,
85 TLS_DH_anon_WITH_AES_128_GCM_SHA256
,
86 TLS_DH_anon_WITH_AES_128_CBC_SHA256
,
87 TLS_DH_anon_WITH_AES_256_CBC_SHA256
,
88 TLS_DH_anon_WITH_AES_128_CBC_SHA
,
89 TLS_DH_anon_WITH_AES_256_CBC_SHA
,
90 SSL_DH_anon_WITH_RC4_128_MD5
,
91 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
,
93 TLS_ECDHE_ECDSA_WITH_NULL_SHA
,
94 TLS_ECDHE_RSA_WITH_NULL_SHA
,
96 TLS_PSK_WITH_AES_256_CBC_SHA384
,
97 TLS_PSK_WITH_AES_128_CBC_SHA256
,
98 TLS_PSK_WITH_AES_256_CBC_SHA
,
99 TLS_PSK_WITH_AES_128_CBC_SHA
,
100 TLS_PSK_WITH_RC4_128_SHA
,
101 TLS_PSK_WITH_3DES_EDE_CBC_SHA
,
102 TLS_PSK_WITH_NULL_SHA384
,
103 TLS_PSK_WITH_NULL_SHA256
,
104 TLS_PSK_WITH_NULL_SHA
,
106 TLS_RSA_WITH_NULL_SHA256
,
107 SSL_RSA_WITH_NULL_SHA
,
108 SSL_RSA_WITH_NULL_MD5
112 static const unsigned SupportedCipherSuitesCount
= sizeof(SupportedCipherSuites
)/sizeof(SupportedCipherSuites
[0]);
115 static int protos
[]={kTLSProtocol1
, kTLSProtocol11
, kTLSProtocol12
, kDTLSProtocol1
};
116 static int nprotos
= sizeof(protos
)/sizeof(protos
[0]);
119 static unsigned char dh_param_1024_bytes
[] = {
120 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0xf2, 0x56, 0xb9, 0x41, 0x74,
121 0x8c, 0x54, 0x22, 0xad, 0x94, 0x2b, 0xed, 0x83, 0xb9, 0xa0, 0x2f, 0x40,
122 0xce, 0xf8, 0xec, 0x96, 0xed, 0xcd, 0x8e, 0xfc, 0xf8, 0xdd, 0x06, 0x15,
123 0xbc, 0x68, 0x0d, 0x0e, 0x2c, 0xef, 0x00, 0x71, 0x28, 0x3d, 0x27, 0x6d,
124 0x5e, 0x42, 0x8c, 0xbd, 0x0f, 0x07, 0x23, 0x9d, 0x07, 0x8e, 0x52, 0x47,
125 0xa2, 0x5d, 0xf8, 0xd9, 0x9a, 0x7b, 0xb4, 0xab, 0xd2, 0xa3, 0x39, 0xe9,
126 0x2c, 0x3b, 0x9b, 0xaa, 0xbe, 0x4e, 0x01, 0x36, 0x16, 0xc2, 0x9e, 0x7b,
127 0x38, 0x78, 0x82, 0xd0, 0xed, 0x8e, 0x1e, 0xce, 0xa6, 0x23, 0x95, 0xae,
128 0x31, 0x66, 0x58, 0x60, 0x44, 0xdf, 0x1f, 0x9c, 0x68, 0xbf, 0x8b, 0xf1,
129 0xb4, 0xa8, 0xe7, 0xb2, 0x43, 0x8b, 0xa9, 0x3d, 0xa1, 0xb7, 0x1a, 0x11,
130 0xcf, 0xf4, 0x5e, 0xf7, 0x08, 0xf6, 0x84, 0x1c, 0xd7, 0xfa, 0x40, 0x10,
131 0xdc, 0x64, 0x83, 0x02, 0x01, 0x02
133 static unsigned char *dh_param_der
= dh_param_1024_bytes
;
134 static unsigned int dh_param_der_len
= sizeof(dh_param_1024_bytes
);
139 bool is_session_resume
;
143 SSLAuthenticate client_side_auth
;
147 CFArrayRef peer_certs
;
149 uint64_t time
; // output
152 #if 0 // currently unused
153 static CFArrayRef
SecIdentityCopySSLClientAuthenticationChain(SecIdentityRef identity
)
155 CFMutableArrayRef chain
= NULL
;
156 SecPolicyRef policy
= NULL
;
157 SecTrustRef trust
= NULL
;
158 SecTrustResultType trust_result
;
161 policy
= SecPolicyCreateSSL(false, NULL
);
165 SecCertificateRef cert
= NULL
;
166 if (SecIdentityCopyCertificate(identity
, &cert
))
169 CFArrayRef certs
= CFArrayCreate(NULL
, (const void **)&cert
,
170 1, &kCFTypeArrayCallBacks
);
175 if (SecTrustCreateWithCertificates(certs
, policy
, &trust
))
179 if (SecTrustEvaluate(trust
, &trust_result
))
182 int i
, count
= SecTrustGetCertificateCount(trust
);
183 chain
= CFArrayCreateMutable(NULL
, count
, &kCFTypeArrayCallBacks
);
184 CFArrayAppendValue(chain
, identity
);
185 for (i
= 1; i
< count
; i
++) {
186 if ((i
+1 == count
) && (trust_result
== kSecTrustResultUnspecified
))
187 continue; /* skip anchor if chain is complete */
188 SecCertificateRef s
= SecTrustGetCertificateAtIndex(trust
, i
);
189 CFArrayAppendValue(chain
, s
);
198 #endif // currently unused
201 // MARK: SecureTransport support
204 static void hexdump(const uint8_t *bytes
, size_t len
) {
206 printf("socket write(%p, %lu)\n", bytes
, len
);
207 for (ix
= 0; ix
< len
; ++ix
) {
210 printf("%02X ", bytes
[ix
]);
215 #define hexdump(bytes, len)
218 static OSStatus
SocketWrite(SSLConnectionRef conn
, const void *data
, size_t *length
)
220 size_t len
= *length
;
221 uint8_t *ptr
= (uint8_t *)data
;
227 ret
= write((int)conn
, ptr
, len
);
228 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
237 *length
= *length
- len
;
238 return errSecSuccess
;
241 static OSStatus
SocketRead(SSLConnectionRef conn
, void *data
, size_t *length
)
243 size_t len
= *length
;
244 uint8_t *ptr
= (uint8_t *)data
;
249 ret
= read((int)conn
, ptr
, len
);
250 } while ((ret
< 0) && (errno
== EINPROGRESS
|| errno
== EAGAIN
|| errno
== EINTR
));
255 printf("read error(%d): ret=%zd, errno=%d\n", (int)conn
, ret
, errno
);
260 *length
= *length
- len
;
261 return errSecSuccess
;
264 static unsigned char dn
[] = {
265 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
266 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
267 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
268 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
269 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
270 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
271 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
272 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
274 static unsigned int dn_len
= 96;
276 static SSLContextRef
make_ssl_ref(bool server
, SSLAuthenticate client_side_auth
, bool dh_anonymous
,
277 bool dtls
, int sock
, CFArrayRef certs
, SSLProtocol proto
)
279 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, server
?kSSLServerSide
:kSSLClientSide
, dtls
?kSSLDatagramType
:kSSLStreamType
);
284 require_noerr(SSLSetMaxDatagramRecordSize(ctx
, 400), out
);
285 require_noerr(SSLGetMaxDatagramRecordSize(ctx
, &mtu
), out
);
287 require_noerr(SSLSetProtocolVersionMax(ctx
, proto
), out
);
289 require_noerr(SSLSetIOFuncs(ctx
,
290 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
291 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)sock
), out
);
292 static const char *peer_domain_name
= "localhost";
293 require_noerr(SSLSetPeerDomainName(ctx
, peer_domain_name
,
294 strlen(peer_domain_name
)), out
);
296 require_noerr(SSLSetMinimumDHGroupSize(ctx
, 512), out
);
300 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
301 if ((client_side_auth
!= kNeverAuthenticate
) && server
) {
302 SSLAuthenticate auth
;
303 require_noerr(SSLSetClientSideAuthenticate(ctx
, client_side_auth
), out
);
304 require_noerr(SSLGetClientSideAuthenticate(ctx
, &auth
), out
);
305 require(auth
==client_side_auth
, out
);
306 require_noerr(SSLAddDistinguishedName(ctx
, dn
, dn_len
), out
);
308 #if 0 /* Setting client certificate in advance */
309 if ((client_side_auth
== kAlwaysAuthenticate
) && !server
)
310 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
312 if ((client_side_auth
!= kNeverAuthenticate
) && !server
) /* enable break from SSLHandshake */
313 require_noerr(SSLSetSessionOption(ctx
,
314 kSSLSessionOptionBreakOnCertRequested
, true), out
);
317 /* Set this option, even if doing anonDH or PSK - it should NOT break out in those case */
318 require_noerr(SSLSetSessionOption(ctx
, kSSLSessionOptionBreakOnServerAuth
, true), out
);
320 /* Tell SecureTransport to not check certs itself: it will break out of the
321 handshake to let us take care of it instead. */
322 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
325 require_noerr(SSLSetDiffieHellmanParams(ctx
,
326 dh_param_der
, dh_param_der_len
), out
);
328 else /* if client */ {
338 static bool check_peer_cert(SSLContextRef ctx
, const ssl_test_handle
*ssl
, SecTrustRef
*trust
)
340 /* verify peer cert chain */
341 require_noerr(SSLCopyPeerTrust(ctx
, trust
), out
);
342 SecTrustResultType trust_result
= 0;
343 /* this won't verify without setting up a trusted anchor */
344 require_noerr(SecTrustEvaluate(*trust
, &trust_result
), out
);
346 CFIndex n_certs
= SecTrustGetCertificateCount(*trust
);
347 /* fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
349 CFMutableArrayRef peer_cert_array
=
350 CFArrayCreateMutable(NULL
, n_certs
, &kCFTypeArrayCallBacks
);
351 CFMutableArrayRef orig_peer_cert_array
=
352 CFArrayCreateMutableCopy(NULL
, n_certs
, ssl
->peer_certs
);
354 CFArrayInsertValueAtIndex(peer_cert_array
, 0,
355 SecTrustGetCertificateAtIndex(*trust
, n_certs
));
357 SecIdentityRef ident
=
358 (SecIdentityRef
)CFArrayGetValueAtIndex(orig_peer_cert_array
, 0);
359 SecCertificateRef peer_cert
= NULL
;
360 require_noerr(SecIdentityCopyCertificate(ident
, &peer_cert
), out
);
361 CFArraySetValueAtIndex(orig_peer_cert_array
, 0, peer_cert
);
362 CFRelease(peer_cert
);
364 require(CFEqual(orig_peer_cert_array
, peer_cert_array
), out
);
365 CFRelease(orig_peer_cert_array
);
366 CFRelease(peer_cert_array
);
369 CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
370 char cert_name_buffer[1024];
371 require(CFStringGetFileSystemRepresentation(cert_name,
372 cert_name_buffer, sizeof(cert_name_buffer)), out);
373 fprintf(stderr, "cert name: %s\n", cert_name_buffer);
382 #include <mach/mach_time.h>
384 #define perf_start() uint64_t _perf_time = mach_absolute_time();
385 #define perf_scale_factor() ({struct mach_timebase_info info; mach_timebase_info(&info); ((double)info.numer) / (1000000.0 * info.denom);})
386 #define perf_time() ((mach_absolute_time() - _perf_time) * perf_scale_factor())
389 static void *securetransport_ssl_thread(void *arg
)
392 ssl_test_handle
* ssl
= (ssl_test_handle
*)arg
;
393 SSLContextRef ctx
= ssl
->st
;
394 SecTrustRef trust
= NULL
;
395 bool got_server_auth
= false, got_client_cert_req
= false;
396 SSLSessionState ssl_state
;
400 pthread_setname_np(ssl
->is_server
?"server thread":"client thread");
402 require_noerr(ortn
=SSLGetSessionState(ctx
,&ssl_state
), out
);
403 require_action(ssl_state
==kSSLIdle
, out
, ortn
= -1);
405 //uint64_t start = mach_absolute_time();
407 ortn
= SSLHandshake(ctx
);
408 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
410 if (ortn
== errSSLPeerAuthCompleted
)
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;
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");
436 CFArrayRef DNs
= NULL
;
437 require_noerr(SSLCopyDistinguishedNames (ctx
, &DNs
), out
);
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
);
445 } else if (ortn
== errSSLWouldBlock
) {
446 require_action(ssl_state
==kSSLHandshake
, out
, ortn
= -1);
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"));
454 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
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");
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)");
466 //uint64_t elapsed = mach_absolute_time() - start;
467 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
470 SSLProtocol proto = kSSLProtocolUnknown;
471 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
473 SSLCipherSuite cipherSuite
;
474 require_noerr_quiet(ortn
= SSLGetNegotiatedCipher(ctx
, &cipherSuite
), out
);
475 //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
479 SSLGetDatagramWriteSize(ctx
, &sz
);
480 //fprintf(stderr, "Max Write Size = %ld\n", sz);
483 Boolean sessionWasResumed
= false;
484 uint8_t session_id_data
[MAX_SESSION_ID_LENGTH
];
485 size_t session_id_length
= sizeof(session_id_data
);
486 require_noerr_quiet(ortn
= SSLGetResumableSessionInfo(ctx
, &sessionWasResumed
, session_id_data
, &session_id_length
), out
);
487 require_action(ssl
->dh_anonymous
|| (ssl
->is_session_resume
== sessionWasResumed
), out
, ortn
= -1);
488 // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
489 //hexdump(session_id_data, session_id_length);
491 #define BUFSIZE (8*1024)
492 unsigned char ibuf
[BUFSIZE
], obuf
[BUFSIZE
];
494 for(int i
=0; i
<10; i
++) {
496 if (ssl
->is_server
) {
497 memset(obuf
, i
, BUFSIZE
);
498 // SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf);
499 require_noerr(ortn
= SSLWrite(ctx
, obuf
, BUFSIZE
, &len
), out
);
500 require_action(len
== BUFSIZE
, out
, ortn
= -1);
502 require_noerr(ortn
= SSLWrite(ctx
, obuf
, 0, &len
), out
);
503 require_action(len
== 0, out
, ortn
= -1);
509 ortn
= SSLRead(ctx
, ibuf
+len
, BUFSIZE
-len
, &l
);
511 //printf("SSLRead [%p] %d, l=%zd len=%zd\n", ctx, (int)ortn, l, len);
514 //printf("SSLRead [%p] done\n", ctx);
516 require_noerr(ortn
, out
);
517 require_action(len
== BUFSIZE
, out
, ortn
= -1);
519 if (ssl
->is_server
) {
520 require_noerr(memcmp(ibuf
, obuf
, BUFSIZE
), out
);
522 require_noerr(ortn
= SSLWrite(ctx
, ibuf
, BUFSIZE
, &len
), out
);
523 require_action(len
== BUFSIZE
, out
, ortn
= -1);
530 if (trust
) CFRelease(trust
);
533 ssl
->time
= perf_time();
535 pthread_exit((void *)(intptr_t)ortn
);
541 static ssl_test_handle
*
542 ssl_test_handle_create(uint32_t session_id
, bool resume
, bool server
, SSLAuthenticate client_side_auth
, bool dh_anonymous
, bool dtls
,
543 int comm
, CFArrayRef certs
, CFArrayRef peer_certs
, SSLProtocol proto
)
545 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
547 handle
->session_id
= session_id
;
548 handle
->is_session_resume
= resume
;
549 handle
->is_server
= server
;
550 handle
->is_dtls
= dtls
;
551 handle
->client_side_auth
= client_side_auth
;
552 handle
->dh_anonymous
= dh_anonymous
;
554 handle
->certs
= certs
;
555 handle
->peer_certs
= peer_certs
;
556 handle
->proto
= proto
;
557 handle
->st
= make_ssl_ref(server
, client_side_auth
, dh_anonymous
, dtls
, comm
, certs
, proto
);
565 pthread_t client_thread
, server_thread
;
567 CFArrayRef server_rsa_certs
= server_chain();
568 CFArrayRef server_ec_certs
= server_ec_chain();
569 CFArrayRef client_certs
= trusted_client_chain();
570 ok(server_rsa_certs
, "got rsa server cert chain");
571 ok(server_ec_certs
, "got ec server cert chain");
572 ok(client_certs
, "got rsa client cert chain");
574 /* Enable this if you want to test a specific d/i/k/l/m/p combination */
576 int i
=0, l
=0, k
=0, p
=0; { {
580 for (p
=0; p
<nprotos
; p
++)
581 for (k
=0; k
<3; k
++) /* client side auth mode:
582 0 (kSSLNeverAuthenticate): server doesn't request ,
583 1 (kSSLAlwaysAuthenticate): server request, client provide,
584 2 (kSSLTryAuthenticate): server request, client does not provide */
587 for (i
=0; i
<SupportedCipherSuitesCount
; i
++)
588 for (l
= 0; l
<2; l
++) { /* resumption or not */
590 uint16_t cs
= (uint16_t)(SupportedCipherSuites
[i
]);
591 KeyExchangeMethod kem
= sslCipherSuiteGetKeyExchangeMethod(cs
);
592 SSL_CipherAlgorithm cipher
= sslCipherSuiteGetSymmetricCipherAlgorithm(cs
);
593 CFArrayRef server_certs
;
595 if(kem
== SSL_ECDHE_ECDSA
) {
596 server_certs
= server_ec_certs
;
598 server_certs
= server_rsa_certs
;
603 bool dtls
= (protos
[p
] == kDTLSProtocol1
);
604 bool dtls_ok
= (cipher
!= SSL_CipherAlgorithmRC4_128
);
605 bool server_ok
= ((kem
!= SSL_ECDH_ECDSA
) && (kem
!= SSL_ECDH_RSA
) && (kem
!= SSL_ECDH_anon
));
606 bool dh_anonymous
= ((kem
== SSL_DH_anon
) || (kem
== TLS_PSK
));
609 skip("This ciphersuite is not supported by Server", 1, server_ok
);
610 skip("This ciphersuite is not supported for DTLS", 1, (dtls_ok
|| !dtls
));
613 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
614 fcntl(sp
[0], F_SETNOSIGPIPE
, 1);
615 fcntl(sp
[1], F_SETNOSIGPIPE
, 1);
617 ssl_test_handle
*server
, *client
;
618 size_t num_supported_ciphers
= 0;
619 SSLCipherSuite
*supported_ciphers
= NULL
;
621 SSLAuthenticate client_side_auth
= k
;
623 uint32_t session_id
= (p
<<24) | (k
<<16) | (i
+1);
624 //fprintf(stderr, "session_id: %d\n", session_id);
625 server
= ssl_test_handle_create(session_id
, (l
== 1), true /*server*/,
626 client_side_auth
, dh_anonymous
, dtls
,
627 sp
[0], server_certs
, client_certs
, protos
[p
]);
628 client
= ssl_test_handle_create(session_id
, (l
== 1), false /*client*/,
629 client_side_auth
, dh_anonymous
, dtls
,
630 sp
[1], client_certs
, server_certs
, protos
[p
]);
632 require_noerr(SSLSetPeerID(server
->st
, &session_id
, sizeof(session_id
)), out
);
633 require_noerr(SSLSetPeerID(client
->st
, &session_id
, sizeof(session_id
)), out
);
635 /* set single cipher on client, default ciphers on server */
636 num_supported_ciphers
= 0;
637 require_noerr(SSLSetEnabledCiphers(client
->st
, &(SupportedCipherSuites
[i
]), 1), out
);
638 require_noerr(SSLGetNumberSupportedCiphers(server
->st
, &num_supported_ciphers
), out
);
639 require(supported_ciphers
=malloc(num_supported_ciphers
*sizeof(SSLCipherSuite
)), out
);
640 require_noerr(SSLGetSupportedCiphers(server
->st
, supported_ciphers
, &num_supported_ciphers
), out
);
641 require_noerr(SSLSetEnabledCiphers(server
->st
, supported_ciphers
, num_supported_ciphers
), out
);
643 require_noerr(SSLSetPSKSharedSecret(client
->st
, "123456789", 9), out
);
644 require_noerr(SSLSetPSKSharedSecret(server
->st
, "123456789", 9), out
);
646 pthread_create(&client_thread
, NULL
, securetransport_ssl_thread
, client
);
647 pthread_create(&server_thread
, NULL
, securetransport_ssl_thread
, server
);
649 int server_err
, client_err
;
650 pthread_join(client_thread
, (void*)&client_err
);
651 pthread_join(server_thread
, (void*)&server_err
);
654 // If you want to print an approximate time for each handshake.
655 printf("%4llu - %40s CSA:%d RESUME:%d PROTO:0x%04x\n",
657 ciphersuite_name(SupportedCipherSuites
[i
]),
658 server
->client_side_auth
,
662 ok(!server_err
&& !client_err
,
663 "%40s CSA:%d RESUME:%d PROTO:0x%04x",
664 ciphersuite_name(SupportedCipherSuites
[i
]),
665 server
->client_side_auth
,
670 free(supported_ciphers
);
676 CFReleaseSafe(server_ec_certs
);
677 CFReleaseSafe(server_rsa_certs
);
678 CFReleaseSafe(client_certs
);
682 int ssl_42_ciphers(int argc
, char *const *argv
)
685 plan_tests(3 * 2 * nprotos
* SupportedCipherSuitesCount
/* client auth 0/1/2 * #resumptions * #protos * #ciphers */
694 TODO: count errSSLWouldBlock
695 TODO: skip tests that don't matter: client_auth and anonymous dh
696 TODO: we seem to only be negotiating tls - force a round of sslv3
697 TODO: allow secure transport to also defer client side auth to client
698 TODO: make sure anonymous dh is never selected if not expicitly enabled
699 TODO: make sure DHE is not available if not explicitly enabled and no parameters
701 TODO: resumable sessions