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