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
,
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
,
83 /* Unsafe ciphersuites */
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
,
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
,
100 TLS_ECDHE_ECDSA_WITH_NULL_SHA
,
101 TLS_ECDHE_RSA_WITH_NULL_SHA
,
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
,
113 TLS_RSA_WITH_NULL_SHA256
,
114 SSL_RSA_WITH_NULL_SHA
,
115 SSL_RSA_WITH_NULL_MD5
119 static const unsigned SupportedCipherSuitesCount
= sizeof(SupportedCipherSuites
)/sizeof(SupportedCipherSuites
[0]);
122 static int protos
[]={kTLSProtocol1
, kTLSProtocol11
, kTLSProtocol12
, kDTLSProtocol1
};
123 static int nprotos
= sizeof(protos
)/sizeof(protos
[0]);
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
140 static unsigned char *dh_param_der
= dh_param_1024_bytes
;
141 static unsigned int dh_param_der_len
= sizeof(dh_param_1024_bytes
);
146 bool is_session_resume
;
150 SSLAuthenticate client_side_auth
;
154 CFArrayRef peer_certs
;
156 uint64_t time
; // output
159 #if 0 // currently unused
160 static CFArrayRef
SecIdentityCopySSLClientAuthenticationChain(SecIdentityRef identity
)
162 CFMutableArrayRef chain
= NULL
;
163 SecPolicyRef policy
= NULL
;
164 SecTrustRef trust
= NULL
;
165 SecTrustResultType trust_result
;
168 policy
= SecPolicyCreateSSL(false, NULL
);
172 SecCertificateRef cert
= NULL
;
173 if (SecIdentityCopyCertificate(identity
, &cert
))
176 CFArrayRef certs
= CFArrayCreate(NULL
, (const void **)&cert
,
177 1, &kCFTypeArrayCallBacks
);
182 if (SecTrustCreateWithCertificates(certs
, policy
, &trust
))
186 if (SecTrustEvaluate(trust
, &trust_result
))
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
);
205 #endif // currently unused
208 // MARK: SecureTransport support
211 static void hexdump(const uint8_t *bytes
, size_t len
) {
213 printf("socket write(%p, %lu)\n", bytes
, len
);
214 for (ix
= 0; ix
< len
; ++ix
) {
217 printf("%02X ", bytes
[ix
]);
222 #define hexdump(bytes, len)
225 static OSStatus
SocketWrite(SSLConnectionRef conn
, const void *data
, size_t *length
)
227 size_t len
= *length
;
228 uint8_t *ptr
= (uint8_t *)data
;
234 ret
= write((int)conn
, ptr
, len
);
235 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
244 *length
= *length
- len
;
245 return errSecSuccess
;
248 static OSStatus
SocketRead(SSLConnectionRef conn
, void *data
, size_t *length
)
250 size_t len
= *length
;
251 uint8_t *ptr
= (uint8_t *)data
;
256 ret
= read((int)conn
, ptr
, len
);
257 } while ((ret
< 0) && (errno
== EINPROGRESS
|| errno
== EAGAIN
|| errno
== EINTR
));
262 printf("read error(%d): ret=%zd, errno=%d\n", (int)conn
, ret
, errno
);
267 *length
= *length
- len
;
268 return errSecSuccess
;
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
281 static unsigned int dn_len
= 96;
283 static SSLContextRef
make_ssl_ref(bool server
, SSLAuthenticate client_side_auth
, bool dh_anonymous
,
284 bool dtls
, int sock
, CFArrayRef certs
, SSLProtocol proto
)
286 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, server
?kSSLServerSide
:kSSLClientSide
, dtls
?kSSLDatagramType
:kSSLStreamType
);
291 require_noerr(SSLSetMaxDatagramRecordSize(ctx
, 400), out
);
292 require_noerr(SSLGetMaxDatagramRecordSize(ctx
, &mtu
), out
);
294 require_noerr(SSLSetProtocolVersionMax(ctx
, proto
), out
);
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
);
303 require_noerr(SSLSetMinimumDHGroupSize(ctx
, 512), out
);
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
);
315 #if 0 /* Setting client certificate in advance */
316 if ((client_side_auth
== kAlwaysAuthenticate
) && !server
)
317 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
319 if ((client_side_auth
!= kNeverAuthenticate
) && !server
) /* enable break from SSLHandshake */
320 require_noerr(SSLSetSessionOption(ctx
,
321 kSSLSessionOptionBreakOnCertRequested
, true), out
);
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
);
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
);
332 require_noerr(SSLSetDiffieHellmanParams(ctx
,
333 dh_param_der
, dh_param_der_len
), out
);
335 else /* if client */ {
345 static bool check_peer_cert(SSLContextRef ctx
, const ssl_test_handle
*ssl
, SecTrustRef
*trust
)
347 /* verify peer cert chain */
348 require_noerr(SSLCopyPeerTrust(ctx
, trust
), out
);
349 SecTrustResultType trust_result
= 0;
350 /* this won't verify without setting up a trusted anchor */
351 require_noerr(SecTrustEvaluate(*trust
, &trust_result
), out
);
353 CFIndex n_certs
= SecTrustGetCertificateCount(*trust
);
354 /* fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
356 CFMutableArrayRef peer_cert_array
=
357 CFArrayCreateMutable(NULL
, n_certs
, &kCFTypeArrayCallBacks
);
358 CFMutableArrayRef orig_peer_cert_array
=
359 CFArrayCreateMutableCopy(NULL
, n_certs
, ssl
->peer_certs
);
361 CFArrayInsertValueAtIndex(peer_cert_array
, 0,
362 SecTrustGetCertificateAtIndex(*trust
, n_certs
));
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
);
371 require(CFEqual(orig_peer_cert_array
, peer_cert_array
), out
);
372 CFRelease(orig_peer_cert_array
);
373 CFRelease(peer_cert_array
);
376 CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
377 char cert_name_buffer[1024];
378 require(CFStringGetFileSystemRepresentation(cert_name,
379 cert_name_buffer, sizeof(cert_name_buffer)), out);
380 fprintf(stderr, "cert name: %s\n", cert_name_buffer);
389 #include <mach/mach_time.h>
391 #define perf_start() uint64_t _perf_time = mach_absolute_time();
392 #define perf_scale_factor() ({struct mach_timebase_info info; mach_timebase_info(&info); ((double)info.numer) / (1000000.0 * info.denom);})
393 #define perf_time() ((mach_absolute_time() - _perf_time) * perf_scale_factor())
396 static void *securetransport_ssl_thread(void *arg
)
399 ssl_test_handle
* ssl
= (ssl_test_handle
*)arg
;
400 SSLContextRef ctx
= ssl
->st
;
401 SecTrustRef trust
= NULL
;
402 bool got_server_auth
= false, got_client_cert_req
= false;
403 SSLSessionState ssl_state
;
407 pthread_setname_np(ssl
->is_server
?"server thread":"client thread");
409 require_noerr(ortn
=SSLGetSessionState(ctx
,&ssl_state
), out
);
410 require_action(ssl_state
==kSSLIdle
, out
, ortn
= -1);
412 //uint64_t start = mach_absolute_time();
414 ortn
= SSLHandshake(ctx
);
415 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
417 if (ortn
== errSSLPeerAuthCompleted
)
419 require_action(ssl_state
==kSSLHandshake
, out
, ortn
= -1);
420 require_string(!got_server_auth
, out
, "second server auth");
421 require_string(!ssl
->dh_anonymous
, out
, "server auth with anon cipher");
422 // Note: Previously, the implementation always returned errSSLPeerAuthCompleted before
423 // errSSLClientCertRequested. Due to OCSP stappling implementation, this is no longer guaranteed.
424 // This behavior change should not be an issue, but it's possible that some applications will
425 // have issue with this new behavior. If we do find out that this is causing an issue, then
426 // the following require statement should be re-enabled, and the implementation changed
427 // to implement the former behavior.
428 //require_string(!got_client_cert_req, out, "got client cert req before server auth");
429 got_server_auth
= true;
430 require_string(!trust
, out
, "Got errSSLServerAuthCompleted twice?");
431 require_string(check_peer_cert(ctx
, ssl
, &trust
), out
, "Certificate check failed");
432 } else if (ortn
== errSSLClientCertRequested
) {
433 require_action(ssl_state
==kSSLHandshake
, out
, ortn
= -1);
434 require_string(!got_client_cert_req
, out
, "second client cert req");
435 // Note: see Note above.
436 //require_string(got_server_auth, out, "didn't get server auth first");
437 got_client_cert_req
= true;
439 /* set client cert */
440 require_string(!ssl
->is_server
, out
, "errSSLClientCertRequested while running server");
441 require_string(!ssl
->dh_anonymous
, out
, "errSSLClientCertRequested while running anon DH");
443 CFArrayRef DNs
= NULL
;
444 require_noerr(SSLCopyDistinguishedNames (ctx
, &DNs
), out
);
448 require_string(ssl
->client_side_auth
!= kNeverAuthenticate
, out
, "errSSLClientCertRequested in run not testing that");
449 if(ssl
->client_side_auth
== kAlwaysAuthenticate
) { // Only set a client cert in mode 1.
450 require_noerr(SSLSetCertificate(ctx
, ssl
->certs
), out
);
452 } else if (ortn
== errSSLWouldBlock
) {
453 require_action(ssl_state
==kSSLHandshake
, out
, ortn
= -1);
455 } while (ortn
== errSSLWouldBlock
456 || ortn
== errSSLServerAuthCompleted
457 || ortn
== errSSLClientCertRequested
);
458 require_noerr_action_quiet(ortn
, out
,
459 fprintf(stderr
, "Fell out of SSLHandshake with error: %d (%s)\n", (int)ortn
, ssl
->is_server
?"server":"client"));
461 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
463 if (!ssl
->is_server
&& !ssl
->dh_anonymous
&& !ssl
->is_session_resume
) {
464 require_string(got_server_auth
, out
, "never got server auth");
465 if (ssl
->client_side_auth
!= kNeverAuthenticate
)
466 require_string(got_client_cert_req
, out
, "never got client cert req");
469 if (!ssl
->is_server
&& !ssl
->dh_anonymous
&& ssl
->is_session_resume
) {
470 require_string(!got_server_auth
, out
, "got server auth during resumption??");
471 require_string(check_peer_cert(ctx
, ssl
, &trust
), out
, "Certificate check failed (resumption case)");
473 //uint64_t elapsed = mach_absolute_time() - start;
474 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
477 SSLProtocol proto = kSSLProtocolUnknown;
478 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
480 SSLCipherSuite cipherSuite
;
481 require_noerr_quiet(ortn
= SSLGetNegotiatedCipher(ctx
, &cipherSuite
), out
);
482 //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
486 SSLGetDatagramWriteSize(ctx
, &sz
);
487 //fprintf(stderr, "Max Write Size = %ld\n", sz);
490 Boolean sessionWasResumed
= false;
491 uint8_t session_id_data
[MAX_SESSION_ID_LENGTH
];
492 size_t session_id_length
= sizeof(session_id_data
);
493 require_noerr_quiet(ortn
= SSLGetResumableSessionInfo(ctx
, &sessionWasResumed
, session_id_data
, &session_id_length
), out
);
494 require_action(ssl
->dh_anonymous
|| (ssl
->is_session_resume
== sessionWasResumed
), out
, ortn
= -1);
495 // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
496 //hexdump(session_id_data, session_id_length);
498 #define BUFSIZE (8*1024)
499 unsigned char ibuf
[BUFSIZE
], obuf
[BUFSIZE
];
501 for(int i
=0; i
<10; i
++) {
503 if (ssl
->is_server
) {
504 memset(obuf
, i
, BUFSIZE
);
505 // SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf);
506 require_noerr(ortn
= SSLWrite(ctx
, obuf
, BUFSIZE
, &len
), out
);
507 require_action(len
== BUFSIZE
, out
, ortn
= -1);
509 require_noerr(ortn
= SSLWrite(ctx
, obuf
, 0, &len
), out
);
510 require_action(len
== 0, out
, ortn
= -1);
516 ortn
= SSLRead(ctx
, ibuf
+len
, BUFSIZE
-len
, &l
);
518 //printf("SSLRead [%p] %d, l=%zd len=%zd\n", ctx, (int)ortn, l, len);
521 //printf("SSLRead [%p] done\n", ctx);
523 require_noerr(ortn
, out
);
524 require_action(len
== BUFSIZE
, out
, ortn
= -1);
526 if (ssl
->is_server
) {
527 require_noerr(memcmp(ibuf
, obuf
, BUFSIZE
), out
);
529 require_noerr(ortn
= SSLWrite(ctx
, ibuf
, BUFSIZE
, &len
), out
);
530 require_action(len
== BUFSIZE
, out
, ortn
= -1);
537 if (trust
) CFRelease(trust
);
540 ssl
->time
= perf_time();
542 pthread_exit((void *)(intptr_t)ortn
);
548 static ssl_test_handle
*
549 ssl_test_handle_create(uint32_t session_id
, bool resume
, bool server
, SSLAuthenticate client_side_auth
, bool dh_anonymous
, bool dtls
,
550 int comm
, CFArrayRef certs
, CFArrayRef peer_certs
, SSLProtocol proto
)
552 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
554 handle
->session_id
= session_id
;
555 handle
->is_session_resume
= resume
;
556 handle
->is_server
= server
;
557 handle
->is_dtls
= dtls
;
558 handle
->client_side_auth
= client_side_auth
;
559 handle
->dh_anonymous
= dh_anonymous
;
561 handle
->certs
= certs
;
562 handle
->peer_certs
= peer_certs
;
563 handle
->proto
= proto
;
564 handle
->st
= make_ssl_ref(server
, client_side_auth
, dh_anonymous
, dtls
, comm
, certs
, proto
);
572 pthread_t client_thread
, server_thread
;
574 CFArrayRef server_rsa_certs
= server_chain();
575 CFArrayRef server_ec_certs
= server_ec_chain();
576 CFArrayRef client_certs
= trusted_client_chain();
577 ok(server_rsa_certs
, "got rsa server cert chain");
578 ok(server_ec_certs
, "got ec server cert chain");
579 ok(client_certs
, "got rsa client cert chain");
581 /* Enable this if you want to test a specific d/i/k/l/m/p combination */
583 int i
=0, l
=0, k
=0, p
=0; { {
587 for (p
=0; p
<nprotos
; p
++)
588 for (k
=0; k
<3; k
++) /* client side auth mode:
589 0 (kSSLNeverAuthenticate): server doesn't request ,
590 1 (kSSLAlwaysAuthenticate): server request, client provide,
591 2 (kSSLTryAuthenticate): server request, client does not provide */
594 for (i
=0; i
<SupportedCipherSuitesCount
; i
++)
595 for (l
= 0; l
<2; l
++) { /* resumption or not */
597 uint16_t cs
= (uint16_t)(SupportedCipherSuites
[i
]);
598 KeyExchangeMethod kem
= sslCipherSuiteGetKeyExchangeMethod(cs
);
599 SSL_CipherAlgorithm cipher
= sslCipherSuiteGetSymmetricCipherAlgorithm(cs
);
600 tls_protocol_version min_version
= sslCipherSuiteGetMinSupportedTLSVersion(cs
);
602 CFArrayRef server_certs
;
604 if(kem
== SSL_ECDHE_ECDSA
) {
605 server_certs
= server_ec_certs
;
607 server_certs
= server_rsa_certs
;
612 bool dtls
= (protos
[p
] == kDTLSProtocol1
);
613 bool server_ok
= ((kem
!= SSL_ECDH_ECDSA
) && (kem
!= SSL_ECDH_RSA
) && (kem
!= SSL_ECDH_anon
));
614 bool dh_anonymous
= ((kem
== SSL_DH_anon
) || (kem
== TLS_PSK
));
619 version_ok
= cipher
!= SSL_CipherAlgorithmRC4_128
&& (min_version
!= tls_protocol_version_TLS_1_2
);
622 version_ok
= (min_version
== tls_protocol_version_SSL_3
);
626 version_ok
= (min_version
!= tls_protocol_version_TLS_1_2
);
636 skip("This ciphersuite is not supported by Server", 1, server_ok
);
637 skip("This ciphersuite is not supported for this protocol version", 1, version_ok
);
640 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
641 fcntl(sp
[0], F_SETNOSIGPIPE
, 1);
642 fcntl(sp
[1], F_SETNOSIGPIPE
, 1);
644 ssl_test_handle
*server
, *client
;
645 size_t num_supported_ciphers
= 0;
646 SSLCipherSuite
*supported_ciphers
= NULL
;
648 SSLAuthenticate client_side_auth
= k
;
650 uint32_t session_id
= (p
<<24) | (k
<<16) | (i
+1);
651 //fprintf(stderr, "session_id: %d\n", session_id);
652 server
= ssl_test_handle_create(session_id
, (l
== 1), true /*server*/,
653 client_side_auth
, dh_anonymous
, dtls
,
654 sp
[0], server_certs
, client_certs
, protos
[p
]);
655 client
= ssl_test_handle_create(session_id
, (l
== 1), false /*client*/,
656 client_side_auth
, dh_anonymous
, dtls
,
657 sp
[1], client_certs
, server_certs
, protos
[p
]);
659 require_noerr(SSLSetPeerID(server
->st
, &session_id
, sizeof(session_id
)), out
);
660 require_noerr(SSLSetPeerID(client
->st
, &session_id
, sizeof(session_id
)), out
);
662 /* set single cipher on client, default ciphers on server */
663 num_supported_ciphers
= 0;
664 require_noerr(SSLSetEnabledCiphers(client
->st
, &(SupportedCipherSuites
[i
]), 1), out
);
665 require_noerr(SSLGetNumberSupportedCiphers(server
->st
, &num_supported_ciphers
), out
);
666 require(supported_ciphers
=malloc(num_supported_ciphers
*sizeof(SSLCipherSuite
)), out
);
667 require_noerr(SSLGetSupportedCiphers(server
->st
, supported_ciphers
, &num_supported_ciphers
), out
);
668 require_noerr(SSLSetEnabledCiphers(server
->st
, supported_ciphers
, num_supported_ciphers
), out
);
670 require_noerr(SSLSetPSKSharedSecret(client
->st
, "123456789", 9), out
);
671 require_noerr(SSLSetPSKSharedSecret(server
->st
, "123456789", 9), out
);
673 pthread_create(&client_thread
, NULL
, securetransport_ssl_thread
, client
);
674 pthread_create(&server_thread
, NULL
, securetransport_ssl_thread
, server
);
676 int server_err
, client_err
;
677 pthread_join(client_thread
, (void*)&client_err
);
678 pthread_join(server_thread
, (void*)&server_err
);
681 // If you want to print an approximate time for each handshake.
682 printf("%4llu - %40s CSA:%d RESUME:%d PROTO:0x%04x\n",
684 ciphersuite_name(SupportedCipherSuites
[i
]),
685 server
->client_side_auth
,
689 ok(!server_err
&& !client_err
,
690 "%40s CSA:%d RESUME:%d PROTO:0x%04x",
691 ciphersuite_name(SupportedCipherSuites
[i
]),
692 server
->client_side_auth
,
697 free(supported_ciphers
);
703 CFReleaseSafe(server_ec_certs
);
704 CFReleaseSafe(server_rsa_certs
);
705 CFReleaseSafe(client_certs
);
709 int ssl_42_ciphers(int argc
, char *const *argv
)
712 plan_tests(3 * 2 * nprotos
* SupportedCipherSuitesCount
/* client auth 0/1/2 * #resumptions * #protos * #ciphers */
721 TODO: count errSSLWouldBlock
722 TODO: skip tests that don't matter: client_auth and anonymous dh
723 TODO: we seem to only be negotiating tls - force a round of sslv3
724 TODO: allow secure transport to also defer client side auth to client
725 TODO: make sure anonymous dh is never selected if not expicitly enabled
726 TODO: make sure DHE is not available if not explicitly enabled and no parameters
728 TODO: resumable sessions