1// 2// st_test.c 3// tlsnke 4// 5// Created by Fabrice Gautier on 1/13/12. 6// Copyright (c) 2012 Apple, Inc. All rights reserved. 7// 8 9 10#include <CoreFoundation/CoreFoundation.h> 11#include <Security/Security.h> 12#include <Security/SecureTransportPriv.h> /* SSLSetOption */ 13#include <Security/SecRandom.h> 14 15#include <AssertMacros.h> 16 17#include "ssl-utils.h" 18 19#if 0 20#include <Security/SecPolicy.h> 21#include <Security/SecTrust.h> 22#include <Security/SecIdentity.h> 23#include <Security/SecIdentityPriv.h> 24#include <Security/SecCertificatePriv.h> 25#include <Security/SecKeyPriv.h> 26#if TARGET_OS_IPHONE 27#include <Security/SecRSAKey.h> 28#endif 29#include <Security/SecItem.h> 30#include <Security/SecRandom.h> 31#endif 32 33#include <string.h> 34#include <errno.h> 35#include <stdlib.h> 36#include <stdio.h> 37#include <stdbool.h> 38#include <pthread.h> 39#include <fcntl.h> 40#include <unistd.h> 41#include <sys/types.h> 42#include <sys/socket.h> 43#include <sys/mman.h> 44#include <mach/mach_time.h> 45#include <netinet/in.h> 46#include <arpa/inet.h> 47#include <netdb.h> 48 49#include "tlssocket.h" 50 51/* 52 SSL CipherSuite tests 53 54 Below are all the ciphers that are individually tested. The first element 55 is the SecureTransport/RFC name; the second is what openssl calls it, which 56 can be looked up in ciphers(1). 57 58 All SSL_DH_* and TLS_DH_* are disabled because neither openssl nor 59 securetranport support them: 60 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_DSS_WITH_DES_CBC_SHA, 61 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, 62 SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, 63 TLS_DH_DSS_WITH_AES_128_CBC_SHA, TLS_DH_RSA_WITH_AES_128_CBC_SHA, 64 TLS_DH_DSS_WITH_AES_256_CBC_SHA, TLS_DH_RSA_WITH_AES_256_CBC_SHA, 65 66 DSS is unimplemented by securetransport on the phone: 67 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, 68 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 69 TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 70 71 SSLv2 ciphersuites disabled by securetransport on phone: 72 SSL_RSA_WITH_RC2_CBC_MD5, SSL_RSA_WITH_IDEA_CBC_MD5, 73 SSL_RSA_WITH_DES_CBC_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5, 74 75 SSLv3 ciphersuites disabled by securetransport on phone: 76 SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5 77 78 Export ciphersuites disabled on iOS 5.0: 79 SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, 80 SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, 81 SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, 82 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA 83 84 */ 85 86typedef struct _CipherSuiteName { 87 SSLCipherSuite cipher; 88 const char *name; 89 bool dh_anonymous; 90} CipherSuiteName; 91 92#define CIPHER(cipher, dh_anonymous) { cipher, #cipher, dh_anonymous }, 93 94static const CipherSuiteName ciphers[] = { 95 //SSL_NULL_WITH_NULL_NULL, unsupported 96 CIPHER(SSL_RSA_WITH_NULL_SHA, false) 97 CIPHER(SSL_RSA_WITH_NULL_MD5, false) 98 CIPHER(TLS_RSA_WITH_NULL_SHA256, false) 99 100 // CIPHER(SSL_RSA_WITH_RC4_128_MD5, false) 101 //CIPHER(SSL_RSA_WITH_RC4_128_SHA, false) 102 CIPHER(SSL_RSA_WITH_3DES_EDE_CBC_SHA, false) 103 104 CIPHER(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, false) 105 //CIPHER(SSL_DH_anon_WITH_RC4_128_MD5, true) 106 CIPHER(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, true) 107 CIPHER(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, false) 108 CIPHER(TLS_DH_anon_WITH_AES_128_CBC_SHA, true) 109 CIPHER(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, false) 110 CIPHER(TLS_DH_anon_WITH_AES_256_CBC_SHA, true) 111 112 CIPHER(TLS_RSA_WITH_AES_128_CBC_SHA, false) 113 CIPHER(TLS_RSA_WITH_AES_256_CBC_SHA, false) 114 115 116#if 0 117 CIPHER(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, false) 118 CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, false) 119 120 CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, false) 121 CIPHER(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, false) 122 123 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, false) 124 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, false) 125 126 CIPHER(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, true) 127 CIPHER(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, true) 128 129 CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, false) 130 CIPHER(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, false) 131 CIPHER(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, false) 132 CIPHER(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, false) 133#endif 134 135#if 0 136 CIPHER(TLS_RSA_WITH_AES_256_GCM_SHA384, false) 137 CIPHER(TLS_RSA_WITH_AES_128_GCM_SHA256, false) 138#endif 139 140 /* Export ciphers are disabled */ 141#if 0 142 CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5, false) 143 CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, false) 144 CIPHER(SSL_RSA_WITH_DES_CBC_SHA, false) 145 CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, false) 146 CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA, false) 147 CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, true) 148 CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, true) 149 CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA, true) 150#endif 151 152 { -1 } 153}; 154 155static int protos[]={kTLSProtocol1, kTLSProtocol11, kTLSProtocol12 }; 156 157#if 0 // currently unused 158static SSLCipherSuite sslcipher_atoi(const char *name) 159{ 160 const CipherSuiteName *a = ciphers; 161 while(a->name) { 162 if (0 == strcmp(a->name, name)) break; 163 a++; 164 } 165 return a->cipher; 166} 167 168static const char * sslcipher_itoa(SSLCipherSuite num) 169{ 170 const CipherSuiteName *a = ciphers; 171 while(a->cipher >= 0) { 172 if (num == a->cipher) break; 173 a++; 174 } 175 return a->name; 176} 177#endif // currently unused 178 179static unsigned char dh_param_512_bytes[] = { 180 0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64, 181 0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0, 182 0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd, 183 0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b, 184 0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb, 185 0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02 186}; 187static unsigned char *dh_param_512_der = dh_param_512_bytes; 188static unsigned int dh_param_512_der_len = 72; 189 190 191typedef struct { 192 uint32_t session_id; 193 bool is_session_resume; 194 SSLContextRef st; 195 bool is_server; 196 bool is_dtls; 197 bool client_side_auth; 198 bool dh_anonymous; 199 int comm; 200 CFArrayRef certs; 201 SSLProtocol proto; 202} ssl_test_handle; 203 204 205// MARK: - 206// MARK: SecureTransport support 207 208#if 0 209static void hexdump(const uint8_t *bytes, size_t len) { 210 size_t ix; 211 printf("socket write(%p, %lu)\n", bytes, len); 212 for (ix = 0; ix < len; ++ix) { 213 if (!(ix % 16)) 214 printf("\n"); 215 printf("%02X ", bytes[ix]); 216 } 217 printf("\n"); 218} 219#else 220#define hexdump(bytes, len) 221#endif 222 223 224/* 2K should be enough for everybody */ 225#define MTU 8000 226static unsigned char readBuffer[MTU]; 227static unsigned int readOff=0; 228static size_t readLeft=0; 229 230static 231OSStatus SocketRead( 232 SSLConnectionRef connection, 233 void *data, 234 size_t *dataLength) 235{ 236 int fd = (int)connection; 237 ssize_t len; 238 239 if(readLeft==0) 240 { 241 // printf("SocketRead(%d): waiting for data %ld\n", fd, *dataLength); 242 243 len = read(fd, readBuffer, MTU); 244 245 if(len>0) { 246 readOff=0; 247 readLeft=(size_t) len; 248 //printf("SocketRead(%d): %ld bytes... epoch: %02x seq=%02x%02x\n", 249 // fd, len, d[4], d[9], d[10]); 250 251 } else { 252 int theErr = errno; 253 switch(theErr) { 254 case EAGAIN: 255 printf("SocketRead(%d): WouldBlock\n", fd); 256 *dataLength=0; 257 /* nonblocking, no data */ 258 return errSSLWouldBlock; 259 default: 260 perror("SocketRead"); 261 return -36; 262 } 263 } 264 } 265 266 if(readLeft<*dataLength) { 267 *dataLength=readLeft; 268 } 269 270 271 memcpy(data, readBuffer+readOff, *dataLength); 272 readLeft-=*dataLength; 273 readOff+=*dataLength; 274 275 // printf("%s: returning %ld bytes, left %ld\n", __FUNCTION__, *dataLength, readLeft); 276 277 return errSecSuccess; 278 279} 280 281static 282OSStatus SocketWrite( 283 SSLConnectionRef connection, 284 const void *data, 285 size_t *dataLength) /* IN/OUT */ 286{ 287 int fd = (int)connection; 288 ssize_t len; 289 OSStatus err = errSecSuccess; 290 291#if 0 292 const uint8_t *d=data; 293 294 if((rand()&3)==1) { 295 296 /* drop 1/8th packets */ 297 printf("SocketWrite: Drop %ld bytes... epoch: %02x seq=%02x%02x\n", 298 *dataLength, d[4], d[9], d[10]); 299 return errSecSuccess; 300 301 } 302#endif 303 304 // printf("SocketWrite(%d): Sending %ld bytes... epoch: %02x seq=%02x%02x\n", 305 // fd, *dataLength, d[4], d[9], d[10]); 306 307 len = send(fd, data, *dataLength, 0); 308 if(len>0) { 309 *dataLength=(size_t)len; 310 return err; 311 } 312 313 int theErr = errno; 314 switch(theErr) { 315 case EAGAIN: 316 /* nonblocking, no data */ 317 printf("SocketWrite(%d): WouldBlock\n", fd); 318 err = errSSLWouldBlock; 319 break; 320 default: 321 perror("SocketWrite"); 322 err = -36; 323 break; 324 } 325 326 return err; 327 328} 329 330 331static unsigned char dn[] = { 332 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 333 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 334 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 335 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 336 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 337 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 338 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 339 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74 340}; 341static unsigned int dn_len = 96; 342 343 344static SSLContextRef make_ssl_ref(bool server, bool client_side_auth, bool dh_anonymous, 345 bool dtls, int sock, CFArrayRef certs, SSLProtocol proto, bool kernel) 346{ 347 SSLContextRef ctx; 348 349 if(kernel) { 350 require(dtls, out); 351 ctx = SSLCreateContextWithRecordFuncs(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, dtls?kSSLDatagramType:kSSLStreamType, &TLSSocket_Funcs); 352 require(ctx, out); 353 printf("Attaching filter\n"); 354 require_noerr(TLSSocket_Attach(sock), out); 355 require_noerr(SSLSetRecordContext(ctx, (intptr_t) sock), out); 356 } else { 357 ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, dtls?kSSLDatagramType:kSSLStreamType); 358 require(ctx, out); 359 require_noerr(SSLSetIOFuncs(ctx, 360 (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); 361 require_noerr(SSLSetConnection(ctx, (intptr_t)sock), out); 362 } 363 require(ctx, out); 364 365 if(dtls) { 366 size_t mtu; 367 require_noerr(SSLSetMaxDatagramRecordSize(ctx, 400), out); 368 require_noerr(SSLGetMaxDatagramRecordSize(ctx, &mtu), out); 369 } else { 370 require_noerr(SSLSetProtocolVersionMax(ctx, proto), out); 371 kernel = false; // not available for tls, only dtls currently. 372 } 373 374 static const char *peer_domain_name = "localhost"; 375 require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name, 376 strlen(peer_domain_name)), out); 377 378 if (!dh_anonymous) { 379 if (server) 380 require_noerr(SSLSetCertificate(ctx, certs), out); 381 if (client_side_auth && server) { 382 SSLAuthenticate auth; 383 require_noerr(SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate), out); 384 require_noerr(SSLGetClientSideAuthenticate(ctx, &auth), out); 385 require(auth==kAlwaysAuthenticate, out); 386 require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out); 387 } 388#if 0 /* Setting client certificate in advance */ 389 if (client_side_auth && !server) 390 require_noerr(SSLSetCertificate(ctx, certs), out); 391#endif 392 if (client_side_auth && !server) /* enable break from SSLHandshake */ 393 require_noerr(SSLSetSessionOption(ctx, 394 kSSLSessionOptionBreakOnCertRequested, true), out); 395 require_noerr(SSLSetSessionOption(ctx, 396 kSSLSessionOptionBreakOnServerAuth, true), out); 397 } 398 399 /* Tell SecureTransport to not check certs itself: it will break out of the 400 handshake to let us take care of it instead. */ 401 require_noerr(SSLSetEnableCertVerify(ctx, false), out); 402 403 if (server) { 404 require_noerr(SSLSetDiffieHellmanParams(ctx, 405 dh_param_512_der, dh_param_512_der_len), out); 406 } 407 else /* if client */ { 408 } 409 410 return ctx; 411out: 412 if (ctx) 413 CFRelease(ctx); 414 return NULL; 415} 416 417static void *securetransport_ssl_thread(void *arg) 418{ 419 OSStatus ortn; 420 ssl_test_handle * ssl = (ssl_test_handle *)arg; 421 SSLContextRef ctx = ssl->st; 422 SecTrustRef trust = NULL; 423 bool got_server_auth = false, got_client_cert_req = false; 424 425 426 if(ssl->is_server) { 427 struct sockaddr_in ca; /* client address for connect */ 428 ssize_t l; 429 int fd = ssl->comm; 430 431 printf("Server waiting for first packet...\n"); 432 /* PEEK only... */ 433 socklen_t slen=sizeof(ca); 434 char b; 435 if((l=recvfrom(fd, &b, 1, MSG_PEEK, (struct sockaddr *)&ca, &slen))==-1) 436 { 437 perror("recvfrom"); 438 return NULL; 439 } 440 441 printf("Received packet from %s:%d (%ld), connecting...\n", inet_ntoa(ca.sin_addr), ca.sin_port, l); 442 443 if(connect(fd, (struct sockaddr *)&ca, sizeof(ca))==-1) 444 { 445 perror("connect"); 446 return NULL; 447 } 448 } 449 450 //uint64_t start = mach_absolute_time(); 451 do { 452 ortn = SSLHandshake(ctx); 453 454 if (ortn == errSSLServerAuthCompleted) 455 { 456 require_string(!got_server_auth, out, "second server auth"); 457 require_string(!got_client_cert_req, out, "got client cert req before server auth"); 458 got_server_auth = true; 459 require_string(!trust, out, "Got errSSLServerAuthCompleted twice?"); 460 /* verify peer cert chain */ 461 require_noerr(SSLCopyPeerTrust(ctx, &trust), out); 462 SecTrustResultType trust_result = 0; 463 /* this won't verify without setting up a trusted anchor */ 464 require_noerr(SecTrustEvaluate(trust, &trust_result), out); 465 466 CFIndex n_certs = SecTrustGetCertificateCount(trust); 467 /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */ 468 469 CFMutableArrayRef peer_cert_array = 470 CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks); 471 CFMutableArrayRef orig_peer_cert_array = 472 CFArrayCreateMutableCopy(NULL, n_certs, ssl->certs); 473 while (n_certs--) 474 CFArrayInsertValueAtIndex(peer_cert_array, 0, 475 SecTrustGetCertificateAtIndex(trust, n_certs)); 476 477 SecIdentityRef ident = 478 (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0); 479 SecCertificateRef peer_cert = NULL; 480 require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out); 481 CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert); 482 CFRelease(peer_cert); 483 484 require(CFEqual(orig_peer_cert_array, peer_cert_array), out); 485 CFRelease(orig_peer_cert_array); 486 CFRelease(peer_cert_array); 487 488 /* 489 CFStringRef cert_name = SecCertificateCopySubjectSummary(cert); 490 char cert_name_buffer[1024]; 491 require(CFStringGetFileSystemRepresentation(cert_name, 492 cert_name_buffer, sizeof(cert_name_buffer)), out); 493 fprintf(stderr, "cert name: %s\n", cert_name_buffer); 494 CFRelease(trust); 495 */ 496 } else if (ortn == errSSLClientCertRequested) { 497 require_string(!got_client_cert_req, out, "second client cert req"); 498 require_string(got_server_auth, out, "didn't get server auth first"); 499 got_client_cert_req = true; 500 501 /* set client cert */ 502 require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server"); 503 require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH"); 504 505 CFArrayRef DNs = NULL; 506 require_noerr(SSLCopyDistinguishedNames (ctx, &DNs), out); 507 require(DNs, out); 508 CFRelease(DNs); 509 510 require_string(ssl->client_side_auth, out, "errSSLClientCertRequested in run not testing that"); 511 require_noerr(SSLSetCertificate(ctx, ssl->certs), out); 512 } 513 } while (ortn == errSSLWouldBlock 514 || ortn == errSSLServerAuthCompleted 515 || ortn == errSSLClientCertRequested); 516 require_noerr_action_quiet(ortn, out, 517 fprintf(stderr, "Fell out of SSLHandshake with error: %ld\n", (long)ortn)); 518 519 if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) { 520 require_string(got_server_auth, out, "never got server auth"); 521 if (ssl->client_side_auth) 522 require_string(got_client_cert_req, out, "never got client cert req"); 523 } 524 //uint64_t elapsed = mach_absolute_time() - start; 525 //fprintf(stderr, "setr elapsed: %lld\n", elapsed); 526 527 /* 528 SSLProtocol proto = kSSLProtocolUnknown; 529 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */ 530 531 SSLCipherSuite cipherSuite; 532 require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out); 533 //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite)); 534 535 if(ssl->is_dtls) { 536 size_t sz; 537 SSLGetDatagramWriteSize(ctx, &sz); 538 // fprintf(stderr, "Max Write Size = %ld\n", sz); 539 } 540 541 Boolean sessionWasResumed = false; 542 uint8_t session_id_data[MAX_SESSION_ID_LENGTH]; 543 size_t session_id_length = sizeof(session_id_data); 544 require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out); 545 require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1); 546 // if (sessionWasResumed) fprintf(stderr, "st resumed session\n"); 547 //hexdump(session_id_data, session_id_length); 548 549 unsigned char ibuf[300], obuf[300]; 550 size_t len; 551 if (ssl->is_server) { 552 SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf); 553 require_noerr_quiet(ortn = SSLWrite(ctx, obuf, sizeof(obuf), &len), out); 554 require_action_quiet(len == sizeof(obuf), out, ortn = -1); 555 } 556 require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out); 557 require_action_quiet(len == sizeof(ibuf), out, ortn = -1); 558 559 if (ssl->is_server) { 560 require_noerr(memcmp(ibuf, obuf, sizeof(ibuf)), out); 561 } else { 562 require_noerr_quiet(ortn = SSLWrite(ctx, ibuf, sizeof(ibuf), &len), out); 563 require_action_quiet(len == sizeof(ibuf), out, ortn = -1); 564 } 565 566out: 567 SSLClose(ctx); 568 CFRelease(ctx); 569 if (trust) CFRelease(trust); 570 close(ssl->comm); 571 pthread_exit((void *)(intptr_t)ortn); 572 return NULL; 573} 574 575 576 577static ssl_test_handle * 578ssl_test_handle_create(uint32_t session_id, bool resume, bool server, bool client_side_auth, bool dh_anonymous, bool dtls, 579 int comm, CFArrayRef certs, SSLProtocol proto, bool kernel) 580{ 581 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle)); 582 if (handle) { 583 handle->session_id = session_id; 584 handle->is_session_resume = resume; 585 handle->is_server = server; 586 handle->is_dtls = dtls; 587 handle->client_side_auth = client_side_auth; 588 handle->dh_anonymous = dh_anonymous; 589 handle->comm = comm; 590 handle->certs = certs; 591 handle->proto = proto; 592 handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, proto, kernel); 593 } 594 return handle; 595} 596 597 598 599static void createsockets(int sp[2]) 600{ 601 602 603 int sock; 604 struct sockaddr_in server_addr; 605 struct hostent *host; 606 int err; 607 608 host = gethostbyname("localhost"); 609 610 server_addr.sin_family = AF_INET; 611 server_addr.sin_port = htons(5000); 612 server_addr.sin_addr = *((struct in_addr *)host->h_addr); 613 bzero(&(server_addr.sin_zero),8); 614 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { 615 perror("server socket"); 616 exit(1); 617 } 618 619 if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) 620 == -1) { 621 perror("Unable to bind"); 622 exit(1); 623 } 624 625 printf("Server Waiting for client on port 5000\n"); 626 627 sp[0]=sock; 628 629 printf("Create client socket\n"); 630 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 631 if(sock<0) { 632 perror("client socket"); 633 exit(1); 634 } 635 636 err = connect(sock, (struct sockaddr *)&server_addr, 637 sizeof(struct sockaddr)); 638 if(err) 639 { 640 perror("connect"); 641 exit(1); 642 } 643 644 sp[1]=sock; 645 646 printf("Connected\n"); 647 648 649} 650 651int st_test(void); 652int st_test(void) 653{ 654 pthread_t client_thread, server_thread; 655 CFArrayRef server_certs = server_chain(); 656 check(server_certs); 657 658 char msg[128]; 659 660 /* Enable this if you want to test a specific d/i/k/l/p/ combination */ 661#if 0 662 int d=0, i=0, l=0, c=0, k=0; { { 663#else 664 int d,i,c,k,l,p; 665 666 p=0; 667 //for (p=0; p<nprotos; p++) 668 d=1; 669 //for (d=0;d<2; d++) /* dtls or not dtls */ 670 //for (c=0; c<2; k++) /* csa or not */ 671 for (k=1; k<2; k++) /* kernel or not */ 672 { 673 for (i=0; ciphers[i].cipher != (SSLCipherSuite)(-1); i++) { 674 l=0; 675 //for (l = 0; l<2; l++) { 676#endif 677 SKIP:{ 678 //skip("Session resumption tests do not work at this point", 1, l != 1); 679 int sp[2]; 680 681#if 0 682 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno); 683 fcntl(sp[0], F_SETNOSIGPIPE, 1); 684 fcntl(sp[1], F_SETNOSIGPIPE, 1); 685#else 686 createsockets(sp); 687#endif 688 ssl_test_handle *server, *client; 689 690 bool client_side_auth = (c); 691 bool kernel = (k); 692 uint32_t session_id = (c+1) << 16 | (i+1); 693 //fprintf(stderr, "session_id: %d\n", session_id); 694 server = ssl_test_handle_create(session_id, (l == 1), true /*server*/, 695 client_side_auth, ciphers[i].dh_anonymous, d, 696 sp[0], server_certs, protos[p], false); 697 client = ssl_test_handle_create(session_id, (l == 1), false/*client*/, 698 client_side_auth, ciphers[i].dh_anonymous, d, 699 sp[1], server_certs, protos[p], kernel); 700 701 require_noerr(SSLSetPeerID(server->st, &session_id, sizeof(session_id)), out); 702 require_noerr(SSLSetPeerID(client->st, &session_id, sizeof(session_id)), out); 703 704 /* set fixed cipher on client and server */ 705 require_noerr(SSLSetEnabledCiphers(client->st, &ciphers[i].cipher, 1), out); 706 require_noerr(SSLSetEnabledCiphers(server->st, &ciphers[i].cipher, 1), out); 707 708 709 snprintf(msg, sizeof(msg), 710 "%40s ADH:%d CSA:%d DTLS:%d RESUME:%d PROTO:%d KERNEL:%d", 711 ciphers[i].name, 712 server->dh_anonymous, 713 server->client_side_auth, 714 d, l, p, k); 715 716 printf("%s\n", msg); 717 718 pthread_create(&client_thread, NULL, securetransport_ssl_thread, client); 719 pthread_create(&server_thread, NULL, securetransport_ssl_thread, server); 720 721 int server_err, client_err; 722 pthread_join(client_thread, (void*)&client_err); 723 pthread_join(server_thread, (void*)&server_err); 724 725 726 __Check_String(!server_err && !client_err, msg); 727 728 out: 729 free(client); 730 free(server); 731 732 printf("\n\n"); 733 sleep(2); 734 } 735 } /* all ciphers */ 736 } /* all configs */ 737 738 CFRelease(server_certs); 739 740 return 0; 741} 742 743 744