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