/ OSX / libsecurity_ssl / lib / sslContext.c
sslContext.c
   1  /*
   2   * Copyright (c) 1999-2001,2005-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   * sslContext.c - SSLContext accessors
  26   */
  27  
  28  #include "SecureTransport.h"
  29  
  30  #include "SSLRecordInternal.h"
  31  #include "SecureTransportPriv.h"
  32  #include "ssl.h"
  33  #include "sslCipherSpecs.h"
  34  #include "sslContext.h"
  35  #include "sslCrypto.h"
  36  #include "sslDebug.h"
  37  #include "sslKeychain.h"
  38  #include "sslMemory.h"
  39  
  40  #include "tlsCallbacks.h"
  41  
  42  #include <AssertMacros.h>
  43  #include <CoreFoundation/CFData.h>
  44  #include <CoreFoundation/CFPreferences.h>
  45  #include <Security/SecCertificate.h>
  46  #include <Security/SecCertificatePriv.h>
  47  #include <Security/SecTrust.h>
  48  #include <Security/SecTrustSettingsPriv.h>
  49  #include <Security/oidsalg.h>
  50  #include "utilities/SecCFRelease.h"
  51  #include "utilities/SecCFWrappers.h"
  52  #include <pthread.h>
  53  #include <string.h>
  54  
  55  #if TARGET_OS_IPHONE
  56  #include <Security/SecCertificateInternal.h>
  57  #else
  58  #include <Security/oidsalg.h>
  59  #include <Security/oidscert.h>
  60  #include <Security/SecTrustSettingsPriv.h>
  61  #endif
  62  
  63  
  64  static void sslFreeDnList(SSLContext *ctx)
  65  {
  66      DNListElem      *dn, *nextDN;
  67  
  68      dn = ctx->acceptableDNList;
  69      while (dn)
  70      {   
  71          SSLFreeBuffer(&dn->derDN);
  72          nextDN = dn->next;
  73          sslFree(dn);
  74          dn = nextDN;
  75      }
  76      ctx->acceptableDNList = NULL;
  77  }
  78  
  79  Boolean sslIsSessionActive(const SSLContext *ctx)
  80  {
  81  	assert(ctx != NULL);
  82  
  83  
  84  	switch(ctx->state) {
  85  		case SSL_HdskStateUninit:
  86  		case SSL_HdskStateGracefulClose:
  87  		case SSL_HdskStateErrorClose:
  88          case SSL_HdskStateOutOfBandError:
  89  			return false;
  90  		default:
  91  			return true;
  92  	}
  93  
  94  }
  95  
  96  /*
  97   * Minimum and maximum supported versions
  98   */
  99  //#define MINIMUM_STREAM_VERSION  SSL_Version_2_0 /* Disabled */
 100  #define MINIMUM_STREAM_VERSION  SSL_Version_3_0
 101  #define MAXIMUM_STREAM_VERSION  TLS_Version_1_2
 102  #define MINIMUM_DATAGRAM_VERSION  DTLS_Version_1_0
 103  
 104  /* This should be changed when we start supporting DTLS_Version_1_x */
 105  #define MAXIMUM_DATAGRAM_VERSION  DTLS_Version_1_0
 106  
 107  #define SSL_ENABLE_ECDSA_SIGN_AUTH			1
 108  #define SSL_ENABLE_RSA_FIXED_ECDH_AUTH		0
 109  #define SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH	0
 110  
 111  #define DEFAULT_DTLS_TIMEOUT    1
 112  #define DEFAULT_DTLS_MTU        1400
 113  #define MIN_ALLOWED_DTLS_MTU    64      /* this ensure than there will be no integer
 114                                              underflow when calculating max write size */
 115  
 116  /* Preferences values */
 117  CFIndex kMinDhGroupSizeDefaultValue;
 118  CFIndex kMinProtocolVersionDefaultValue;
 119  CFStringRef kSSLSessionConfigDefaultValue;
 120  Boolean kSSLDisableRecordSplittingDefaultValue;
 121  
 122  static tls_cache_t g_session_cache = NULL;
 123  
 124  #if TARGET_OS_IPHONE
 125  /*
 126   * Instead of using CFPropertyListReadFromFile we use a
 127   * CFPropertyListCreateWithStream directly
 128   * here. CFPropertyListReadFromFile() uses
 129   * CFURLCopyResourcePropertyForKey() and CF pulls in CoreServices for
 130   * CFURLCopyResourcePropertyForKey() and that doesn't work in install
 131   * enviroment.
 132   */
 133  static CFPropertyListRef
 134  CopyPlistFromFile(CFURLRef url)
 135  {
 136      CFDictionaryRef d = NULL;
 137      CFReadStreamRef s = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
 138      if (s && CFReadStreamOpen(s)) {
 139          d = (CFDictionaryRef)CFPropertyListCreateWithStream(kCFAllocatorDefault, s, 0, kCFPropertyListImmutable, NULL, NULL);
 140      }
 141      CFReleaseSafe(s);
 142  
 143      return d;
 144  }
 145  #endif
 146  
 147  
 148  static
 149  CFTypeRef SSLPreferencesCopyValue(CFStringRef key, CFPropertyListRef managed_prefs)
 150  {
 151      CFTypeRef value = (CFTypeRef) CFPreferencesCopyAppValue(CFSTR("SSLSessionConfig"), kCFPreferencesCurrentApplication);
 152  
 153      if(!value && managed_prefs) {
 154          value =  CFDictionaryGetValue(managed_prefs, key);
 155          if (value)
 156              CFRetain(value);
 157      }
 158  
 159      return value;
 160  }
 161  
 162  static
 163  CFIndex SSLPreferencesGetInteger(CFStringRef key, CFPropertyListRef managed_prefs)
 164  {
 165      CFTypeRef value = SSLPreferencesCopyValue(key, managed_prefs);
 166      CFIndex int_value = 0;
 167      if (isNumber(value)) {
 168          CFNumberGetValue(value, kCFNumberCFIndexType, &int_value);
 169      }
 170      CFReleaseSafe(value);
 171      return int_value;
 172  }
 173  
 174  static
 175  Boolean SSLPreferencesGetBoolean(CFStringRef key, CFPropertyListRef managed_prefs)
 176  {
 177      CFTypeRef value = SSLPreferencesCopyValue(key, managed_prefs);
 178      Boolean bool_value = FALSE;
 179      if (isBoolean(value)) {
 180          bool_value = CFBooleanGetValue(value);
 181      }
 182  
 183      CFReleaseSafe(value);
 184      return bool_value;
 185  }
 186  
 187  static
 188  CFStringRef SSLPreferencesCopyString(CFStringRef key, CFPropertyListRef managed_prefs)
 189  {
 190      CFTypeRef value = SSLPreferencesCopyValue(key, managed_prefs);
 191      if (isString(value)) {
 192          return value;
 193      } else {
 194          CFReleaseSafe(value);
 195          return NULL;
 196      }
 197  }
 198  
 199  static void _SSLContextReadDefault()
 200  {
 201      CFPropertyListRef managed_prefs = NULL;
 202  
 203  #if TARGET_OS_IPHONE
 204      /* on iOS, we also look for preferences from mobile's Managed Preferences */
 205      /* Note that if the process is running as mobile, the above call will already have read the Managed Preference plist.
 206       As a result, if you have some preferences set manually with defaults, which preference applies may be different for mobile vs not-mobile. */
 207      CFURLRef prefURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/Library/Managed Preferences/mobile/.GlobalPreferences.plist"), kCFURLPOSIXPathStyle, false);
 208      if(prefURL) {
 209          managed_prefs = CopyPlistFromFile(prefURL);
 210      }
 211      CFReleaseSafe(prefURL);
 212  #endif
 213  
 214      /* Disable record splitting */
 215      /* Enabled by default, this may cause some interop issues, see <rdar://problem/12307662> and <rdar://problem/12323307> */
 216      kSSLDisableRecordSplittingDefaultValue = SSLPreferencesGetBoolean(CFSTR("SSLDisableRecordSplitting"), managed_prefs);
 217  
 218      /* Min DH Group Size */
 219      kMinDhGroupSizeDefaultValue = SSLPreferencesGetInteger(CFSTR("SSLMinDhGroupSize"), managed_prefs);
 220  
 221      /* Default Min Prototcol Version */
 222      kMinProtocolVersionDefaultValue = SSLPreferencesGetInteger(CFSTR("SSLMinProtocolVersion"), managed_prefs);
 223  
 224      /* Default Config */
 225      kSSLSessionConfigDefaultValue = SSLPreferencesCopyString(CFSTR("SSLSessionConfig"), managed_prefs);
 226  
 227      CFReleaseSafe(managed_prefs);
 228  }
 229  
 230  /* This functions initialize global variables, run once per process */
 231  static void SSLContextOnce(void)
 232  {
 233      _SSLContextReadDefault();
 234      g_session_cache = tls_cache_create();
 235  }
 236  
 237  CFGiblisWithHashFor(SSLContext)
 238  
 239  OSStatus
 240  SSLNewContext				(Boolean 			isServer,
 241  							 SSLContextRef 		*contextPtr)	/* RETURNED */
 242  {
 243  	if(contextPtr == NULL) {
 244  		return errSecParam;
 245  	}
 246  
 247  	*contextPtr = SSLCreateContext(kCFAllocatorDefault, isServer?kSSLServerSide:kSSLClientSide, kSSLStreamType);
 248  
 249  	if (*contextPtr == NULL)
 250  		return errSecAllocate;
 251  
 252  	return errSecSuccess;
 253  }
 254  
 255  SSLContextRef SSLCreateContext(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType)
 256  {
 257      SSLContextRef ctx;
 258      SSLRecordContextRef recCtx;
 259      
 260      ctx = SSLCreateContextWithRecordFuncs(alloc, protocolSide, connectionType, &SSLRecordLayerInternal);
 261  
 262      if(ctx==NULL)
 263          return NULL;
 264  
 265      recCtx = SSLCreateInternalRecordLayer(ctx);
 266      if(recCtx==NULL) {
 267      	CFRelease(ctx);
 268  		return NULL;
 269      }
 270  
 271      SSLSetRecordContext(ctx, recCtx);
 272  
 273      return ctx;
 274  }
 275  
 276  SSLContextRef SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType, const struct SSLRecordFuncs *recFuncs)
 277  {
 278  	SSLContext  *ctx = (SSLContext*) _CFRuntimeCreateInstance(alloc, SSLContextGetTypeID(), sizeof(SSLContext) - sizeof(CFRuntimeBase), NULL);
 279  
 280  	if(ctx == NULL) {
 281  		return NULL;
 282  	}
 283  
 284  	/* subsequent errors to errOut: */
 285      memset(((uint8_t*) ctx) + sizeof(CFRuntimeBase), 0, sizeof(SSLContext) - sizeof(CFRuntimeBase));
 286  
 287  
 288      ctx->hdsk = tls_handshake_create(connectionType==kSSLDatagramType, protocolSide==kSSLServerSide);
 289      if(ctx->hdsk == NULL) {
 290          CFRelease(ctx);
 291          return NULL;
 292      }
 293  
 294      static dispatch_once_t onceToken;
 295      dispatch_once(&onceToken, ^{
 296          SSLContextOnce();
 297      });
 298  
 299      ctx->cache = g_session_cache;
 300  
 301      tls_handshake_set_callbacks(ctx->hdsk,
 302                                  &tls_handshake_callbacks,
 303                                  ctx);
 304  
 305      ctx->isDTLS = (connectionType==kSSLDatagramType);
 306  
 307      ctx->state = SSL_HdskStateUninit;
 308      ctx->timeout_duration = DEFAULT_DTLS_TIMEOUT;
 309      ctx->mtu = DEFAULT_DTLS_MTU;
 310  
 311      tls_handshake_get_min_protocol_version(ctx->hdsk, &ctx->minProtocolVersion);
 312      tls_handshake_get_max_protocol_version(ctx->hdsk, &ctx->maxProtocolVersion);
 313  
 314      if(protocolSide == kSSLClientSide) {
 315          tls_handshake_set_sct_enable(ctx->hdsk, true);
 316          tls_handshake_set_ocsp_enable(ctx->hdsk, true);
 317      }
 318      
 319  	ctx->negProtocolVersion = SSL_Version_Undetermined;
 320      ctx->protocolSide = protocolSide;
 321      ctx->recFuncs = recFuncs;
 322  
 323  	/* Initial cert verify state: verify with default system roots */
 324  	ctx->enableCertVerify = true;
 325  
 326  	/* Default for RSA blinding is ENABLED */
 327  	ctx->rsaBlindingEnable = true;
 328  
 329  	/* Default for sending one-byte app data record is ENABLED */
 330      ctx->oneByteRecordEnable = !kSSLDisableRecordSplittingDefaultValue;
 331  
 332      /* Dont enable fallback behavior by default */
 333      ctx->fallbackEnabled = false;
 334  
 335      if(kSSLSessionConfigDefaultValue) {
 336          SSLSetSessionConfig(ctx, kSSLSessionConfigDefaultValue);
 337      }
 338  
 339      if(kMinDhGroupSizeDefaultValue) {
 340          tls_handshake_set_min_dh_group_size(ctx->hdsk, (unsigned)kMinDhGroupSizeDefaultValue);
 341      }
 342  
 343      if(kMinProtocolVersionDefaultValue) {
 344          SSLSetProtocolVersionMin(ctx, (unsigned)kMinProtocolVersionDefaultValue);
 345      }
 346  
 347  	/* default for anonymous ciphers is DISABLED */
 348  	ctx->anonCipherEnable = false;
 349  
 350      ctx->breakOnServerAuth = false;
 351      ctx->breakOnCertRequest = false;
 352      ctx->breakOnClientAuth = false;
 353      ctx->signalServerAuth = false;
 354      ctx->signalCertRequest = false;
 355      ctx->signalClientAuth = false;
 356  
 357  	return ctx;
 358  }
 359  
 360  OSStatus
 361  SSLNewDatagramContext       (Boolean 			isServer,
 362  							 SSLContextRef 		*contextPtr)	/* RETURNED */
 363  {
 364  	if (contextPtr == NULL)
 365  		return errSecParam;
 366  	*contextPtr = SSLCreateContext(kCFAllocatorDefault, isServer?kSSLServerSide:kSSLClientSide, kSSLDatagramType);
 367  	if (*contextPtr == NULL)
 368  		return errSecAllocate;
 369      return errSecSuccess;
 370  }
 371  
 372  /*
 373   * Dispose of an SSLContext. (private)
 374   * This function is invoked after our dispatch queue is safely released,
 375   * or directly from SSLDisposeContext if there is no dispatch queue.
 376   */
 377  OSStatus
 378  SSLDisposeContext				(SSLContextRef context)
 379  {
 380      if(context == NULL) {
 381          return errSecParam;
 382      }
 383  	CFRelease(context);
 384  	return errSecSuccess;
 385  }
 386  
 387  CFStringRef SSLContextCopyFormatDescription(CFTypeRef arg, CFDictionaryRef formatOptions)
 388  {
 389      SSLContext* ctx = (SSLContext*) arg;
 390  
 391      if (ctx == NULL) {
 392          return NULL;
 393      } else {
 394  		CFStringRef result = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("<SSLContext(%p) { ... }>"), ctx);
 395  		return result;
 396      }
 397  }
 398  
 399  Boolean SSLContextCompare(CFTypeRef a, CFTypeRef b)
 400  {
 401  	return a == b;
 402  }
 403  
 404  CFHashCode SSLContextHash(CFTypeRef arg)
 405  {
 406  	return (CFHashCode) arg;
 407  }
 408  
 409  void SSLContextDestroy(CFTypeRef arg)
 410  {
 411  	SSLContext* ctx = (SSLContext*) arg;
 412  
 413      /* destroy the coreTLS handshake object */
 414      tls_handshake_destroy(ctx->hdsk);
 415  
 416      /* Only destroy if we were using the internal record layer */
 417      if(ctx->recFuncs==&SSLRecordLayerInternal)
 418          SSLDestroyInternalRecordLayer(ctx->recCtx);
 419  
 420      SSLFreeBuffer(&ctx->sessionTicket);
 421      SSLFreeBuffer(&ctx->sessionID);
 422      SSLFreeBuffer(&ctx->peerID);
 423      SSLFreeBuffer(&ctx->resumableSession);
 424      SSLFreeBuffer(&ctx->receivedDataBuffer);
 425      SSLFreeBuffer(&ctx->contextConfigurationBuffer);
 426  
 427      CFReleaseSafe(ctx->acceptableCAs);
 428  #if !TARGET_OS_IPHONE
 429      CFReleaseSafe(ctx->trustedLeafCerts);
 430  #endif
 431      CFReleaseSafe(ctx->localCertArray);
 432      CFReleaseSafe(ctx->encryptCertArray);
 433      CFReleaseSafe(ctx->trustedCerts);
 434      CFReleaseSafe(ctx->peerSecTrust);
 435  
 436      sslFreeDnList(ctx);
 437  
 438      SSLFreeBuffer(&ctx->ownVerifyData);
 439      SSLFreeBuffer(&ctx->peerVerifyData);
 440  
 441      SSLFreeBuffer(&ctx->pskIdentity);
 442      SSLFreeBuffer(&ctx->pskSharedSecret);
 443  
 444      SSLFreeBuffer(&ctx->dhParamsEncoded);
 445  
 446      if(ctx->cache)
 447          tls_cache_cleanup(ctx->cache);
 448  
 449      memset(((uint8_t*) ctx) + sizeof(CFRuntimeBase), 0, sizeof(SSLContext) - sizeof(CFRuntimeBase));
 450  }
 451  
 452  /*
 453   * Determine the state of an SSL session.
 454   */
 455  OSStatus
 456  SSLGetSessionState			(SSLContextRef		context,
 457  							 SSLSessionState	*state)		/* RETURNED */
 458  {
 459  	SSLSessionState rtnState = kSSLIdle;
 460  
 461  	if(context == NULL) {
 462  		return errSecParam;
 463  	}
 464  	*state = rtnState;
 465  	switch(context->state) {
 466  		case SSL_HdskStateUninit:
 467  			rtnState = kSSLIdle;
 468  			break;
 469  		case SSL_HdskStateGracefulClose:
 470  			rtnState = kSSLClosed;
 471  			break;
 472  		case SSL_HdskStateErrorClose:
 473  		case SSL_HdskStateNoNotifyClose:
 474          case SSL_HdskStateOutOfBandError:
 475  			rtnState = kSSLAborted;
 476  			break;
 477  		case SSL_HdskStateReady:
 478  			rtnState = kSSLConnected;
 479  			break;
 480          case SSL_HdskStatePending:
 481  			rtnState = kSSLHandshake;
 482  			break;
 483  	}
 484  	*state = rtnState;
 485  	return errSecSuccess;
 486  }
 487  
 488  /*
 489   * Set options for an SSL session.
 490   */
 491  OSStatus
 492  SSLSetSessionOption			(SSLContextRef		context,
 493  							 SSLSessionOption	option,
 494  							 Boolean			value)
 495  {
 496      if (context == NULL) {
 497          return errSecParam;
 498      }
 499  
 500      if (sslIsSessionActive(context)) {
 501          /* can't do this with an active session */
 502          return errSecBadReq;
 503      }
 504  
 505      switch(option) {
 506          case kSSLSessionOptionBreakOnServerAuth:
 507              context->breakOnServerAuth = value;
 508              context->enableCertVerify = !value;
 509              break;
 510          case kSSLSessionOptionBreakOnCertRequested:
 511              context->breakOnCertRequest = value;
 512              break;
 513          case kSSLSessionOptionBreakOnClientAuth:
 514              context->breakOnClientAuth = value;
 515              context->enableCertVerify = !value;
 516              break;
 517          case kSSLSessionOptionSendOneByteRecord:
 518              /* Only call the record layer function if the value changed */
 519              if (value != context->oneByteRecordEnable) {
 520                  context->recFuncs->setOption(context->recCtx, kSSLRecordOptionSendOneByteRecord, value);
 521              }
 522              context->oneByteRecordEnable = value;
 523              break;
 524          case kSSLSessionOptionFalseStart:
 525              tls_handshake_set_false_start(context->hdsk, value);
 526              context->falseStartEnabled = value;
 527              break;
 528          case kSSLSessionOptionFallback:
 529              tls_handshake_set_fallback(context->hdsk, value);
 530              context->fallbackEnabled = value;
 531              break;
 532          case kSSLSessionOptionBreakOnClientHello:
 533              context->breakOnClientHello = value;
 534              break;
 535          case kSSLSessionOptionAllowServerIdentityChange:
 536              tls_handshake_set_server_identity_change(context->hdsk, value);
 537              context->allowServerIdentityChange = true;
 538              break;
 539          case kSSLSessionOptionAllowRenegotiation:
 540              tls_handshake_set_renegotiation(context->hdsk, value);
 541              context->allowRenegotiation = true;
 542              break;
 543          case kSSLSessionOptionEnableSessionTickets:
 544              tls_handshake_set_session_ticket_enabled(context->hdsk, value);
 545              context->enableSessionTickets = true;
 546              break;
 547          default:
 548              return errSecParam;
 549      }
 550  
 551      return errSecSuccess;
 552  }
 553  
 554  /*
 555   * Determine current value for the specified option in an SSL session.
 556   */
 557  OSStatus
 558  SSLGetSessionOption			(SSLContextRef		context,
 559  							 SSLSessionOption	option,
 560  							 Boolean			*value)
 561  {
 562      if(context == NULL || value == NULL) {
 563          return errSecParam;
 564      }
 565      switch(option) {
 566          case kSSLSessionOptionBreakOnServerAuth:
 567              *value = context->breakOnServerAuth;
 568              break;
 569          case kSSLSessionOptionBreakOnCertRequested:
 570              *value = context->breakOnCertRequest;
 571              break;
 572          case kSSLSessionOptionBreakOnClientAuth:
 573              *value = context->breakOnClientAuth;
 574              break;
 575          case kSSLSessionOptionSendOneByteRecord:
 576              *value = context->oneByteRecordEnable;
 577              break;
 578          case kSSLSessionOptionFalseStart:
 579              *value = context->falseStartEnabled;
 580              break;
 581          case kSSLSessionOptionBreakOnClientHello:
 582              *value = context->breakOnClientHello;
 583              break;
 584          case kSSLSessionOptionAllowServerIdentityChange:
 585              tls_handshake_get_server_identity_change(context->hdsk, (bool *)value);
 586              break;
 587          default:
 588              return errSecParam;
 589      }
 590  
 591      return errSecSuccess;
 592  }
 593  
 594  OSStatus
 595  SSLSetRecordContext         (SSLContextRef          ctx,
 596                               SSLRecordContextRef    recCtx)
 597  {
 598  	if(ctx == NULL) {
 599  		return errSecParam;
 600  	}
 601  	if(sslIsSessionActive(ctx)) {
 602  		/* can't do this with an active session */
 603  		return errSecBadReq;
 604  	}
 605      ctx->recCtx = recCtx;
 606      return errSecSuccess;
 607  }
 608  
 609  OSStatus
 610  SSLSetIOFuncs				(SSLContextRef		ctx,
 611  							 SSLReadFunc 		readFunc,
 612  							 SSLWriteFunc		writeFunc)
 613  {
 614  	if(ctx == NULL) {
 615  		return errSecParam;
 616  	}
 617      if(ctx->recFuncs!=&SSLRecordLayerInternal) {
 618          /* Can Only do this with the internal record layer */
 619          check(0);
 620          return errSecBadReq;
 621      }
 622  	if(sslIsSessionActive(ctx)) {
 623  		/* can't do this with an active session */
 624  		return errSecBadReq;
 625  	}
 626  
 627      ctx->ioCtx.read=readFunc;
 628      ctx->ioCtx.write=writeFunc;
 629  
 630      return 0;
 631  }
 632  
 633  void
 634  SSLSetNPNFunc(SSLContextRef      context,
 635  			  SSLNPNFunc         npnFunc,
 636  			  void               *info)
 637  {
 638      if (context == NULL) {
 639          return;
 640  	}
 641  	if (sslIsSessionActive(context)) {
 642  		return;
 643  	}
 644      context->npnFunc = npnFunc;
 645      context->npnFuncInfo = info;
 646      if(context->protocolSide==kSSLClientSide) {
 647          tls_handshake_set_npn_enable(context->hdsk, npnFunc!=NULL);
 648      }
 649  }
 650  
 651  OSStatus
 652  SSLSetNPNData(SSLContextRef      context,
 653  			  const void		 *data,
 654  			  size_t			 length)
 655  {
 656      if (context == NULL || data == NULL || length == 0) {
 657          return errSecParam;
 658  	}
 659  
 660  	if (length > 255) {
 661  		return errSecParam;
 662  	}
 663  
 664      tls_buffer npn_data;
 665  
 666      npn_data.data = (uint8_t *)data;
 667      npn_data.length = length;
 668  
 669      return tls_handshake_set_npn_data(context->hdsk, npn_data);
 670  }
 671  
 672  const void *
 673  SSLGetNPNData(SSLContextRef      context,
 674  							 size_t				*length)
 675  {
 676  	if (context == NULL || length == NULL)
 677  		return NULL;
 678  
 679      const tls_buffer *npn_data;
 680  
 681      npn_data = tls_handshake_get_peer_npn_data(context->hdsk);
 682  
 683      if(npn_data) {
 684          *length = npn_data->length;
 685          return npn_data->data;
 686      } else {
 687          return NULL;
 688      }
 689  }
 690  
 691  // ALNP begin
 692  
 693  void
 694  SSLSetALPNFunc(SSLContextRef      context,
 695                 SSLALPNFunc        alpnFunc,
 696                 void               *info)
 697  {
 698      if (context == NULL) {
 699          return;
 700      }
 701      if (sslIsSessionActive(context)) {
 702          return;
 703      }
 704      context->alpnFunc = alpnFunc;
 705      context->alpnFuncInfo = info;
 706      if(context->protocolSide==kSSLServerSide) {
 707          // to do :
 708      }
 709  }
 710  
 711  OSStatus
 712  SSLSetALPNData(SSLContextRef      context,
 713                const void		 *data,
 714                size_t			 length)
 715  {
 716      if (context == NULL || data == NULL || length == 0) {
 717          return errSecParam;
 718      }
 719  
 720      if (length > 255) {
 721          return errSecParam;
 722      }
 723  
 724      tls_buffer alpn_data;
 725  
 726      alpn_data.data = (uint8_t *)data;
 727      alpn_data.length = length;
 728  
 729      return tls_handshake_set_alpn_data(context->hdsk, alpn_data);
 730  }
 731  
 732  const void *
 733  SSLGetALPNData(SSLContextRef      context,
 734                 size_t             *length)
 735  {
 736      if (context == NULL || length == NULL) {
 737          return NULL;
 738      }
 739  
 740      const tls_buffer *alpnData = tls_handshake_get_peer_alpn_data(context->hdsk);
 741  
 742      if (alpnData) {
 743          *length = alpnData->length;
 744          return alpnData->data;
 745      } else {
 746        return NULL;
 747      }
 748  }
 749  
 750  OSStatus
 751  SSLSetALPNProtocols(SSLContextRef      context,
 752                      CFArrayRef         protocols)
 753  {
 754      if (context == NULL || protocols == NULL || CFArrayGetCount(protocols) == 0) {
 755          return errSecParam;
 756      }
 757  
 758      // Per RFC 7301, the protocol name can be at most 32B long.
 759      const int maxBufferLength = 32;
 760  
 761      // Append each element in the array to a mutable buffer
 762      CFMutableDataRef alpnData = CFDataCreateMutable(NULL, 0);
 763      CFArrayForEach(protocols, ^(const void *value) {
 764          CFStringRef protocolString = (CFStringRef) value;
 765          uint8_t len = CFStringGetLength(protocolString);
 766          if (len <= maxBufferLength) {
 767              char stringBytes[maxBufferLength];
 768              if (CFStringGetCString(protocolString, stringBytes, maxBufferLength, kCFStringEncodingASCII)) {
 769                  CFDataAppendBytes(alpnData, (const UInt8 *) &len, sizeof(len));
 770                  CFDataAppendBytes(alpnData, (const UInt8 *) stringBytes, len);
 771              }
 772          }
 773      });
 774  
 775      // Length check
 776      if (CFDataGetLength(alpnData) > 255) {
 777          CFRelease(alpnData);
 778          return errSecParam;
 779      }
 780  
 781      // Pass the buffer down to coreTLS
 782      tls_buffer payload;
 783      payload.data = (uint8_t *) CFDataGetBytePtr(alpnData);
 784      payload.length = CFDataGetLength(alpnData);
 785      int success = tls_handshake_set_alpn_data(context->hdsk, payload);
 786  
 787      // Free up memory and return
 788      CFRelease(alpnData);
 789  
 790      return success;
 791  }
 792  
 793  OSStatus
 794  SSLCopyALPNProtocols(SSLContextRef      context,
 795                       CFArrayRef         *protocolArray)
 796  {
 797      if (context == NULL || protocolArray == NULL) {
 798          return errSecParam;
 799      }
 800  
 801      CFMutableArrayRef array = CFArrayCreateMutableForCFTypes(NULL);
 802  
 803      const tls_buffer *alpnData = tls_handshake_get_peer_alpn_data(context->hdsk);
 804      if (alpnData) {
 805          size_t offset = 0;
 806  
 807          // Extract each encoded parameter, wrap it in a CFStringRef, and append it to the running list
 808          while (offset < alpnData->length) {
 809              char length = alpnData->data[offset];
 810              offset++;
 811  
 812              // Make sure we don't exceed the buffer bounds
 813              if (offset + length > alpnData->length) {
 814                  CFReleaseNull(array);
 815                  *protocolArray = NULL;
 816                  return errSecParam;
 817              }
 818  
 819              CFStringRef protocol = CFStringCreateWithBytes(NULL, alpnData->data + offset, length, kCFStringEncodingASCII, false);
 820              offset += length;
 821              CFArrayAppendValue(array, protocol);
 822              CFReleaseNull(protocol);
 823  
 824              // Sanity check
 825              if (offset > alpnData->length) {
 826                  CFReleaseNull(array);
 827                  *protocolArray = NULL;
 828                  return errSecParam;
 829              }
 830          }
 831  
 832          *protocolArray = array;
 833          return errSecSuccess;
 834      } else {
 835          CFReleaseNull(array);
 836          *protocolArray = NULL;
 837          return errSecParam;
 838      }
 839  }
 840  
 841  // ALPN end
 842  
 843  // OCSP response begin
 844  
 845  OSStatus
 846  SSLSetOCSPResponse(SSLContextRef      context,
 847                     CFDataRef          response)
 848  {
 849      if (context == NULL || response == NULL) {
 850          return errSecParam;
 851      }
 852  
 853      tls_buffer responsePayload;
 854      responsePayload.data = (uint8_t *) CFDataGetBytePtr(response);
 855      responsePayload.length = CFDataGetLength(response);
 856  
 857      int success = tls_handshake_set_ocsp_response(context->hdsk, &responsePayload);
 858      return success;
 859  }
 860  
 861  // OCSP response end
 862  
 863  OSStatus
 864  SSLSetConnection			(SSLContextRef		ctx,
 865  							 SSLConnectionRef	connection)
 866  {
 867  	if(ctx == NULL) {
 868  		return errSecParam;
 869  	}
 870      if(ctx->recFuncs!=&SSLRecordLayerInternal) {
 871          /* Can Only do this with the internal record layer */
 872          check(0);
 873          return errSecBadReq;
 874      }
 875  	if(sslIsSessionActive(ctx)) {
 876  		/* can't do this with an active session */
 877  		return errSecBadReq;
 878  	}
 879  
 880      /* Need to keep a copy of it this layer for the Get function */
 881      ctx->ioCtx.ioRef = connection;
 882  
 883      return 0;
 884  }
 885  
 886  OSStatus
 887  SSLGetConnection			(SSLContextRef		ctx,
 888  							 SSLConnectionRef	*connection)
 889  {
 890  	if((ctx == NULL) || (connection == NULL)) {
 891  		return errSecParam;
 892  	}
 893  	*connection = ctx->ioCtx.ioRef;
 894  	return errSecSuccess;
 895  }
 896  
 897  OSStatus
 898  SSLSetPeerDomainName		(SSLContextRef		ctx,
 899  							 const char			*peerName,
 900  							 size_t				peerNameLen)
 901  {
 902  	if(ctx == NULL) {
 903  		return errSecParam;
 904  	}
 905  	if(sslIsSessionActive(ctx)) {
 906  		/* can't do this with an active session */
 907  		return errSecBadReq;
 908  	}
 909  
 910      if(ctx->protocolSide == kSSLClientSide) {
 911          return tls_handshake_set_peer_hostname(ctx->hdsk, peerName, peerNameLen);
 912      } else {
 913          return 0; // This should probably return an error, but historically didnt.
 914      }
 915  }
 916  
 917  /*
 918   * Determine the buffer size needed for SSLGetPeerDomainName().
 919   */
 920  OSStatus
 921  SSLGetPeerDomainNameLength	(SSLContextRef		ctx,
 922  							 size_t				*peerNameLen)	// RETURNED
 923  {
 924  	if(ctx == NULL) {
 925  		return errSecParam;
 926  	}
 927      const char *hostname;
 928  
 929      return tls_handshake_get_peer_hostname(ctx->hdsk, &hostname, peerNameLen);
 930  }
 931  
 932  OSStatus
 933  SSLGetPeerDomainName		(SSLContextRef		ctx,
 934  							 char				*peerName,		// returned here
 935  							 size_t				*peerNameLen)	// IN/OUT
 936  {
 937      const char *hostname;
 938      size_t len;
 939  
 940      int err;
 941  
 942  	if(ctx == NULL) {
 943  		return errSecParam;
 944  	}
 945  
 946      err=tls_handshake_get_peer_hostname(ctx->hdsk, &hostname, &len);
 947  
 948      if(err) {
 949          return err;
 950      } else if(*peerNameLen<len) {
 951          return errSSLBufferOverflow;
 952      } else {
 953          memcpy(peerName, hostname, len);
 954          *peerNameLen = len;
 955          return 0;
 956      }
 957  }
 958  
 959  OSStatus
 960  SSLCopyRequestedPeerNameLength	(SSLContextRef		ctx,
 961                                   size_t				*peerNameLen)	// RETURNED
 962  {
 963      const tls_buffer *hostname;
 964      if(ctx == NULL) {
 965          return errSecParam;
 966      }
 967      hostname = tls_handshake_get_sni_hostname(ctx->hdsk);
 968      if(!hostname) {
 969          return errSecParam;
 970      } else {
 971          *peerNameLen = hostname->length;
 972      }
 973      return 0;
 974  }
 975  
 976  OSStatus
 977  SSLCopyRequestedPeerName    (SSLContextRef		ctx,
 978                               char				*peerName,		// returned here
 979                               size_t				*peerNameLen)	// IN/OUT
 980  {
 981      const tls_buffer *hostname;
 982  
 983      if(ctx == NULL) {
 984          return errSecParam;
 985      }
 986  
 987      hostname = tls_handshake_get_sni_hostname(ctx->hdsk);
 988  
 989      if(!hostname) {
 990          return errSecParam;
 991      } else if(*peerNameLen < hostname->length) {
 992          return errSSLBufferOverflow;
 993      } else {
 994          memcpy(peerName, hostname->data, hostname->length);
 995          *peerNameLen = hostname->length;
 996          return 0;
 997      }
 998  
 999  }
1000  
1001  OSStatus
1002  SSLSetDatagramHelloCookie   (SSLContextRef	ctx,
1003                               const void         *cookie,
1004                               size_t             cookieLen)
1005  {
1006      OSStatus err;
1007  
1008      if(ctx == NULL) {
1009  		return errSecParam;
1010  	}
1011  
1012      if(!ctx->isDTLS) return errSecParam;
1013  
1014  	if((ctx == NULL) || (cookieLen>32)) {
1015  		return errSecParam;
1016  	}
1017  	if(sslIsSessionActive(ctx)) {
1018  		/* can't do this with an active session */
1019  		return errSecBadReq;
1020  	}
1021  
1022  	/* free possible existing cookie */
1023  	if(ctx->dtlsCookie.data) {
1024          SSLFreeBuffer(&ctx->dtlsCookie);
1025  	}
1026  
1027  	/* copy in */
1028      if((err=SSLAllocBuffer(&ctx->dtlsCookie, cookieLen)))
1029         return err;
1030  
1031  	memmove(ctx->dtlsCookie.data, cookie, cookieLen);
1032      return errSecSuccess;
1033  }
1034  
1035  OSStatus
1036  SSLSetMaxDatagramRecordSize (SSLContextRef		ctx,
1037                               size_t             maxSize)
1038  {
1039  
1040      if(ctx == NULL) return errSecParam;
1041      if(!ctx->isDTLS) return errSecParam;
1042  
1043      tls_handshake_set_mtu(ctx->hdsk, maxSize);
1044  
1045      return errSecSuccess;
1046  }
1047  
1048  OSStatus
1049  SSLGetMaxDatagramRecordSize (SSLContextRef		ctx,
1050                               size_t             *maxSize)
1051  {
1052      if(ctx == NULL) return errSecParam;
1053      if(!ctx->isDTLS) return errSecParam;
1054  
1055      *maxSize = ctx->mtu;
1056  
1057      return errSecSuccess;
1058  }
1059  
1060  /*
1061  
1062   Keys to to math below:
1063  
1064   A DTLS record looks like this: | header (13 bytes) | fragment |
1065  
1066   For Null cipher, fragment is clear text as follows:
1067   | Contents | Mac |
1068  
1069   For block cipher, fragment size must be a multiple of the cipher block size, and is the
1070   encryption of the following plaintext :
1071   | IV (1 block) | content | MAC | padding (0 to 255 bytes) | Padlen (1 byte) |
1072  
1073   The maximum content length in that case is achieved for 0 padding bytes.
1074  
1075  */
1076  
1077  OSStatus
1078  SSLGetDatagramWriteSize		(SSLContextRef ctx,
1079  							 size_t *bufSize)
1080  {
1081      if(ctx == NULL) return errSecParam;
1082      if(!ctx->isDTLS) return errSecParam;
1083      if(bufSize == NULL) return errSecParam;
1084  
1085      size_t max_fragment_size = ctx->mtu-13; /* 13 = dtls record header */
1086  
1087  #if 0
1088      SSLCipherSpecParams *currCipher = &ctx->selectedCipherSpecParams;
1089  
1090      size_t blockSize = currCipher->blockSize;
1091      size_t macSize = currCipher->macSize;
1092  #else
1093      size_t blockSize = 16;
1094      size_t macSize = 32;
1095  #endif
1096  
1097      if (blockSize > 0) {
1098          /* max_fragment_size must be a multiple of blocksize */
1099          max_fragment_size = max_fragment_size & ~(blockSize-1);
1100          max_fragment_size -= blockSize; /* 1 block for IV */
1101          max_fragment_size -= 1; /* 1 byte for pad length */
1102      }
1103  
1104      /* less the mac size */
1105      max_fragment_size -= macSize;
1106  
1107      /* Thats just a sanity check */
1108      assert(max_fragment_size<ctx->mtu);
1109  
1110      *bufSize = max_fragment_size;
1111  
1112      return errSecSuccess;
1113  }
1114  
1115  /* 
1116   All the complexity around protocol version is to support legacy APIs.
1117   Eventually that should go away:
1118   <rdar://problem/20842025> Remove deprecated SecureTransport function related to protocol version selection.
1119   */
1120  
1121  static tls_protocol_version SSLProtocolToProtocolVersion(SSLProtocol protocol) {
1122      switch (protocol) {
1123          case kSSLProtocol2:             return SSL_Version_2_0;
1124          case kSSLProtocol3:             return tls_protocol_version_SSL_3;
1125          case kTLSProtocol1:             return tls_protocol_version_TLS_1_0;
1126          case kTLSProtocol11:            return tls_protocol_version_TLS_1_1;
1127          case kTLSProtocol12:            return tls_protocol_version_TLS_1_2;
1128          case kDTLSProtocol1:            return tls_protocol_version_DTLS_1_0;
1129          default:                        return tls_protocol_version_Undertermined;
1130      }
1131  }
1132  
1133  /* concert between private SSLProtocolVersion and public SSLProtocol */
1134  static SSLProtocol SSLProtocolVersionToProtocol(SSLProtocolVersion version)
1135  {
1136  	switch(version) {
1137  		case tls_protocol_version_SSL_3:     return kSSLProtocol3;
1138  		case tls_protocol_version_TLS_1_0:   return kTLSProtocol1;
1139  		case tls_protocol_version_TLS_1_1:   return kTLSProtocol11;
1140  		case tls_protocol_version_TLS_1_2:   return kTLSProtocol12;
1141  		case tls_protocol_version_DTLS_1_0:  return kDTLSProtocol1;
1142  		default:
1143  			sslErrorLog("SSLProtocolVersionToProtocol: bad prot (%04x)\n",
1144                          version);
1145              /* DROPTHROUGH */
1146  		case tls_protocol_version_Undertermined:  return kSSLProtocolUnknown;
1147  	}
1148  }
1149  
1150  OSStatus
1151  SSLSetProtocolVersionMin  (SSLContextRef      ctx,
1152                             SSLProtocol        minVersion)
1153  {
1154      if(ctx == NULL) return errSecParam;
1155  
1156      tls_protocol_version version = SSLProtocolToProtocolVersion(minVersion);
1157      if (ctx->isDTLS) {
1158          if (version > MINIMUM_DATAGRAM_VERSION ||
1159              version < MAXIMUM_DATAGRAM_VERSION)
1160              return errSSLIllegalParam;
1161          if (version < ctx->maxProtocolVersion)
1162              ctx->maxProtocolVersion = version;
1163      } else {
1164          if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION)
1165              return errSSLIllegalParam;
1166          if (version > ctx->maxProtocolVersion)
1167              ctx->maxProtocolVersion = version;
1168      }
1169      ctx->minProtocolVersion = version;
1170  
1171      tls_handshake_set_min_protocol_version(ctx->hdsk, ctx->minProtocolVersion);
1172      tls_handshake_set_max_protocol_version(ctx->hdsk, ctx->maxProtocolVersion);
1173  
1174      return errSecSuccess;
1175  }
1176  
1177  OSStatus
1178  SSLGetProtocolVersionMin  (SSLContextRef      ctx,
1179                             SSLProtocol        *minVersion)
1180  {
1181      if(ctx == NULL) return errSecParam;
1182  
1183      *minVersion = SSLProtocolVersionToProtocol(ctx->minProtocolVersion);
1184      return errSecSuccess;
1185  }
1186  
1187  OSStatus
1188  SSLSetProtocolVersionMax  (SSLContextRef      ctx,
1189                             SSLProtocol        maxVersion)
1190  {
1191      if(ctx == NULL) return errSecParam;
1192  
1193      SSLProtocolVersion version = SSLProtocolToProtocolVersion(maxVersion);
1194      if (ctx->isDTLS) {
1195          if (version > MINIMUM_DATAGRAM_VERSION ||
1196              version < MAXIMUM_DATAGRAM_VERSION)
1197              return errSSLIllegalParam;
1198          if (version > (SSLProtocolVersion)ctx->minProtocolVersion)
1199              ctx->minProtocolVersion = version;
1200      } else {
1201          if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION)
1202              return errSSLIllegalParam;
1203          if (version < (SSLProtocolVersion)ctx->minProtocolVersion)
1204              ctx->minProtocolVersion = version;
1205      }
1206      ctx->maxProtocolVersion = version;
1207  
1208      tls_handshake_set_min_protocol_version(ctx->hdsk, ctx->minProtocolVersion);
1209      tls_handshake_set_max_protocol_version(ctx->hdsk, ctx->maxProtocolVersion);
1210  
1211      return errSecSuccess;
1212  }
1213  
1214  OSStatus
1215  SSLGetProtocolVersionMax  (SSLContextRef      ctx,
1216                             SSLProtocol        *maxVersion)
1217  {
1218      if(ctx == NULL) return errSecParam;
1219  
1220      *maxVersion = SSLProtocolVersionToProtocol(ctx->maxProtocolVersion);
1221      return errSecSuccess;
1222  }
1223  
1224  tls_protocol_version
1225  _SSLProtocolVersionToWireFormatValue   (SSLProtocol protocol)
1226  {
1227      switch (protocol) {
1228          case kSSLProtocol3: {
1229              return tls_protocol_version_SSL_3;
1230          }
1231          case kTLSProtocol1: {
1232              return tls_protocol_version_TLS_1_0;
1233          }
1234          case kTLSProtocol11: {
1235              return tls_protocol_version_TLS_1_1;
1236          }
1237          case kTLSProtocol12: {
1238              return tls_protocol_version_TLS_1_2;
1239          }
1240          case kTLSProtocol13: {
1241              return tls_protocol_version_TLS_1_3;
1242          }
1243          case kTLSProtocolMaxSupported: {
1244              return tls_protocol_version_TLS_1_3;
1245          }
1246          case kDTLSProtocol1: {
1247              return tls_protocol_version_DTLS_1_0;
1248          }
1249          case kDTLSProtocol12: {
1250              return tls_protocol_version_DTLS_1_2;
1251          }
1252          case kSSLProtocolUnknown: {
1253              return tls_protocol_version_Undertermined;
1254          }
1255          case kSSLProtocol2:
1256          case kSSLProtocol3Only:
1257          case kTLSProtocol1Only:
1258          case kSSLProtocolAll: {
1259              sslErrorLog("SSLProtocol %d is deprecated. Setting to the default value (%d)", protocol, tls_protocol_version_Undertermined);
1260              return tls_protocol_version_Undertermined;
1261          }
1262      }
1263  
1264      return tls_protocol_version_Undertermined;
1265  }
1266  
1267  #define max(x,y) ((x)<(y)?(y):(x))
1268  
1269  OSStatus
1270  SSLSetProtocolVersionEnabled(SSLContextRef     ctx,
1271  							 SSLProtocol		protocol,
1272  							 Boolean			enable)
1273  {
1274  	if(ctx == NULL) {
1275  		return errSecParam;
1276  	}
1277  	if(sslIsSessionActive(ctx) || ctx->isDTLS) {
1278  		/* Can't do this with an active session, nor with a DTLS session */
1279  		return errSecBadReq;
1280  	}
1281      if (protocol == kSSLProtocolAll) {
1282          if (enable) {
1283              ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
1284              ctx->maxProtocolVersion = MAXIMUM_STREAM_VERSION;
1285          } else {
1286              ctx->minProtocolVersion = SSL_Version_Undetermined;
1287              ctx->maxProtocolVersion = SSL_Version_Undetermined;
1288          }
1289  	} else {
1290  		SSLProtocolVersion version = SSLProtocolToProtocolVersion(protocol);
1291          if (enable) {
1292  			if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION) {
1293  				return errSecParam;
1294  			}
1295              if (version > (SSLProtocolVersion)ctx->maxProtocolVersion) {
1296                  ctx->maxProtocolVersion = version;
1297                  if (ctx->minProtocolVersion == SSL_Version_Undetermined)
1298                      ctx->minProtocolVersion = version;
1299              }
1300              if (version < (SSLProtocolVersion)ctx->minProtocolVersion) {
1301                  ctx->minProtocolVersion = version;
1302              }
1303          } else {
1304  			if (version < SSL_Version_2_0 || version > MAXIMUM_STREAM_VERSION) {
1305  				return errSecParam;
1306  			}
1307  			/* Disabling a protocol version now resets the minimum acceptable
1308  			 * version to the next higher version. This means it's no longer
1309  			 * possible to enable a discontiguous set of protocol versions.
1310  			 */
1311  			SSLProtocolVersion nextVersion;
1312  			switch (version) {
1313  				case SSL_Version_2_0:
1314  					nextVersion = SSL_Version_3_0;
1315  					break;
1316  				case SSL_Version_3_0:
1317  					nextVersion = TLS_Version_1_0;
1318  					break;
1319  				case TLS_Version_1_0:
1320  					nextVersion = TLS_Version_1_1;
1321  					break;
1322  				case TLS_Version_1_1:
1323  					nextVersion = TLS_Version_1_2;
1324  					break;
1325  				case TLS_Version_1_2:
1326  				default:
1327  					nextVersion = SSL_Version_Undetermined;
1328  					break;
1329  			}
1330  			ctx->minProtocolVersion = (tls_protocol_version)max((SSLProtocolVersion)ctx->minProtocolVersion, nextVersion);
1331  			if (ctx->minProtocolVersion > ctx->maxProtocolVersion) {
1332  				ctx->minProtocolVersion = SSL_Version_Undetermined;
1333  				ctx->maxProtocolVersion = SSL_Version_Undetermined;
1334  			}
1335          }
1336      }
1337  
1338      tls_handshake_set_min_protocol_version(ctx->hdsk, ctx->minProtocolVersion);
1339      tls_handshake_set_max_protocol_version(ctx->hdsk, ctx->maxProtocolVersion);
1340  
1341  	return errSecSuccess;
1342  }
1343  
1344  OSStatus
1345  SSLGetProtocolVersionEnabled(SSLContextRef 		ctx,
1346  							 SSLProtocol		protocol,
1347  							 Boolean			*enable)		/* RETURNED */
1348  {
1349  	if(ctx == NULL) {
1350  		return errSecParam;
1351  	}
1352  	if(ctx->isDTLS) {
1353  		/* Can't do this with a DTLS session */
1354  		return errSecBadReq;
1355  	}
1356  	switch(protocol) {
1357  		case kSSLProtocol2:
1358  		case kSSLProtocol3:
1359  		case kTLSProtocol1:
1360          case kTLSProtocol11:
1361          case kTLSProtocol12:
1362          {
1363              SSLProtocolVersion version = SSLProtocolToProtocolVersion(protocol);
1364  			*enable = ((SSLProtocolVersion)ctx->minProtocolVersion <= version
1365                         && (SSLProtocolVersion)ctx->maxProtocolVersion >= version);
1366  			break;
1367          }
1368  		case kSSLProtocolAll:
1369              *enable = (ctx->minProtocolVersion <= MINIMUM_STREAM_VERSION
1370                         && ctx->maxProtocolVersion >= MAXIMUM_STREAM_VERSION);
1371  			break;
1372  		default:
1373  			return errSecParam;
1374  	}
1375  	return errSecSuccess;
1376  }
1377  
1378  /* deprecated */
1379  OSStatus
1380  SSLSetProtocolVersion		(SSLContextRef 		ctx,
1381  							 SSLProtocol		version)
1382  {
1383  	if(ctx == NULL) {
1384  		return errSecParam;
1385  	}
1386  	if(sslIsSessionActive(ctx) || ctx->isDTLS) {
1387  		/* Can't do this with an active session, nor with a DTLS session */
1388  		return errSecBadReq;
1389  	}
1390  
1391  	switch(version) {
1392  		case kSSLProtocol3:
1393  			/* this tells us to do our best, up to 3.0 */
1394              ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
1395              ctx->maxProtocolVersion = SSL_Version_3_0;
1396  			break;
1397  		case kSSLProtocol3Only:
1398              ctx->minProtocolVersion = SSL_Version_3_0;
1399              ctx->maxProtocolVersion = SSL_Version_3_0;
1400  			break;
1401  		case kTLSProtocol1:
1402  			/* this tells us to do our best, up to TLS, but allows 3.0 */
1403              ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
1404              ctx->maxProtocolVersion = TLS_Version_1_0;
1405              break;
1406          case kTLSProtocol1Only:
1407              ctx->minProtocolVersion = TLS_Version_1_0;
1408              ctx->maxProtocolVersion = TLS_Version_1_0;
1409  			break;
1410          case kTLSProtocol11:
1411  			/* This tells us to do our best, up to TLS 1.1, currently also
1412                 allows 3.0 or TLS 1.0 */
1413              ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
1414              ctx->maxProtocolVersion = TLS_Version_1_1;
1415  			break;
1416          case kTLSProtocol12:
1417          case kSSLProtocolAll:
1418  		case kSSLProtocolUnknown:
1419  			/* This tells us to do our best, up to TLS 1.2, currently also
1420                 allows 3.0 or TLS 1.0 or TLS 1.1 */
1421              ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
1422              ctx->maxProtocolVersion = MAXIMUM_STREAM_VERSION;
1423  			break;
1424  		default:
1425  			return errSecParam;
1426  	}
1427  
1428      tls_handshake_set_min_protocol_version(ctx->hdsk, ctx->minProtocolVersion);
1429      tls_handshake_set_max_protocol_version(ctx->hdsk, ctx->maxProtocolVersion);
1430  
1431      return errSecSuccess;
1432  }
1433  
1434  /* deprecated */
1435  OSStatus
1436  SSLGetProtocolVersion		(SSLContextRef		ctx,
1437  							 SSLProtocol		*protocol)		/* RETURNED */
1438  {
1439  	if(ctx == NULL) {
1440  		return errSecParam;
1441  	}
1442  	/* translate array of booleans to public value; not all combinations
1443  	 * are legal (i.e., meaningful) for this call */
1444      if (ctx->maxProtocolVersion == MAXIMUM_STREAM_VERSION) {
1445          if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
1446              /* traditional 'all enabled' */
1447              *protocol = kSSLProtocolAll;
1448              return errSecSuccess;
1449  		}
1450  	} else if (ctx->maxProtocolVersion == TLS_Version_1_1) {
1451          if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
1452              /* traditional 'all enabled' */
1453              *protocol = kTLSProtocol11;
1454              return errSecSuccess;
1455          }
1456  	} else if (ctx->maxProtocolVersion == TLS_Version_1_0) {
1457          if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
1458              /* TLS1.1 and below enabled */
1459              *protocol = kTLSProtocol1;
1460              return errSecSuccess;
1461          } else if(ctx->minProtocolVersion == TLS_Version_1_0) {
1462          	*protocol = kTLSProtocol1Only;
1463  		}
1464  	} else if(ctx->maxProtocolVersion == SSL_Version_3_0) {
1465          if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
1466              /* Could also return kSSLProtocol3Only since
1467                 MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
1468              *protocol = kSSLProtocol3;
1469  			return errSecSuccess;
1470  		}
1471  	}
1472  
1473      return errSecParam;
1474  }
1475  
1476  OSStatus
1477  SSLGetNegotiatedProtocolVersion		(SSLContextRef		ctx,
1478  									 SSLProtocol		*protocol) /* RETURNED */
1479  {
1480  	if(ctx == NULL) {
1481  		return errSecParam;
1482  	}
1483  	*protocol = SSLProtocolVersionToProtocol(ctx->negProtocolVersion);
1484  	return errSecSuccess;
1485  }
1486  
1487  OSStatus
1488  SSLSetEnableCertVerify		(SSLContextRef		ctx,
1489  							 Boolean			enableVerify)
1490  {
1491  	if(ctx == NULL) {
1492  		return errSecParam;
1493  	}
1494  	sslCertDebug("SSLSetEnableCertVerify %s",
1495  		enableVerify ? "true" : "false");
1496  	if(sslIsSessionActive(ctx)) {
1497  		/* can't do this with an active session */
1498  		return errSecBadReq;
1499  	}
1500  	ctx->enableCertVerify = enableVerify;
1501  	return errSecSuccess;
1502  }
1503  
1504  OSStatus
1505  SSLGetEnableCertVerify		(SSLContextRef		ctx,
1506  							Boolean				*enableVerify)
1507  {
1508  	if(ctx == NULL) {
1509  		return errSecParam;
1510  	}
1511  	*enableVerify = ctx->enableCertVerify;
1512  	return errSecSuccess;
1513  }
1514  
1515  OSStatus
1516  SSLSetAllowsExpiredCerts(SSLContextRef		ctx,
1517  						 Boolean			allowExpired)
1518  {
1519      /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1520      return 0;
1521  }
1522  
1523  OSStatus
1524  SSLGetAllowsExpiredCerts	(SSLContextRef		ctx,
1525  							 Boolean			*allowExpired)
1526  {
1527      /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1528      return errSecUnimplemented;
1529  }
1530  
1531  OSStatus
1532  SSLSetAllowsExpiredRoots(SSLContextRef		ctx,
1533  						 Boolean			allowExpired)
1534  {
1535      /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1536      return 0;
1537  }
1538  
1539  OSStatus
1540  SSLGetAllowsExpiredRoots	(SSLContextRef		ctx,
1541  							 Boolean			*allowExpired)
1542  {
1543      /* This has been deprecated since 10.9, and non-functional since at least 10.10 */
1544      return errSecUnimplemented;
1545  }
1546  
1547  OSStatus SSLSetAllowsAnyRoot(
1548  	SSLContextRef	ctx,
1549  	Boolean			anyRoot)
1550  {
1551  	if(ctx == NULL) {
1552  		return errSecParam;
1553  	}
1554  	sslCertDebug("SSLSetAllowsAnyRoot %s",	anyRoot ? "true" : "false");
1555  	ctx->allowAnyRoot = anyRoot;
1556  	return errSecSuccess;
1557  }
1558  
1559  OSStatus
1560  SSLGetAllowsAnyRoot(
1561  	SSLContextRef	ctx,
1562  	Boolean			*anyRoot)
1563  {
1564  	if(ctx == NULL) {
1565  		return errSecParam;
1566  	}
1567  	*anyRoot = ctx->allowAnyRoot;
1568  	return errSecSuccess;
1569  }
1570  
1571  #if !TARGET_OS_IPHONE
1572  /* obtain the system roots sets for this app, policy SSL */
1573  static OSStatus sslDefaultSystemRoots(
1574  	SSLContextRef ctx,
1575  	CFArrayRef *systemRoots)				// created and RETURNED
1576  
1577  {
1578      const char *hostname;
1579      size_t len;
1580  
1581      tls_handshake_get_peer_hostname(ctx->hdsk, &hostname, &len);
1582  
1583  	return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL,
1584  		hostname,
1585  		(uint32_t)len,
1586  		(ctx->protocolSide == kSSLServerSide) ?
1587  			/* server verifies, client encrypts */
1588  			CSSM_KEYUSE_VERIFY : CSSM_KEYUSE_ENCRYPT,
1589  		systemRoots);
1590  }
1591  #endif /* OS X only */
1592  
1593  OSStatus
1594  SSLSetTrustedRoots			(SSLContextRef 		ctx,
1595  							 CFArrayRef 		trustedRoots,
1596  							 Boolean 			replaceExisting)
1597  {
1598  	if (sslIsSessionActive(ctx)) {
1599  		/* can't do this with an active session */
1600  		return errSecBadReq;
1601  	}
1602  	sslCertDebug("SSLSetTrustedRoot  numCerts %d  replaceExist %s",
1603  		(int)CFArrayGetCount(trustedRoots), replaceExisting ? "true" : "false");
1604  
1605      if (replaceExisting) {
1606          ctx->trustedCertsOnly = true;
1607          CFReleaseNull(ctx->trustedCerts);
1608      }
1609  
1610      if (ctx->trustedCerts) {
1611          CFIndex count = CFArrayGetCount(trustedRoots);
1612          CFRange range = { 0, count };
1613          CFArrayAppendArray(ctx->trustedCerts, trustedRoots, range);
1614      } else {
1615          require(ctx->trustedCerts =
1616              CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, trustedRoots),
1617              errOut);
1618      }
1619  
1620      return errSecSuccess;
1621  
1622  errOut:
1623      return errSecAllocate;
1624  }
1625  
1626  OSStatus
1627  SSLCopyTrustedRoots			(SSLContextRef 		ctx,
1628  							 CFArrayRef 		*trustedRoots)	/* RETURNED */
1629  {
1630  	if(ctx == NULL || trustedRoots == NULL) {
1631  		return errSecParam;
1632  	}
1633  	if(ctx->trustedCerts != NULL) {
1634  		*trustedRoots = ctx->trustedCerts;
1635  		CFRetain(ctx->trustedCerts);
1636  		return errSecSuccess;
1637  	}
1638  #if TARGET_OS_OSX
1639  	/* use default system roots */
1640      return sslDefaultSystemRoots(ctx, trustedRoots);
1641  #else
1642      *trustedRoots = NULL;
1643      return errSecSuccess;
1644  #endif
1645  }
1646  
1647  #if !TARGET_OS_IPHONE
1648  OSStatus
1649  SSLSetTrustedLeafCertificates	(SSLContextRef 		ctx,
1650  								 CFArrayRef 		trustedCerts)
1651  {
1652  	if(ctx == NULL) {
1653  		return errSecParam;
1654  	}
1655  	if(sslIsSessionActive(ctx)) {
1656  		/* can't do this with an active session */
1657  		return errSecBadReq;
1658  	}
1659  
1660  	if(ctx->trustedLeafCerts) {
1661  		CFRelease(ctx->trustedLeafCerts);
1662  	}
1663  	ctx->trustedLeafCerts = CFRetainSafe(trustedCerts);
1664  	return errSecSuccess;
1665  }
1666  
1667  OSStatus
1668  SSLCopyTrustedLeafCertificates	(SSLContextRef 		ctx,
1669  								 CFArrayRef 		*trustedCerts)	/* RETURNED */
1670  {
1671  	if(ctx == NULL) {
1672  		return errSecParam;
1673  	}
1674  	if(ctx->trustedLeafCerts != NULL) {
1675  		*trustedCerts = ctx->trustedLeafCerts;
1676  		CFRetain(ctx->trustedCerts);
1677  		return errSecSuccess;
1678  	}
1679  	*trustedCerts = NULL;
1680  	return errSecSuccess;
1681  }
1682  #endif
1683  
1684  OSStatus
1685  SSLSetClientSideAuthenticate 	(SSLContext			*ctx,
1686  								 SSLAuthenticate	auth)
1687  {
1688  	if(ctx == NULL) {
1689  		return errSecParam;
1690  	}
1691  	if(sslIsSessionActive(ctx)) {
1692  		/* can't do this with an active session */
1693  		return errSecBadReq;
1694  	}
1695  	ctx->clientAuth = auth;
1696  	switch(auth) {
1697  		case kNeverAuthenticate:
1698              tls_handshake_set_client_auth(ctx->hdsk, false);
1699  			break;
1700  		case kAlwaysAuthenticate:
1701  		case kTryAuthenticate:
1702              tls_handshake_set_client_auth(ctx->hdsk, true);
1703  			break;
1704  	}
1705  	return errSecSuccess;
1706  }
1707  
1708  OSStatus
1709  SSLGetClientSideAuthenticate 	(SSLContext			*ctx,
1710  								 SSLAuthenticate	*auth)	/* RETURNED */
1711  {
1712  	if(ctx == NULL || auth == NULL) {
1713  		return errSecParam;
1714  	}
1715  	*auth = ctx->clientAuth;
1716  	return errSecSuccess;
1717  }
1718  
1719  OSStatus
1720  SSLGetClientCertificateState	(SSLContextRef				ctx,
1721  								 SSLClientCertificateState	*clientState)
1722  {
1723  	if(ctx == NULL) {
1724  		return errSecParam;
1725  	}
1726      if(ctx->protocolSide == kSSLClientSide) {
1727          /* Client Side */
1728         switch(ctx->clientCertState) {
1729             case kSSLClientCertNone:
1730                 *clientState = kSSLClientCertNone;
1731                 break;
1732             case kSSLClientCertRequested:
1733                 if(ctx->localCertArray) {
1734                     *clientState = kSSLClientCertSent;
1735                 } else {
1736                     *clientState = kSSLClientCertRequested;
1737                 }
1738                 break;
1739             default:
1740                 /* Anything else is an internal error */
1741                 sslErrorLog("TLS client has invalid internal clientCertState (%d)\n", ctx->clientCertState);
1742                 return errSSLInternal;
1743         }
1744      } else {
1745          /* Server side */
1746          switch(ctx->clientCertState) {
1747              case kSSLClientCertNone:
1748              case kSSLClientCertRejected:
1749                  *clientState = ctx->clientCertState;
1750                  break;
1751              case kSSLClientCertRequested:
1752                  if(ctx->peerSecTrust) {
1753                      *clientState = kSSLClientCertSent;
1754                  } else {
1755                      *clientState = kSSLClientCertRequested;
1756                  }
1757                  break;
1758              default:
1759                  /* Anything else is an internal error */
1760                  sslErrorLog("TLS server has invalid internal clientCertState (%d)\n", ctx->clientCertState);
1761                  return errSSLInternal;
1762          }
1763      }
1764  	return errSecSuccess;
1765  }
1766  
1767  #include <tls_helpers.h>
1768  
1769  OSStatus
1770  SSLSetCertificate			(SSLContextRef		ctx,
1771  							 CFArrayRef			_Nullable certRefs)
1772  {
1773      OSStatus ortn;
1774  	/*
1775  	 * -- free localCerts if we have any
1776  	 * -- Get raw cert data, convert to ctx->localCert
1777  	 * -- get pub, priv keys from certRef[0]
1778  	 * -- validate cert chain
1779  	 */
1780  	if(ctx == NULL) {
1781  		return errSecParam;
1782  	}
1783  
1784      CFReleaseNull(ctx->localCertArray);
1785  	if(certRefs == NULL) {
1786  		return errSecSuccess; // we have cleared the cert, as requested
1787  	}
1788  
1789      ortn = tls_helper_set_identity_from_array(ctx->hdsk, certRefs);
1790  
1791      if(ortn == noErr) {
1792          ctx->localCertArray = certRefs;
1793          CFRetain(certRefs);
1794      }
1795  
1796  	return ortn;
1797  }
1798  
1799  OSStatus
1800  SSLSetEncryptionCertificate	(SSLContextRef		ctx,
1801  							 CFArrayRef			certRefs)
1802  {
1803  	if(ctx == NULL) {
1804  		return errSecParam;
1805  	}
1806  	if(sslIsSessionActive(ctx)) {
1807  		/* can't do this with an active session */
1808  		return errSecBadReq;
1809  	}
1810      CFReleaseNull(ctx->encryptCertArray);
1811      ctx->encryptCertArray = certRefs;
1812      CFRetain(certRefs);
1813  	return errSecSuccess;
1814  }
1815  
1816  OSStatus SSLGetCertificate(SSLContextRef		ctx,
1817  						   CFArrayRef			*certRefs)
1818  {
1819  	if(ctx == NULL) {
1820  		return errSecParam;
1821  	}
1822  	*certRefs = ctx->localCertArray;
1823  	return errSecSuccess;
1824  }
1825  
1826  OSStatus SSLGetEncryptionCertificate(SSLContextRef		ctx,
1827  								     CFArrayRef			*certRefs)
1828  {
1829  	if(ctx == NULL) {
1830  		return errSecParam;
1831  	}
1832  	*certRefs = ctx->encryptCertArray;
1833  	return errSecSuccess;
1834  }
1835  
1836  OSStatus
1837  SSLSetPeerID				(SSLContext 		*ctx,
1838  							 const void 		*peerID,
1839  							 size_t				peerIDLen)
1840  {
1841  	OSStatus serr;
1842  
1843  	/* copy peerId to context->peerId */
1844  	if((ctx == NULL) ||
1845  	   (peerID == NULL) ||
1846  	   (peerIDLen == 0)) {
1847  		return errSecParam;
1848  	}
1849  	if(sslIsSessionActive(ctx) &&
1850          /* kSSLClientCertRequested implies client side */
1851          (ctx->clientCertState != kSSLClientCertRequested))
1852      {
1853  		return errSecBadReq;
1854  	}
1855  	SSLFreeBuffer(&ctx->peerID);
1856  	serr = SSLAllocBuffer(&ctx->peerID, peerIDLen);
1857  	if(serr) {
1858  		return serr;
1859  	}
1860      tls_handshake_set_resumption(ctx->hdsk, true);
1861  	memmove(ctx->peerID.data, peerID, peerIDLen);
1862  	return errSecSuccess;
1863  }
1864  
1865  OSStatus
1866  SSLGetPeerID				(SSLContextRef 		ctx,
1867  							 const void 		**peerID,
1868  							 size_t				*peerIDLen)
1869  {
1870  	*peerID = ctx->peerID.data;			// may be NULL
1871  	*peerIDLen = ctx->peerID.length;
1872  	return errSecSuccess;
1873  }
1874  
1875  OSStatus
1876  SSLGetNegotiatedCipher		(SSLContextRef 		ctx,
1877  							 SSLCipherSuite 	*cipherSuite)
1878  {
1879  	if(ctx == NULL) {
1880  		return errSecParam;
1881  	}
1882  
1883      if(!sslIsSessionActive(ctx)) {
1884  		return errSecBadReq;
1885  	}
1886  
1887      *cipherSuite = (SSLCipherSuite)tls_handshake_get_negotiated_cipherspec(ctx->hdsk);
1888  
1889  	return errSecSuccess;
1890  }
1891  
1892  /*
1893   * Add an acceptable distinguished name (client authentication only).
1894   */
1895  OSStatus
1896  SSLAddDistinguishedName(
1897  	SSLContextRef ctx,
1898  	const void *derDN,
1899  	size_t derDNLen)
1900  {
1901      DNListElem      *dn;
1902      OSStatus        err;
1903  
1904  	if(ctx == NULL) {
1905  		return errSecParam;
1906  	}
1907  	if(sslIsSessionActive(ctx)) {
1908  		return errSecBadReq;
1909  	}
1910  
1911  	dn = (DNListElem *)sslMalloc(sizeof(DNListElem));
1912  	if(dn == NULL) {
1913  		return errSecAllocate;
1914  	}
1915      if ((err = SSLAllocBuffer(&dn->derDN, derDNLen)))
1916      {
1917          sslFree(dn);
1918          return err;
1919      }
1920      memcpy(dn->derDN.data, derDN, derDNLen);
1921      dn->next = ctx->acceptableDNList;
1922      ctx->acceptableDNList = dn;
1923  
1924      tls_handshake_set_acceptable_dn_list(ctx->hdsk, dn);
1925  
1926      return errSecSuccess;
1927  }
1928  
1929  /* single-cert version of SSLSetCertificateAuthorities() */
1930  static OSStatus
1931  sslAddCA(SSLContextRef		ctx,
1932  		 SecCertificateRef	cert)
1933  {
1934  	OSStatus ortn = errSecParam;
1935  
1936      /* Get subject from certificate. */
1937  #if TARGET_OS_IPHONE
1938      CFDataRef subjectName = NULL;
1939      subjectName = SecCertificateCopySubjectSequence(cert);
1940      require(subjectName, errOut);
1941  #else
1942      CSSM_DATA_PTR subjectName = NULL;
1943      ortn = SecCertificateCopyFirstFieldValue(cert, &CSSMOID_X509V1SubjectNameStd, &subjectName);
1944      require_noerr(ortn, errOut);
1945  #endif
1946  
1947  	/* add to acceptableCAs as cert, creating array if necessary */
1948  	if(ctx->acceptableCAs == NULL) {
1949  		require(ctx->acceptableCAs = CFArrayCreateMutable(NULL, 0,
1950              &kCFTypeArrayCallBacks), errOut);
1951  		if(ctx->acceptableCAs == NULL) {
1952  			return errSecAllocate;
1953  		}
1954  	}
1955  	CFArrayAppendValue(ctx->acceptableCAs, cert);
1956  
1957  	/* then add this cert's subject name to acceptableDNList */
1958  #if TARGET_OS_IPHONE
1959  	ortn = SSLAddDistinguishedName(ctx,
1960                                     CFDataGetBytePtr(subjectName),
1961                                     CFDataGetLength(subjectName));
1962  #else
1963      ortn = SSLAddDistinguishedName(ctx, subjectName->Data, subjectName->Length);
1964  #endif
1965  
1966  errOut:
1967  #if TARGET_OS_IPHONE
1968      CFReleaseSafe(subjectName);
1969  #endif
1970  	return ortn;
1971  }
1972  
1973  /*
1974   * Add a SecCertificateRef, or a CFArray of them, to a server's list
1975   * of acceptable Certificate Authorities (CAs) to present to the client
1976   * when client authentication is performed.
1977   */
1978  OSStatus
1979  SSLSetCertificateAuthorities(SSLContextRef		ctx,
1980  							 CFTypeRef			certificateOrArray,
1981  							 Boolean 			replaceExisting)
1982  {
1983  	CFTypeID itemType;
1984  	OSStatus ortn = errSecSuccess;
1985  
1986  	if((ctx == NULL) || sslIsSessionActive(ctx) ||
1987  	   (ctx->protocolSide != kSSLServerSide)) {
1988  		return errSecParam;
1989  	}
1990  	if(replaceExisting) {
1991  		sslFreeDnList(ctx);
1992  		if(ctx->acceptableCAs) {
1993  			CFRelease(ctx->acceptableCAs);
1994  			ctx->acceptableCAs = NULL;
1995  		}
1996  	}
1997  	/* else appending */
1998  
1999  	itemType = CFGetTypeID(certificateOrArray);
2000  	if(itemType == SecCertificateGetTypeID()) {
2001  		/* one cert */
2002  		ortn = sslAddCA(ctx, (SecCertificateRef)certificateOrArray);
2003  	}
2004  	else if(itemType == CFArrayGetTypeID()) {
2005  		CFArrayRef cfa = (CFArrayRef)certificateOrArray;
2006  		CFIndex numCerts = CFArrayGetCount(cfa);
2007  		CFIndex dex;
2008  
2009  		/* array of certs */
2010  		for(dex=0; dex<numCerts; dex++) {
2011  			SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(cfa, dex);
2012  			if(CFGetTypeID(cert) != SecCertificateGetTypeID()) {
2013  				return errSecParam;
2014  			}
2015  			ortn = sslAddCA(ctx, cert);
2016  			if(ortn) {
2017  				break;
2018  			}
2019  		}
2020  	}
2021  	else {
2022  		ortn = errSecParam;
2023  	}
2024  	return ortn;
2025  }
2026  
2027  
2028  /*
2029   * Obtain the certificates specified in SSLSetCertificateAuthorities(),
2030   * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
2031   * been called.
2032   * Caller must CFRelease the returned array.
2033   */
2034  OSStatus
2035  SSLCopyCertificateAuthorities(SSLContextRef		ctx,
2036  							  CFArrayRef		*certificates)	/* RETURNED */
2037  {
2038  	if((ctx == NULL) || (certificates == NULL)) {
2039  		return errSecParam;
2040  	}
2041  	if(ctx->acceptableCAs == NULL) {
2042  		*certificates = NULL;
2043  		return errSecSuccess;
2044  	}
2045  	*certificates = ctx->acceptableCAs;
2046  	CFRetain(ctx->acceptableCAs);
2047  	return errSecSuccess;
2048  }
2049  
2050  
2051  /*
2052   * Obtain the list of acceptable distinguished names as provided by
2053   * a server (if the SSLCotextRef is configured as a client), or as
2054   * specified by SSLSetCertificateAuthorities() (if the SSLContextRef
2055   * is configured as a server).
2056    */
2057  OSStatus
2058  SSLCopyDistinguishedNames	(SSLContextRef		ctx,
2059  							 CFArrayRef			*names)
2060  {
2061  	CFMutableArrayRef outArray = NULL;
2062  	const DNListElem *dn;
2063  
2064  	if((ctx == NULL) || (names == NULL)) {
2065  		return errSecParam;
2066  	}
2067      if(ctx->protocolSide==kSSLServerSide) {
2068          dn = ctx->acceptableDNList;
2069      } else {
2070          dn = tls_handshake_get_peer_acceptable_dn_list(ctx->hdsk); // ctx->acceptableDNList;
2071      }
2072  
2073  	if(dn == NULL) {
2074  		*names = NULL;
2075  		return errSecSuccess;
2076  	}
2077  	outArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
2078  
2079  	while (dn) {
2080  		CFDataRef cfDn = CFDataCreate(NULL, dn->derDN.data, dn->derDN.length);
2081  		CFArrayAppendValue(outArray, cfDn);
2082  		CFRelease(cfDn);
2083  		dn = dn->next;
2084  	}
2085  	*names = outArray;
2086  	return errSecSuccess;
2087  }
2088  
2089  
2090  /*
2091   * Request peer certificates. Valid anytime, subsequent to
2092   * a handshake attempt.
2093   */
2094  OSStatus
2095  SSLCopyPeerCertificates	(SSLContextRef ctx, CFArrayRef *certs)
2096  {
2097  	if(ctx == NULL) {
2098  		return errSecParam;
2099  	}
2100  
2101  	if (!ctx->peerSecTrust) {
2102  		*certs = NULL;
2103  		return errSecBadReq;
2104  	}
2105  
2106      CFIndex count = SecTrustGetCertificateCount(ctx->peerSecTrust);
2107      CFMutableArrayRef ca = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks);
2108      if (ca == NULL) {
2109          return errSecAllocate;
2110      }
2111  
2112      for (CFIndex ix = 0; ix < count; ++ix) {
2113          CFArrayAppendValue(ca, SecTrustGetCertificateAtIndex(ctx->peerSecTrust, ix));
2114      }
2115  
2116      *certs = ca;
2117      
2118  	return errSecSuccess;
2119  }
2120  
2121  #if !TARGET_OS_IPHONE
2122  // Permanently removing from iOS, keep for OSX (deprecated), removed from headers.
2123  // <rdar://problem/14215831> Mailsmith Crashes While Getting New Mail Under Mavericks Developer Preview
2124  OSStatus
2125  SSLGetPeerCertificates (SSLContextRef ctx,
2126                          CFArrayRef *certs);
2127  OSStatus
2128  SSLGetPeerCertificates (SSLContextRef ctx,
2129                          CFArrayRef *certs)
2130  {
2131      return errSecUnimplemented;
2132  }
2133  #endif
2134  
2135  /*
2136   * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
2137   * for D-H ciphers and a D-H cipher is negotiated, and this function has not
2138   * been called, a set of process-wide parameters will be calculated. However
2139   * that can take a long time (30 seconds).
2140   */
2141  OSStatus SSLSetDiffieHellmanParams(
2142  	SSLContextRef	ctx,
2143  	const void 		*dhParams,
2144  	size_t			dhParamsLen)
2145  {
2146  #if APPLE_DH
2147  	if(ctx == NULL) {
2148  		return errSecParam;
2149  	}
2150  	if(sslIsSessionActive(ctx)) {
2151  		return errSecBadReq;
2152  	}
2153  	SSLFreeBuffer(&ctx->dhParamsEncoded);
2154  
2155  	OSStatus ortn;
2156  	ortn = SSLCopyBufferFromData(dhParams, dhParamsLen,
2157  		&ctx->dhParamsEncoded);
2158  
2159      if(ortn) {
2160          return ortn;
2161      } else {
2162          return tls_handshake_set_dh_parameters(ctx->hdsk, &ctx->dhParamsEncoded);
2163      }
2164  
2165  #endif /* APPLE_DH */
2166  }
2167  
2168  /*
2169   * Return parameter block specified in SSLSetDiffieHellmanParams.
2170   * Returned data is not copied and belongs to the SSLContextRef.
2171   */
2172  OSStatus SSLGetDiffieHellmanParams(
2173  	SSLContextRef	ctx,
2174  	const void 		**dhParams,
2175  	size_t			*dhParamsLen)
2176  {
2177  #if APPLE_DH
2178  	if(ctx == NULL) {
2179  		return errSecParam;
2180  	}
2181  	*dhParams = ctx->dhParamsEncoded.data;
2182  	*dhParamsLen = ctx->dhParamsEncoded.length;
2183  	return errSecSuccess;
2184  #else
2185      return errSecUnimplemented;
2186  #endif /* APPLE_DH */
2187  }
2188  
2189  OSStatus SSLSetDHEEnabled(SSLContextRef ctx, bool enabled)
2190  {
2191      ctx->dheEnabled = enabled;
2192      /* Hack a little so that only the ciphersuites change */
2193      tls_protocol_version min, max;
2194      unsigned nbits;
2195      tls_handshake_get_min_protocol_version(ctx->hdsk, &min);
2196      tls_handshake_get_max_protocol_version(ctx->hdsk, &max);
2197      tls_handshake_get_min_dh_group_size(ctx->hdsk, &nbits);
2198      tls_handshake_set_config(ctx->hdsk, enabled?tls_handshake_config_legacy_DHE:tls_handshake_config_legacy);
2199      tls_handshake_set_min_protocol_version(ctx->hdsk, min);
2200      tls_handshake_set_max_protocol_version(ctx->hdsk, max);
2201      tls_handshake_set_min_dh_group_size(ctx->hdsk, nbits);
2202  
2203      return noErr;
2204  }
2205  
2206  OSStatus SSLGetDHEEnabled(SSLContextRef ctx, bool *enabled)
2207  {
2208      *enabled = ctx->dheEnabled;
2209      return noErr;
2210  }
2211  
2212  OSStatus SSLSetMinimumDHGroupSize(SSLContextRef ctx, unsigned nbits)
2213  {
2214      return tls_handshake_set_min_dh_group_size(ctx->hdsk, nbits);
2215  }
2216  
2217  OSStatus SSLGetMinimumDHGroupSize(SSLContextRef ctx, unsigned *nbits)
2218  {
2219      return tls_handshake_get_min_dh_group_size(ctx->hdsk, nbits);
2220  }
2221  
2222  OSStatus SSLSetRsaBlinding(
2223  	SSLContextRef	ctx,
2224  	Boolean			blinding)
2225  {
2226  	if(ctx == NULL) {
2227  		return errSecParam;
2228  	}
2229  	ctx->rsaBlindingEnable = blinding;
2230  	return errSecSuccess;
2231  }
2232  
2233  OSStatus SSLGetRsaBlinding(
2234  	SSLContextRef	ctx,
2235  	Boolean			*blinding)
2236  {
2237  	if(ctx == NULL) {
2238  		return errSecParam;
2239  	}
2240  	*blinding = ctx->rsaBlindingEnable;
2241  	return errSecSuccess;
2242  }
2243  
2244  OSStatus
2245  SSLCopyPeerTrust(
2246      SSLContextRef 		ctx,
2247      SecTrustRef        *trust)	/* RETURNED */
2248  {
2249      OSStatus status = errSecSuccess;
2250      if (ctx == NULL || trust == NULL) {
2251          return errSecParam;
2252      }
2253  
2254      /* Create a SecTrustRef if this was a resumed session and we
2255       didn't have one yet. */
2256      if (!ctx->peerSecTrust) {
2257          status = sslCreateSecTrust(ctx, &ctx->peerSecTrust);
2258      }
2259  
2260      *trust = ctx->peerSecTrust;
2261      if (ctx->peerSecTrust) {
2262          CFRetain(ctx->peerSecTrust);
2263      }
2264  
2265      return status;
2266  }
2267  
2268  OSStatus SSLGetPeerSecTrust(
2269  	SSLContextRef	ctx,
2270  	SecTrustRef		*trust)	/* RETURNED */
2271  {
2272      OSStatus status = errSecSuccess;
2273  	if (ctx == NULL || trust == NULL)
2274  		return errSecParam;
2275  
2276  	/* Create a SecTrustRef if this was a resumed session and we
2277  	   didn't have one yet. */
2278  	if (!ctx->peerSecTrust) {
2279  		status = sslCreateSecTrust(ctx, &ctx->peerSecTrust);
2280      }
2281  
2282  	*trust = ctx->peerSecTrust;
2283  	return status;
2284  }
2285  
2286  OSStatus SSLInternalMasterSecret(
2287     SSLContextRef ctx,
2288     void *secret,        // mallocd by caller, SSL_MASTER_SECRET_SIZE
2289     size_t *secretSize)  // in/out
2290  {
2291  	if((ctx == NULL) || (secret == NULL) || (secretSize == NULL)) {
2292  		return errSecParam;
2293  	}
2294      return tls_handshake_internal_master_secret(ctx->hdsk, secret, secretSize);
2295  }
2296  
2297  OSStatus SSLInternalServerRandom(
2298     SSLContextRef ctx,
2299     void *randBuf, 			// mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2300     size_t *randSize)	// in/out
2301  {
2302  	if((ctx == NULL) || (randBuf == NULL) || (randSize == NULL)) {
2303  		return errSecParam;
2304  	}
2305      return tls_handshake_internal_server_random(ctx->hdsk, randBuf, randSize);
2306  }
2307  
2308  OSStatus SSLInternalClientRandom(
2309     SSLContextRef ctx,
2310     void *randBuf,  		// mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
2311     size_t *randSize)	// in/out
2312  {
2313  	if((ctx == NULL) || (randBuf == NULL) || (randSize == NULL)) {
2314  		return errSecParam;
2315  	}
2316      return tls_handshake_internal_client_random(ctx->hdsk, randBuf, randSize);
2317  }
2318  
2319  /* This is used by EAP 802.1x */
2320  OSStatus SSLGetCipherSizes(
2321  	SSLContextRef ctx,
2322  	size_t *digestSize,
2323  	size_t *symmetricKeySize,
2324  	size_t *ivSize)
2325  {
2326  	if((ctx == NULL) || (digestSize == NULL) ||
2327  	   (symmetricKeySize == NULL) || (ivSize == NULL)) {
2328  		return errSecParam;
2329  	}
2330  
2331      SSLCipherSuite cipher=tls_handshake_get_negotiated_cipherspec(ctx->hdsk);
2332  
2333  	*digestSize = sslCipherSuiteGetMacSize(cipher);
2334  	*symmetricKeySize = sslCipherSuiteGetSymmetricCipherKeySize(cipher);
2335  	*ivSize = sslCipherSuiteGetSymmetricCipherBlockIvSize(cipher);
2336  	return errSecSuccess;
2337  }
2338  
2339  OSStatus
2340  SSLGetResumableSessionInfo(
2341  	SSLContextRef	ctx,
2342  	Boolean			*sessionWasResumed,		// RETURNED
2343  	void			*sessionID,				// RETURNED, mallocd by caller
2344  	size_t			*sessionIDLength)		// IN/OUT
2345  {
2346  	if((ctx == NULL) || (sessionWasResumed == NULL) ||
2347  	   (sessionID == NULL) || (sessionIDLength == NULL) ||
2348  	   (*sessionIDLength < MAX_SESSION_ID_LENGTH)) {
2349  		return errSecParam;
2350  	}
2351  
2352      SSLBuffer localSessionID;
2353      bool sessionMatch = tls_handshake_get_session_match(ctx->hdsk, &localSessionID);
2354  
2355  	if(sessionMatch) {
2356  		*sessionWasResumed = true;
2357  		if(localSessionID.length > *sessionIDLength) {
2358  			/* really should never happen - means ID > 32 */
2359  			return errSecParam;
2360  		}
2361  		if(localSessionID.length) {
2362  			/*
2363   			 * Note PAC-based session resumption can result in sessionMatch
2364  			 * with no sessionID
2365  			 */
2366  			memmove(sessionID, localSessionID.data, localSessionID.length);
2367  		}
2368  		*sessionIDLength = localSessionID.length;
2369  	}
2370  	else {
2371  		*sessionWasResumed = false;
2372  		*sessionIDLength = 0;
2373  	}
2374  	return errSecSuccess;
2375  }
2376  
2377  /*
2378   * Get/set enable of anonymous ciphers. This is deprecated and now a no-op.
2379   */
2380  OSStatus
2381  SSLSetAllowAnonymousCiphers(
2382  	SSLContextRef	ctx,
2383  	Boolean			enable)
2384  {
2385      return errSecSuccess;
2386  }
2387  
2388  OSStatus
2389  SSLGetAllowAnonymousCiphers(
2390  	SSLContextRef	ctx,
2391  	Boolean			*enable)
2392  {
2393      return errSecSuccess;
2394  }
2395  
2396  /*
2397   * Override the default session cache timeout for a cache entry created for
2398   * the current session.
2399   */
2400  OSStatus
2401  SSLSetSessionCacheTimeout(
2402  	SSLContextRef ctx,
2403  	uint32_t timeoutInSeconds)
2404  {
2405  	if(ctx == NULL) {
2406  		return errSecParam;
2407  	}
2408  	ctx->sessionCacheTimeout = timeoutInSeconds;
2409  	return errSecSuccess;
2410  }
2411  
2412  
2413  static
2414  void tls_handshake_master_secret_function(const void *arg,         /* opaque to coreTLS; app-specific */
2415                                            void *secret,			/* mallocd by caller, SSL_MASTER_SECRET_SIZE */
2416                                            size_t *secretLength)
2417  {
2418      SSLContextRef ctx = (SSLContextRef) arg;
2419      ctx->masterSecretCallback(ctx, ctx->masterSecretArg, secret, secretLength);
2420  }
2421  
2422  
2423  /*
2424   * Register a callback for obtaining the master_secret when performing
2425   * PAC-based session resumption.
2426   */
2427  OSStatus
2428  SSLInternalSetMasterSecretFunction(
2429  	SSLContextRef ctx,
2430  	SSLInternalMasterSecretFunction mFunc,
2431  	const void *arg)		/* opaque to SecureTransport; app-specific */
2432  {
2433  	if(ctx == NULL) {
2434  		return errSecParam;
2435  	}
2436  
2437      ctx->masterSecretArg = arg;
2438      ctx->masterSecretCallback = mFunc;
2439  
2440      return tls_handshake_internal_set_master_secret_function(ctx->hdsk, &tls_handshake_master_secret_function, ctx);
2441  }
2442  
2443  /*
2444   * Provide an opaque SessionTicket for use in PAC-based session
2445   * resumption. Client side only. The provided ticket is sent in
2446   * the ClientHello message as a SessionTicket extension.
2447   *
2448   * We won't reject this on the server side, but server-side support
2449   * for PAC-based session resumption is currently enabled for
2450   * Development builds only. To fully support this for server side,
2451   * besides the rudimentary support that's here for Development builds,
2452   * we'd need a getter for the session ticket, so the app code can
2453   * access the SessionTicket when its SSLInternalMasterSecretFunction
2454   * callback is called.
2455   */
2456  OSStatus SSLInternalSetSessionTicket(
2457     SSLContextRef ctx,
2458     const void *ticket,
2459     size_t ticketLength)
2460  {
2461  	if(ctx == NULL) {
2462  		return errSecParam;
2463  	}
2464  	if(sslIsSessionActive(ctx)) {
2465  		/* can't do this with an active session */
2466  		return errSecBadReq;
2467  	}
2468      return tls_handshake_internal_set_session_ticket(ctx->hdsk, ticket, ticketLength);
2469  }
2470  
2471  
2472  /*
2473   * ECDSA curve accessors.
2474   */
2475  
2476  /*
2477   * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
2478   * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
2479   */
2480  OSStatus SSLGetNegotiatedCurve(
2481     SSLContextRef ctx,
2482     SSL_ECDSA_NamedCurve *namedCurve)    /* RETURNED */
2483  {
2484  	if((ctx == NULL) || (namedCurve == NULL)) {
2485  		return errSecParam;
2486  	}
2487      unsigned int curve = tls_handshake_get_negotiated_curve(ctx->hdsk);
2488      if(curve == SSL_Curve_None) {
2489  		return errSecParam;
2490  	}
2491  	*namedCurve = curve;
2492  	return errSecSuccess;
2493  }
2494  
2495  /*
2496   * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
2497   */
2498  OSStatus SSLGetNumberOfECDSACurves(
2499     SSLContextRef ctx,
2500     unsigned *numCurves)	/* RETURNED */
2501  {
2502  	if((ctx == NULL) || (numCurves == NULL)) {
2503  		return errSecParam;
2504  	}
2505  	*numCurves = ctx->ecdhNumCurves;
2506  	return errSecSuccess;
2507  }
2508  
2509  /*
2510   * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
2511   */
2512  OSStatus SSLGetECDSACurves(
2513     SSLContextRef ctx,
2514     SSL_ECDSA_NamedCurve *namedCurves,		/* RETURNED */
2515     unsigned *numCurves)						/* IN/OUT */
2516  {
2517  	if((ctx == NULL) || (namedCurves == NULL) || (numCurves == NULL)) {
2518  		return errSecParam;
2519  	}
2520  	if(*numCurves < ctx->ecdhNumCurves) {
2521  		return errSecParam;
2522  	}
2523  	static_assert(sizeof(*namedCurves) >= sizeof(*(ctx->ecdhCurves)),
2524  		"SSL_ECDSA_NamedCurve must be large enough for SSLContext ecdhCurves.");
2525  	for (unsigned i = 0; i < ctx->ecdhNumCurves; i++) {
2526  		namedCurves[i] = ctx->ecdhCurves[i];
2527  	}
2528  	*numCurves = ctx->ecdhNumCurves;
2529  	return errSecSuccess;
2530  }
2531  
2532  /*
2533   * Specify ordered list of allowable named curves.
2534   */
2535  OSStatus SSLSetECDSACurves(
2536     SSLContextRef ctx,
2537     const SSL_ECDSA_NamedCurve *namedCurves,
2538     unsigned numCurves)
2539  {
2540  	if((ctx == NULL) || (namedCurves == NULL) || (numCurves == 0)) {
2541  		return errSecParam;
2542  	}
2543  	if(sslIsSessionActive(ctx)) {
2544  		/* can't do this with an active session */
2545  		return errSecBadReq;
2546  	}
2547  
2548  	if (SIZE_MAX / sizeof(*(ctx->ecdhCurves)) < (size_t)numCurves) {
2549  		return errSecParam;
2550  	}
2551  	ctx->ecdhCurves = sslMalloc((size_t)numCurves * sizeof(*(ctx->ecdhCurves)));
2552  	if(ctx->ecdhCurves == NULL) {
2553  		ctx->ecdhNumCurves = 0;
2554  		return errSecAllocate;
2555  	}
2556  
2557  	for (unsigned i=0; i<numCurves; i++) {
2558  		if (namedCurves[i] > UINT16_MAX - 1) {
2559  			ctx->ecdhCurves[i] = SSL_Curve_None;
2560  			continue;
2561  		}
2562  		ctx->ecdhCurves[i] = namedCurves[i];
2563  	}
2564  
2565  	ctx->ecdhNumCurves = numCurves;
2566  
2567  	tls_handshake_set_curves(ctx->hdsk, ctx->ecdhCurves, ctx->ecdhNumCurves);
2568  	return errSecSuccess;
2569  }
2570  
2571  /*
2572   * Obtain the number of client authentication mechanisms specified by
2573   * the server in its Certificate Request message.
2574   * Returns errSecParam if server hasn't sent a Certificate Request message
2575   * (i.e., client certificate state is kSSLClientCertNone).
2576   */
2577  OSStatus SSLGetNumberOfClientAuthTypes(
2578  	SSLContextRef ctx,
2579  	unsigned *numTypes)
2580  {
2581  	if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
2582  		return errSecParam;
2583  	}
2584  	*numTypes = ctx->numAuthTypes;
2585  	return errSecSuccess;
2586  }
2587  
2588  /*
2589   * Obtain the client authentication mechanisms specified by
2590   * the server in its Certificate Request message.
2591   * Caller allocates returned array and specifies its size (in
2592   * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
2593   * is the actual size of the returned array on successful return.
2594   */
2595  OSStatus SSLGetClientAuthTypes(
2596     SSLContextRef ctx,
2597     SSLClientAuthenticationType *authTypes,		/* RETURNED */
2598     unsigned *numTypes)							/* IN/OUT */
2599  {
2600  	if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
2601  		return errSecParam;
2602  	}
2603  	memmove(authTypes, ctx->clientAuthTypes,
2604  		ctx->numAuthTypes * sizeof(SSLClientAuthenticationType));
2605  	*numTypes = ctx->numAuthTypes;
2606  	return errSecSuccess;
2607  }
2608  
2609  /*
2610   * -- DEPRECATED -- Return errSecUnimplemented.
2611   */
2612  OSStatus SSLGetNegotiatedClientAuthType(
2613     SSLContextRef ctx,
2614     SSLClientAuthenticationType *authType)		/* RETURNED */
2615  {
2616      return errSecUnimplemented;
2617  }
2618  
2619  OSStatus SSLGetNumberOfSignatureAlgorithms(
2620      SSLContextRef ctx,
2621      unsigned *numSigAlgs)
2622  {
2623  	if(ctx == NULL){
2624  		return errSecParam;
2625  	}
2626  
2627      tls_handshake_get_peer_signature_algorithms(ctx->hdsk, numSigAlgs);
2628  	return errSecSuccess;
2629  }
2630  
2631  _Static_assert(sizeof(SSLSignatureAndHashAlgorithm)==sizeof(tls_signature_and_hash_algorithm),
2632                 "SSLSignatureAndHashAlgorithm and tls_signature_and_hash_algorithm do not match");
2633  
2634  OSStatus SSLGetSignatureAlgorithms(
2635      SSLContextRef ctx,
2636      SSLSignatureAndHashAlgorithm *sigAlgs,		/* RETURNED */
2637      unsigned *numSigAlgs)							/* IN/OUT */
2638  {
2639  	if(ctx == NULL) {
2640  		return errSecParam;
2641  	}
2642  
2643      unsigned numPeerSigAlgs;
2644      const tls_signature_and_hash_algorithm *peerAlgs = tls_handshake_get_peer_signature_algorithms(ctx->hdsk, &numPeerSigAlgs);
2645  
2646  	memmove(sigAlgs, peerAlgs,
2647              numPeerSigAlgs * sizeof(SSLSignatureAndHashAlgorithm));
2648  	*numSigAlgs = numPeerSigAlgs;
2649      return errSecSuccess;
2650  }
2651  
2652  /* PSK SPIs */
2653  OSStatus SSLSetPSKSharedSecret(SSLContextRef ctx,
2654                                 const void *secret,
2655                                 size_t secretLen)
2656  {
2657      if(ctx == NULL) return errSecParam;
2658  
2659      if(ctx->pskSharedSecret.data)
2660          SSLFreeBuffer(&ctx->pskSharedSecret);
2661  
2662      if(SSLCopyBufferFromData(secret, secretLen, &ctx->pskSharedSecret))
2663          return errSecAllocate;
2664  
2665      tls_handshake_set_psk_secret(ctx->hdsk, &ctx->pskSharedSecret);
2666  
2667      return errSecSuccess;
2668  }
2669  
2670  OSStatus SSLSetPSKIdentity(SSLContextRef ctx,
2671                             const void *pskIdentity,
2672                             size_t pskIdentityLen)
2673  {
2674      if((ctx == NULL) || (pskIdentity == NULL) || (pskIdentityLen == 0)) return errSecParam;
2675  
2676      if(ctx->pskIdentity.data)
2677          SSLFreeBuffer(&ctx->pskIdentity);
2678  
2679      if(SSLCopyBufferFromData(pskIdentity, pskIdentityLen, &ctx->pskIdentity))
2680          return errSecAllocate;
2681  
2682      tls_handshake_set_psk_identity(ctx->hdsk, &ctx->pskIdentity);
2683  
2684      return errSecSuccess;
2685  
2686  }
2687  
2688  OSStatus SSLGetPSKIdentity(SSLContextRef ctx,
2689                             const void **pskIdentity,
2690                             size_t *pskIdentityLen)
2691  {
2692      if((ctx == NULL) || (pskIdentity == NULL) || (pskIdentityLen == NULL)) return errSecParam;
2693  
2694      *pskIdentity=ctx->pskIdentity.data;
2695      *pskIdentityLen=ctx->pskIdentity.length;
2696  
2697      return errSecSuccess;
2698  }
2699  
2700  OSStatus SSLInternal_PRF(
2701                           SSLContext *ctx,
2702                           const void *vsecret,
2703                           size_t secretLen,
2704                           const void *label,			// optional, NULL implies that seed contains
2705                           //   the label
2706                           size_t labelLen,
2707                           const void *seed,
2708                           size_t seedLen,
2709                           void *vout,					// mallocd by caller, length >= outLen
2710                           size_t outLen)
2711  {
2712      return tls_handshake_internal_prf(ctx->hdsk,
2713                                        vsecret, secretLen,
2714                                        label, labelLen,
2715                                        seed, seedLen,
2716                                        vout, outLen);
2717  }
2718  
2719  const CFStringRef kSSLSessionConfig_default = CFSTR("default");
2720  const CFStringRef kSSLSessionConfig_ATSv1 = CFSTR("ATSv1");
2721  const CFStringRef kSSLSessionConfig_ATSv1_noPFS = CFSTR("ATSv1_noPFS");
2722  const CFStringRef kSSLSessionConfig_legacy = CFSTR("legacy");
2723  const CFStringRef kSSLSessionConfig_standard = CFSTR("standard");
2724  const CFStringRef kSSLSessionConfig_RC4_fallback = CFSTR("RC4_fallback");
2725  const CFStringRef kSSLSessionConfig_TLSv1_fallback = CFSTR("TLSv1_fallback");
2726  const CFStringRef kSSLSessionConfig_TLSv1_RC4_fallback = CFSTR("TLSv1_RC4_fallback");
2727  const CFStringRef kSSLSessionConfig_legacy_DHE = CFSTR("legacy_DHE");
2728  const CFStringRef kSSLSessionConfig_anonymous = CFSTR("anonymous");
2729  const CFStringRef kSSLSessionConfig_3DES_fallback = CFSTR("3DES_fallback");
2730  const CFStringRef kSSLSessionConfig_TLSv1_3DES_fallback = CFSTR("TLSv1_3DES_fallback");
2731  
2732  
2733  static
2734  tls_handshake_config_t SSLSessionConfig_to_tls_handshake_config(CFStringRef config)
2735  {
2736      if(CFEqual(config, kSSLSessionConfig_ATSv1)){
2737          return tls_handshake_config_ATSv1;
2738      } else if(CFEqual(config, kSSLSessionConfig_ATSv1_noPFS)){
2739          return tls_handshake_config_ATSv1_noPFS;
2740      } else if(CFEqual(config, kSSLSessionConfig_standard)){
2741          return tls_handshake_config_standard;
2742      } else if(CFEqual(config, kSSLSessionConfig_TLSv1_fallback)){
2743          return tls_handshake_config_TLSv1_fallback;
2744      } else if(CFEqual(config, kSSLSessionConfig_TLSv1_RC4_fallback)){
2745          return tls_handshake_config_TLSv1_RC4_fallback;
2746      } else if(CFEqual(config, kSSLSessionConfig_RC4_fallback)){
2747          return tls_handshake_config_RC4_fallback;
2748      } else if(CFEqual(config, kSSLSessionConfig_3DES_fallback)){
2749          return tls_handshake_config_3DES_fallback;
2750      } else if(CFEqual(config, kSSLSessionConfig_TLSv1_3DES_fallback)){
2751          return tls_handshake_config_TLSv1_3DES_fallback;
2752      } else if(CFEqual(config, kSSLSessionConfig_legacy)){
2753          return tls_handshake_config_legacy;
2754      } else if(CFEqual(config, kSSLSessionConfig_legacy_DHE)){
2755          return tls_handshake_config_legacy_DHE;
2756      } else if(CFEqual(config, kSSLSessionConfig_anonymous)){
2757          return tls_handshake_config_anonymous;
2758      } else if(CFEqual(config, kSSLSessionConfig_default)){
2759          return tls_handshake_config_default;
2760      } else {
2761          return tls_handshake_config_none;
2762      }
2763  }
2764  
2765  /* Set Predefined TLS Configuration */
2766  OSStatus
2767  SSLSetSessionConfig(SSLContextRef context,
2768                      CFStringRef config)
2769  {
2770      tls_handshake_config_t cfg = SSLSessionConfig_to_tls_handshake_config(config);
2771      if(cfg>=0) {
2772          return tls_handshake_set_config(context->hdsk, cfg);
2773      } else {
2774          return errSecParam;
2775      }
2776  }
2777  
2778  OSStatus
2779  SSLGetSessionConfigurationIdentifier(SSLContext *ctx, SSLBuffer *buffer)
2780  {
2781      if (buffer == NULL) {
2782          return errSecParam;
2783      }
2784  
2785      // Don't recompute the buffer if we've done it before and cached the result.
2786      // Just copy out the result.
2787      if (ctx->contextConfigurationBuffer.data != NULL) {
2788          buffer->length = ctx->contextConfigurationBuffer.length;
2789          buffer->data = (uint8_t *) malloc(buffer->length);
2790          if (buffer->data == NULL) {
2791              return errSecAllocate;
2792          }
2793          memcpy(buffer->data, ctx->contextConfigurationBuffer.data, buffer->length);
2794          return errSecSuccess;
2795      }
2796  
2797      // Allocate the buffer, freeing up any data that was previously stored
2798      // 10 here is the number of attributes we're adding below. Change it as needed.
2799      buffer->length = 10 * sizeof(Boolean);
2800      if (buffer->data) {
2801          free(buffer->data);
2802      }
2803      buffer->data = malloc(buffer->length);
2804      if (buffer->data == NULL) {
2805          return errSecAllocate;
2806      }
2807  
2808      // Copy in the session configuration options
2809      int offset = 0;
2810      memcpy(buffer->data + offset, &ctx->breakOnServerAuth, sizeof(ctx->breakOnServerAuth));
2811      offset += sizeof(ctx->breakOnServerAuth);
2812  
2813      memcpy(buffer->data + offset, &ctx->breakOnCertRequest, sizeof(ctx->breakOnCertRequest));
2814      offset += sizeof(ctx->breakOnCertRequest);
2815  
2816      memcpy(buffer->data + offset, &ctx->breakOnClientAuth, sizeof(ctx->breakOnClientAuth));
2817      offset += sizeof(ctx->breakOnClientAuth);
2818  
2819      memcpy(buffer->data + offset, &ctx->signalServerAuth, sizeof(ctx->signalServerAuth));
2820      offset += sizeof(ctx->signalServerAuth);
2821  
2822      memcpy(buffer->data + offset, &ctx->signalCertRequest, sizeof(ctx->signalCertRequest));
2823      offset += sizeof(ctx->signalCertRequest);
2824  
2825      memcpy(buffer->data + offset, &ctx->signalClientAuth, sizeof(ctx->signalClientAuth));
2826      offset += sizeof(ctx->signalClientAuth);
2827  
2828      memcpy(buffer->data + offset, &ctx->breakOnClientHello, sizeof(ctx->breakOnClientHello));
2829      offset += sizeof(ctx->breakOnClientHello);
2830  
2831      memcpy(buffer->data + offset, &ctx->allowServerIdentityChange, sizeof(ctx->allowServerIdentityChange));
2832      offset += sizeof(ctx->allowServerIdentityChange);
2833  
2834      memcpy(buffer->data + offset, &ctx->allowRenegotiation, sizeof(ctx->allowRenegotiation));
2835      offset += sizeof(ctx->allowRenegotiation);
2836  
2837      memcpy(buffer->data + offset, &ctx->enableSessionTickets, sizeof(ctx->enableSessionTickets));
2838      offset += sizeof(ctx->enableSessionTickets);
2839  
2840      // Sanity check on the length
2841      if (offset != buffer->length) {
2842          free(buffer->data);
2843          return errSecInternal;
2844      }
2845  
2846      // Save the configuration buffer for later use
2847      ctx->contextConfigurationBuffer.length = buffer->length;
2848      ctx->contextConfigurationBuffer.data = (uint8_t *) malloc(buffer->length);
2849      memcpy(ctx->contextConfigurationBuffer.data, buffer->data, buffer->length);
2850  
2851      return errSecSuccess;
2852  }