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#if TARGET_OS_IPHONE 31#include <Security/SecRSAKey.h> 32#endif 33 34#include "ssl_regressions.h" 35#include "ssl-utils.h" 36 37/* 38 SSL CipherSuite tests 39 40 Below are all the ciphers that are individually tested. The first element 41 is the SecureTransport/RFC name; the second is what openssl calls it, which 42 can be looked up in ciphers(1). 43 44 All SSL_DH_* and TLS_DH_* are disabled because neither openssl nor 45 securetranport support them: 46 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_DSS_WITH_DES_CBC_SHA, 47 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, 48 SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, 49 TLS_DH_DSS_WITH_AES_128_CBC_SHA, TLS_DH_RSA_WITH_AES_128_CBC_SHA, 50 TLS_DH_DSS_WITH_AES_256_CBC_SHA, TLS_DH_RSA_WITH_AES_256_CBC_SHA, 51 52 DSS is unimplemented by securetransport on the phone: 53 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, 54 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 55 TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 56 57 SSLv2 ciphersuites disabled by securetransport on phone: 58 SSL_RSA_WITH_RC2_CBC_MD5, SSL_RSA_WITH_IDEA_CBC_MD5, 59 SSL_RSA_WITH_DES_CBC_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5, 60 61 SSLv3 ciphersuites disabled by securetransport on phone: 62 SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 63 64 Export ciphersuites disabled on iOS 5.0: 65 SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, 66 SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, 67 SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, 68 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA 69 70*/ 71 72typedef struct _CipherSuiteName { 73 SSLCipherSuite cipher; 74 const char *name; 75 bool dh_anonymous; 76} CipherSuiteName; 77 78#define CIPHER(cipher, dh_anonymous) { cipher, #cipher, dh_anonymous }, 79 80static const CipherSuiteName ciphers[] = { 81 //SSL_NULL_WITH_NULL_NULL, unsupported 82 CIPHER(SSL_RSA_WITH_NULL_SHA, false) 83 CIPHER(SSL_RSA_WITH_NULL_MD5, false) 84 CIPHER(TLS_RSA_WITH_NULL_SHA256, false) 85 86 CIPHER(SSL_RSA_WITH_RC4_128_MD5, false) 87 CIPHER(SSL_RSA_WITH_RC4_128_SHA, false) 88 CIPHER(SSL_RSA_WITH_3DES_EDE_CBC_SHA, false) 89 90 CIPHER(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, false) 91 CIPHER(SSL_DH_anon_WITH_RC4_128_MD5, true) 92 CIPHER(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, true) 93 CIPHER(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, false) 94 CIPHER(TLS_DH_anon_WITH_AES_128_CBC_SHA, true) 95 CIPHER(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, false) 96 CIPHER(TLS_DH_anon_WITH_AES_256_CBC_SHA, true) 97 98 CIPHER(TLS_RSA_WITH_AES_128_CBC_SHA, false) 99 CIPHER(TLS_RSA_WITH_AES_256_CBC_SHA, false) 100 101 102 CIPHER(TLS_PSK_WITH_AES_128_CBC_SHA, true) 103 CIPHER(TLS_PSK_WITH_AES_256_CBC_SHA384, true) 104 CIPHER(TLS_PSK_WITH_AES_128_CBC_SHA256, true) 105 CIPHER(TLS_PSK_WITH_AES_256_CBC_SHA, true) 106 CIPHER(TLS_PSK_WITH_AES_128_CBC_SHA, true) 107 CIPHER(TLS_PSK_WITH_RC4_128_SHA, true) 108 CIPHER(TLS_PSK_WITH_3DES_EDE_CBC_SHA, true) 109 CIPHER(TLS_PSK_WITH_NULL_SHA384, true) 110 CIPHER(TLS_PSK_WITH_NULL_SHA256, true) 111 CIPHER(TLS_PSK_WITH_NULL_SHA, true) 112 113 114#if 0 115 CIPHER(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, false) 116 CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, false) 117 118 CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, false) 119 CIPHER(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, false) 120 121 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, false) 122 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, false) 123 124 CIPHER(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, true) 125 CIPHER(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, true) 126 127 CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, false) 128 CIPHER(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, false) 129 CIPHER(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, false) 130 CIPHER(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, false) 131#endif 132 133#if 0 134 CIPHER(TLS_RSA_WITH_AES_256_GCM_SHA384, false) 135 CIPHER(TLS_RSA_WITH_AES_128_GCM_SHA256, false) 136#endif 137 138/* Export ciphers are disabled */ 139#if 0 140 CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5, false) 141 CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, false) 142 CIPHER(SSL_RSA_WITH_DES_CBC_SHA, false) 143 CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, false) 144 CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA, false) 145 CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, true) 146 CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, true) 147 CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA, true) 148#endif 149 150 { -1 } 151}; 152 153static int ciphers_len = array_size(ciphers); 154 155 156static int protos[]={kTLSProtocol1, kTLSProtocol11, kTLSProtocol12 }; 157static int nprotos = sizeof(protos)/sizeof(protos[0]); 158 159 160#if 0 // currently unused 161static SSLCipherSuite sslcipher_atoi(const char *name) 162{ 163 const CipherSuiteName *a = ciphers; 164 while(a->name) { 165 if (0 == strcmp(a->name, name)) break; 166 a++; 167 } 168 return a->cipher; 169} 170 171static const char * sslcipher_itoa(SSLCipherSuite num) 172{ 173 const CipherSuiteName *a = ciphers; 174 while(a->cipher >= 0) { 175 if (num == a->cipher) break; 176 a++; 177 } 178 return a->name; 179} 180#endif // currently unused 181 182static unsigned char dh_param_512_bytes[] = { 183 0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64, 184 0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0, 185 0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd, 186 0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b, 187 0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb, 188 0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02 189}; 190static unsigned char *dh_param_512_der = dh_param_512_bytes; 191static unsigned int dh_param_512_der_len = 72; 192 193 194typedef struct { 195 uint32_t session_id; 196 bool is_session_resume; 197 SSLContextRef st; 198 bool is_server; 199 bool is_dtls; 200 bool client_side_auth; 201 bool dh_anonymous; 202 int comm; 203 CFArrayRef certs; 204 SSLProtocol proto; 205} ssl_test_handle; 206 207#if 0 // currently unused 208static CFArrayRef SecIdentityCopySSLClientAuthenticationChain(SecIdentityRef identity) 209{ 210 CFMutableArrayRef chain = NULL; 211 SecPolicyRef policy = NULL; 212 SecTrustRef trust = NULL; 213 SecTrustResultType trust_result; 214 215 do { 216 policy = SecPolicyCreateSSL(false, NULL); 217 if (!policy) 218 break; 219 220 SecCertificateRef cert = NULL; 221 if (SecIdentityCopyCertificate(identity, &cert)) 222 break; 223 224 CFArrayRef certs = CFArrayCreate(NULL, (const void **)&cert, 225 1, &kCFTypeArrayCallBacks); 226 CFRelease(cert); 227 if (!certs) 228 break; 229 230 if (SecTrustCreateWithCertificates(certs, policy, &trust)) 231 break; 232 CFRelease(certs); 233 CFRelease(policy); 234 if (SecTrustEvaluate(trust, &trust_result)) 235 break; 236 237 int i, count = SecTrustGetCertificateCount(trust); 238 chain = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks); 239 CFArrayAppendValue(chain, identity); 240 for (i = 1; i < count; i++) { 241 if ((i+1 == count) && (trust_result == kSecTrustResultUnspecified)) 242 continue; /* skip anchor if chain is complete */ 243 SecCertificateRef s = SecTrustGetCertificateAtIndex(trust, i); 244 CFArrayAppendValue(chain, s); 245 } 246 } while (0); 247 if (trust) 248 CFRelease(trust); 249 if (policy) 250 CFRelease(policy); 251 return chain; 252} 253#endif // currently unused 254 255// MARK: - 256// MARK: SecureTransport support 257 258#if 0 259static void hexdump(const uint8_t *bytes, size_t len) { 260 size_t ix; 261 printf("socket write(%p, %lu)\n", bytes, len); 262 for (ix = 0; ix < len; ++ix) { 263 if (!(ix % 16)) 264 printf("\n"); 265 printf("%02X ", bytes[ix]); 266 } 267 printf("\n"); 268} 269#else 270#define hexdump(bytes, len) 271#endif 272 273static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length) 274{ 275 size_t len = *length; 276 uint8_t *ptr = (uint8_t *)data; 277 278 do { 279 ssize_t ret; 280 do { 281 hexdump(ptr, len); 282 ret = write((int)conn, ptr, len); 283 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); 284 if (ret > 0) { 285 len -= ret; 286 ptr += ret; 287 } 288 else 289 return -36; 290 } while (len > 0); 291 292 *length = *length - len; 293 return errSecSuccess; 294} 295 296static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length) 297{ 298 size_t len = *length; 299 uint8_t *ptr = (uint8_t *)data; 300 301 do { 302 ssize_t ret; 303 do { 304 ret = read((int)conn, ptr, len); 305 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); 306 if (ret > 0) { 307 len -= ret; 308 ptr += ret; 309 } 310 else 311 return -36; 312 } while (len > 0); 313 314 *length = *length - len; 315 return errSecSuccess; 316} 317 318static unsigned char dn[] = { 319 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 320 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 321 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 322 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 323 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 324 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 325 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 326 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74 327}; 328static unsigned int dn_len = 96; 329 330static SSLContextRef make_ssl_ref(bool server, bool client_side_auth, bool dh_anonymous, 331 bool dtls, int sock, CFArrayRef certs, SSLProtocol proto) 332{ 333 SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, dtls?kSSLDatagramType:kSSLStreamType); 334 require(ctx, out); 335 336 if(dtls) { 337 size_t mtu; 338 require_noerr(SSLSetMaxDatagramRecordSize(ctx, 400), out); 339 require_noerr(SSLGetMaxDatagramRecordSize(ctx, &mtu), out); 340 } else { 341 require_noerr(SSLSetProtocolVersionMax(ctx, proto), out); 342 } 343 require_noerr(SSLSetIOFuncs(ctx, 344 (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); 345 require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out); 346 static const char *peer_domain_name = "localhost"; 347 require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name, 348 strlen(peer_domain_name)), out); 349 350 351 if (!dh_anonymous) { 352 if (server) 353 require_noerr(SSLSetCertificate(ctx, certs), out); 354 if (client_side_auth && server) { 355 SSLAuthenticate auth; 356 require_noerr(SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate), out); 357 require_noerr(SSLGetClientSideAuthenticate(ctx, &auth), out); 358 require(auth==kAlwaysAuthenticate, out); 359 require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out); 360 } 361#if 0 /* Setting client certificate in advance */ 362 if (client_side_auth && !server) 363 require_noerr(SSLSetCertificate(ctx, certs), out); 364#endif 365 if (client_side_auth && !server) /* enable break from SSLHandshake */ 366 require_noerr(SSLSetSessionOption(ctx, 367 kSSLSessionOptionBreakOnCertRequested, true), out); 368 require_noerr(SSLSetSessionOption(ctx, 369 kSSLSessionOptionBreakOnServerAuth, true), out); 370 } 371 372 /* Tell SecureTransport to not check certs itself: it will break out of the 373 handshake to let us take care of it instead. */ 374 require_noerr(SSLSetEnableCertVerify(ctx, false), out); 375 376 if (server) { 377 require_noerr(SSLSetDiffieHellmanParams(ctx, 378 dh_param_512_der, dh_param_512_der_len), out); 379 } 380 else /* if client */ { 381 } 382 383 return ctx; 384out: 385 if (ctx) 386 CFRelease(ctx); 387 return NULL; 388} 389 390static void *securetransport_ssl_thread(void *arg) 391{ 392 OSStatus ortn; 393 ssl_test_handle * ssl = (ssl_test_handle *)arg; 394 SSLContextRef ctx = ssl->st; 395 SecTrustRef trust = NULL; 396 bool got_server_auth = false, got_client_cert_req = false; 397 398 pthread_setname_np(ssl->is_server?"server thread":"client thread"); 399 400 //uint64_t start = mach_absolute_time(); 401 do { 402 ortn = SSLHandshake(ctx); 403 404 if (ortn == errSSLPeerAuthCompleted) 405 { 406 require_string(!got_server_auth, out, "second server auth"); 407 require_string(!got_client_cert_req, out, "got client cert req before server auth"); 408 got_server_auth = true; 409 require_string(!trust, out, "Got errSSLServerAuthCompleted twice?"); 410 /* verify peer cert chain */ 411 require_noerr(SSLCopyPeerTrust(ctx, &trust), out); 412 SecTrustResultType trust_result = 0; 413 /* this won't verify without setting up a trusted anchor */ 414 require_noerr(SecTrustEvaluate(trust, &trust_result), out); 415 416 CFIndex n_certs = SecTrustGetCertificateCount(trust); 417 /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */ 418 419 CFMutableArrayRef peer_cert_array = 420 CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks); 421 CFMutableArrayRef orig_peer_cert_array = 422 CFArrayCreateMutableCopy(NULL, n_certs, ssl->certs); 423 while (n_certs--) 424 CFArrayInsertValueAtIndex(peer_cert_array, 0, 425 SecTrustGetCertificateAtIndex(trust, n_certs)); 426 427 SecIdentityRef ident = 428 (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0); 429 SecCertificateRef peer_cert = NULL; 430 require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out); 431 CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert); 432 CFRelease(peer_cert); 433 434 require(CFEqual(orig_peer_cert_array, peer_cert_array), out); 435 CFRelease(orig_peer_cert_array); 436 CFRelease(peer_cert_array); 437 438 /* 439 CFStringRef cert_name = SecCertificateCopySubjectSummary(cert); 440 char cert_name_buffer[1024]; 441 require(CFStringGetFileSystemRepresentation(cert_name, 442 cert_name_buffer, sizeof(cert_name_buffer)), out); 443 fprintf(stderr, "cert name: %s\n", cert_name_buffer); 444 CFRelease(trust); 445 */ 446 } else if (ortn == errSSLClientCertRequested) { 447 require_string(!got_client_cert_req, out, "second client cert req"); 448 require_string(got_server_auth, out, "didn't get server auth first"); 449 got_client_cert_req = true; 450 451 /* set client cert */ 452 require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server"); 453 require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH"); 454 455 CFArrayRef DNs = NULL; 456 require_noerr(SSLCopyDistinguishedNames (ctx, &DNs), out); 457 require(DNs, out); 458 CFRelease(DNs); 459 460 require_string(ssl->client_side_auth, out, "errSSLClientCertRequested in run not testing that"); 461 require_noerr(SSLSetCertificate(ctx, ssl->certs), out); 462 } 463 } while (ortn == errSSLWouldBlock 464 || ortn == errSSLServerAuthCompleted 465 || ortn == errSSLClientCertRequested); 466 require_noerr_action_quiet(ortn, out, 467 fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn)); 468 469 if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) { 470 require_string(got_server_auth, out, "never got server auth"); 471 if (ssl->client_side_auth) 472 require_string(got_client_cert_req, out, "never got client cert req"); 473 } 474 //uint64_t elapsed = mach_absolute_time() - start; 475 //fprintf(stderr, "setr elapsed: %lld\n", elapsed); 476 477 /* 478 SSLProtocol proto = kSSLProtocolUnknown; 479 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */ 480 481 SSLCipherSuite cipherSuite; 482 require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out); 483 //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite)); 484 485 if(ssl->is_dtls) { 486 size_t sz; 487 SSLGetDatagramWriteSize(ctx, &sz); 488 //fprintf(stderr, "Max Write Size = %ld\n", sz); 489 } 490 491 Boolean sessionWasResumed = false; 492 uint8_t session_id_data[MAX_SESSION_ID_LENGTH]; 493 size_t session_id_length = sizeof(session_id_data); 494 require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out); 495 require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1); 496 // if (sessionWasResumed) fprintf(stderr, "st resumed session\n"); 497 //hexdump(session_id_data, session_id_length); 498 499 unsigned char ibuf[4096], obuf[4096]; 500 size_t len; 501 if (ssl->is_server) { 502 SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf); 503 require_noerr_quiet(ortn = SSLWrite(ctx, obuf, sizeof(obuf), &len), out); 504 require_action_quiet(len == sizeof(obuf), out, ortn = -1); 505 } 506 require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out); 507 require_action_quiet(len == sizeof(ibuf), out, ortn = -1); 508 509 if (ssl->is_server) { 510 require_noerr(memcmp(ibuf, obuf, sizeof(ibuf)), out); 511 } else { 512 require_noerr_quiet(ortn = SSLWrite(ctx, ibuf, sizeof(ibuf), &len), out); 513 require_action_quiet(len == sizeof(ibuf), out, ortn = -1); 514 } 515 516out: 517 SSLClose(ctx); 518 CFRelease(ctx); 519 if (trust) CFRelease(trust); 520 close(ssl->comm); 521 pthread_exit((void *)(intptr_t)ortn); 522 return NULL; 523} 524 525 526 527static ssl_test_handle * 528ssl_test_handle_create(uint32_t session_id, bool resume, bool server, bool client_side_auth, bool dh_anonymous, bool dtls, 529 int comm, CFArrayRef certs, SSLProtocol proto) 530{ 531 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle)); 532 if (handle) { 533 handle->session_id = session_id; 534 handle->is_session_resume = resume; 535 handle->is_server = server; 536 handle->is_dtls = dtls; 537 handle->client_side_auth = client_side_auth; 538 handle->dh_anonymous = dh_anonymous; 539 handle->comm = comm; 540 handle->certs = certs; 541 handle->proto = proto; 542 handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, proto); 543 } 544 return handle; 545} 546 547static void 548tests(void) 549{ 550 pthread_t client_thread, server_thread; 551 CFArrayRef server_certs = server_chain(); 552 ok(server_certs, "got server certs"); 553 554/* Enable this if you want to test a specific d/i/k/l combination */ 555#if 0 556 int d=0, i=0, l=0, k=0; { { 557#else 558 int d,i,k,l,p; 559 560 for (p=0; p<nprotos; p++) 561 for (d=0;d<2; d++) /* dtls or not dtls */ 562 for (k=0; k<2; k++) 563 { 564 for (i=0; ciphers[i].cipher != (SSLCipherSuite)(-1); i++) 565 for (l = 0; l<2; l++) { 566#endif 567 SKIP:{ 568 //skip("Session resumption tests do not work at this point", 1, l != 1); 569 570 int sp[2]; 571 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno); 572 fcntl(sp[0], F_SETNOSIGPIPE, 1); 573 fcntl(sp[1], F_SETNOSIGPIPE, 1); 574 575 ssl_test_handle *server, *client; 576 577 bool client_side_auth = (k); 578 579 uint32_t session_id = (k+1) << 16 | (i+1); 580 //fprintf(stderr, "session_id: %d\n", session_id); 581 server = ssl_test_handle_create(session_id, (l == 1), true /*server*/, 582 client_side_auth, ciphers[i].dh_anonymous, d, 583 sp[0], server_certs, protos[p]); 584 client = ssl_test_handle_create(session_id, (l == 1), false/*client*/, 585 client_side_auth, ciphers[i].dh_anonymous, d, 586 sp[1], server_certs, protos[p]); 587 588 require_noerr(SSLSetPeerID(server->st, &session_id, sizeof(session_id)), out); 589 require_noerr(SSLSetPeerID(client->st, &session_id, sizeof(session_id)), out); 590 591 /* set fixed cipher on client and server */ 592 require_noerr(SSLSetEnabledCiphers(client->st, &ciphers[i].cipher, 1), out); 593 require_noerr(SSLSetEnabledCiphers(server->st, &ciphers[i].cipher, 1), out); 594 595 require_noerr(SSLSetPSKSharedSecret(client->st, "123456789", 9), out); 596 require_noerr(SSLSetPSKSharedSecret(server->st, "123456789", 9), out); 597 598 599 pthread_create(&client_thread, NULL, securetransport_ssl_thread, client); 600 pthread_create(&server_thread, NULL, securetransport_ssl_thread, server); 601 602 int server_err, client_err; 603 pthread_join(client_thread, (void*)&client_err); 604 pthread_join(server_thread, (void*)&server_err); 605 606 607 ok(!server_err && !client_err, 608 "%40s ADH:%d CSA:%d DTLS:%d RESUME:%d PROTO:%d", 609 ciphers[i].name, 610 server->dh_anonymous, 611 server->client_side_auth, 612 d, l, p); 613out: 614 free(client); 615 free(server); 616 617 } 618 } /* all ciphers */ 619 } /* all configs */ 620 621 CFRelease(server_certs); 622} 623 624int ssl_42_ciphers(int argc, char *const *argv) 625{ 626 627 plan_tests(2 * 2 * 2 * nprotos * (ciphers_len-1)/* client auth on/off * #configs * #ciphers */ 628 + 1 /*cert*/); 629 630 631 tests(); 632 633 return 0; 634} 635 636/* 637TODO: count errSSLWouldBlock 638TODO: skip tests that don't matter: client_auth and anonymous dh 639TODO: we seem to only be negotiating tls - force a round of sslv3 640TODO: allow secure transport to also defer client side auth to client 641TODO: make sure anonymous dh is never selected if not expicitly enabled 642TODO: make sure DHE is not available if not explicitly enabled and no parameters 643 are set 644TODO: resumable sessions 645*/ 646