]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_ssl/lib/sslContext.c
Security-57336.1.9.tar.gz
[apple/security.git] / Security / libsecurity_ssl / lib / sslContext.c
diff --git a/Security/libsecurity_ssl/lib/sslContext.c b/Security/libsecurity_ssl/lib/sslContext.c
deleted file mode 100644 (file)
index a0f35ae..0000000
+++ /dev/null
@@ -1,2576 +0,0 @@
-/*
- * Copyright (c) 1999-2001,2005-2014 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * sslContext.c - SSLContext accessors
- */
-
-#include "SecureTransport.h"
-
-#include "SSLRecordInternal.h"
-#include "SecureTransportPriv.h"
-#include "appleSession.h"
-#include "ssl.h"
-#include "sslCipherSpecs.h"
-#include "sslContext.h"
-#include "sslCrypto.h"
-#include "sslDebug.h"
-#include "sslDigests.h"
-#include "sslKeychain.h"
-#include "sslMemory.h"
-#include "sslUtils.h"
-
-#include "tlsCallbacks.h"
-
-#include <AssertMacros.h>
-#include <CoreFoundation/CFData.h>
-#include <CoreFoundation/CFPreferences.h>
-#include <Security/SecCertificate.h>
-#include <Security/SecCertificatePriv.h>
-#include <Security/SecTrust.h>
-#include <Security/SecTrustSettingsPriv.h>
-#include <Security/oidsalg.h>
-#include "utilities/SecCFRelease.h"
-#include "utilities/SecCFWrappers.h"
-#include <pthread.h>
-#include <string.h>
-
-#if TARGET_OS_IPHONE
-#include <Security/SecCertificateInternal.h>
-#else
-#include <Security/oidsalg.h>
-#include <Security/oidscert.h>
-#include <Security/SecTrustSettingsPriv.h>
-#endif
-
-
-static void sslFreeDnList(
-       SSLContext *ctx)
-{
-    DNListElem      *dn, *nextDN;
-
-    dn = ctx->acceptableDNList;
-    while (dn)
-    {   
-        SSLFreeBuffer(&dn->derDN);
-        nextDN = dn->next;
-        sslFree(dn);
-        dn = nextDN;
-    }
-    ctx->acceptableDNList = NULL;
-}
-
-
-Boolean sslIsSessionActive(const SSLContext *ctx)
-{
-       assert(ctx != NULL);
-
-
-       switch(ctx->state) {
-               case SSL_HdskStateUninit:
-               case SSL_HdskStateGracefulClose:
-               case SSL_HdskStateErrorClose:
-                       return false;
-               default:
-                       return true;
-       }
-
-}
-
-/*
- * Minimum and maximum supported versions
- */
-//#define MINIMUM_STREAM_VERSION  SSL_Version_2_0 /* Disabled */
-#define MINIMUM_STREAM_VERSION  SSL_Version_3_0
-#define MAXIMUM_STREAM_VERSION  TLS_Version_1_2
-#define MINIMUM_DATAGRAM_VERSION  DTLS_Version_1_0
-
-/* This should be changed when we start supporting DTLS_Version_1_x */
-#define MAXIMUM_DATAGRAM_VERSION  DTLS_Version_1_0
-
-#define SSL_ENABLE_ECDSA_SIGN_AUTH                     0
-#define SSL_ENABLE_RSA_FIXED_ECDH_AUTH         0
-#define SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH       0
-
-#define DEFAULT_DTLS_TIMEOUT    1
-#define DEFAULT_DTLS_MTU        1400
-#define MIN_ALLOWED_DTLS_MTU    64      /* this ensure than there will be no integer
-                                            underflow when calculating max write size */
-
-int kSplitDefaultValue;
-CFIndex kMinDhGroupSizeDefaultValue;
-
-#if TARGET_OS_IPHONE
-/*
- * Instead of using CFPropertyListReadFromFile we use a
- * CFPropertyListCreateWithStream directly
- * here. CFPropertyListReadFromFile() uses
- * CFURLCopyResourcePropertyForKey() andCF pulls in CoreServices for
- * CFURLCopyResourcePropertyForKey() and that doesn't work in install
- * enviroment.
- */
-static CFPropertyListRef
-CopyPlistFromFile(CFURLRef url)
-{
-    CFDictionaryRef d = NULL;
-    CFReadStreamRef s = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
-    if (s && CFReadStreamOpen(s)) {
-        d = (CFDictionaryRef)CFPropertyListCreateWithStream(kCFAllocatorDefault, s, 0, kCFPropertyListImmutable, NULL, NULL);
-    }
-    CFReleaseSafe(s);
-
-    return d;
-}
-#endif
-
-static void _SSLContextReadDefault()
-{
-       /* 0 = disabled, 1 = split every write, 2 = split second and subsequent writes */
-    /* Enabled by default, this may cause some interop issues, see <rdar://problem/12307662> and <rdar://problem/12323307> */
-    const int defaultSplitDefaultValue = 2;
-
-       CFTypeRef value = (CFTypeRef)CFPreferencesCopyValue(CFSTR("SSLWriteSplit"),
-                                                       CFSTR("com.apple.security"),
-                                                       kCFPreferencesAnyUser,
-                                                       kCFPreferencesCurrentHost);
-       if (value) {
-               if (CFGetTypeID(value) == CFBooleanGetTypeID())
-                       kSplitDefaultValue = CFBooleanGetValue((CFBooleanRef)value) ? 1 : 0;
-               else if (CFGetTypeID(value) == CFNumberGetTypeID()) {
-                       if (!CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &kSplitDefaultValue))
-                               kSplitDefaultValue = defaultSplitDefaultValue;
-               }
-               if (kSplitDefaultValue < 0 || kSplitDefaultValue > 2) {
-                       kSplitDefaultValue = defaultSplitDefaultValue;
-               }
-               CFRelease(value);
-       }
-       else {
-               kSplitDefaultValue = defaultSplitDefaultValue;
-       }
-
-    /* Min DH Group Size */
-    kMinDhGroupSizeDefaultValue = CFPreferencesGetAppIntegerValue(CFSTR("SSLMinDhGroupSize"), kCFPreferencesCurrentApplication, NULL);
-
-#if TARGET_OS_IPHONE
-    /* on iOS, if the above returned nothing, we manually look into mobile's Managed Preferences */
-    /* Note that if the process is running as mobile, the above call will already have read the Managed Preference plist.
-       As a result, if you have some preferences set manually with defaults, which preference applies may be different for mobile vs not-mobile. */
-    if(kMinDhGroupSizeDefaultValue == 0) {
-        CFURLRef prefURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/Library/Managed Preferences/mobile/.GlobalPreferences.plist"), kCFURLPOSIXPathStyle, false);
-        if(prefURL) {
-            CFPropertyListRef plist = CopyPlistFromFile(prefURL);
-            if (plist) {
-                value =  CFDictionaryGetValue(plist, CFSTR("SSLMinDhGroupSize"));
-                if (isNumber(value)) {
-                    CFNumberGetValue(value, kCFNumberCFIndexType, &kMinDhGroupSizeDefaultValue);
-                }
-            }
-            CFReleaseSafe(plist);
-        }
-        CFReleaseSafe(prefURL);
-    }
-#endif
-}
-
-CFGiblisWithHashFor(SSLContext)
-
-OSStatus
-SSLNewContext                          (Boolean                        isServer,
-                                                        SSLContextRef          *contextPtr)    /* RETURNED */
-{
-       if(contextPtr == NULL) {
-               return errSecParam;
-       }
-
-       *contextPtr = SSLCreateContext(kCFAllocatorDefault, isServer?kSSLServerSide:kSSLClientSide, kSSLStreamType);
-
-       if (*contextPtr == NULL)
-               return errSecAllocate;
-
-       return errSecSuccess;
-}
-
-SSLContextRef SSLCreateContext(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType)
-{
-    SSLContextRef ctx;
-    SSLRecordContextRef recCtx;
-    
-    ctx = SSLCreateContextWithRecordFuncs(alloc, protocolSide, connectionType, &SSLRecordLayerInternal);
-
-    if(ctx==NULL)
-        return NULL;
-
-    recCtx = SSLCreateInternalRecordLayer(connectionType);
-    if(recCtx==NULL) {
-       CFRelease(ctx);
-               return NULL;
-    }
-
-    SSLSetRecordContext(ctx, recCtx);
-
-    return ctx;
-}
-
-SSLContextRef SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType, const struct SSLRecordFuncs *recFuncs)
-{
-       OSStatus        serr = errSecSuccess;
-       SSLContext *ctx = (SSLContext*) _CFRuntimeCreateInstance(alloc, SSLContextGetTypeID(), sizeof(SSLContext) - sizeof(CFRuntimeBase), NULL);
-
-       if(ctx == NULL) {
-               return NULL;
-       }
-
-       /* subsequent errors to errOut: */
-    memset(((uint8_t*) ctx) + sizeof(CFRuntimeBase), 0, sizeof(SSLContext) - sizeof(CFRuntimeBase));
-
-
-    ctx->hdsk = tls_handshake_create(connectionType==kSSLDatagramType, protocolSide==kSSLServerSide);
-
-
-    tls_handshake_set_callbacks(ctx->hdsk,
-                                &tls_handshake_callbacks,
-                                ctx);
-
-    ctx->isDTLS = (connectionType==kSSLDatagramType);
-
-    ctx->state = SSL_HdskStateUninit;
-    ctx->timeout_duration = DEFAULT_DTLS_TIMEOUT;
-    ctx->mtu = DEFAULT_DTLS_MTU;
-
-    if(ctx->isDTLS) {
-        ctx->minProtocolVersion = MINIMUM_DATAGRAM_VERSION;
-        ctx->maxProtocolVersion = MAXIMUM_DATAGRAM_VERSION;
-    } else {
-        ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
-        ctx->maxProtocolVersion = MAXIMUM_STREAM_VERSION;
-    }
-    tls_handshake_set_min_protocol_version(ctx->hdsk, ctx->minProtocolVersion);
-    tls_handshake_set_max_protocol_version(ctx->hdsk, ctx->maxProtocolVersion);
-
-       ctx->negProtocolVersion = SSL_Version_Undetermined;
-    ctx->protocolSide = protocolSide;
-    ctx->recFuncs = recFuncs;
-
-       /* Initial cert verify state: verify with default system roots */
-       ctx->enableCertVerify = true;
-
-       /* Default for RSA blinding is ENABLED */
-       ctx->rsaBlindingEnable = true;
-
-       /* Default for sending one-byte app data record is DISABLED */
-       ctx->oneByteRecordEnable = false;
-
-    /* Dont enable fallback behavior by default */
-    ctx->fallbackEnabled = false;
-
-       /* Consult global system preference for default behavior:
-        * 0 = disabled, 1 = split every write, 2 = split second and subsequent writes
-        * (caller can override by setting kSSLSessionOptionSendOneByteRecord)
-        */
-       static pthread_once_t sReadDefault = PTHREAD_ONCE_INIT;
-       pthread_once(&sReadDefault, _SSLContextReadDefault);
-    if (kSplitDefaultValue > 0) {
-               ctx->oneByteRecordEnable = true;
-    }
-
-    if(kMinDhGroupSizeDefaultValue) {
-        tls_handshake_set_min_dh_group_size(ctx->hdsk, (unsigned)kMinDhGroupSizeDefaultValue);
-    }
-
-       /* default for anonymous ciphers is DISABLED */
-       ctx->anonCipherEnable = false;
-
-    ctx->breakOnServerAuth = false;
-    ctx->breakOnCertRequest = false;
-    ctx->breakOnClientAuth = false;
-    ctx->signalServerAuth = false;
-    ctx->signalCertRequest = false;
-    ctx->signalClientAuth = false;
-
-       ctx->negAuthType = SSLClientAuthNone;           /* ditto */
-
-       if (serr != errSecSuccess) {
-               CFRelease(ctx);
-               ctx = NULL;
-    }
-       return ctx;
-}
-
-OSStatus
-SSLNewDatagramContext       (Boolean                   isServer,
-                                                        SSLContextRef          *contextPtr)    /* RETURNED */
-{
-       if (contextPtr == NULL)
-               return errSecParam;
-       *contextPtr = SSLCreateContext(kCFAllocatorDefault, isServer?kSSLServerSide:kSSLClientSide, kSSLDatagramType);
-       if (*contextPtr == NULL)
-               return errSecAllocate;
-    return errSecSuccess;
-}
-
-/*
- * Dispose of an SSLContext. (private)
- * This function is invoked after our dispatch queue is safely released,
- * or directly from SSLDisposeContext if there is no dispatch queue.
- */
-OSStatus
-SSLDisposeContext                              (SSLContextRef context)
-{
-    if(context == NULL) {
-        return errSecParam;
-    }
-       CFRelease(context);
-       return errSecSuccess;
-}
-
-CFStringRef SSLContextCopyFormatDescription(CFTypeRef arg, CFDictionaryRef formatOptions)
-{
-    SSLContext* ctx = (SSLContext*) arg;
-
-    if (ctx == NULL) {
-        return NULL;
-    } else {
-               CFStringRef result = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("<SSLContext(%p) { ... }>"), ctx);
-               return result;
-    }
-}
-
-Boolean SSLContextCompare(CFTypeRef a, CFTypeRef b)
-{
-       return a == b;
-}
-
-CFHashCode SSLContextHash(CFTypeRef arg)
-{
-       return (CFHashCode) arg;
-}
-
-void SSLContextDestroy(CFTypeRef arg)
-{
-       SSLContext* ctx = (SSLContext*) arg;
-
-    /* destroy the coreTLS handshake object */
-    tls_handshake_destroy(ctx->hdsk);
-
-    /* Only destroy if we were using the internal record layer */
-    if(ctx->recFuncs==&SSLRecordLayerInternal)
-        SSLDestroyInternalRecordLayer(ctx->recCtx);
-
-    SSLFreeBuffer(&ctx->sessionTicket);
-    SSLFreeBuffer(&ctx->sessionID);
-    SSLFreeBuffer(&ctx->peerID);
-    SSLFreeBuffer(&ctx->resumableSession);
-    SSLFreeBuffer(&ctx->receivedDataBuffer);
-
-       sslFree(ctx->validCipherSuites);
-       ctx->validCipherSuites = NULL;
-       ctx->numValidCipherSuites = 0;
-
-    CFReleaseSafe(ctx->acceptableCAs);
-    CFReleaseSafe(ctx->trustedLeafCerts);
-    CFReleaseSafe(ctx->localCertArray);
-    CFReleaseSafe(ctx->encryptCertArray);
-    CFReleaseSafe(ctx->encryptCertArray);
-    CFReleaseSafe(ctx->peerCert);
-    CFReleaseSafe(ctx->trustedCerts);
-    CFReleaseSafe(ctx->peerSecTrust);
-
-    sslFreePrivKey(&ctx->signingPrivKeyRef);
-    sslFreePrivKey(&ctx->encryptPrivKeyRef);
-
-    sslFree(ctx->localCert);
-    sslFree(ctx->encryptCert);
-
-
-       sslFreeDnList(ctx);
-
-    SSLFreeBuffer(&ctx->ownVerifyData);
-    SSLFreeBuffer(&ctx->peerVerifyData);
-
-    SSLFreeBuffer(&ctx->pskIdentity);
-    SSLFreeBuffer(&ctx->pskSharedSecret);
-
-    SSLFreeBuffer(&ctx->dhParamsEncoded);
-
-    memset(((uint8_t*) ctx) + sizeof(CFRuntimeBase), 0, sizeof(SSLContext) - sizeof(CFRuntimeBase));
-
-       sslCleanupSession();
-}
-
-/*
- * Determine the state of an SSL session.
- */
-OSStatus
-SSLGetSessionState                     (SSLContextRef          context,
-                                                        SSLSessionState        *state)         /* RETURNED */
-{
-       SSLSessionState rtnState = kSSLIdle;
-
-       if(context == NULL) {
-               return errSecParam;
-       }
-       *state = rtnState;
-       switch(context->state) {
-               case SSL_HdskStateUninit:
-                       rtnState = kSSLIdle;
-                       break;
-               case SSL_HdskStateGracefulClose:
-                       rtnState = kSSLClosed;
-                       break;
-               case SSL_HdskStateErrorClose:
-               case SSL_HdskStateNoNotifyClose:
-                       rtnState = kSSLAborted;
-                       break;
-               case SSL_HdskStateReady:
-                       rtnState = kSSLConnected;
-                       break;
-        case SSL_HdskStatePending:
-                       rtnState = kSSLHandshake;
-                       break;
-       }
-       *state = rtnState;
-       return errSecSuccess;
-}
-
-/*
- * Set options for an SSL session.
- */
-OSStatus
-SSLSetSessionOption                    (SSLContextRef          context,
-                                                        SSLSessionOption       option,
-                                                        Boolean                        value)
-{
-    if(context == NULL) {
-       return errSecParam;
-    }
-    if(sslIsSessionActive(context)) {
-       /* can't do this with an active session */
-       return errSecBadReq;
-    }
-    switch(option) {
-        case kSSLSessionOptionBreakOnServerAuth:
-            context->breakOnServerAuth = value;
-            context->enableCertVerify = !value;
-            break;
-        case kSSLSessionOptionBreakOnCertRequested:
-            context->breakOnCertRequest = value;
-            break;
-        case kSSLSessionOptionBreakOnClientAuth:
-            context->breakOnClientAuth = value;
-            context->enableCertVerify = !value;
-            break;
-        case kSSLSessionOptionSendOneByteRecord:
-            /* Only call the record layer function if the value changed */
-            if(value != context->oneByteRecordEnable)
-                context->recFuncs->setOption(context->recCtx, kSSLRecordOptionSendOneByteRecord, value);
-            context->oneByteRecordEnable = value;
-            break;
-        case kSSLSessionOptionFalseStart:
-            context->falseStartEnabled = value;
-            break;
-        case kSSLSessionOptionFallback:
-            tls_handshake_set_fallback(context->hdsk, value);
-            context->fallbackEnabled = value;
-            break;
-        default:
-            return errSecParam;
-    }
-
-    return errSecSuccess;
-}
-
-/*
- * Determine current value for the specified option in an SSL session.
- */
-OSStatus
-SSLGetSessionOption                    (SSLContextRef          context,
-                                                        SSLSessionOption       option,
-                                                        Boolean                        *value)
-{
-    if(context == NULL || value == NULL) {
-        return errSecParam;
-    }
-    switch(option) {
-        case kSSLSessionOptionBreakOnServerAuth:
-            *value = context->breakOnServerAuth;
-            break;
-        case kSSLSessionOptionBreakOnCertRequested:
-            *value = context->breakOnCertRequest;
-            break;
-        case kSSLSessionOptionBreakOnClientAuth:
-            *value = context->breakOnClientAuth;
-            break;
-        case kSSLSessionOptionSendOneByteRecord:
-            *value = context->oneByteRecordEnable;
-            break;
-        case kSSLSessionOptionFalseStart:
-            *value = context->falseStartEnabled;
-            break;
-        default:
-            return errSecParam;
-    }
-
-    return errSecSuccess;
-}
-
-OSStatus
-SSLSetRecordContext         (SSLContextRef          ctx,
-                             SSLRecordContextRef    recCtx)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-    ctx->recCtx = recCtx;
-    return errSecSuccess;
-}
-
-/* Those two trampolines are used to make the connetion between
-   the record layer IO callbacks and the user provided IO callbacks.
-   Those are currently necessary because the record layer read/write callbacks
-   have different prototypes that the user callbacks advertised in the API.
-   They have different prototypes because the record layer callback have to build in kernelland.
-
-   This situation is not desirable. So we should figure out a way to get rid of them.
- */
-static int IORead(SSLIOConnectionRef   connection,
-                  void                                 *data,
-                  size_t                       *dataLength)
-{
-    OSStatus rc;
-    SSLContextRef ctx = connection;
-
-
-    rc = ctx->ioCtx.read(ctx->ioCtx.ioRef, data, dataLength);
-
-    /* We may need to translate error codes at this layer */
-    if(rc==errSSLWouldBlock) {
-        rc=errSSLRecordWouldBlock;
-    }
-
-    return rc;
-}
-
-static int IOWrite(SSLIOConnectionRef  connection,
-                   const void          *data,
-                   size_t                      *dataLength)
-{
-    OSStatus rc;
-    SSLContextRef ctx = connection;
-
-    rc = ctx->ioCtx.write(ctx->ioCtx.ioRef, data, dataLength);
-
-    /* We may need to translate error codes at this layer */
-    if(rc==errSSLWouldBlock) {
-        rc=errSSLRecordWouldBlock;
-    }
-    return rc;
-}
-
-
-OSStatus
-SSLSetIOFuncs                          (SSLContextRef          ctx,
-                                                        SSLReadFunc            readFunc,
-                                                        SSLWriteFunc           writeFunc)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-    if(ctx->recFuncs!=&SSLRecordLayerInternal) {
-        /* Can Only do this with the internal record layer */
-        check(0);
-        return errSecBadReq;
-    }
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-
-    ctx->ioCtx.read=readFunc;
-    ctx->ioCtx.write=writeFunc;
-
-    return SSLSetInternalRecordLayerIOFuncs(ctx->recCtx, IORead, IOWrite);
-}
-
-void
-SSLSetNPNFunc(SSLContextRef      context,
-                         SSLNPNFunc         npnFunc,
-                         void               *info)
-{
-    if (context == NULL) {
-        return;
-       }
-       if (sslIsSessionActive(context)) {
-               return;
-       }
-    context->npnFunc = npnFunc;
-    context->npnFuncInfo = info;
-    if(context->protocolSide==kSSLClientSide) {
-        tls_handshake_set_npn_enable(context->hdsk, npnFunc!=NULL);
-    }
-}
-
-OSStatus
-SSLSetNPNData(SSLContextRef      context,
-                         const void             *data,
-                         size_t                         length)
-{
-    if (context == NULL || data == NULL || length == 0) {
-        return errSecParam;
-       }
-
-       if (length > 255) {
-               return errSecParam;
-       }
-
-    tls_buffer npn_data;
-
-    npn_data.data = (uint8_t *)data;
-    npn_data.length = length;
-
-    return tls_handshake_set_npn_data(context->hdsk, npn_data);
-}
-
-const void *
-SSLGetNPNData(SSLContextRef      context,
-                                                        size_t                         *length)
-{
-       if (context == NULL || length == NULL)
-               return NULL;
-
-    const tls_buffer *npn_data;
-
-    npn_data = tls_handshake_get_peer_npn_data(context->hdsk);
-
-    if(npn_data) {
-        *length = npn_data->length;
-        return npn_data->data;
-    } else {
-        return NULL;
-    }
-}
-
-OSStatus
-SSLSetConnection                       (SSLContextRef          ctx,
-                                                        SSLConnectionRef       connection)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-    if(ctx->recFuncs!=&SSLRecordLayerInternal) {
-        /* Can Only do this with the internal record layer */
-        check(0);
-        return errSecBadReq;
-    }
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-
-    /* Need to keep a copy of it this layer for the Get function */
-    ctx->ioCtx.ioRef = connection;
-
-    return SSLSetInternalRecordLayerConnection(ctx->recCtx, ctx);
-}
-
-OSStatus
-SSLGetConnection                       (SSLContextRef          ctx,
-                                                        SSLConnectionRef       *connection)
-{
-       if((ctx == NULL) || (connection == NULL)) {
-               return errSecParam;
-       }
-       *connection = ctx->ioCtx.ioRef;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLSetPeerDomainName           (SSLContextRef          ctx,
-                                                        const char                     *peerName,
-                                                        size_t                         peerNameLen)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-
-    if(ctx->protocolSide == kSSLClientSide) {
-        return tls_handshake_set_peer_hostname(ctx->hdsk, peerName, peerNameLen);
-    } else {
-        return 0; // This should probably return an error, but historically didnt.
-    }
-}
-
-/*
- * Determine the buffer size needed for SSLGetPeerDomainName().
- */
-OSStatus
-SSLGetPeerDomainNameLength     (SSLContextRef          ctx,
-                                                        size_t                         *peerNameLen)   // RETURNED
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-    const char *hostname;
-
-    return tls_handshake_get_peer_hostname(ctx->hdsk, &hostname, peerNameLen);
-}
-
-OSStatus
-SSLGetPeerDomainName           (SSLContextRef          ctx,
-                                                        char                           *peerName,              // returned here
-                                                        size_t                         *peerNameLen)   // IN/OUT
-{
-    const char *hostname;
-    size_t len;
-
-    int err;
-
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-
-    err=tls_handshake_get_peer_hostname(ctx->hdsk, &hostname, &len);
-
-    if(err) {
-        return err;
-    } else if(*peerNameLen<len) {
-        return errSSLBufferOverflow;
-    } else {
-        memcpy(peerName, hostname, len);
-        *peerNameLen = len;
-        return 0;
-    }
-}
-
-OSStatus
-SSLSetDatagramHelloCookie   (SSLContextRef     ctx,
-                             const void         *cookie,
-                             size_t             cookieLen)
-{
-    OSStatus err;
-
-    if(ctx == NULL) {
-               return errSecParam;
-       }
-
-    if(!ctx->isDTLS) return errSecParam;
-
-       if((ctx == NULL) || (cookieLen>32)) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-
-       /* free possible existing cookie */
-       if(ctx->dtlsCookie.data) {
-        SSLFreeBuffer(&ctx->dtlsCookie);
-       }
-
-       /* copy in */
-    if((err=SSLAllocBuffer(&ctx->dtlsCookie, cookieLen)))
-       return err;
-
-       memmove(ctx->dtlsCookie.data, cookie, cookieLen);
-    return errSecSuccess;
-}
-
-OSStatus
-SSLSetMaxDatagramRecordSize (SSLContextRef             ctx,
-                             size_t             maxSize)
-{
-
-    if(ctx == NULL) return errSecParam;
-    if(!ctx->isDTLS) return errSecParam;
-
-    tls_handshake_set_mtu(ctx->hdsk, maxSize);
-
-    return errSecSuccess;
-}
-
-OSStatus
-SSLGetMaxDatagramRecordSize (SSLContextRef             ctx,
-                             size_t             *maxSize)
-{
-    if(ctx == NULL) return errSecParam;
-    if(!ctx->isDTLS) return errSecParam;
-
-    *maxSize = ctx->mtu;
-
-    return errSecSuccess;
-}
-
-/*
-
- Keys to to math below:
-
- A DTLS record looks like this: | header (13 bytes) | fragment |
-
- For Null cipher, fragment is clear text as follows:
- | Contents | Mac |
-
- For block cipher, fragment size must be a multiple of the cipher block size, and is the
- encryption of the following plaintext :
- | IV (1 block) | content | MAC | padding (0 to 255 bytes) | Padlen (1 byte) |
-
- The maximum content length in that case is achieved for 0 padding bytes.
-
-*/
-
-OSStatus
-SSLGetDatagramWriteSize                (SSLContextRef ctx,
-                                                        size_t *bufSize)
-{
-    if(ctx == NULL) return errSecParam;
-    if(!ctx->isDTLS) return errSecParam;
-    if(bufSize == NULL) return errSecParam;
-
-    size_t max_fragment_size = ctx->mtu-13; /* 13 = dtls record header */
-
-#warning <rdar://problem/16060896> SecureTransport: SSLGetDatagramWriteSize is wrong, need hookup with coreTLS
-#if 0
-    SSLCipherSpecParams *currCipher = &ctx->selectedCipherSpecParams;
-
-    size_t blockSize = currCipher->blockSize;
-    size_t macSize = currCipher->macSize;
-#else
-    size_t blockSize = 16;
-    size_t macSize = 32;
-#endif
-
-    if (blockSize > 0) {
-        /* max_fragment_size must be a multiple of blocksize */
-        max_fragment_size = max_fragment_size & ~(blockSize-1);
-        max_fragment_size -= blockSize; /* 1 block for IV */
-        max_fragment_size -= 1; /* 1 byte for pad length */
-    }
-
-    /* less the mac size */
-    max_fragment_size -= macSize;
-
-    /* Thats just a sanity check */
-    assert(max_fragment_size<ctx->mtu);
-
-    *bufSize = max_fragment_size;
-
-    return errSecSuccess;
-}
-
-static SSLProtocolVersion SSLProtocolToProtocolVersion(SSLProtocol protocol) {
-    switch (protocol) {
-        case kSSLProtocol2:             return SSL_Version_2_0;
-        case kSSLProtocol3:             return SSL_Version_3_0;
-        case kTLSProtocol1:             return TLS_Version_1_0;
-        case kTLSProtocol11:            return TLS_Version_1_1;
-        case kTLSProtocol12:            return TLS_Version_1_2;
-        case kDTLSProtocol1:            return DTLS_Version_1_0;
-        default:                        return SSL_Version_Undetermined;
-    }
-}
-
-/* concert between private SSLProtocolVersion and public SSLProtocol */
-static SSLProtocol SSLProtocolVersionToProtocol(SSLProtocolVersion version)
-{
-       switch(version) {
-               case SSL_Version_2_0:           return kSSLProtocol2;
-               case SSL_Version_3_0:           return kSSLProtocol3;
-               case TLS_Version_1_0:           return kTLSProtocol1;
-               case TLS_Version_1_1:           return kTLSProtocol11;
-               case TLS_Version_1_2:           return kTLSProtocol12;
-               case DTLS_Version_1_0:          return kDTLSProtocol1;
-               default:
-                       sslErrorLog("SSLProtocolVersionToProtocol: bad prot (%04x)\n",
-                        version);
-            /* DROPTHROUGH */
-               case SSL_Version_Undetermined:  return kSSLProtocolUnknown;
-       }
-}
-
-OSStatus
-SSLSetProtocolVersionMin  (SSLContextRef      ctx,
-                           SSLProtocol        minVersion)
-{
-    if(ctx == NULL) return errSecParam;
-
-    SSLProtocolVersion version = SSLProtocolToProtocolVersion(minVersion);
-    if (ctx->isDTLS) {
-        if (version > MINIMUM_DATAGRAM_VERSION ||
-            version < MAXIMUM_DATAGRAM_VERSION)
-            return errSSLIllegalParam;
-        if (version < ctx->maxProtocolVersion)
-            ctx->maxProtocolVersion = version;
-    } else {
-        if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION)
-            return errSSLIllegalParam;
-        if (version > ctx->maxProtocolVersion)
-            ctx->maxProtocolVersion = version;
-    }
-    ctx->minProtocolVersion = version;
-
-    tls_handshake_set_min_protocol_version(ctx->hdsk, ctx->minProtocolVersion);
-    tls_handshake_set_max_protocol_version(ctx->hdsk, ctx->maxProtocolVersion);
-
-    return errSecSuccess;
-}
-
-OSStatus
-SSLGetProtocolVersionMin  (SSLContextRef      ctx,
-                           SSLProtocol        *minVersion)
-{
-    if(ctx == NULL) return errSecParam;
-
-    *minVersion = SSLProtocolVersionToProtocol(ctx->minProtocolVersion);
-    return errSecSuccess;
-}
-
-OSStatus
-SSLSetProtocolVersionMax  (SSLContextRef      ctx,
-                           SSLProtocol        maxVersion)
-{
-    if(ctx == NULL) return errSecParam;
-
-    SSLProtocolVersion version = SSLProtocolToProtocolVersion(maxVersion);
-    if (ctx->isDTLS) {
-        if (version > MINIMUM_DATAGRAM_VERSION ||
-            version < MAXIMUM_DATAGRAM_VERSION)
-            return errSSLIllegalParam;
-        if (version > ctx->minProtocolVersion)
-            ctx->minProtocolVersion = version;
-    } else {
-        if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION)
-            return errSSLIllegalParam;
-        if (version < ctx->minProtocolVersion)
-            ctx->minProtocolVersion = version;
-    }
-    ctx->maxProtocolVersion = version;
-
-    tls_handshake_set_min_protocol_version(ctx->hdsk, ctx->minProtocolVersion);
-    tls_handshake_set_max_protocol_version(ctx->hdsk, ctx->maxProtocolVersion);
-
-    return errSecSuccess;
-}
-
-OSStatus
-SSLGetProtocolVersionMax  (SSLContextRef      ctx,
-                           SSLProtocol        *maxVersion)
-{
-    if(ctx == NULL) return errSecParam;
-
-    *maxVersion = SSLProtocolVersionToProtocol(ctx->maxProtocolVersion);
-    return errSecSuccess;
-}
-
-#define max(x,y) ((x)<(y)?(y):(x))
-
-OSStatus
-SSLSetProtocolVersionEnabled(SSLContextRef     ctx,
-                                                        SSLProtocol            protocol,
-                                                        Boolean                        enable)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx) || ctx->isDTLS) {
-               /* Can't do this with an active session, nor with a DTLS session */
-               return errSecBadReq;
-       }
-    if (protocol == kSSLProtocolAll) {
-        if (enable) {
-            ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
-            ctx->maxProtocolVersion = MAXIMUM_STREAM_VERSION;
-        } else {
-            ctx->minProtocolVersion = SSL_Version_Undetermined;
-            ctx->maxProtocolVersion = SSL_Version_Undetermined;
-        }
-       } else {
-               SSLProtocolVersion version = SSLProtocolToProtocolVersion(protocol);
-        if (enable) {
-                       if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION) {
-                               return errSecParam;
-                       }
-            if (version > ctx->maxProtocolVersion) {
-                ctx->maxProtocolVersion = version;
-                if (ctx->minProtocolVersion == SSL_Version_Undetermined)
-                    ctx->minProtocolVersion = version;
-            }
-            if (version < ctx->minProtocolVersion) {
-                ctx->minProtocolVersion = version;
-            }
-        } else {
-                       if (version < SSL_Version_2_0 || version > MAXIMUM_STREAM_VERSION) {
-                               return errSecParam;
-                       }
-                       /* Disabling a protocol version now resets the minimum acceptable
-                        * version to the next higher version. This means it's no longer
-                        * possible to enable a discontiguous set of protocol versions.
-                        */
-                       SSLProtocolVersion nextVersion;
-                       switch (version) {
-                               case SSL_Version_2_0:
-                                       nextVersion = SSL_Version_3_0;
-                                       break;
-                               case SSL_Version_3_0:
-                                       nextVersion = TLS_Version_1_0;
-                                       break;
-                               case TLS_Version_1_0:
-                                       nextVersion = TLS_Version_1_1;
-                                       break;
-                               case TLS_Version_1_1:
-                                       nextVersion = TLS_Version_1_2;
-                                       break;
-                               case TLS_Version_1_2:
-                               default:
-                                       nextVersion = SSL_Version_Undetermined;
-                                       break;
-                       }
-                       ctx->minProtocolVersion = max(ctx->minProtocolVersion, nextVersion);
-                       if (ctx->minProtocolVersion > ctx->maxProtocolVersion) {
-                               ctx->minProtocolVersion = SSL_Version_Undetermined;
-                               ctx->maxProtocolVersion = SSL_Version_Undetermined;
-                       }
-        }
-    }
-
-    tls_handshake_set_min_protocol_version(ctx->hdsk, ctx->minProtocolVersion);
-    tls_handshake_set_max_protocol_version(ctx->hdsk, ctx->maxProtocolVersion);
-
-       return errSecSuccess;
-}
-
-OSStatus
-SSLGetProtocolVersionEnabled(SSLContextRef             ctx,
-                                                        SSLProtocol            protocol,
-                                                        Boolean                        *enable)                /* RETURNED */
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(ctx->isDTLS) {
-               /* Can't do this with a DTLS session */
-               return errSecBadReq;
-       }
-       switch(protocol) {
-               case kSSLProtocol2:
-               case kSSLProtocol3:
-               case kTLSProtocol1:
-        case kTLSProtocol11:
-        case kTLSProtocol12:
-        {
-            SSLProtocolVersion version = SSLProtocolToProtocolVersion(protocol);
-                       *enable = (ctx->minProtocolVersion <= version
-                       && ctx->maxProtocolVersion >= version);
-                       break;
-        }
-               case kSSLProtocolAll:
-            *enable = (ctx->minProtocolVersion <= MINIMUM_STREAM_VERSION
-                       && ctx->maxProtocolVersion >= MAXIMUM_STREAM_VERSION);
-                       break;
-               default:
-                       return errSecParam;
-       }
-       return errSecSuccess;
-}
-
-/* deprecated */
-OSStatus
-SSLSetProtocolVersion          (SSLContextRef          ctx,
-                                                        SSLProtocol            version)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx) || ctx->isDTLS) {
-               /* Can't do this with an active session, nor with a DTLS session */
-               return errSecBadReq;
-       }
-
-       switch(version) {
-               case kSSLProtocol3:
-                       /* this tells us to do our best, up to 3.0 */
-            ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
-            ctx->maxProtocolVersion = SSL_Version_3_0;
-                       break;
-               case kSSLProtocol3Only:
-            ctx->minProtocolVersion = SSL_Version_3_0;
-            ctx->maxProtocolVersion = SSL_Version_3_0;
-                       break;
-               case kTLSProtocol1:
-                       /* this tells us to do our best, up to TLS, but allows 3.0 */
-            ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
-            ctx->maxProtocolVersion = TLS_Version_1_0;
-            break;
-        case kTLSProtocol1Only:
-            ctx->minProtocolVersion = TLS_Version_1_0;
-            ctx->maxProtocolVersion = TLS_Version_1_0;
-                       break;
-        case kTLSProtocol11:
-                       /* This tells us to do our best, up to TLS 1.1, currently also
-               allows 3.0 or TLS 1.0 */
-            ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
-            ctx->maxProtocolVersion = TLS_Version_1_1;
-                       break;
-        case kTLSProtocol12:
-        case kSSLProtocolAll:
-               case kSSLProtocolUnknown:
-                       /* This tells us to do our best, up to TLS 1.2, currently also
-               allows 3.0 or TLS 1.0 or TLS 1.1 */
-            ctx->minProtocolVersion = MINIMUM_STREAM_VERSION;
-            ctx->maxProtocolVersion = MAXIMUM_STREAM_VERSION;
-                       break;
-               default:
-                       return errSecParam;
-       }
-
-    tls_handshake_set_min_protocol_version(ctx->hdsk, ctx->minProtocolVersion);
-    tls_handshake_set_max_protocol_version(ctx->hdsk, ctx->maxProtocolVersion);
-
-    return errSecSuccess;
-}
-
-/* deprecated */
-OSStatus
-SSLGetProtocolVersion          (SSLContextRef          ctx,
-                                                        SSLProtocol            *protocol)              /* RETURNED */
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       /* translate array of booleans to public value; not all combinations
-        * are legal (i.e., meaningful) for this call */
-    if (ctx->maxProtocolVersion == MAXIMUM_STREAM_VERSION) {
-        if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
-            /* traditional 'all enabled' */
-            *protocol = kSSLProtocolAll;
-            return errSecSuccess;
-               }
-       } else if (ctx->maxProtocolVersion == TLS_Version_1_1) {
-        if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
-            /* traditional 'all enabled' */
-            *protocol = kTLSProtocol11;
-            return errSecSuccess;
-        }
-       } else if (ctx->maxProtocolVersion == TLS_Version_1_0) {
-        if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
-            /* TLS1.1 and below enabled */
-            *protocol = kTLSProtocol1;
-            return errSecSuccess;
-        } else if(ctx->minProtocolVersion == TLS_Version_1_0) {
-               *protocol = kTLSProtocol1Only;
-               }
-       } else if(ctx->maxProtocolVersion == SSL_Version_3_0) {
-        if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
-            /* Could also return kSSLProtocol3Only since
-               MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
-            *protocol = kSSLProtocol3;
-                       return errSecSuccess;
-               }
-       }
-
-    return errSecParam;
-}
-
-OSStatus
-SSLGetNegotiatedProtocolVersion                (SSLContextRef          ctx,
-                                                                        SSLProtocol            *protocol) /* RETURNED */
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       *protocol = SSLProtocolVersionToProtocol(ctx->negProtocolVersion);
-       return errSecSuccess;
-}
-
-OSStatus
-SSLSetEnableCertVerify         (SSLContextRef          ctx,
-                                                        Boolean                        enableVerify)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       sslCertDebug("SSLSetEnableCertVerify %s",
-               enableVerify ? "true" : "false");
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-       ctx->enableCertVerify = enableVerify;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLGetEnableCertVerify         (SSLContextRef          ctx,
-                                                       Boolean                         *enableVerify)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       *enableVerify = ctx->enableCertVerify;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLSetAllowsExpiredCerts(SSLContextRef         ctx,
-                                                Boolean                        allowExpired)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       sslCertDebug("SSLSetAllowsExpiredCerts %s",
-               allowExpired ? "true" : "false");
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-       ctx->allowExpiredCerts = allowExpired;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLGetAllowsExpiredCerts       (SSLContextRef          ctx,
-                                                        Boolean                        *allowExpired)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       *allowExpired = ctx->allowExpiredCerts;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLSetAllowsExpiredRoots(SSLContextRef         ctx,
-                                                Boolean                        allowExpired)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       sslCertDebug("SSLSetAllowsExpiredRoots %s",
-               allowExpired ? "true" : "false");
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-       ctx->allowExpiredRoots = allowExpired;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLGetAllowsExpiredRoots       (SSLContextRef          ctx,
-                                                        Boolean                        *allowExpired)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       *allowExpired = ctx->allowExpiredRoots;
-       return errSecSuccess;
-}
-
-OSStatus SSLSetAllowsAnyRoot(
-       SSLContextRef   ctx,
-       Boolean                 anyRoot)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       sslCertDebug("SSLSetAllowsAnyRoot %s",  anyRoot ? "true" : "false");
-       ctx->allowAnyRoot = anyRoot;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLGetAllowsAnyRoot(
-       SSLContextRef   ctx,
-       Boolean                 *anyRoot)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       *anyRoot = ctx->allowAnyRoot;
-       return errSecSuccess;
-}
-
-#if !TARGET_OS_IPHONE
-/* obtain the system roots sets for this app, policy SSL */
-static OSStatus sslDefaultSystemRoots(
-       SSLContextRef ctx,
-       CFArrayRef *systemRoots)                                // created and RETURNED
-
-{
-    const char *hostname;
-    size_t len;
-
-    tls_handshake_get_peer_hostname(ctx->hdsk, &hostname, &len);
-
-       return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL,
-               hostname,
-               (uint32_t)len,
-               (ctx->protocolSide == kSSLServerSide) ?
-                       /* server verifies, client encrypts */
-                       CSSM_KEYUSE_VERIFY : CSSM_KEYUSE_ENCRYPT,
-               systemRoots);
-}
-#endif /* OS X only */
-
-OSStatus
-SSLSetTrustedRoots                     (SSLContextRef          ctx,
-                                                        CFArrayRef             trustedRoots,
-                                                        Boolean                        replaceExisting)
-{
-#ifdef USE_CDSA_CRYPTO
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-
-       if(replaceExisting) {
-               /* trivial case - retain the new, throw out the old.  */
-               if (trustedRoots)
-            CFRetain(trustedRoots);
-        CFReleaseSafe(ctx->trustedCerts);
-               ctx->trustedCerts = trustedRoots;
-               return errSecSuccess;
-       }
-
-       /* adding new trusted roots - to either our existing set, or the system set */
-       CFArrayRef existingRoots = NULL;
-       OSStatus ortn;
-       if(ctx->trustedCerts != NULL) {
-               /* we'll release these as we exit */
-               existingRoots = ctx->trustedCerts;
-       }
-       else {
-               /* get system set for this app, policy SSL */
-               ortn = sslDefaultSystemRoots(ctx, &existingRoots);
-               if(ortn) {
-            CFReleaseSafe(existingRoots);
-                       return ortn;
-               }
-       }
-
-       /* Create a new root array with caller's roots first */
-       CFMutableArrayRef newRoots = CFArrayCreateMutableCopy(NULL, 0, trustedRoots);
-       CFRange existRange = { 0, CFArrayGetCount(existingRoots) };
-       CFArrayAppendArray(newRoots, existingRoots, existRange);
-       CFRelease(existingRoots);
-       ctx->trustedCerts = newRoots;
-       return errSecSuccess;
-
-#else
-       if (sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-       sslCertDebug("SSLSetTrustedRoot  numCerts %d  replaceExist %s",
-               (int)CFArrayGetCount(trustedRoots), replaceExisting ? "true" : "false");
-
-    if (replaceExisting) {
-        ctx->trustedCertsOnly = true;
-        CFReleaseNull(ctx->trustedCerts);
-    }
-
-    if (ctx->trustedCerts) {
-        CFIndex count = CFArrayGetCount(trustedRoots);
-        CFRange range = { 0, count };
-        CFArrayAppendArray(ctx->trustedCerts, trustedRoots, range);
-    } else {
-        require(ctx->trustedCerts =
-            CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, trustedRoots),
-            errOut);
-    }
-
-    return errSecSuccess;
-
-errOut:
-    return errSecAllocate;
-#endif /* !USE_CDSA_CRYPTO */
-}
-
-OSStatus
-SSLCopyTrustedRoots                    (SSLContextRef          ctx,
-                                                        CFArrayRef             *trustedRoots)  /* RETURNED */
-{
-       if(ctx == NULL || trustedRoots == NULL) {
-               return errSecParam;
-       }
-       if(ctx->trustedCerts != NULL) {
-               *trustedRoots = ctx->trustedCerts;
-               CFRetain(ctx->trustedCerts);
-               return errSecSuccess;
-       }
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
-       /* use default system roots */
-    return sslDefaultSystemRoots(ctx, trustedRoots);
-#else
-    *trustedRoots = NULL;
-    return errSecSuccess;
-#endif
-}
-
-OSStatus
-SSLSetTrustedLeafCertificates  (SSLContextRef          ctx,
-                                                                CFArrayRef             trustedCerts)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-
-       if(ctx->trustedLeafCerts) {
-               CFRelease(ctx->trustedLeafCerts);
-       }
-       ctx->trustedLeafCerts = trustedCerts;
-       CFRetain(trustedCerts);
-       return errSecSuccess;
-}
-
-OSStatus
-SSLCopyTrustedLeafCertificates (SSLContextRef          ctx,
-                                                                CFArrayRef             *trustedCerts)  /* RETURNED */
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(ctx->trustedLeafCerts != NULL) {
-               *trustedCerts = ctx->trustedLeafCerts;
-               CFRetain(ctx->trustedCerts);
-               return errSecSuccess;
-       }
-       *trustedCerts = NULL;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLSetClientSideAuthenticate   (SSLContext                     *ctx,
-                                                                SSLAuthenticate        auth)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-       ctx->clientAuth = auth;
-       switch(auth) {
-               case kNeverAuthenticate:
-            tls_handshake_set_client_auth(ctx->hdsk, false);
-                       break;
-               case kAlwaysAuthenticate:
-               case kTryAuthenticate:
-            tls_handshake_set_client_auth(ctx->hdsk, true);
-                       break;
-       }
-       return errSecSuccess;
-}
-
-OSStatus
-SSLGetClientSideAuthenticate   (SSLContext                     *ctx,
-                                                                SSLAuthenticate        *auth)  /* RETURNED */
-{
-       if(ctx == NULL || auth == NULL) {
-               return errSecParam;
-       }
-       *auth = ctx->clientAuth;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLGetClientCertificateState   (SSLContextRef                          ctx,
-                                                                SSLClientCertificateState      *clientState)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       *clientState = ctx->clientCertState;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLSetCertificate                      (SSLContextRef          ctx,
-                                                        CFArrayRef                     certRefs)
-{
-       /*
-        * -- free localCerts if we have any
-        * -- Get raw cert data, convert to ctx->localCert
-        * -- get pub, priv keys from certRef[0]
-        * -- validate cert chain
-        */
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-
-       /* can't do this with an active session */
-       if(sslIsSessionActive(ctx) &&
-          /* kSSLClientCertRequested implies client side */
-          (ctx->clientCertState != kSSLClientCertRequested))
-       {
-                       return errSecBadReq;
-       }
-
-    CFReleaseNull(ctx->localCertArray);
-       /* changing the client cert invalidates negotiated auth type */
-       ctx->negAuthType = SSLClientAuthNone;
-       if(certRefs == NULL) {
-               return errSecSuccess; // we have cleared the cert, as requested
-       }
-       OSStatus ortn = parseIncomingCerts(ctx,
-               certRefs,
-               &ctx->localCert,
-        &ctx->signingPrivKeyRef);
-    if(ortn == errSecSuccess) {
-               ctx->localCertArray = certRefs;
-               CFRetain(certRefs);
-        if(ctx->protocolSide==kSSLClientSide)
-            SSLUpdateNegotiatedClientAuthType(ctx);
-        tls_handshake_set_identity(ctx->hdsk, ctx->localCert, ctx->signingPrivKeyRef);
-    }
-       return ortn;
-}
-
-OSStatus
-SSLSetEncryptionCertificate    (SSLContextRef          ctx,
-                                                        CFArrayRef                     certRefs)
-{
-       /*
-        * -- free encryptCert if we have any
-        * -- Get raw cert data, convert to ctx->encryptCert
-        * -- get pub, priv keys from certRef[0]
-        * -- validate cert chain
-        */
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-    CFReleaseNull(ctx->encryptCertArray);
-    OSStatus ortn = parseIncomingCerts(ctx,
-               certRefs,
-               &ctx->encryptCert,
-               &ctx->encryptPrivKeyRef);
-       if(ortn == errSecSuccess) {
-               ctx->encryptCertArray = certRefs;
-               CFRetain(certRefs);
-       }
-       return ortn;
-}
-
-OSStatus SSLGetCertificate(SSLContextRef               ctx,
-                                                  CFArrayRef                   *certRefs)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       *certRefs = ctx->localCertArray;
-       return errSecSuccess;
-}
-
-OSStatus SSLGetEncryptionCertificate(SSLContextRef             ctx,
-                                                                    CFArrayRef                 *certRefs)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       *certRefs = ctx->encryptCertArray;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLSetPeerID                           (SSLContext             *ctx,
-                                                        const void             *peerID,
-                                                        size_t                         peerIDLen)
-{
-       OSStatus serr;
-
-       /* copy peerId to context->peerId */
-       if((ctx == NULL) ||
-          (peerID == NULL) ||
-          (peerIDLen == 0)) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx) &&
-        /* kSSLClientCertRequested implies client side */
-        (ctx->clientCertState != kSSLClientCertRequested))
-    {
-               return errSecBadReq;
-       }
-       SSLFreeBuffer(&ctx->peerID);
-       serr = SSLAllocBuffer(&ctx->peerID, peerIDLen);
-       if(serr) {
-               return serr;
-       }
-    tls_handshake_set_resumption(ctx->hdsk, true);
-       memmove(ctx->peerID.data, peerID, peerIDLen);
-       return errSecSuccess;
-}
-
-OSStatus
-SSLGetPeerID                           (SSLContextRef          ctx,
-                                                        const void             **peerID,
-                                                        size_t                         *peerIDLen)
-{
-       *peerID = ctx->peerID.data;                     // may be NULL
-       *peerIDLen = ctx->peerID.length;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLGetNegotiatedCipher         (SSLContextRef          ctx,
-                                                        SSLCipherSuite         *cipherSuite)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-
-    if(!sslIsSessionActive(ctx)) {
-               return errSecBadReq;
-       }
-
-    *cipherSuite = (SSLCipherSuite)tls_handshake_get_negotiated_cipherspec(ctx->hdsk);
-
-       return errSecSuccess;
-}
-
-/*
- * Add an acceptable distinguished name (client authentication only).
- */
-OSStatus
-SSLAddDistinguishedName(
-       SSLContextRef ctx,
-       const void *derDN,
-       size_t derDNLen)
-{
-    DNListElem      *dn;
-    OSStatus        err;
-
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx)) {
-               return errSecBadReq;
-       }
-
-       dn = (DNListElem *)sslMalloc(sizeof(DNListElem));
-       if(dn == NULL) {
-               return errSecAllocate;
-       }
-    if ((err = SSLAllocBuffer(&dn->derDN, derDNLen)))
-        return err;
-    memcpy(dn->derDN.data, derDN, derDNLen);
-    dn->next = ctx->acceptableDNList;
-    ctx->acceptableDNList = dn;
-
-    tls_handshake_set_acceptable_dn_list(ctx->hdsk, dn);
-
-    return errSecSuccess;
-}
-
-/* single-cert version of SSLSetCertificateAuthorities() */
-static OSStatus
-sslAddCA(SSLContextRef         ctx,
-                SecCertificateRef      cert)
-{
-       OSStatus ortn = errSecParam;
-
-    /* Get subject from certificate. */
-#if TARGET_OS_IPHONE
-    CFDataRef subjectName = NULL;
-    subjectName = SecCertificateCopySubjectSequence(cert);
-    require(subjectName, errOut);
-#else
-    CSSM_DATA_PTR subjectName = NULL;
-    ortn = SecCertificateCopyFirstFieldValue(cert, &CSSMOID_X509V1SubjectNameStd, &subjectName);
-    require_noerr(ortn, errOut);
-#endif
-
-       /* add to acceptableCAs as cert, creating array if necessary */
-       if(ctx->acceptableCAs == NULL) {
-               require(ctx->acceptableCAs = CFArrayCreateMutable(NULL, 0,
-            &kCFTypeArrayCallBacks), errOut);
-               if(ctx->acceptableCAs == NULL) {
-                       return errSecAllocate;
-               }
-       }
-       CFArrayAppendValue(ctx->acceptableCAs, cert);
-
-       /* then add this cert's subject name to acceptableDNList */
-#if TARGET_OS_IPHONE
-       ortn = SSLAddDistinguishedName(ctx,
-                                   CFDataGetBytePtr(subjectName),
-                                   CFDataGetLength(subjectName));
-#else
-    ortn = SSLAddDistinguishedName(ctx, subjectName->Data, subjectName->Length);
-#endif
-
-errOut:
-#if TARGET_OS_IPHONE
-    CFReleaseSafe(subjectName);
-#endif
-       return ortn;
-}
-
-/*
- * Add a SecCertificateRef, or a CFArray of them, to a server's list
- * of acceptable Certificate Authorities (CAs) to present to the client
- * when client authentication is performed.
- */
-OSStatus
-SSLSetCertificateAuthorities(SSLContextRef             ctx,
-                                                        CFTypeRef                      certificateOrArray,
-                                                        Boolean                        replaceExisting)
-{
-       CFTypeID itemType;
-       OSStatus ortn = errSecSuccess;
-
-       if((ctx == NULL) || sslIsSessionActive(ctx) ||
-          (ctx->protocolSide != kSSLServerSide)) {
-               return errSecParam;
-       }
-       if(replaceExisting) {
-               sslFreeDnList(ctx);
-               if(ctx->acceptableCAs) {
-                       CFRelease(ctx->acceptableCAs);
-                       ctx->acceptableCAs = NULL;
-               }
-       }
-       /* else appending */
-
-       itemType = CFGetTypeID(certificateOrArray);
-       if(itemType == SecCertificateGetTypeID()) {
-               /* one cert */
-               ortn = sslAddCA(ctx, (SecCertificateRef)certificateOrArray);
-       }
-       else if(itemType == CFArrayGetTypeID()) {
-               CFArrayRef cfa = (CFArrayRef)certificateOrArray;
-               CFIndex numCerts = CFArrayGetCount(cfa);
-               CFIndex dex;
-
-               /* array of certs */
-               for(dex=0; dex<numCerts; dex++) {
-                       SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(cfa, dex);
-                       if(CFGetTypeID(cert) != SecCertificateGetTypeID()) {
-                               return errSecParam;
-                       }
-                       ortn = sslAddCA(ctx, cert);
-                       if(ortn) {
-                               break;
-                       }
-               }
-       }
-       else {
-               ortn = errSecParam;
-       }
-       return ortn;
-}
-
-
-/*
- * Obtain the certificates specified in SSLSetCertificateAuthorities(),
- * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not
- * been called.
- * Caller must CFRelease the returned array.
- */
-OSStatus
-SSLCopyCertificateAuthorities(SSLContextRef            ctx,
-                                                         CFArrayRef            *certificates)  /* RETURNED */
-{
-       if((ctx == NULL) || (certificates == NULL)) {
-               return errSecParam;
-       }
-       if(ctx->acceptableCAs == NULL) {
-               *certificates = NULL;
-               return errSecSuccess;
-       }
-       *certificates = ctx->acceptableCAs;
-       CFRetain(ctx->acceptableCAs);
-       return errSecSuccess;
-}
-
-
-/*
- * Obtain the list of acceptable distinguished names as provided by
- * a server (if the SSLCotextRef is configured as a client), or as
- * specified by SSLSetCertificateAuthorities() (if the SSLContextRef
- * is configured as a server).
-  */
-OSStatus
-SSLCopyDistinguishedNames      (SSLContextRef          ctx,
-                                                        CFArrayRef                     *names)
-{
-       CFMutableArrayRef outArray = NULL;
-       const DNListElem *dn;
-
-       if((ctx == NULL) || (names == NULL)) {
-               return errSecParam;
-       }
-    if(ctx->protocolSide==kSSLServerSide) {
-        dn = ctx->acceptableDNList;
-    } else {
-        dn = tls_handshake_get_peer_acceptable_dn_list(ctx->hdsk); // ctx->acceptableDNList;
-    }
-
-       if(dn == NULL) {
-               *names = NULL;
-               return errSecSuccess;
-       }
-       outArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-
-       while (dn) {
-               CFDataRef cfDn = CFDataCreate(NULL, dn->derDN.data, dn->derDN.length);
-               CFArrayAppendValue(outArray, cfDn);
-               CFRelease(cfDn);
-               dn = dn->next;
-       }
-       *names = outArray;
-       return errSecSuccess;
-}
-
-
-/*
- * Request peer certificates. Valid anytime, subsequent to
- * a handshake attempt.
- * Common code for SSLGetPeerCertificates() and SSLCopyPeerCertificates().
- * TODO: the 'legacy' argument is not used anymore.
- */
-static OSStatus
-sslCopyPeerCertificates                (SSLContextRef          ctx,
-                                                        CFArrayRef                     *certs,
-                                                        Boolean                        legacy)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-
-       if (!ctx->peerCert) {
-               *certs = NULL;
-               return errSecBadReq;
-       }
-
-    CFArrayRef ca = CFArrayCreateCopy(kCFAllocatorDefault, ctx->peerCert);
-    *certs = ca;
-    if (ca == NULL) {
-        return errSecAllocate;
-    }
-
-       if (legacy) {
-               CFIndex ix, count = CFArrayGetCount(ca);
-               for (ix = 0; ix < count; ++ix) {
-                       CFRetain(CFArrayGetValueAtIndex(ca, ix));
-               }
-       }
-
-       return errSecSuccess;
-}
-
-OSStatus
-SSLCopyPeerCertificates                (SSLContextRef          ctx,
-                                                        CFArrayRef                     *certs)
-{
-       return sslCopyPeerCertificates(ctx, certs, false);
-}
-
-#if !TARGET_OS_IPHONE
-// Permanently removing from iOS, keep for OSX (deprecated), removed from headers.
-// <rdar://problem/14215831> Mailsmith Crashes While Getting New Mail Under Mavericks Developer Preview
-OSStatus
-SSLGetPeerCertificates (SSLContextRef ctx,
-                        CFArrayRef *certs);
-OSStatus
-SSLGetPeerCertificates (SSLContextRef ctx,
-                        CFArrayRef *certs)
-{
-    return sslCopyPeerCertificates(ctx, certs, true);
-}
-#endif
-
-/*
- * Specify Diffie-Hellman parameters. Optional; if we are configured to allow
- * for D-H ciphers and a D-H cipher is negotiated, and this function has not
- * been called, a set of process-wide parameters will be calculated. However
- * that can take a long time (30 seconds).
- */
-OSStatus SSLSetDiffieHellmanParams(
-       SSLContextRef   ctx,
-       const void              *dhParams,
-       size_t                  dhParamsLen)
-{
-#if APPLE_DH
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx)) {
-               return errSecBadReq;
-       }
-       SSLFreeBuffer(&ctx->dhParamsEncoded);
-
-       OSStatus ortn;
-       ortn = SSLCopyBufferFromData(dhParams, dhParamsLen,
-               &ctx->dhParamsEncoded);
-
-    return ortn;
-
-#endif /* APPLE_DH */
-}
-
-/*
- * Return parameter block specified in SSLSetDiffieHellmanParams.
- * Returned data is not copied and belongs to the SSLContextRef.
- */
-OSStatus SSLGetDiffieHellmanParams(
-       SSLContextRef   ctx,
-       const void              **dhParams,
-       size_t                  *dhParamsLen)
-{
-#if APPLE_DH
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       *dhParams = ctx->dhParamsEncoded.data;
-       *dhParamsLen = ctx->dhParamsEncoded.length;
-       return errSecSuccess;
-#else
-    return errSecUnimplemented;
-#endif /* APPLE_DH */
-}
-
-OSStatus SSLSetMinimumDHGroupSize(SSLContextRef ctx, unsigned nbits)
-{
-    return tls_handshake_set_min_dh_group_size(ctx->hdsk, nbits);
-}
-
-OSStatus SSLGetMinimumDHGroupSize(SSLContextRef ctx, unsigned *nbits)
-{
-    return tls_handshake_get_min_dh_group_size(ctx->hdsk, nbits);
-}
-
-OSStatus SSLSetRsaBlinding(
-       SSLContextRef   ctx,
-       Boolean                 blinding)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       ctx->rsaBlindingEnable = blinding;
-       return errSecSuccess;
-}
-
-OSStatus SSLGetRsaBlinding(
-       SSLContextRef   ctx,
-       Boolean                 *blinding)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       *blinding = ctx->rsaBlindingEnable;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLCopyPeerTrust(
-    SSLContextRef              ctx,
-    SecTrustRef        *trust) /* RETURNED */
-{
-       OSStatus status = errSecSuccess;
-       if (ctx == NULL || trust == NULL)
-               return errSecParam;
-
-       /* Create a SecTrustRef if this was a resumed session and we
-          didn't have one yet. */
-    if (!ctx->peerCert) {
-        ctx->peerCert = tls_get_peer_certs(tls_handshake_get_peer_certificates(ctx->hdsk));
-    }
-       if (!ctx->peerSecTrust && ctx->peerCert) {
-               status = sslCreateSecTrust(ctx, ctx->peerCert, true,
-                       &ctx->peerSecTrust);
-    }
-
-       *trust = ctx->peerSecTrust;
-    if (ctx->peerSecTrust)
-        CFRetain(ctx->peerSecTrust);
-
-       return status;
-}
-
-OSStatus SSLGetPeerSecTrust(
-       SSLContextRef   ctx,
-       SecTrustRef             *trust) /* RETURNED */
-{
-    OSStatus status = errSecSuccess;
-       if (ctx == NULL || trust == NULL)
-               return errSecParam;
-
-       /* Create a SecTrustRef if this was a resumed session and we
-          didn't have one yet. */
-       if (!ctx->peerSecTrust && ctx->peerCert) {
-               status = sslCreateSecTrust(ctx, ctx->peerCert, true,
-                       &ctx->peerSecTrust);
-    }
-
-       *trust = ctx->peerSecTrust;
-       return status;
-}
-
-OSStatus SSLInternalMasterSecret(
-   SSLContextRef ctx,
-   void *secret,        // mallocd by caller, SSL_MASTER_SECRET_SIZE
-   size_t *secretSize)  // in/out
-{
-       if((ctx == NULL) || (secret == NULL) || (secretSize == NULL)) {
-               return errSecParam;
-       }
-    return tls_handshake_internal_master_secret(ctx->hdsk, secret, secretSize);
-}
-
-OSStatus SSLInternalServerRandom(
-   SSLContextRef ctx,
-   void *randBuf,                      // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
-   size_t *randSize)   // in/out
-{
-       if((ctx == NULL) || (randBuf == NULL) || (randSize == NULL)) {
-               return errSecParam;
-       }
-    return tls_handshake_internal_server_random(ctx->hdsk, randBuf, randSize);
-}
-
-OSStatus SSLInternalClientRandom(
-   SSLContextRef ctx,
-   void *randBuf,              // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE
-   size_t *randSize)   // in/out
-{
-       if((ctx == NULL) || (randBuf == NULL) || (randSize == NULL)) {
-               return errSecParam;
-       }
-    return tls_handshake_internal_client_random(ctx->hdsk, randBuf, randSize);
-}
-
-/* This is used by EAP 802.1x */
-OSStatus SSLGetCipherSizes(
-       SSLContextRef ctx,
-       size_t *digestSize,
-       size_t *symmetricKeySize,
-       size_t *ivSize)
-{
-       if((ctx == NULL) || (digestSize == NULL) ||
-          (symmetricKeySize == NULL) || (ivSize == NULL)) {
-               return errSecParam;
-       }
-
-    SSLCipherSuite cipher=tls_handshake_get_negotiated_cipherspec(ctx->hdsk);
-
-       *digestSize = sslCipherSuiteGetMacSize(cipher);
-       *symmetricKeySize = sslCipherSuiteGetSymmetricCipherKeySize(cipher);
-       *ivSize = sslCipherSuiteGetSymmetricCipherBlockIvSize(cipher);
-       return errSecSuccess;
-}
-
-OSStatus
-SSLGetResumableSessionInfo(
-       SSLContextRef   ctx,
-       Boolean                 *sessionWasResumed,             // RETURNED
-       void                    *sessionID,                             // RETURNED, mallocd by caller
-       size_t                  *sessionIDLength)               // IN/OUT
-{
-       if((ctx == NULL) || (sessionWasResumed == NULL) ||
-          (sessionID == NULL) || (sessionIDLength == NULL) ||
-          (*sessionIDLength < MAX_SESSION_ID_LENGTH)) {
-               return errSecParam;
-       }
-
-    SSLBuffer localSessionID;
-    bool sessionMatch = tls_handshake_get_session_match(ctx->hdsk, &localSessionID);
-
-       if(sessionMatch) {
-               *sessionWasResumed = true;
-               if(localSessionID.length > *sessionIDLength) {
-                       /* really should never happen - means ID > 32 */
-                       return errSecParam;
-               }
-               if(localSessionID.length) {
-                       /*
-                        * Note PAC-based session resumption can result in sessionMatch
-                        * with no sessionID
-                        */
-                       memmove(sessionID, localSessionID.data, localSessionID.length);
-               }
-               *sessionIDLength = localSessionID.length;
-       }
-       else {
-               *sessionWasResumed = false;
-               *sessionIDLength = 0;
-       }
-       return errSecSuccess;
-}
-
-/*
- * Get/set enable of anonymous ciphers. Default is enabled.
- */
-OSStatus
-SSLSetAllowAnonymousCiphers(
-       SSLContextRef   ctx,
-       Boolean                 enable)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx)) {
-               return errSecBadReq;
-       }
-       if(ctx->validCipherSuites != NULL) {
-               /* SSLSetEnabledCiphers() has already been called */
-               return errSecBadReq;
-       }
-       ctx->anonCipherEnable = enable;
-       return errSecSuccess;
-}
-
-OSStatus
-SSLGetAllowAnonymousCiphers(
-       SSLContextRef   ctx,
-       Boolean                 *enable)
-{
-       if((ctx == NULL) || (enable == NULL)) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx)) {
-               return errSecBadReq;
-       }
-       *enable = ctx->anonCipherEnable;
-       return errSecSuccess;
-}
-
-/*
- * Override the default session cache timeout for a cache entry created for
- * the current session.
- */
-OSStatus
-SSLSetSessionCacheTimeout(
-       SSLContextRef ctx,
-       uint32_t timeoutInSeconds)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       ctx->sessionCacheTimeout = timeoutInSeconds;
-       return errSecSuccess;
-}
-
-
-static
-void tls_handshake_master_secret_function(const void *arg,         /* opaque to coreTLS; app-specific */
-                                          void *secret,                        /* mallocd by caller, SSL_MASTER_SECRET_SIZE */
-                                          size_t *secretLength)
-{
-    SSLContextRef ctx = (SSLContextRef) arg;
-    ctx->masterSecretCallback(ctx, ctx->masterSecretArg, secret, secretLength);
-}
-
-
-/*
- * Register a callback for obtaining the master_secret when performing
- * PAC-based session resumption.
- */
-OSStatus
-SSLInternalSetMasterSecretFunction(
-       SSLContextRef ctx,
-       SSLInternalMasterSecretFunction mFunc,
-       const void *arg)                /* opaque to SecureTransport; app-specific */
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-
-    ctx->masterSecretArg = arg;
-    ctx->masterSecretCallback = mFunc;
-
-    return tls_handshake_internal_set_master_secret_function(ctx->hdsk, &tls_handshake_master_secret_function, ctx);
-}
-
-/*
- * Provide an opaque SessionTicket for use in PAC-based session
- * resumption. Client side only. The provided ticket is sent in
- * the ClientHello message as a SessionTicket extension.
- *
- * We won't reject this on the server side, but server-side support
- * for PAC-based session resumption is currently enabled for
- * Development builds only. To fully support this for server side,
- * besides the rudimentary support that's here for Development builds,
- * we'd need a getter for the session ticket, so the app code can
- * access the SessionTicket when its SSLInternalMasterSecretFunction
- * callback is called.
- */
-OSStatus SSLInternalSetSessionTicket(
-   SSLContextRef ctx,
-   const void *ticket,
-   size_t ticketLength)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-    return tls_handshake_internal_set_session_ticket(ctx->hdsk, ticket, ticketLength);
-}
-
-
-/*
- * ECDSA curve accessors.
- */
-
-/*
- * Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
- * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
- */
-OSStatus SSLGetNegotiatedCurve(
-   SSLContextRef ctx,
-   SSL_ECDSA_NamedCurve *namedCurve)    /* RETURNED */
-{
-       if((ctx == NULL) || (namedCurve == NULL)) {
-               return errSecParam;
-       }
-    unsigned int curve = tls_handshake_get_negotiated_curve(ctx->hdsk);
-    if(curve == SSL_Curve_None) {
-               return errSecParam;
-       }
-       *namedCurve = curve;
-       return errSecSuccess;
-}
-
-/*
- * Obtain the number of currently enabled SSL_ECDSA_NamedCurves.
- */
-OSStatus SSLGetNumberOfECDSACurves(
-   SSLContextRef ctx,
-   unsigned *numCurves)        /* RETURNED */
-{
-       if((ctx == NULL) || (numCurves == NULL)) {
-               return errSecParam;
-       }
-       *numCurves = ctx->ecdhNumCurves;
-       return errSecSuccess;
-}
-
-/*
- * Obtain the ordered list of currently enabled SSL_ECDSA_NamedCurves.
- */
-OSStatus SSLGetECDSACurves(
-   SSLContextRef ctx,
-   SSL_ECDSA_NamedCurve *namedCurves,          /* RETURNED */
-   unsigned *numCurves)                                                /* IN/OUT */
-{
-       if((ctx == NULL) || (namedCurves == NULL) || (numCurves == NULL)) {
-               return errSecParam;
-       }
-       if(*numCurves < ctx->ecdhNumCurves) {
-               return errSecParam;
-       }
-       memmove(namedCurves, ctx->ecdhCurves,
-               (ctx->ecdhNumCurves * sizeof(SSL_ECDSA_NamedCurve)));
-       *numCurves = ctx->ecdhNumCurves;
-       return errSecSuccess;
-}
-
-/*
- * Specify ordered list of allowable named curves.
- */
-OSStatus SSLSetECDSACurves(
-   SSLContextRef ctx,
-   const SSL_ECDSA_NamedCurve *namedCurves,
-   unsigned numCurves)
-{
-       if((ctx == NULL) || (namedCurves == NULL) || (numCurves == 0)) {
-               return errSecParam;
-       }
-       if(sslIsSessionActive(ctx)) {
-               /* can't do this with an active session */
-               return errSecBadReq;
-       }
-
-       size_t size = numCurves * sizeof(uint16_t);
-       ctx->ecdhCurves = (uint16_t *)sslMalloc(size);
-       if(ctx->ecdhCurves == NULL) {
-               ctx->ecdhNumCurves = 0;
-               return errSecAllocate;
-       }
-
-    for (unsigned i=0; i<numCurves; i++) {
-        ctx->ecdhCurves[i] = namedCurves[i];
-    }
-
-       ctx->ecdhNumCurves = numCurves;
-
-    tls_handshake_set_curves(ctx->hdsk, ctx->ecdhCurves, ctx->ecdhNumCurves);
-       return errSecSuccess;
-}
-
-/*
- * Obtain the number of client authentication mechanisms specified by
- * the server in its Certificate Request message.
- * Returns errSecParam if server hasn't sent a Certificate Request message
- * (i.e., client certificate state is kSSLClientCertNone).
- */
-OSStatus SSLGetNumberOfClientAuthTypes(
-       SSLContextRef ctx,
-       unsigned *numTypes)
-{
-       if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
-               return errSecParam;
-       }
-       *numTypes = ctx->numAuthTypes;
-       return errSecSuccess;
-}
-
-/*
- * Obtain the client authentication mechanisms specified by
- * the server in its Certificate Request message.
- * Caller allocates returned array and specifies its size (in
- * SSLClientAuthenticationTypes) in *numType on entry; *numTypes
- * is the actual size of the returned array on successful return.
- */
-OSStatus SSLGetClientAuthTypes(
-   SSLContextRef ctx,
-   SSLClientAuthenticationType *authTypes,             /* RETURNED */
-   unsigned *numTypes)                                                 /* IN/OUT */
-{
-       if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
-               return errSecParam;
-       }
-       memmove(authTypes, ctx->clientAuthTypes,
-               ctx->numAuthTypes * sizeof(SSLClientAuthenticationType));
-       *numTypes = ctx->numAuthTypes;
-       return errSecSuccess;
-}
-
-/*
- * Obtain the SSLClientAuthenticationType actually performed.
- * Only valid if client certificate state is kSSLClientCertSent
- * or kSSLClientCertRejected; returns errSecParam otherwise.
- */
-OSStatus SSLGetNegotiatedClientAuthType(
-   SSLContextRef ctx,
-   SSLClientAuthenticationType *authType)              /* RETURNED */
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-
-       *authType = ctx->negAuthType;
-
-       return errSecSuccess;
-}
-
-/*
- * Update the negotiated client authentication type.
- * This function may be called at any time; however, note that
- * the negotiated authentication type will be SSLClientAuthNone
- * until both of the following have taken place (in either order):
- *   - a CertificateRequest message from the server has been processed
- *   - a client certificate has been specified
- * As such, this function (only) needs to be called from (both)
- * SSLProcessCertificateRequest and SSLSetCertificate.
- */
-OSStatus SSLUpdateNegotiatedClientAuthType(
-       SSLContextRef ctx)
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-    assert(ctx->protocolSide==kSSLClientSide);
-       /*
-        * See if we have a signing cert that matches one of the
-        * allowed auth types. The x509Requested flag indicates "we
-        * have a cert that we think the server will accept".
-        */
-       ctx->x509Requested = 0;
-       ctx->negAuthType = SSLClientAuthNone;
-       if(ctx->signingPrivKeyRef != NULL) {
-        CFIndex ourKeyAlg = sslPrivKeyGetAlgorithmID((SecKeyRef)tls_private_key_get_context(ctx->signingPrivKeyRef));
-        assert(ourKeyAlg==kSecRSAAlgorithmID); /* We don't suport anything else */
-
-               unsigned i;
-               for(i=0; i<ctx->numAuthTypes; i++) {
-                       switch(ctx->clientAuthTypes[i]) {
-                               case SSLClientAuth_RSASign:
-                                       if(ourKeyAlg == kSecRSAAlgorithmID) {
-                                               ctx->x509Requested = 1;
-                                               ctx->negAuthType = SSLClientAuth_RSASign;
-                                       }
-                                       break;
-#if 0
-// The code below is hopelessly broken: ctx->ourSignerAlg is never set
-                       #if SSL_ENABLE_ECDSA_SIGN_AUTH
-                               case SSLClientAuth_ECDSASign:
-                       #endif
-                       #if SSL_ENABLE_ECDSA_FIXED_ECDH_AUTH
-                               case SSLClientAuth_ECDSAFixedECDH:
-                       #endif
-                                       if((ourKeyAlg == kSecECDSAAlgorithmID) &&
-                                          (ctx->ourSignerAlg == kSecECDSAAlgorithmID)) {
-                                               ctx->x509Requested = 1;
-                                               ctx->negAuthType = ctx->clientAuthTypes[i];
-                                       }
-                                       break;
-                       #if SSL_ENABLE_RSA_FIXED_ECDH_AUTH
-                               case SSLClientAuth_RSAFixedECDH:
-                                       /* Odd case, we differ from our signer */
-                                       if((ourKeyAlg == kSecECDSAAlgorithmID) &&
-                                          (ctx->ourSignerAlg == kSecRSAAlgorithmID)) {
-                                               ctx->x509Requested = 1;
-                                               ctx->negAuthType = SSLClientAuth_RSAFixedECDH;
-                                       }
-                                       break;
-                       #endif
-#endif
-                               default:
-                                       /* None others supported */
-                                       break;
-                       }
-                       if(ctx->x509Requested) {
-                               sslLogNegotiateDebug("===CHOOSING authType %d", (int)ctx->negAuthType);
-                               break;
-                       }
-               }       /* parsing authTypes */
-       }       /* we have a signing key */
-
-    tls_handshake_set_client_auth_type(ctx->hdsk, ctx->negAuthType);
-
-       return errSecSuccess;
-}
-
-OSStatus SSLGetNumberOfSignatureAlgorithms(
-    SSLContextRef ctx,
-    unsigned *numSigAlgs)
-{
-       if(ctx == NULL){
-               return errSecParam;
-       }
-
-    tls_handshake_get_peer_signature_algorithms(ctx->hdsk, numSigAlgs);
-       return errSecSuccess;
-}
-
-_Static_assert(sizeof(SSLSignatureAndHashAlgorithm)==sizeof(tls_signature_and_hash_algorithm),
-               "SSLSignatureAndHashAlgorithm and tls_signature_and_hash_algorithm do not match");
-
-OSStatus SSLGetSignatureAlgorithms(
-    SSLContextRef ctx,
-    SSLSignatureAndHashAlgorithm *sigAlgs,             /* RETURNED */
-    unsigned *numSigAlgs)                                                      /* IN/OUT */
-{
-       if(ctx == NULL) {
-               return errSecParam;
-       }
-
-    unsigned numPeerSigAlgs;
-    const tls_signature_and_hash_algorithm *peerAlgs = tls_handshake_get_peer_signature_algorithms(ctx->hdsk, &numPeerSigAlgs);
-
-       memmove(sigAlgs, peerAlgs,
-            numPeerSigAlgs * sizeof(SSLSignatureAndHashAlgorithm));
-       *numSigAlgs = numPeerSigAlgs;
-    return errSecSuccess;
-}
-
-/* PSK SPIs */
-OSStatus SSLSetPSKSharedSecret(SSLContextRef ctx,
-                               const void *secret,
-                               size_t secretLen)
-{
-    if(ctx == NULL) return errSecParam;
-
-    if(ctx->pskSharedSecret.data)
-        SSLFreeBuffer(&ctx->pskSharedSecret);
-
-    if(SSLCopyBufferFromData(secret, secretLen, &ctx->pskSharedSecret))
-        return errSecAllocate;
-
-    tls_handshake_set_psk_secret(ctx->hdsk, &ctx->pskSharedSecret);
-
-    return errSecSuccess;
-}
-
-OSStatus SSLSetPSKIdentity(SSLContextRef ctx,
-                           const void *pskIdentity,
-                           size_t pskIdentityLen)
-{
-    if((ctx == NULL) || (pskIdentity == NULL) || (pskIdentityLen == 0)) return errSecParam;
-
-    if(ctx->pskIdentity.data)
-        SSLFreeBuffer(&ctx->pskIdentity);
-
-    if(SSLCopyBufferFromData(pskIdentity, pskIdentityLen, &ctx->pskIdentity))
-        return errSecAllocate;
-
-    tls_handshake_set_psk_identity(ctx->hdsk, &ctx->pskIdentity);
-
-    return errSecSuccess;
-
-}
-
-OSStatus SSLGetPSKIdentity(SSLContextRef ctx,
-                           const void **pskIdentity,
-                           size_t *pskIdentityLen)
-{
-    if((ctx == NULL) || (pskIdentity == NULL) || (pskIdentityLen == NULL)) return errSecParam;
-
-    *pskIdentity=ctx->pskIdentity.data;
-    *pskIdentityLen=ctx->pskIdentity.length;
-
-    return errSecSuccess;
-}
-
-OSStatus SSLInternal_PRF(
-                         SSLContext *ctx,
-                         const void *vsecret,
-                         size_t secretLen,
-                         const void *label,                    // optional, NULL implies that seed contains
-                         //   the label
-                         size_t labelLen,
-                         const void *seed,
-                         size_t seedLen,
-                         void *vout,                                   // mallocd by caller, length >= outLen
-                         size_t outLen)
-{
-    return tls_handshake_internal_prf(ctx->hdsk,
-                                      vsecret, secretLen,
-                                      label, labelLen,
-                                      seed, seedLen,
-                                      vout, outLen);
-}
-
-