* 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 "sslMemory.h"
-#include "sslDigests.h"
-#include "sslDebug.h"
#include "sslCrypto.h"
+#include "sslDebug.h"
+#include "sslDigests.h"
+#include "sslKeychain.h"
+#include "sslMemory.h"
+#include "sslUtils.h"
-#include "SecureTransport.h"
-
+#include <AssertMacros.h>
#include <CoreFoundation/CFData.h>
#include <CoreFoundation/CFPreferences.h>
-
+#include <Security/SecCertificate.h>
+#include <Security/SecCertificatePriv.h>
#include <Security/SecTrust.h>
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
-#include <Security/oidsalg.h>
#include <Security/SecTrustSettingsPriv.h>
-#endif
-
-#include "sslKeychain.h"
-#include "sslUtils.h"
-#include "cipherSpecs.h"
-#include "appleSession.h"
-#include "SecureTransportPriv.h"
-#include <string.h>
+#include <Security/oidsalg.h>
+#include "utilities/SecCFRelease.h"
#include <pthread.h>
-#include <Security/SecCertificate.h>
-#include <Security/SecCertificatePriv.h>
+#include <string.h>
+
+#if TARGET_OS_IPHONE
#include <Security/SecCertificateInternal.h>
-#include <Security/SecInternal.h>
-#include <Security/SecTrust.h>
+#else
#include <Security/oidsalg.h>
+#include <Security/oidscert.h>
#include <Security/SecTrustSettingsPriv.h>
-#include <AssertMacros.h>
+#endif
+
static void sslFreeDnList(
SSLContext *ctx)
dn = ctx->acceptableDNList;
while (dn)
- {
- SSLFreeBuffer(&dn->derDN, ctx);
+ {
+ SSLFreeBuffer(&dn->derDN);
nextDN = dn->next;
sslFree(dn);
dn = nextDN;
ctx->acceptableDNList = NULL;
}
-#define min(a,b) ( ((a) < (b)) ? (a) : (b) )
-#define max(a,b) ( ((a) > (b)) ? (a) : (b) )
+
+Boolean sslIsSessionActive(const SSLContext *ctx)
+{
+ assert(ctx != NULL);
+ switch(ctx->state) {
+ case SSL_HdskStateUninit:
+ case SSL_HdskStateServerUninit:
+ case SSL_HdskStateClientUninit:
+ case SSL_HdskStateGracefulClose:
+ case SSL_HdskStateErrorClose:
+ return false;
+ default:
+ return true;
+ }
+}
/*
* Minimum and maximum supported versions
static CFTypeID kSSLContextTypeID;
int kSplitDefaultValue;
+bool kAllowServerIdentityChangeDefaultValue;
static void _sslContextDestroy(CFTypeRef arg);
static Boolean _sslContextEqual(CFTypeRef a, CFTypeRef b);
static void _SSLContextReadDefault()
{
+ /* 0 = disabled, 1 = split every write, 2 = split second and subsequent writes */
+ /* Enabled by default, this make cause some interop issues, see <rdar://problem/12307662> and <rdar://problem/12323307> */
+ const int defaultSplitDefaultValue = 2;
+ //To change:
+ //sudo defaults write /Library/Preferences/com.apple.security SSLWriteSplit -int 0
CFTypeRef value = (CFTypeRef)CFPreferencesCopyValue(CFSTR("SSLWriteSplit"),
CFSTR("com.apple.security"),
kCFPreferencesAnyUser,
- kCFPreferencesAnyHost);
+ 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 = 0;
+ kSplitDefaultValue = defaultSplitDefaultValue;
}
if (kSplitDefaultValue < 0 || kSplitDefaultValue > 2) {
- kSplitDefaultValue = 0;
+ kSplitDefaultValue = defaultSplitDefaultValue;
}
CFRelease(value);
}
else {
- kSplitDefaultValue = 0;
+ kSplitDefaultValue = defaultSplitDefaultValue;
+ }
+
+
+ /* 0 = disallowed, 1 = allowed */
+ /* Disallowed by default */
+ const bool defaultValue = false;
+ //To change:
+ //sudo defaults write /Library/Preferences/com.apple.security SSLAllowServerIdentityChange -bool YES
+ value = (CFTypeRef)CFPreferencesCopyValue(CFSTR("SSLAllowServerIdentityChange"),
+ CFSTR("com.apple.security"),
+ kCFPreferencesAnyUser,
+ kCFPreferencesCurrentHost);
+ if (value) {
+ if (CFGetTypeID(value) == CFBooleanGetTypeID())
+ kAllowServerIdentityChangeDefaultValue = CFBooleanGetValue((CFBooleanRef)value);
+ else if (CFGetTypeID(value) == CFNumberGetTypeID()) {
+ int localValue;
+ if (!CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &localValue)) {
+ kAllowServerIdentityChangeDefaultValue = defaultValue;
+ } else {
+ kAllowServerIdentityChangeDefaultValue = localValue;
+ }
+ }
+ CFRelease(value);
+ }
+ else {
+ kAllowServerIdentityChangeDefaultValue = defaultValue;
}
}
SSLContextRef *contextPtr) /* RETURNED */
{
if(contextPtr == NULL) {
- return paramErr;
+ return errSecParam;
}
*contextPtr = SSLCreateContext(kCFAllocatorDefault, isServer?kSSLServerSide:kSSLClientSide, kSSLStreamType);
if (*contextPtr == NULL)
- return memFullErr;
+ return errSecAllocate;
- return noErr;
+ return errSecSuccess;
}
SSLContextRef SSLCreateContext(CFAllocatorRef alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType)
{
- OSStatus serr = noErr;
+ SSLContextRef ctx;
+
+ ctx = SSLCreateContextWithRecordFuncs(alloc, protocolSide, connectionType, &SSLRecordLayerInternal);
+
+ if(ctx==NULL)
+ return NULL;
+
+ ctx->recCtx = SSLCreateInternalRecordLayer(connectionType);
+ if(ctx->recCtx==NULL) {
+ CFRelease(ctx);
+ return NULL;
+ }
+
+ 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) {
/* Default value so we can send and receive hello msgs */
ctx->sslTslCalls = &Ssl3Callouts;
- /* Initialize the cipher state to NULL_WITH_NULL_NULL */
+ ctx->recFuncs = recFuncs;
+ /* Initialize the cipher state to NULL_WITH_NULL_NULL */
ctx->selectedCipher = TLS_NULL_WITH_NULL_NULL;
- InitCipherSpec(ctx);
- ctx->writeCipher.macRef = ctx->selectedCipherSpec.macAlgorithm;
- ctx->readCipher.macRef = ctx->selectedCipherSpec.macAlgorithm;
- ctx->readCipher.symCipher = ctx->selectedCipherSpec.cipher;
- ctx->writeCipher.symCipher = ctx->selectedCipherSpec.cipher;
-
- /* these two are invariant */
- ctx->writeCipher.encrypting = 1;
- ctx->writePending.encrypting = 1;
+ InitCipherSpecParams(ctx);
/* this gets init'd on first call to SSLHandshake() */
ctx->validCipherSuites = NULL;
/* Default for sending one-byte app data record is DISABLED */
ctx->oneByteRecordEnable = false;
+ /* Default for allowing server identity change on renegotiation is FALSE */
+ ctx->allowServerIdentityChange = 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)
pthread_once(&sReadDefault, _SSLContextReadDefault);
if (kSplitDefaultValue > 0)
ctx->oneByteRecordEnable = true;
+ if (kAllowServerIdentityChangeDefaultValue>0)
+ ctx->allowServerIdentityChange = true;
/* default for anonymous ciphers is DISABLED */
ctx->anonCipherEnable = false;
ctx->ecdhPeerCurve = SSL_Curve_None; /* until we negotiate one */
ctx->negAuthType = SSLClientAuthNone; /* ditto */
- ctx->recordWriteQueue = NULL;
ctx->messageWriteQueue = NULL;
if(connectionType==kSSLDatagramType) {
- ctx->minProtocolVersion = MINIMUM_DATAGRAM_VERSION;
- ctx->maxProtocolVersion = MAXIMUM_DATAGRAM_VERSION;
+ ctx->minProtocolVersion = MINIMUM_DATAGRAM_VERSION;
+ ctx->maxProtocolVersion = MAXIMUM_DATAGRAM_VERSION;
ctx->isDTLS = true;
}
ctx->secure_renegotiation = false;
-#ifdef USE_CDSA_CRYPTO
-errOut:
-#endif /* USE_CDSA_CRYPTO */
- if (serr != noErr) {
+ if (serr != errSecSuccess) {
CFRelease(ctx);
ctx = NULL;
}
SSLContextRef *contextPtr) /* RETURNED */
{
if (contextPtr == NULL)
- return paramErr;
+ return errSecParam;
*contextPtr = SSLCreateContext(kCFAllocatorDefault, isServer?kSSLServerSide:kSSLClientSide, kSSLDatagramType);
if (*contextPtr == NULL)
- return memFullErr;
- return noErr;
+ return errSecAllocate;
+ return errSecSuccess;
}
/*
SSLDisposeContext (SSLContextRef context)
{
if(context == NULL) {
- return paramErr;
+ return errSecParam;
}
CFRelease(context);
- return noErr;
+ return errSecSuccess;
}
-CFStringRef _sslContextDescribe(CFTypeRef arg)
+CF_RETURNS_RETAINED CFStringRef _sslContextDescribe(CFTypeRef arg)
{
SSLContext* ctx = (SSLContext*) arg;
void _sslContextDestroy(CFTypeRef arg)
{
SSLContext* ctx = (SSLContext*) arg;
- WaitingRecord *waitRecord, *next;
#if USE_SSLCERTIFICATE
sslDeleteCertificateChain(ctx->localCert, ctx);
/* Free the last handshake message flight */
SSLResetFlight(ctx);
- SSLFreeBuffer(&ctx->partialReadBuffer, ctx);
- if(ctx->peerSecTrust) {
+ if(ctx->peerSecTrust) {
CFRelease(ctx->peerSecTrust);
ctx->peerSecTrust = NULL;
}
- waitRecord = ctx->recordWriteQueue;
- while (waitRecord)
- { next = waitRecord->next;
- sslFree(waitRecord);
- waitRecord = next;
- }
- SSLFreeBuffer(&ctx->sessionTicket, ctx);
-
+ SSLFreeBuffer(&ctx->sessionTicket);
+
#if APPLE_DH
- SSLFreeBuffer(&ctx->dhParamsEncoded, ctx);
+ SSLFreeBuffer(&ctx->dhParamsEncoded);
#ifdef USE_CDSA_CRYPTO
sslFreeKey(ctx->cspHand, &ctx->dhPrivate, NULL);
#else
if (ctx->secDHContext)
SecDHDestroy(ctx->secDHContext);
#endif /* !USE_CDSA_CRYPTO */
- SSLFreeBuffer(&ctx->dhPeerPublic, ctx);
- SSLFreeBuffer(&ctx->dhExchangePublic, ctx);
+ SSLFreeBuffer(&ctx->dhPeerPublic);
+ SSLFreeBuffer(&ctx->dhExchangePublic);
#endif /* APPLE_DH */
- SSLFreeBuffer(&ctx->ecdhPeerPublic, ctx);
- SSLFreeBuffer(&ctx->ecdhExchangePublic, ctx);
+ SSLFreeBuffer(&ctx->ecdhPeerPublic);
+ SSLFreeBuffer(&ctx->ecdhExchangePublic);
#if USE_CDSA_CRYPTO
if(ctx->ecdhPrivCspHand == ctx->cspHand) {
sslFreeKey(ctx->ecdhPrivCspHand, &ctx->ecdhPrivate, NULL);
/* else we got this key from a SecKeyRef, no free needed */
#endif
- CloseHash(&SSLHashSHA1, &ctx->shaState, ctx);
- CloseHash(&SSLHashMD5, &ctx->md5State, ctx);
- CloseHash(&SSLHashSHA256, &ctx->sha256State, ctx);
- CloseHash(&SSLHashSHA384, &ctx->sha512State, ctx);
+ /* Only destroy if we were using the internal record layer */
+ if(ctx->recFuncs==&SSLRecordLayerInternal)
+ SSLDestroyInternalRecordLayer(ctx->recCtx);
+
+ CloseHash(&SSLHashSHA1, &ctx->shaState);
+ CloseHash(&SSLHashMD5, &ctx->md5State);
+ CloseHash(&SSLHashSHA256, &ctx->sha256State);
+ CloseHash(&SSLHashSHA384, &ctx->sha512State);
- SSLFreeBuffer(&ctx->sessionID, ctx);
- SSLFreeBuffer(&ctx->peerID, ctx);
- SSLFreeBuffer(&ctx->resumableSession, ctx);
- SSLFreeBuffer(&ctx->preMasterSecret, ctx);
- SSLFreeBuffer(&ctx->partialReadBuffer, ctx);
- SSLFreeBuffer(&ctx->fragmentedMessageCache, ctx);
- SSLFreeBuffer(&ctx->receivedDataBuffer, ctx);
+ SSLFreeBuffer(&ctx->sessionID);
+ SSLFreeBuffer(&ctx->peerID);
+ SSLFreeBuffer(&ctx->resumableSession);
+ SSLFreeBuffer(&ctx->preMasterSecret);
+ SSLFreeBuffer(&ctx->fragmentedMessageCache);
+ SSLFreeBuffer(&ctx->receivedDataBuffer);
if(ctx->peerDomainName) {
sslFree(ctx->peerDomainName);
ctx->peerDomainName = NULL;
ctx->peerDomainNameLen = 0;
}
- SSLDisposeCipherSuite(&ctx->readCipher, ctx);
- SSLDisposeCipherSuite(&ctx->writeCipher, ctx);
- SSLDisposeCipherSuite(&ctx->readPending, ctx);
- SSLDisposeCipherSuite(&ctx->writePending, ctx);
sslFree(ctx->validCipherSuites);
ctx->validCipherSuites = NULL;
}
sslFreeDnList(ctx);
- SSLFreeBuffer(&ctx->ownVerifyData, ctx);
- SSLFreeBuffer(&ctx->peerVerifyData, ctx);
+ SSLFreeBuffer(&ctx->ownVerifyData);
+ SSLFreeBuffer(&ctx->peerVerifyData);
+
+ SSLFreeBuffer(&ctx->pskIdentity);
+ SSLFreeBuffer(&ctx->pskSharedSecret);
memset(((uint8_t*) ctx) + sizeof(CFRuntimeBase), 0, sizeof(SSLContext) - sizeof(CFRuntimeBase));
SSLSessionState rtnState = kSSLIdle;
if(context == NULL) {
- return paramErr;
+ return errSecParam;
}
*state = rtnState;
switch(context->state) {
break;
default:
assert((context->state >= SSL_HdskStateServerHello) &&
- (context->state <= SSL2_HdskStateServerFinished));
+ (context->state <= SSL_HdskStateFinished));
rtnState = kSSLHandshake;
break;
}
*state = rtnState;
- return noErr;
+ return errSecSuccess;
}
/*
SSLSessionOption option,
Boolean value)
{
- if(context == NULL) {
- return paramErr;
- }
- if(sslIsSessionActive(context)) {
- /* can't do this with an active session */
- return badReqErr;
- }
+ 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->breakOnClientAuth = value;
context->enableCertVerify = !value;
break;
- case kSSLSessionOptionSendOneByteRecord:
- context->oneByteRecordEnable = value;
- break;
- default:
- return paramErr;
+ case kSSLSessionOptionSendOneByteRecord:
+ context->oneByteRecordEnable = value;
+ break;
+ case kSSLSessionOptionFalseStart:
+ context->falseStartEnabled = value;
+ break;
+ case kSSLSessionOptionAllowServerIdentityChange:
+ context->allowServerIdentityChange = value;
+ break;
+ default:
+ return errSecParam;
}
- return noErr;
+ return errSecSuccess;
}
/*
SSLSessionOption option,
Boolean *value)
{
- if(context == NULL || value == NULL) {
- return paramErr;
- }
+ if(context == NULL || value == NULL) {
+ return errSecParam;
+ }
switch(option) {
case kSSLSessionOptionBreakOnServerAuth:
*value = context->breakOnServerAuth;
case kSSLSessionOptionBreakOnClientAuth:
*value = context->breakOnClientAuth;
break;
- case kSSLSessionOptionSendOneByteRecord:
- *value = context->oneByteRecordEnable;
- break;
+ case kSSLSessionOptionSendOneByteRecord:
+ *value = context->oneByteRecordEnable;
+ break;
+ case kSSLSessionOptionFalseStart:
+ *value = context->falseStartEnabled;
+ break;
default:
- return paramErr;
+ return errSecParam;
}
- return noErr;
+ return errSecSuccess;
}
OSStatus
-SSLSetIOFuncs (SSLContextRef ctx,
+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 paramErr;
+ 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 badReqErr;
+ return errSecBadReq;
}
- ctx->ioCtx.read = readFunc;
- ctx->ioCtx.write = writeFunc;
- return noErr;
+ ctx->ioCtx.read=readFunc;
+ ctx->ioCtx.write=writeFunc;
+
+ return SSLSetInternalRecordLayerIOFuncs(ctx->recCtx, IORead, IOWrite);
}
OSStatus
SSLConnectionRef connection)
{
if(ctx == NULL) {
- return paramErr;
+ 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 badReqErr;
+ return errSecBadReq;
}
- ctx->ioCtx.ioRef = connection;
- return noErr;
+ /* Need to keep a copy of it this layer for the Get function */
+ ctx->ioCtx.ioRef = connection;
+
+ return SSLSetInternalRecordLayerConnection(ctx->recCtx, ctx);
}
OSStatus
SSLConnectionRef *connection)
{
if((ctx == NULL) || (connection == NULL)) {
- return paramErr;
+ return errSecParam;
}
*connection = ctx->ioCtx.ioRef;
- return noErr;
+ return errSecSuccess;
}
OSStatus
size_t peerNameLen)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx)) {
/* can't do this with an active session */
- return badReqErr;
+ return errSecBadReq;
}
/* free possible existing name */
/* copy in */
ctx->peerDomainName = (char *)sslMalloc(peerNameLen);
if(ctx->peerDomainName == NULL) {
- return memFullErr;
+ return errSecAllocate;
}
memmove(ctx->peerDomainName, peerName, peerNameLen);
ctx->peerDomainNameLen = peerNameLen;
- return noErr;
+ return errSecSuccess;
}
/*
size_t *peerNameLen) // RETURNED
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
*peerNameLen = ctx->peerDomainNameLen;
- return noErr;
+ return errSecSuccess;
}
OSStatus
size_t *peerNameLen) // IN/OUT
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(*peerNameLen < ctx->peerDomainNameLen) {
return errSSLBufferOverflow;
}
memmove(peerName, ctx->peerDomainName, ctx->peerDomainNameLen);
*peerNameLen = ctx->peerDomainNameLen;
- return noErr;
+ return errSecSuccess;
}
OSStatus
OSStatus err;
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
- if(!ctx->isDTLS) return paramErr;
+ if(!ctx->isDTLS) return errSecParam;
if((ctx == NULL) || (cookieLen>32)) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx)) {
/* can't do this with an active session */
- return badReqErr;
+ return errSecBadReq;
}
/* free possible existing cookie */
if(ctx->dtlsCookie.data) {
- SSLFreeBuffer(&ctx->dtlsCookie, ctx);
+ SSLFreeBuffer(&ctx->dtlsCookie);
}
/* copy in */
- if((err=SSLAllocBuffer(&ctx->dtlsCookie, cookieLen, ctx))!=noErr)
+ if((err=SSLAllocBuffer(&ctx->dtlsCookie, cookieLen)))
return err;
memmove(ctx->dtlsCookie.data, cookie, cookieLen);
- return noErr;
+ return errSecSuccess;
}
OSStatus
size_t maxSize)
{
- if(ctx == NULL) return paramErr;
- if(!ctx->isDTLS) return paramErr;
- if(maxSize < MIN_ALLOWED_DTLS_MTU) return paramErr;
+ if(ctx == NULL) return errSecParam;
+ if(!ctx->isDTLS) return errSecParam;
+ if(maxSize < MIN_ALLOWED_DTLS_MTU) return errSecParam;
ctx->mtu = maxSize;
- return noErr;
+ return errSecSuccess;
}
OSStatus
SSLGetMaxDatagramRecordSize (SSLContextRef ctx,
size_t *maxSize)
{
- if(ctx == NULL) return paramErr;
- if(!ctx->isDTLS) return paramErr;
+ if(ctx == NULL) return errSecParam;
+ if(!ctx->isDTLS) return errSecParam;
*maxSize = ctx->mtu;
- return noErr;
+ return errSecSuccess;
}
/*
SSLGetDatagramWriteSize (SSLContextRef ctx,
size_t *bufSize)
{
- if(ctx == NULL) return paramErr;
- if(!ctx->isDTLS) return paramErr;
- if(bufSize == NULL) return paramErr;
+ 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 */
- UInt16 blockSize = ctx->writeCipher.symCipher->blockSize;
+ SSLCipherSpecParams *currCipher = &ctx->selectedCipherSpecParams;
+
+ size_t blockSize = currCipher->blockSize;
+ size_t macSize = currCipher->macSize;
if (blockSize > 0) {
/* max_fragment_size must be a multiple of blocksize */
}
/* less the mac size */
- max_fragment_size -= ctx->writeCipher.macRef->hash->digestSize;
+ max_fragment_size -= macSize;
/* Thats just a sanity check */
assert(max_fragment_size<ctx->mtu);
*bufSize = max_fragment_size;
- return noErr;
+ return errSecSuccess;
}
static SSLProtocolVersion SSLProtocolToProtocolVersion(SSLProtocol protocol) {
SSLSetProtocolVersionMin (SSLContextRef ctx,
SSLProtocol minVersion)
{
- if(ctx == NULL) return paramErr;
+ if(ctx == NULL) return errSecParam;
SSLProtocolVersion version = SSLProtocolToProtocolVersion(minVersion);
if (ctx->isDTLS) {
}
ctx->minProtocolVersion = version;
- return noErr;
+ return errSecSuccess;
}
OSStatus
SSLGetProtocolVersionMin (SSLContextRef ctx,
SSLProtocol *minVersion)
{
- if(ctx == NULL) return paramErr;
+ if(ctx == NULL) return errSecParam;
*minVersion = SSLProtocolVersionToProtocol(ctx->minProtocolVersion);
- return noErr;
+ return errSecSuccess;
}
OSStatus
SSLSetProtocolVersionMax (SSLContextRef ctx,
SSLProtocol maxVersion)
{
- if(ctx == NULL) return paramErr;
+ if(ctx == NULL) return errSecParam;
SSLProtocolVersion version = SSLProtocolToProtocolVersion(maxVersion);
if (ctx->isDTLS) {
}
ctx->maxProtocolVersion = version;
- return noErr;
+ return errSecSuccess;
}
OSStatus
SSLGetProtocolVersionMax (SSLContextRef ctx,
SSLProtocol *maxVersion)
{
- if(ctx == NULL) return paramErr;
+ if(ctx == NULL) return errSecParam;
*maxVersion = SSLProtocolVersionToProtocol(ctx->maxProtocolVersion);
- return noErr;
+ return errSecSuccess;
}
+#define max(x,y) ((x)<(y)?(y):(x))
OSStatus
SSLSetProtocolVersionEnabled(SSLContextRef ctx,
Boolean enable)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx) || ctx->isDTLS) {
/* Can't do this with an active session, nor with a DTLS session */
- return badReqErr;
+ return errSecBadReq;
}
if (protocol == kSSLProtocolAll) {
if (enable) {
SSLProtocolVersion version = SSLProtocolToProtocolVersion(protocol);
if (enable) {
if (version < MINIMUM_STREAM_VERSION || version > MAXIMUM_STREAM_VERSION) {
- return paramErr;
+ return errSecParam;
}
if (version > ctx->maxProtocolVersion) {
ctx->maxProtocolVersion = version;
}
} else {
if (version < SSL_Version_2_0 || version > MAXIMUM_STREAM_VERSION) {
- return paramErr;
+ return errSecParam;
}
/* Disabling a protocol version now resets the minimum acceptable
* version to the next higher version. This means it's no longer
}
}
- return noErr;
+ return errSecSuccess;
}
OSStatus
Boolean *enable) /* RETURNED */
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(ctx->isDTLS) {
/* Can't do this with a DTLS session */
- return badReqErr;
+ return errSecBadReq;
}
switch(protocol) {
case kSSLProtocol2:
&& ctx->maxProtocolVersion >= MAXIMUM_STREAM_VERSION);
break;
default:
- return paramErr;
+ return errSecParam;
}
- return noErr;
+ return errSecSuccess;
}
/* deprecated */
SSLProtocol version)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx) || ctx->isDTLS) {
/* Can't do this with an active session, nor with a DTLS session */
- return badReqErr;
+ return errSecBadReq;
}
switch(version) {
ctx->maxProtocolVersion = MAXIMUM_STREAM_VERSION;
break;
default:
- return paramErr;
+ return errSecParam;
}
- return noErr;
+ return errSecSuccess;
}
/* deprecated */
SSLProtocol *protocol) /* RETURNED */
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
/* translate array of booleans to public value; not all combinations
* are legal (i.e., meaningful) for this call */
if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
/* traditional 'all enabled' */
*protocol = kSSLProtocolAll;
- return noErr;
+ return errSecSuccess;
}
} else if (ctx->maxProtocolVersion == TLS_Version_1_1) {
if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
/* traditional 'all enabled' */
*protocol = kTLSProtocol11;
- return noErr;
+ return errSecSuccess;
}
} else if (ctx->maxProtocolVersion == TLS_Version_1_0) {
if(ctx->minProtocolVersion == MINIMUM_STREAM_VERSION) {
/* TLS1.1 and below enabled */
*protocol = kTLSProtocol1;
- return noErr;
+ return errSecSuccess;
} else if(ctx->minProtocolVersion == TLS_Version_1_0) {
*protocol = kTLSProtocol1Only;
}
/* Could also return kSSLProtocol3Only since
MINIMUM_STREAM_VERSION == SSL_Version_3_0. */
*protocol = kSSLProtocol3;
- return noErr;
+ return errSecSuccess;
}
}
- return paramErr;
+ return errSecParam;
}
OSStatus
SSLProtocol *protocol) /* RETURNED */
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
*protocol = SSLProtocolVersionToProtocol(ctx->negProtocolVersion);
- return noErr;
+ return errSecSuccess;
}
OSStatus
Boolean enableVerify)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
sslCertDebug("SSLSetEnableCertVerify %s",
enableVerify ? "true" : "false");
if(sslIsSessionActive(ctx)) {
/* can't do this with an active session */
- return badReqErr;
+ return errSecBadReq;
}
ctx->enableCertVerify = enableVerify;
- return noErr;
+ return errSecSuccess;
}
OSStatus
Boolean *enableVerify)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
*enableVerify = ctx->enableCertVerify;
- return noErr;
+ return errSecSuccess;
}
OSStatus
Boolean allowExpired)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
sslCertDebug("SSLSetAllowsExpiredCerts %s",
allowExpired ? "true" : "false");
if(sslIsSessionActive(ctx)) {
/* can't do this with an active session */
- return badReqErr;
+ return errSecBadReq;
}
ctx->allowExpiredCerts = allowExpired;
- return noErr;
+ return errSecSuccess;
}
OSStatus
Boolean *allowExpired)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
*allowExpired = ctx->allowExpiredCerts;
- return noErr;
+ return errSecSuccess;
}
OSStatus
Boolean allowExpired)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
sslCertDebug("SSLSetAllowsExpiredRoots %s",
allowExpired ? "true" : "false");
if(sslIsSessionActive(ctx)) {
/* can't do this with an active session */
- return badReqErr;
+ return errSecBadReq;
}
ctx->allowExpiredRoots = allowExpired;
- return noErr;
+ return errSecSuccess;
}
OSStatus
Boolean *allowExpired)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
*allowExpired = ctx->allowExpiredRoots;
- return noErr;
+ return errSecSuccess;
}
OSStatus SSLSetAllowsAnyRoot(
Boolean anyRoot)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot ? "true" : "false");
ctx->allowAnyRoot = anyRoot;
- return noErr;
+ return errSecSuccess;
}
OSStatus
Boolean *anyRoot)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
*anyRoot = ctx->allowAnyRoot;
- return noErr;
+ return errSecSuccess;
}
-#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+#if !TARGET_OS_IPHONE
/* obtain the system roots sets for this app, policy SSL */
static OSStatus sslDefaultSystemRoots(
SSLContextRef ctx,
{
return SecTrustSettingsCopyQualifiedCerts(&CSSMOID_APPLE_TP_SSL,
- NULL, true, // application - us
ctx->peerDomainName,
- ctx->peerDomainNameLen,
+ (uint32_t)ctx->peerDomainNameLen,
(ctx->protocolSide == kSSLServerSide) ?
/* server verifies, client encrypts */
CSSM_KEYUSE_VERIFY : CSSM_KEYUSE_ENCRYPT,
{
#ifdef USE_CDSA_CRYPTO
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx)) {
/* can't do this with an active session */
- return badReqErr;
+ return errSecBadReq;
}
if(replaceExisting) {
CFRetain(trustedRoots);
CFReleaseSafe(ctx->trustedCerts);
ctx->trustedCerts = trustedRoots;
- return noErr;
+ return errSecSuccess;
}
/* adding new trusted roots - to either our existing set, or the system set */
CFArrayAppendArray(newRoots, existingRoots, existRange);
CFRelease(existingRoots);
ctx->trustedCerts = newRoots;
- return noErr;
+ return errSecSuccess;
#else
if (sslIsSessionActive(ctx)) {
/* can't do this with an active session */
- return badReqErr;
+ return errSecBadReq;
}
sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s",
(int)CFArrayGetCount(trustedRoots), replaceExisting ? "true" : "false");
errOut);
}
- return noErr;
+ return errSecSuccess;
errOut:
- return memFullErr;
+ return errSecAllocate;
#endif /* !USE_CDSA_CRYPTO */
}
CFArrayRef *trustedRoots) /* RETURNED */
{
if(ctx == NULL || trustedRoots == NULL) {
- return paramErr;
+ return errSecParam;
}
if(ctx->trustedCerts != NULL) {
*trustedRoots = ctx->trustedCerts;
CFRetain(ctx->trustedCerts);
- return noErr;
+ return errSecSuccess;
}
#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
/* use default system roots */
return sslDefaultSystemRoots(ctx, trustedRoots);
#else
*trustedRoots = NULL;
- return noErr;
+ return errSecSuccess;
#endif
}
-/* legacy version, caller must CFRelease each cert */
-OSStatus
-SSLGetTrustedRoots (SSLContextRef ctx,
- CFArrayRef *trustedRoots) /* RETURNED */
-{
- OSStatus ortn;
-
- if((ctx == NULL) || (trustedRoots == NULL)) {
- return paramErr;
- }
-
- ortn = SSLCopyTrustedRoots(ctx, trustedRoots);
- if(ortn) {
- return ortn;
- }
- /* apply the legacy bug */
- CFIndex numCerts = CFArrayGetCount(*trustedRoots);
- CFIndex dex;
- for(dex=0; dex<numCerts; dex++) {
- CFRetain(CFArrayGetValueAtIndex(*trustedRoots, dex));
- }
- return noErr;
-}
-
OSStatus
SSLSetTrustedLeafCertificates (SSLContextRef ctx,
CFArrayRef trustedCerts)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx)) {
/* can't do this with an active session */
- return badReqErr;
+ return errSecBadReq;
}
if(ctx->trustedLeafCerts) {
}
ctx->trustedLeafCerts = trustedCerts;
CFRetain(trustedCerts);
- return noErr;
+ return errSecSuccess;
}
OSStatus
CFArrayRef *trustedCerts) /* RETURNED */
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(ctx->trustedLeafCerts != NULL) {
*trustedCerts = ctx->trustedLeafCerts;
CFRetain(ctx->trustedCerts);
- return noErr;
+ return errSecSuccess;
}
*trustedCerts = NULL;
- return noErr;
+ return errSecSuccess;
}
OSStatus
SSLAuthenticate auth)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx)) {
/* can't do this with an active session */
- return badReqErr;
+ return errSecBadReq;
}
ctx->clientAuth = auth;
switch(auth) {
ctx->tryClientAuth = true;
break;
}
- return noErr;
+ return errSecSuccess;
}
OSStatus
SSLAuthenticate *auth) /* RETURNED */
{
if(ctx == NULL || auth == NULL) {
- return paramErr;
+ return errSecParam;
}
*auth = ctx->clientAuth;
- return noErr;
+ return errSecSuccess;
}
OSStatus
SSLClientCertificateState *clientState)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
*clientState = ctx->clientCertState;
- return noErr;
+ return errSecSuccess;
}
OSStatus
* -- validate cert chain
*/
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
/* can't do this with an active session */
/* kSSLClientCertRequested implies client side */
(ctx->clientCertState != kSSLClientCertRequested))
{
- return badReqErr;
+ return errSecBadReq;
}
CFReleaseNull(ctx->localCertArray);
/* changing the client cert invalidates negotiated auth type */
ctx->negAuthType = SSLClientAuthNone;
if(certRefs == NULL) {
- return noErr; // we have cleared the cert, as requested
+ return errSecSuccess; // we have cleared the cert, as requested
}
OSStatus ortn = parseIncomingCerts(ctx,
certRefs,
&ctx->signingPubKey,
&ctx->signingPrivKeyRef,
&ctx->ourSignerAlg);
- if(ortn == noErr) {
+ if(ortn == errSecSuccess) {
ctx->localCertArray = certRefs;
CFRetain(certRefs);
/* client cert was changed, must update auth type */
* -- validate cert chain
*/
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx)) {
/* can't do this with an active session */
- return badReqErr;
+ return errSecBadReq;
}
CFReleaseNull(ctx->encryptCertArray);
OSStatus ortn = parseIncomingCerts(ctx,
&ctx->encryptPubKey,
&ctx->encryptPrivKeyRef,
NULL); /* Signer alg */
- if(ortn == noErr) {
+ if(ortn == errSecSuccess) {
ctx->encryptCertArray = certRefs;
CFRetain(certRefs);
}
CFArrayRef *certRefs)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
*certRefs = ctx->localCertArray;
- return noErr;
+ return errSecSuccess;
}
OSStatus SSLGetEncryptionCertificate(SSLContextRef ctx,
CFArrayRef *certRefs)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
*certRefs = ctx->encryptCertArray;
- return noErr;
+ return errSecSuccess;
}
OSStatus
if((ctx == NULL) ||
(peerID == NULL) ||
(peerIDLen == 0)) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx) &&
/* kSSLClientCertRequested implies client side */
(ctx->clientCertState != kSSLClientCertRequested))
{
- return badReqErr;
+ return errSecBadReq;
}
- SSLFreeBuffer(&ctx->peerID, ctx);
- serr = SSLAllocBuffer(&ctx->peerID, peerIDLen, ctx);
+ SSLFreeBuffer(&ctx->peerID);
+ serr = SSLAllocBuffer(&ctx->peerID, peerIDLen);
if(serr) {
return serr;
}
memmove(ctx->peerID.data, peerID, peerIDLen);
- return noErr;
+ return errSecSuccess;
}
OSStatus
{
*peerID = ctx->peerID.data; // may be NULL
*peerIDLen = ctx->peerID.length;
- return noErr;
+ return errSecSuccess;
}
OSStatus
SSLCipherSuite *cipherSuite)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(!sslIsSessionActive(ctx)) {
- return badReqErr;
+ return errSecBadReq;
}
*cipherSuite = (SSLCipherSuite)ctx->selectedCipher;
- return noErr;
+ return errSecSuccess;
}
/*
OSStatus err;
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx)) {
- return badReqErr;
+ return errSecBadReq;
}
dn = (DNListElem *)sslMalloc(sizeof(DNListElem));
if(dn == NULL) {
- return memFullErr;
+ return errSecAllocate;
}
- if ((err = SSLAllocBuffer(&dn->derDN, derDNLen, ctx)) != 0)
+ if ((err = SSLAllocBuffer(&dn->derDN, derDNLen)))
return err;
memcpy(dn->derDN.data, derDN, derDNLen);
dn->next = ctx->acceptableDNList;
ctx->acceptableDNList = dn;
- return noErr;
+ return errSecSuccess;
}
/* single-cert version of SSLSetCertificateAuthorities() */
sslAddCA(SSLContextRef ctx,
SecCertificateRef cert)
{
- OSStatus ortn = paramErr;
- CFDataRef subjectName;
+ OSStatus ortn = errSecParam;
/* Get subject from certificate. */
- require(subjectName = SecCertificateCopySubjectSequence(cert), errOut);
+#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 memFullErr;
+ return errSecAllocate;
}
}
CFArrayAppendValue(ctx->acceptableCAs, cert);
/* then add this cert's subject name to acceptableDNList */
- ortn = SSLAddDistinguishedName(ctx, CFDataGetBytePtr(subjectName),
- CFDataGetLength(subjectName));
+#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;
}
Boolean replaceExisting)
{
CFTypeID itemType;
- OSStatus ortn = noErr;
+ OSStatus ortn = errSecSuccess;
if((ctx == NULL) || sslIsSessionActive(ctx) ||
(ctx->protocolSide != kSSLServerSide)) {
- return paramErr;
+ return errSecParam;
}
if(replaceExisting) {
sslFreeDnList(ctx);
for(dex=0; dex<numCerts; dex++) {
SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(cfa, dex);
if(CFGetTypeID(cert) != SecCertificateGetTypeID()) {
- return paramErr;
+ return errSecParam;
}
ortn = sslAddCA(ctx, cert);
if(ortn) {
}
}
else {
- ortn = paramErr;
+ ortn = errSecParam;
}
return ortn;
}
CFArrayRef *certificates) /* RETURNED */
{
if((ctx == NULL) || (certificates == NULL)) {
- return paramErr;
+ return errSecParam;
}
if(ctx->acceptableCAs == NULL) {
*certificates = NULL;
- return noErr;
+ return errSecSuccess;
}
*certificates = ctx->acceptableCAs;
CFRetain(ctx->acceptableCAs);
- return noErr;
+ return errSecSuccess;
}
DNListElem *dn;
if((ctx == NULL) || (names == NULL)) {
- return paramErr;
+ return errSecParam;
}
if(ctx->acceptableDNList == NULL) {
*names = NULL;
- return noErr;
+ return errSecSuccess;
}
outArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
dn = ctx->acceptableDNList;
dn = dn->next;
}
*names = outArray;
- return noErr;
+ 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,
Boolean legacy)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
#ifdef USE_SSLCERTIFICATE
*/
numCerts = SSLGetCertificateChainLength(ctx->peerCert);
if(numCerts == 0) {
- return noErr;
+ return errSecSuccess;
}
ca = CFArrayCreateMutable(kCFAllocatorDefault,
(CFIndex)numCerts, &kCFTypeArrayCallBacks);
if(ca == NULL) {
- return memFullErr;
+ return errSecAllocate;
}
/*
#else
if (!ctx->peerCert) {
*certs = NULL;
- return badReqErr;
+ return errSecBadReq;
}
CFArrayRef ca = CFArrayCreateCopy(kCFAllocatorDefault, ctx->peerCert);
*certs = ca;
if (ca == NULL) {
- return memFullErr;
+ return errSecAllocate;
}
if (legacy) {
}
#endif
- return noErr;
+ return errSecSuccess;
}
OSStatus
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)
- {
- return sslCopyPeerCertificates(ctx, certs, true);
- }
-
+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
{
#if APPLE_DH
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx)) {
- return badReqErr;
+ return errSecBadReq;
}
- SSLFreeBuffer(&ctx->dhParamsEncoded, ctx);
+ SSLFreeBuffer(&ctx->dhParamsEncoded);
#if !USE_CDSA_CRYPTO
if (ctx->secDHContext)
SecDHDestroy(ctx->secDHContext);
{
#if APPLE_DH
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
*dhParams = ctx->dhParamsEncoded.data;
*dhParamsLen = ctx->dhParamsEncoded.length;
- return noErr;
+ return errSecSuccess;
#else
- return unimpErr;
+ return errSecUnimplemented;
#endif /* APPLE_DH */
}
Boolean blinding)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
ctx->rsaBlindingEnable = blinding;
- return noErr;
+ return errSecSuccess;
}
OSStatus SSLGetRsaBlinding(
Boolean *blinding)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
*blinding = ctx->rsaBlindingEnable;
- return noErr;
+ return errSecSuccess;
}
OSStatus
SSLContextRef ctx,
SecTrustRef *trust) /* RETURNED */
{
- OSStatus status = noErr;
+ OSStatus status = errSecSuccess;
if (ctx == NULL || trust == NULL)
- return paramErr;
+ return errSecParam;
/* Create a SecTrustRef if this was a resumed session and we
didn't have one yet. */
SSLContextRef ctx,
SecTrustRef *trust) /* RETURNED */
{
- OSStatus status = noErr;
+ OSStatus status = errSecSuccess;
if (ctx == NULL || trust == NULL)
- return paramErr;
+ return errSecParam;
/* Create a SecTrustRef if this was a resumed session and we
didn't have one yet. */
size_t *secretSize) // in/out
{
if((ctx == NULL) || (secret == NULL) || (secretSize == NULL)) {
- return paramErr;
+ return errSecParam;
}
if(*secretSize < SSL_MASTER_SECRET_SIZE) {
- return paramErr;
+ return errSecParam;
}
memmove(secret, ctx->masterSecret, SSL_MASTER_SECRET_SIZE);
*secretSize = SSL_MASTER_SECRET_SIZE;
- return noErr;
+ return errSecSuccess;
}
OSStatus SSLInternalServerRandom(
size_t *randSize) // in/out
{
if((ctx == NULL) || (randBuf == NULL) || (randSize == NULL)) {
- return paramErr;
+ return errSecParam;
}
if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
- return paramErr;
+ return errSecParam;
}
memmove(randBuf, ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE);
*randSize = SSL_CLIENT_SRVR_RAND_SIZE;
- return noErr;
+ return errSecSuccess;
}
OSStatus SSLInternalClientRandom(
size_t *randSize) // in/out
{
if((ctx == NULL) || (randBuf == NULL) || (randSize == NULL)) {
- return paramErr;
+ return errSecParam;
}
if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) {
- return paramErr;
+ return errSecParam;
}
memmove(randBuf, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE);
*randSize = SSL_CLIENT_SRVR_RAND_SIZE;
- return noErr;
+ return errSecSuccess;
}
+/* This is used by EAP 802.1x */
OSStatus SSLGetCipherSizes(
SSLContextRef ctx,
size_t *digestSize,
size_t *symmetricKeySize,
size_t *ivSize)
{
- const SSLCipherSpec *currCipher;
-
- if((ctx == NULL) || (digestSize == NULL) ||
+ const SSLCipherSpecParams *currCipher;
+
+ if((ctx == NULL) || (digestSize == NULL) ||
(symmetricKeySize == NULL) || (ivSize == NULL)) {
- return paramErr;
+ return errSecParam;
}
- currCipher = &ctx->selectedCipherSpec;
- *digestSize = currCipher->macAlgorithm->hash->digestSize;
- *symmetricKeySize = currCipher->cipher->secretKeySize;
- *ivSize = currCipher->cipher->ivSize;
- return noErr;
+ currCipher = &ctx->selectedCipherSpecParams;
+ *digestSize = currCipher->macSize;
+ *symmetricKeySize = currCipher->keySize;
+ *ivSize = currCipher->ivSize;
+ return errSecSuccess;
}
OSStatus
if((ctx == NULL) || (sessionWasResumed == NULL) ||
(sessionID == NULL) || (sessionIDLength == NULL) ||
(*sessionIDLength < MAX_SESSION_ID_LENGTH)) {
- return paramErr;
+ return errSecParam;
}
if(ctx->sessionMatch) {
*sessionWasResumed = true;
if(ctx->sessionID.length > *sessionIDLength) {
/* really should never happen - means ID > 32 */
- return paramErr;
+ return errSecParam;
}
if(ctx->sessionID.length) {
/*
*sessionWasResumed = false;
*sessionIDLength = 0;
}
- return noErr;
+ return errSecSuccess;
}
/*
Boolean enable)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx)) {
- return badReqErr;
+ return errSecBadReq;
}
if(ctx->validCipherSuites != NULL) {
/* SSLSetEnabledCiphers() has already been called */
- return badReqErr;
+ return errSecBadReq;
}
ctx->anonCipherEnable = enable;
- return noErr;
+ return errSecSuccess;
}
OSStatus
Boolean *enable)
{
if((ctx == NULL) || (enable == NULL)) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx)) {
- return badReqErr;
+ return errSecBadReq;
}
*enable = ctx->anonCipherEnable;
- return noErr;
+ return errSecSuccess;
}
/*
uint32_t timeoutInSeconds)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
ctx->sessionCacheTimeout = timeoutInSeconds;
- return noErr;
+ return errSecSuccess;
}
/*
const void *arg) /* opaque to SecureTransport; app-specific */
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
ctx->masterSecretCallback = mFunc;
ctx->masterSecretArg = arg;
- return noErr;
+ return errSecSuccess;
}
/*
size_t ticketLength)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx)) {
/* can't do this with an active session */
- return badReqErr;
+ return errSecBadReq;
}
if(ticketLength > 0xffff) {
/* extension data encoded with a 2-byte length! */
- return paramErr;
+ return errSecParam;
}
- SSLFreeBuffer(&ctx->sessionTicket, NULL);
+ SSLFreeBuffer(&ctx->sessionTicket);
return SSLCopyBufferFromData(ticket, ticketLength, &ctx->sessionTicket);
}
/*
* Obtain the SSL_ECDSA_NamedCurve negotiated during a handshake.
- * Returns paramErr if no ECDH-related ciphersuite was negotiated.
+ * Returns errSecParam if no ECDH-related ciphersuite was negotiated.
*/
OSStatus SSLGetNegotiatedCurve(
SSLContextRef ctx,
SSL_ECDSA_NamedCurve *namedCurve) /* RETURNED */
{
if((ctx == NULL) || (namedCurve == NULL)) {
- return paramErr;
+ return errSecParam;
}
if(ctx->ecdhPeerCurve == SSL_Curve_None) {
- return paramErr;
+ return errSecParam;
}
*namedCurve = ctx->ecdhPeerCurve;
- return noErr;
+ return errSecSuccess;
}
/*
unsigned *numCurves) /* RETURNED */
{
if((ctx == NULL) || (numCurves == NULL)) {
- return paramErr;
+ return errSecParam;
}
*numCurves = ctx->ecdhNumCurves;
- return noErr;
+ return errSecSuccess;
}
/*
unsigned *numCurves) /* IN/OUT */
{
if((ctx == NULL) || (namedCurves == NULL) || (numCurves == NULL)) {
- return paramErr;
+ return errSecParam;
}
if(*numCurves < ctx->ecdhNumCurves) {
- return paramErr;
+ return errSecParam;
}
memmove(namedCurves, ctx->ecdhCurves,
(ctx->ecdhNumCurves * sizeof(SSL_ECDSA_NamedCurve)));
*numCurves = ctx->ecdhNumCurves;
- return noErr;
+ return errSecSuccess;
}
/*
unsigned numCurves)
{
if((ctx == NULL) || (namedCurves == NULL) || (numCurves == 0)) {
- return paramErr;
+ return errSecParam;
}
if(numCurves > SSL_ECDSA_NUM_CURVES) {
- return paramErr;
+ return errSecParam;
}
if(sslIsSessionActive(ctx)) {
/* can't do this with an active session */
- return badReqErr;
+ return errSecBadReq;
}
memmove(ctx->ecdhCurves, namedCurves, (numCurves * sizeof(SSL_ECDSA_NamedCurve)));
ctx->ecdhNumCurves = numCurves;
- return noErr;
+ return errSecSuccess;
}
/*
* Obtain the number of client authentication mechanisms specified by
* the server in its Certificate Request message.
- * Returns paramErr if server hasn't sent a Certificate Request message
+ * Returns errSecParam if server hasn't sent a Certificate Request message
* (i.e., client certificate state is kSSLClientCertNone).
*/
OSStatus SSLGetNumberOfClientAuthTypes(
unsigned *numTypes)
{
if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
- return paramErr;
+ return errSecParam;
}
*numTypes = ctx->numAuthTypes;
- return noErr;
+ return errSecSuccess;
}
/*
unsigned *numTypes) /* IN/OUT */
{
if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
- return paramErr;
+ return errSecParam;
}
memmove(authTypes, ctx->clientAuthTypes,
ctx->numAuthTypes * sizeof(SSLClientAuthenticationType));
*numTypes = ctx->numAuthTypes;
- return noErr;
+ return errSecSuccess;
}
/*
* Obtain the SSLClientAuthenticationType actually performed.
* Only valid if client certificate state is kSSLClientCertSent
- * or kSSLClientCertRejected; returns paramErr otherwise.
+ * or kSSLClientCertRejected; returns errSecParam otherwise.
*/
OSStatus SSLGetNegotiatedClientAuthType(
SSLContextRef ctx,
SSLClientAuthenticationType *authType) /* RETURNED */
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
*authType = ctx->negAuthType;
- return noErr;
+ return errSecSuccess;
}
/*
SSLContextRef ctx)
{
if(ctx == NULL) {
- return paramErr;
+ return errSecParam;
}
/*
* See if we have a signing cert that matches one of the
} /* parsing authTypes */
} /* we have a signing key */
- return noErr;
+ return errSecSuccess;
}
OSStatus SSLGetNumberOfSignatureAlgorithms(
unsigned *numSigAlgs)
{
if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
- return paramErr;
+ return errSecParam;
}
*numSigAlgs = ctx->numServerSigAlgs;
- return noErr;
+ return errSecSuccess;
}
OSStatus SSLGetSignatureAlgorithms(
unsigned *numSigAlgs) /* IN/OUT */
{
if((ctx == NULL) || (ctx->clientCertState == kSSLClientCertNone)) {
- return paramErr;
+ return errSecParam;
}
memmove(sigAlgs, ctx->serverSigAlgs,
ctx->numServerSigAlgs * sizeof(SSLSignatureAndHashAlgorithm));
*numSigAlgs = ctx->numServerSigAlgs;
- return noErr;
+ 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;
+
+ 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;
+
+ 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;
+}
+
+
+#ifdef USE_SSLCERTIFICATE
+
+size_t
+SSLGetCertificateChainLength(const SSLCertificate *c)
+{
+ size_t rtn = 0;
+
+ while (c)
+ {
+ rtn++;
+ c = c->next;
+ }
+ return rtn;
+}
+
+OSStatus sslDeleteCertificateChain(
+ SSLCertificate *certs,
+ SSLContext *ctx)
+{
+ SSLCertificate *cert;
+ SSLCertificate *nextCert;
+
+ assert(ctx != NULL);
+ cert=certs;
+ while(cert != NULL) {
+ nextCert = cert->next;
+ SSLFreeBuffer(&cert->derCert);
+ sslFree(cert);
+ cert = nextCert;
+ }
+ return errSecSuccess;
}
+#endif /* USE_SSLCERTIFICATE */