X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/ed6778a32ecff23bc2dfb6ca452badd0c68774a0..563f4f96f568bcdc0a04a82f89cafe3bebbe43f1:/SecureTransport/sslContext.cpp diff --git a/SecureTransport/sslContext.cpp b/SecureTransport/sslContext.cpp deleted file mode 100644 index 5d3be3c7..00000000 --- a/SecureTransport/sslContext.cpp +++ /dev/null @@ -1,1226 +0,0 @@ -/* - * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - - -/* - File: sslContext.cpp - - Contains: SSLContext accessors - - Written by: Doug Mitchell - - Copyright: (c) 1999 by Apple Computer, Inc., all rights reserved. - -*/ - -#include "ssl.h" -#include "sslContext.h" -#include "sslMemory.h" -#include -#include "sslDigests.h" -#include "sslDebug.h" -#include "appleCdsa.h" -#include "sslKeychain.h" -#include "sslUtils.h" -#include "cipherSpecs.h" -#include "appleSession.h" -#include "sslBER.h" -#include -#include -#include - -static void sslFreeDnList( - SSLContext *ctx) -{ - DNListElem *dn, *nextDN; - - dn = ctx->acceptableDNList; - while (dn) - { - SSLFreeBuffer(dn->derDN, ctx); - nextDN = dn->next; - sslFree(dn); - dn = nextDN; - } - ctx->acceptableDNList = NULL; -} - -static OSStatus sslFreeTrustedRoots( - SSLContext *ctx) -{ - unsigned i; - - assert(ctx != NULL); - if((ctx->numTrustedCerts == 0) || (ctx->trustedCerts == NULL)) { - /* they really should both be zero, right? */ - assert((ctx->numTrustedCerts == 0) && (ctx->trustedCerts == NULL)); - } - else { - for(i=0; inumTrustedCerts; i++) { - stFreeCssmData(&ctx->trustedCerts[i], CSSM_FALSE); - } - sslFree(ctx->trustedCerts); - } - ctx->numTrustedCerts = 0; - ctx->trustedCerts = NULL; - sslFreeDnList(ctx); - return noErr; -} - -/* - * Default version enables. - */ -#define DEFAULT_SSL2_ENABLE true -#define DEFAULT_SSL3_ENABLE true -#define DEFAULT_TLS1_ENABLE true - -OSStatus -SSLNewContext (Boolean isServer, - SSLContextRef *contextPtr) /* RETURNED */ -{ - SSLContext *ctx; - OSStatus serr; - - if(contextPtr == NULL) { - return paramErr; - } - *contextPtr = NULL; - ctx = (SSLContext *)sslMalloc(sizeof(SSLContext)); - if(ctx == NULL) { - return memFullErr; - } - /* subsequent errors to errOut: */ - - memset(ctx, 0, sizeof(SSLContext)); - ctx->state = SSL_HdskStateUninit; - ctx->clientCertState = kSSLClientCertNone; - - ctx->versionSsl2Enable = DEFAULT_SSL2_ENABLE; - ctx->versionSsl3Enable = DEFAULT_SSL3_ENABLE; - ctx->versionTls1Enable = DEFAULT_TLS1_ENABLE; - ctx->negProtocolVersion = SSL_Version_Undetermined; - - if(isServer) { - ctx->protocolSide = SSL_ServerSide; - } - else { - ctx->protocolSide = SSL_ClientSide; - } - - /* Default value so we can send and receive hello msgs */ - ctx->sslTslCalls = &Ssl3Callouts; - - /* Initialize the cipher state to NULL_WITH_NULL_NULL */ - ctx->selectedCipherSpec = &SSL_NULL_WITH_NULL_NULL_CipherSpec; - ctx->selectedCipher = ctx->selectedCipherSpec->cipherSpec; - 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; - - /* this gets init'd on first call to SSLHandshake() */ - ctx->validCipherSpecs = NULL; - ctx->numValidCipherSpecs = 0; - - ctx->peerDomainName = NULL; - ctx->peerDomainNameLen = 0; - - /* attach to CSP, CL, TP */ - serr = attachToAll(ctx); - if(serr) { - goto errOut; - } - - /* Initial cert verify state: verify with default system roots */ - ctx->enableCertVerify = true; - - /* Default for RSA blinding is ENABLED */ - ctx->rsaBlindingEnable = true; - - *contextPtr = ctx; - return noErr; - -errOut: - sslFree(ctx); - return serr; -} - - -/* - * Dispose of an SSLContext. - */ -OSStatus -SSLDisposeContext (SSLContext *ctx) -{ - WaitingRecord *wait, *next; - SSLBuffer buf; - - if(ctx == NULL) { - return paramErr; - } - sslDeleteCertificateChain(ctx->localCert, ctx); - sslDeleteCertificateChain(ctx->encryptCert, ctx); - sslDeleteCertificateChain(ctx->peerCert, ctx); - ctx->localCert = ctx->encryptCert = ctx->peerCert = NULL; - SSLFreeBuffer(ctx->partialReadBuffer, ctx); - if(ctx->peerSecTrust) { - CFRelease(ctx->peerSecTrust); - ctx->peerSecTrust = NULL; - } - wait = ctx->recordWriteQueue; - while (wait) - { SSLFreeBuffer(wait->data, ctx); - next = wait->next; - buf.data = (uint8*)wait; - buf.length = sizeof(WaitingRecord); - SSLFreeBuffer(buf, ctx); - wait = next; - } - - #if APPLE_DH - SSLFreeBuffer(ctx->dhParamsPrime, ctx); - SSLFreeBuffer(ctx->dhParamsGenerator, ctx); - SSLFreeBuffer(ctx->dhParamsEncoded, ctx); - SSLFreeBuffer(ctx->dhPeerPublic, ctx); - SSLFreeBuffer(ctx->dhExchangePublic, ctx); - sslFreeKey(ctx->cspHand, &ctx->dhPrivate, NULL); - #endif /* APPLE_DH */ - - CloseHash(SSLHashSHA1, ctx->shaState, ctx); - CloseHash(SSLHashMD5, ctx->md5State, ctx); - - 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); - - 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->validCipherSpecs); - ctx->validCipherSpecs = NULL; - ctx->numValidCipherSpecs = 0; - - /* - * NOTE: currently, all public keys come from the CL via CSSM_CL_CertGetKeyInfo. - * We really don't know what CSP the CL used to generate a public key (in fact, - * it uses the raw CSP only to get LogicalKeySizeInBits, but we can't know - * that). Thus using e.g. signingKeyCsp (or any other CSP) to free - * signingPubKey is not tecnically accurate. However, our public keys - * are all raw keys, and all Apple CSPs dispose of raw keys in the same - * way. - */ - sslFreeKey(ctx->cspHand, &ctx->signingPubKey, NULL); - sslFreeKey(ctx->cspHand, &ctx->encryptPubKey, NULL); - sslFreeKey(ctx->peerPubKeyCsp, &ctx->peerPubKey, NULL); - - if(ctx->signingPrivKeyRef) { - CFRelease(ctx->signingPrivKeyRef); - } - if(ctx->encryptPrivKeyRef) { - CFRelease(ctx->encryptPrivKeyRef); - } - sslFreeTrustedRoots(ctx); - - detachFromAll(ctx); - - memset(ctx, 0, sizeof(SSLContext)); - sslFree(ctx); - sslCleanupSession(); - return noErr; -} - -/* - * Determine the state of an SSL session. - */ -OSStatus -SSLGetSessionState (SSLContextRef context, - SSLSessionState *state) /* RETURNED */ -{ - SSLSessionState rtnState = kSSLIdle; - - if(context == NULL) { - return paramErr; - } - *state = rtnState; - switch(context->state) { - case SSL_HdskStateUninit: - case SSL_HdskStateServerUninit: - case SSL_HdskStateClientUninit: - rtnState = kSSLIdle; - break; - case SSL_HdskStateGracefulClose: - rtnState = kSSLClosed; - break; - case SSL_HdskStateErrorClose: - case SSL_HdskStateNoNotifyClose: - rtnState = kSSLAborted; - break; - case SSL_HdskStateServerReady: - case SSL_HdskStateClientReady: - rtnState = kSSLConnected; - break; - default: - assert((context->state >= SSL_HdskStateServerHello) && - (context->state <= SSL2_HdskStateServerFinished)); - rtnState = kSSLHandshake; - break; - - } - *state = rtnState; - return noErr; -} - -OSStatus -SSLSetIOFuncs (SSLContextRef ctx, - SSLReadFunc read, - SSLWriteFunc write) -{ - if(ctx == NULL) { - return paramErr; - } - if(sslIsSessionActive(ctx)) { - /* can't do this with an active session */ - return badReqErr; - } - ctx->ioCtx.read = read; - ctx->ioCtx.write = write; - return noErr; -} - -OSStatus -SSLSetConnection (SSLContextRef ctx, - SSLConnectionRef connection) -{ - if(ctx == NULL) { - return paramErr; - } - if(sslIsSessionActive(ctx)) { - /* can't do this with an active session */ - return badReqErr; - } - ctx->ioCtx.ioRef = connection; - return noErr; -} - -OSStatus -SSLGetConnection (SSLContextRef ctx, - SSLConnectionRef *connection) -{ - if((ctx == NULL) || (connection == NULL)) { - return paramErr; - } - *connection = ctx->ioCtx.ioRef; - return noErr; -} - -OSStatus -SSLSetPeerDomainName (SSLContextRef ctx, - const char *peerName, - size_t peerNameLen) -{ - if(ctx == NULL) { - return paramErr; - } - if(sslIsSessionActive(ctx)) { - /* can't do this with an active session */ - return badReqErr; - } - - /* free possible existing name */ - if(ctx->peerDomainName) { - sslFree(ctx->peerDomainName); - } - - /* copy in */ - ctx->peerDomainName = (char *)sslMalloc(peerNameLen); - if(ctx->peerDomainName == NULL) { - return memFullErr; - } - memmove(ctx->peerDomainName, peerName, peerNameLen); - ctx->peerDomainNameLen = peerNameLen; - return noErr; -} - -/* - * Determine the buffer size needed for SSLGetPeerDomainName(). - */ -OSStatus -SSLGetPeerDomainNameLength (SSLContextRef ctx, - size_t *peerNameLen) // RETURNED -{ - if(ctx == NULL) { - return paramErr; - } - *peerNameLen = ctx->peerDomainNameLen; - return noErr; -} - -OSStatus -SSLGetPeerDomainName (SSLContextRef ctx, - char *peerName, // returned here - size_t *peerNameLen) // IN/OUT -{ - if(ctx == NULL) { - return paramErr; - } - if(*peerNameLen < ctx->peerDomainNameLen) { - return errSSLBufferOverflow; - } - memmove(peerName, ctx->peerDomainName, ctx->peerDomainNameLen); - *peerNameLen = ctx->peerDomainNameLen; - return noErr; -} - -/* concert between private SSLProtocolVersion and public SSLProtocol */ -static SSLProtocol convertProtToExtern(SSLProtocolVersion prot) -{ - switch(prot) { - case SSL_Version_Undetermined: - return kSSLProtocolUnknown; - case SSL_Version_2_0: - return kSSLProtocol2; - case SSL_Version_3_0: - return kSSLProtocol3; - case TLS_Version_1_0: - return kTLSProtocol1; - default: - sslErrorLog("convertProtToExtern: bad prot\n"); - return kSSLProtocolUnknown; - } - /* not reached but make compiler happy */ - return kSSLProtocolUnknown; -} - -OSStatus -SSLSetProtocolVersionEnabled(SSLContextRef ctx, - SSLProtocol protocol, - Boolean enable) /* RETURNED */ -{ - if(ctx == NULL) { - return paramErr; - } - if(sslIsSessionActive(ctx)) { - /* can't do this with an active session */ - return badReqErr; - } - switch(protocol) { - case kSSLProtocol2: - ctx->versionSsl2Enable = enable; - break; - case kSSLProtocol3: - ctx->versionSsl3Enable = enable; - break; - case kTLSProtocol1: - ctx->versionTls1Enable = enable; - break; - case kSSLProtocolAll: - ctx->versionTls1Enable = ctx->versionSsl3Enable = - ctx->versionSsl2Enable = enable; - break; - default: - return paramErr; - } - return noErr; -} - -OSStatus -SSLGetProtocolVersionEnabled(SSLContextRef ctx, - SSLProtocol protocol, - Boolean *enable) /* RETURNED */ -{ - if(ctx == NULL) { - return paramErr; - } - switch(protocol) { - case kSSLProtocol2: - *enable = ctx->versionSsl2Enable; - break; - case kSSLProtocol3: - *enable = ctx->versionSsl3Enable; - break; - case kTLSProtocol1: - *enable = ctx->versionTls1Enable; - break; - case kSSLProtocolAll: - if(ctx->versionTls1Enable && ctx->versionSsl3Enable && - ctx->versionSsl2Enable) { - *enable = true; - } - else { - *enable = false; - } - break; - default: - return paramErr; - } - return noErr; -} - -/* deprecated */ -OSStatus -SSLSetProtocolVersion (SSLContextRef ctx, - SSLProtocol version) -{ - if(ctx == NULL) { - return paramErr; - } - if(sslIsSessionActive(ctx)) { - /* can't do this with an active session */ - return badReqErr; - } - - /* convert external representation to three booleans */ - switch(version) { - case kSSLProtocolUnknown: - ctx->versionSsl2Enable = DEFAULT_SSL2_ENABLE; - ctx->versionSsl3Enable = DEFAULT_SSL3_ENABLE; - ctx->versionTls1Enable = DEFAULT_TLS1_ENABLE; - break; - case kSSLProtocol2: - ctx->versionSsl2Enable = true; - ctx->versionSsl3Enable = false; - ctx->versionTls1Enable = false; - break; - case kSSLProtocol3: - /* this tells us to do our best, up to 3.0, but allows 2.0 */ - ctx->versionSsl2Enable = true; - ctx->versionSsl3Enable = true; - ctx->versionTls1Enable = false; - break; - case kSSLProtocol3Only: - ctx->versionSsl2Enable = false; - ctx->versionSsl3Enable = true; - ctx->versionTls1Enable = false; - break; - case kTLSProtocol1: - case kSSLProtocolAll: - /* this tells us to do our best, up to TLS, but allows 2.0 or 3.0 */ - ctx->versionSsl2Enable = true; - ctx->versionSsl3Enable = true; - ctx->versionTls1Enable = true; - break; - case kTLSProtocol1Only: - ctx->versionSsl2Enable = false; - ctx->versionSsl3Enable = false; - ctx->versionTls1Enable = true; - break; - default: - return paramErr; - } - return noErr; -} - -/* deprecated */ -OSStatus -SSLGetProtocolVersion (SSLContextRef ctx, - SSLProtocol *protocol) /* RETURNED */ -{ - if(ctx == NULL) { - return paramErr; - } - - /* translate array of booleans to public value; not all combinations - * are legal (i.e., meaningful) for this call */ - if(ctx->versionTls1Enable) { - if(ctx->versionSsl2Enable) { - if(ctx->versionSsl3Enable) { - /* traditional 'all enabled' */ - *protocol = kTLSProtocol1; - return noErr; - } - else { - /* SSL2 true, SSL3 false, TLS1 true - invalid here */ - return paramErr; - } - } - else if(ctx->versionSsl3Enable) { - /* SSL2 false, SSL3 true, TLS1 true - invalid here */ - return paramErr; - } - else { - *protocol = kTLSProtocol1Only; - return noErr; - } - } - else { - /* TLS1 false */ - if(ctx->versionSsl3Enable) { - *protocol = ctx->versionSsl2Enable ? - kSSLProtocol3 : kSSLProtocol3Only; - return noErr; - } - else if(ctx->versionSsl2Enable) { - *protocol = kSSLProtocol2; - return noErr; - } - else { - /* - * Bogus state - no enables - the API does provide a way - * to get into this state. Other than this path, the app - * will discover this bogon when attempting to do the - * handshake; sslGetMaxProtVersion will detect this. - */ - return paramErr; - } - } - /* NOT REACHED */ -} - -OSStatus -SSLGetNegotiatedProtocolVersion (SSLContextRef ctx, - SSLProtocol *protocol) /* RETURNED */ -{ - if(ctx == NULL) { - return paramErr; - } - *protocol = convertProtToExtern(ctx->negProtocolVersion); - return noErr; -} - -OSStatus -SSLSetEnableCertVerify (SSLContextRef ctx, - Boolean enableVerify) -{ - if(ctx == NULL) { - return paramErr; - } - sslCertDebug("SSLSetEnableCertVerify %s", - enableVerify ? "true" : "false"); - if(sslIsSessionActive(ctx)) { - /* can't do this with an active session */ - return badReqErr; - } - ctx->enableCertVerify = enableVerify; - return noErr; -} - -OSStatus -SSLGetEnableCertVerify (SSLContextRef ctx, - Boolean *enableVerify) -{ - if(ctx == NULL) { - return paramErr; - } - *enableVerify = ctx->enableCertVerify; - return noErr; -} - -OSStatus -SSLSetAllowsExpiredCerts(SSLContextRef ctx, - Boolean allowExpired) -{ - if(ctx == NULL) { - return paramErr; - } - sslCertDebug("SSLSetAllowsExpiredCerts %s", - allowExpired ? "true" : "false"); - if(sslIsSessionActive(ctx)) { - /* can't do this with an active session */ - return badReqErr; - } - ctx->allowExpiredCerts = allowExpired; - return noErr; -} - -OSStatus -SSLGetAllowsExpiredCerts (SSLContextRef ctx, - Boolean *allowExpired) -{ - if(ctx == NULL) { - return paramErr; - } - *allowExpired = ctx->allowExpiredCerts; - return noErr; -} - -OSStatus -SSLSetAllowsExpiredRoots(SSLContextRef ctx, - Boolean allowExpired) -{ - if(ctx == NULL) { - return paramErr; - } - sslCertDebug("SSLSetAllowsExpiredRoots %s", - allowExpired ? "true" : "false"); - if(sslIsSessionActive(ctx)) { - /* can't do this with an active session */ - return badReqErr; - } - ctx->allowExpiredRoots = allowExpired; - return noErr; -} - -OSStatus -SSLGetAllowsExpiredRoots (SSLContextRef ctx, - Boolean *allowExpired) -{ - if(ctx == NULL) { - return paramErr; - } - *allowExpired = ctx->allowExpiredRoots; - return noErr; -} - -OSStatus SSLSetAllowsAnyRoot( - SSLContextRef ctx, - Boolean anyRoot) -{ - if(ctx == NULL) { - return paramErr; - } - sslCertDebug("SSLSetAllowsAnyRoot %s", anyRoot ? "true" : "false"); - ctx->allowAnyRoot = anyRoot; - return noErr; -} - -OSStatus -SSLGetAllowsAnyRoot( - SSLContextRef ctx, - Boolean *anyRoot) -{ - if(ctx == NULL) { - return paramErr; - } - *anyRoot = ctx->allowAnyRoot; - return noErr; -} - -OSStatus -SSLSetTrustedRoots (SSLContextRef ctx, - CFArrayRef trustedRoots, - Boolean replaceExisting) -{ - unsigned dex; - unsigned outDex; - unsigned numIncoming; - uint32 numCerts; - CSSM_DATA_PTR newRoots = NULL; - const CSSM_DATA *existAnchors = NULL; - uint32 numExistAnchors = 0; - OSStatus ortn = noErr; - - if(ctx == NULL) { - return paramErr; - } - if(sslIsSessionActive(ctx)) { - /* can't do this with an active session */ - return badReqErr; - } - numCerts = numIncoming = CFArrayGetCount(trustedRoots); - sslCertDebug("SSLSetTrustedRoot numCerts %d replaceExist %s", - (int)numCerts, replaceExisting ? "true" : "false"); - if(!replaceExisting) { - if(ctx->trustedCerts != NULL) { - /* adding to existing store */ - existAnchors = ctx->trustedCerts; - numExistAnchors = ctx->numTrustedCerts; - } - else { - /* adding to system roots */ - ortn = SecTrustGetCSSMAnchorCertificates(&existAnchors, - &numExistAnchors); - if(ortn) { - /* should never happen */ - return ortn; - } - } - numCerts += numExistAnchors; - } - newRoots = (CSSM_DATA_PTR)sslMalloc(numCerts * sizeof(CSSM_DATA)); - memset(newRoots, 0, numCerts * sizeof(CSSM_DATA)); - - /* Caller's certs first */ - for(dex=0, outDex=0; dexnumTrustedCerts = numCerts; - ctx->trustedCerts = newRoots; - return noErr; - -abort: - sslFree(newRoots); - return ortn; -} - -OSStatus -SSLGetTrustedRoots (SSLContextRef ctx, - CFArrayRef *trustedRoots) /* RETURNED */ -{ - uint32 numCerts; - const CSSM_DATA *certs; - CFMutableArrayRef certArray; - unsigned dex; - SecCertificateRef secCert; - OSStatus ortn; - - if(ctx == NULL) { - return paramErr; - } - if(ctx->trustedCerts != NULL) { - /* use ours */ - certs = ctx->trustedCerts; - numCerts = ctx->numTrustedCerts; - } - else { - /* use default system roots */ - OSStatus ortn = SecTrustGetCSSMAnchorCertificates(&certs, - &numCerts); - if(ortn) { - /* should never happen */ - return ortn; - } - } - - certArray = CFArrayCreateMutable(kCFAllocatorDefault, - (CFIndex)numCerts, &kCFTypeArrayCallBacks); - if(certArray == NULL) { - return memFullErr; - } - for(dex=0; dexclientAuth = auth; - switch(auth) { - case kNeverAuthenticate: - ctx->tryClientAuth = false; - break; - case kAlwaysAuthenticate: - case kTryAuthenticate: - ctx->tryClientAuth = true; - break; - } - return noErr; -} - -OSStatus -SSLGetClientCertificateState (SSLContextRef ctx, - SSLClientCertificateState *clientState) -{ - if(ctx == NULL) { - return paramErr; - } - *clientState = ctx->clientCertState; - return noErr; -} - -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 paramErr; - } - if(sslIsSessionActive(ctx)) { - /* can't do this with an active session */ - return badReqErr; - } - return parseIncomingCerts(ctx, - certRefs, - &ctx->localCert, - &ctx->signingPubKey, - &ctx->signingPrivKeyRef); -} - -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 paramErr; - } - if(sslIsSessionActive(ctx)) { - /* can't do this with an active session */ - return badReqErr; - } - return parseIncomingCerts(ctx, - certRefs, - &ctx->encryptCert, - &ctx->encryptPubKey, - &ctx->encryptPrivKeyRef); -} - -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 paramErr; - } - if(sslIsSessionActive(ctx)) { - /* can't do this with an active session */ - return badReqErr; - } - SSLFreeBuffer(ctx->peerID, ctx); - serr = SSLAllocBuffer(ctx->peerID, peerIDLen, ctx); - if(serr) { - return serr; - } - memmove(ctx->peerID.data, peerID, peerIDLen); - return noErr; -} - -OSStatus -SSLGetPeerID (SSLContextRef ctx, - const void **peerID, - size_t *peerIDLen) -{ - *peerID = ctx->peerID.data; // may be NULL - *peerIDLen = ctx->peerID.length; - return noErr; -} - -OSStatus -SSLGetNegotiatedCipher (SSLContextRef ctx, - SSLCipherSuite *cipherSuite) -{ - if(ctx == NULL) { - return paramErr; - } - if(!sslIsSessionActive(ctx)) { - return badReqErr; - } - *cipherSuite = (SSLCipherSuite)ctx->selectedCipher; - return noErr; -} - -/* - * Add an acceptable distinguished name (client authentication only). - */ -OSStatus -SSLAddDistinguishedName( - SSLContextRef ctx, - const void *derDN, - size_t derDNLen) -{ - DNListElem *dn; - OSStatus err; - - dn = (DNListElem *)sslMalloc(sizeof(DNListElem)); - if(dn == NULL) { - return memFullErr; - } - if ((err = SSLAllocBuffer(dn->derDN, derDNLen, ctx)) != 0) - return err; - memcpy(dn->derDN.data, derDN, derDNLen); - dn->next = ctx->acceptableDNList; - ctx->acceptableDNList = dn; - return noErr; -} - -/* - * Request peer certificates. Valid anytime, subsequent to - * a handshake attempt. - */ -OSStatus -SSLGetPeerCertificates (SSLContextRef ctx, - CFArrayRef *certs) -{ - uint32 numCerts; - CFMutableArrayRef ca; - CFIndex i; - SecCertificateRef cfd; - OSStatus ortn; - CSSM_DATA certData; - SSLCertificate *scert; - - if(ctx == NULL) { - return paramErr; - } - *certs = NULL; - - /* - * Copy peerCert, a chain of SSLCertificates, to a CFArray of - * CFDataRefs, each of which is one DER-encoded cert. - */ - numCerts = SSLGetCertificateChainLength(ctx->peerCert); - if(numCerts == 0) { - return noErr; - } - ca = CFArrayCreateMutable(kCFAllocatorDefault, - (CFIndex)numCerts, &kCFTypeArrayCallBacks); - if(ca == NULL) { - return memFullErr; - } - - /* - * Caller gets leaf cert first, the opposite of the way we store them. - */ - scert = ctx->peerCert; - for(i=0; (unsigned)iderCert, &certData); - ortn = SecCertificateCreateFromData(&certData, - CSSM_CERT_X_509v3, - CSSM_CERT_ENCODING_DER, - &cfd); - if(ortn) { - CFRelease(ca); - return ortn; - } - /* insert at head of array */ - CFArrayInsertValueAtIndex(ca, 0, cfd); - scert = scert->next; - } - *certs = ca; - return noErr; -} - -/* - * 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(ctx == NULL) { - return paramErr; - } - if(sslIsSessionActive(ctx)) { - return badReqErr; - } - SSLFreeBuffer(ctx->dhParamsPrime, ctx); - SSLFreeBuffer(ctx->dhParamsGenerator, ctx); - SSLFreeBuffer(ctx->dhParamsEncoded, ctx); - - OSStatus ortn; - ortn = SSLCopyBufferFromData(dhParams, dhParamsLen, - ctx->dhParamsEncoded); - if(ortn) { - return ortn; - } - - /* decode for use by server over the wire */ - SSLBuffer sParams; - sParams.data = (UInt8 *)dhParams; - sParams.length = dhParamsLen; - return sslDecodeDhParams(&sParams, &ctx->dhParamsPrime, - &ctx->dhParamsGenerator); -} - -/* - * 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(ctx == NULL) { - return paramErr; - } - *dhParams = ctx->dhParamsEncoded.data; - *dhParamsLen = ctx->dhParamsEncoded.length; - return noErr; -} - -OSStatus SSLSetRsaBlinding( - SSLContextRef ctx, - Boolean blinding) -{ - if(ctx == NULL) { - return paramErr; - } - ctx->rsaBlindingEnable = blinding; - return noErr; -} - -OSStatus SSLGetRsaBlinding( - SSLContextRef ctx, - Boolean *blinding) -{ - if(ctx == NULL) { - return paramErr; - } - *blinding = ctx->rsaBlindingEnable; - return noErr; -} - -OSStatus SSLGetPeerSecTrust( - SSLContextRef ctx, - SecTrustRef *secTrust) /* RETURNED */ -{ - if(ctx == NULL) { - return paramErr; - } - *secTrust = ctx->peerSecTrust; - return noErr; -} - -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 paramErr; - } - if(*secretSize < SSL_MASTER_SECRET_SIZE) { - return paramErr; - } - memmove(secret, ctx->masterSecret, SSL_MASTER_SECRET_SIZE); - *secretSize = SSL_MASTER_SECRET_SIZE; - return noErr; -} - -OSStatus SSLInternalServerRandom( - SSLContextRef ctx, - void *rand, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE - size_t *randSize) // in/out -{ - if((ctx == NULL) || (rand == NULL) || (randSize == NULL)) { - return paramErr; - } - if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) { - return paramErr; - } - memmove(rand, ctx->serverRandom, SSL_CLIENT_SRVR_RAND_SIZE); - *randSize = SSL_CLIENT_SRVR_RAND_SIZE; - return noErr; -} - -OSStatus SSLInternalClientRandom( - SSLContextRef ctx, - void *rand, // mallocd by caller, SSL_CLIENT_SRVR_RAND_SIZE - size_t *randSize) // in/out -{ - if((ctx == NULL) || (rand == NULL) || (randSize == NULL)) { - return paramErr; - } - if(*randSize < SSL_CLIENT_SRVR_RAND_SIZE) { - return paramErr; - } - memmove(rand, ctx->clientRandom, SSL_CLIENT_SRVR_RAND_SIZE); - *randSize = SSL_CLIENT_SRVR_RAND_SIZE; - return noErr; -} - -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 paramErr; - } - if(ctx->sessionMatch) { - assert(ctx->sessionID.data != NULL); - *sessionWasResumed = true; - if(ctx->sessionID.length > *sessionIDLength) { - /* really should never happen - means ID > 32 */ - return paramErr; - } - memmove(sessionID, ctx->sessionID.data, ctx->sessionID.length); - *sessionIDLength = ctx->sessionID.length; - } - else { - *sessionWasResumed = false; - *sessionIDLength = 0; - } - return noErr; -} - -