X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_apple_cspdl/lib/SSContext.cpp?ds=inline diff --git a/libsecurity_apple_cspdl/lib/SSContext.cpp b/libsecurity_apple_cspdl/lib/SSContext.cpp deleted file mode 100644 index df3e887b..00000000 --- a/libsecurity_apple_cspdl/lib/SSContext.cpp +++ /dev/null @@ -1,622 +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. - */ - - -// -// SSContext - cryptographic contexts for the security server -// -#include "SSContext.h" - -#include "SSCSPSession.h" -#include "SSKey.h" -#include - -#define ssCryptDebug(args...) secdebug("ssCrypt", ## args) - -using namespace SecurityServer; - -// -// SSContext -// -SSContext::SSContext(SSCSPSession &session) -: mSession(session), mContext(NULL) -{ -} - -void SSContext::clearOutBuf() -{ - if(mOutBuf.Data) { - mSession.free(mOutBuf.Data); - mOutBuf.clear(); - } -} - -void SSContext::copyOutBuf(CssmData &out) -{ - if(out.length() < mOutBuf.length()) { - CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR); - } - memmove(out.Data, mOutBuf.Data, mOutBuf.Length); - out.Length = mOutBuf.Length; - clearOutBuf(); -} - -void -SSContext::init(const Context &context, - bool /* encoding */) // @@@ should be removed from API since it's already in mDirection -{ - mContext = &context; - clearOutBuf(); -} - -SecurityServer::ClientSession & -SSContext::clientSession() -{ - return mSession.clientSession(); -} - - -// -// SSRandomContext -- Context for GenerateRandom operations -// -SSRandomContext::SSRandomContext(SSCSPSession &session) : SSContext(session) {} - -void -SSRandomContext::init(const Context &context, bool encoding) -{ - SSContext::init(context, encoding); - - // set/freeze output size - mOutSize = context.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE, CSSMERR_CSP_MISSING_ATTR_OUTPUT_SIZE); - -#if 0 - // seed the PRNG (if specified) - if (const CssmCryptoData *seed = context.get(CSSM_ATTRIBUTE_SEED)) { - const CssmData &seedValue = (*seed)(); - clientSession().seedRandom(seedValue); - } -#endif -} - -size_t -SSRandomContext::outputSize(bool final, size_t inSize) -{ - return mOutSize; -} - -void -SSRandomContext::final(CssmData &out) -{ - clientSession().generateRandom(*mContext, out); -} - - -// signature contexts -SSSignatureContext::SSSignatureContext(SSCSPSession &session) - : SSContext(session), - mKeyHandle(noKey), - mNullDigest(NULL), - mDigest(NULL) -{ - /* nothing else for now */ -} - -SSSignatureContext::~SSSignatureContext() -{ - delete mNullDigest; - delete mDigest; -} - -void SSSignatureContext::init(const Context &context, bool signing) -{ - SSContext::init(context, signing); - - /* reusable: skip everything except resetting digest state */ - if((mNullDigest != NULL) || (mDigest != NULL)) { - if(mNullDigest != NULL) { - mNullDigest->digestInit(); - } - return; - } - - /* snag key from context */ - const CssmKey &keyInContext = - context.get(CSSM_ATTRIBUTE_KEY, - CSSMERR_CSP_MISSING_ATTR_KEY); - mKeyHandle = mSession.lookupKey(keyInContext).keyHandle(); - - /* get digest alg and sig alg from Context.algorithm */ - switch(context.algorithm()) { - /*** DSA ***/ - case CSSM_ALGID_SHA1WithDSA: - mDigestAlg = CSSM_ALGID_SHA1; - mSigAlg = CSSM_ALGID_DSA; - break; - case CSSM_ALGID_DSA: // Raw - mDigestAlg = CSSM_ALGID_NONE; - mSigAlg = CSSM_ALGID_DSA; - break; - /*** RSA ***/ - case CSSM_ALGID_SHA1WithRSA: - mDigestAlg = CSSM_ALGID_SHA1; - mSigAlg = CSSM_ALGID_RSA; - break; - case CSSM_ALGID_MD5WithRSA: - mDigestAlg = CSSM_ALGID_MD5; - mSigAlg = CSSM_ALGID_RSA; - break; - case CSSM_ALGID_MD2WithRSA: - mDigestAlg = CSSM_ALGID_MD2; - mSigAlg = CSSM_ALGID_RSA; - break; - case CSSM_ALGID_SHA256WithRSA: - mDigestAlg = CSSM_ALGID_SHA256; - mSigAlg = CSSM_ALGID_RSA; - break; - case CSSM_ALGID_SHA224WithRSA: - mDigestAlg = CSSM_ALGID_SHA224; - mSigAlg = CSSM_ALGID_RSA; - break; - case CSSM_ALGID_SHA384WithRSA: - mDigestAlg = CSSM_ALGID_SHA384; - mSigAlg = CSSM_ALGID_RSA; - break; - case CSSM_ALGID_SHA512WithRSA: - mDigestAlg = CSSM_ALGID_SHA512; - mSigAlg = CSSM_ALGID_RSA; - break; - case CSSM_ALGID_RSA: // Raw - mDigestAlg = CSSM_ALGID_NONE; - mSigAlg = CSSM_ALGID_RSA; - break; - /*** FEE ***/ - case CSSM_ALGID_FEE_SHA1: - mDigestAlg = CSSM_ALGID_SHA1; - mSigAlg = CSSM_ALGID_FEE; - break; - case CSSM_ALGID_FEE_MD5: - mDigestAlg = CSSM_ALGID_MD5; - mSigAlg = CSSM_ALGID_FEE; - break; - case CSSM_ALGID_FEE: // Raw - mDigestAlg = CSSM_ALGID_NONE; - mSigAlg = CSSM_ALGID_FEE; - break; - /*** ECDSA ***/ - case CSSM_ALGID_SHA1WithECDSA: - mDigestAlg = CSSM_ALGID_SHA1; - mSigAlg = CSSM_ALGID_ECDSA; - break; - case CSSM_ALGID_SHA224WithECDSA: - mDigestAlg = CSSM_ALGID_SHA224; - mSigAlg = CSSM_ALGID_ECDSA; - break; - case CSSM_ALGID_SHA256WithECDSA: - mDigestAlg = CSSM_ALGID_SHA256; - mSigAlg = CSSM_ALGID_ECDSA; - break; - case CSSM_ALGID_SHA384WithECDSA: - mDigestAlg = CSSM_ALGID_SHA384; - mSigAlg = CSSM_ALGID_ECDSA; - break; - case CSSM_ALGID_SHA512WithECDSA: - mDigestAlg = CSSM_ALGID_SHA512; - mSigAlg = CSSM_ALGID_ECDSA; - break; - case CSSM_ALGID_ECDSA: // Raw - mDigestAlg = CSSM_ALGID_NONE; - mSigAlg = CSSM_ALGID_ECDSA; - break; - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM); - } - - /* set up mNullDigest or mDigest */ - if(mDigestAlg == CSSM_ALGID_NONE) { - mNullDigest = new NullDigest(); - } - else { - mDigest = new CssmClient::Digest(mSession.mRawCsp, mDigestAlg); - } -} - -/* - * for raw sign/verify - optionally called after init. - * Note that in init (in this case), we set mDigestAlg to ALGID_NONE and set up - * a NullDigest. We now overwrite mDigestAlg, and we'll useÊthis - * new value when we do the actual sign/vfy. - */ -void SSSignatureContext::setDigestAlgorithm(CSSM_ALGORITHMS digestAlg) -{ - mDigestAlg = digestAlg; -} - -void SSSignatureContext::update(const CssmData &data) -{ - /* Note that for this context, we really can not deal with an out-of-sequence - * update --> final(true, 0) --> update since we lose the pending digest state - * when we perform the implied final() during outputSize(true, 0). */ - assert(mOutBuf.Data == NULL); - - /* add incoming data to digest or accumulator */ - if(mNullDigest) { - mNullDigest->digestUpdate(data.data(), data.length()); - } - else { - mDigest->digest(data); - } -} - -size_t SSSignatureContext::outputSize(bool final, size_t inSize) -{ - if(!final) { - ssCryptDebug("===sig outputSize !final\n"); - return 0; - } - if(!encoding()) { - ssCryptDebug("===sig outputSize final, !encoding\n"); - /* don't see why this is even called... */ - return 0; - } - if(inSize == 0) { - /* - * This is the implied signal to go for it. Note that in this case, - * we can not go back and re-do the op in case of an unexpected - * sequence of update/outputSize(final, 0)/final - we lose the digest - * state. Perhaps we should save the digest...? But still it would - * be impossible to do another update. - */ - clearOutBuf(); - sign(mOutBuf); - ssCryptDebug("===sig outputSize(pre-op) %u", (unsigned)mOutBuf.Length); - return (size_t)mOutBuf.Length; - } - else { - /* out-of-band case, ask CSP via SS */ - uint32 outSize = clientSession().getOutputSize(*mContext, - mKeyHandle, - /* FIXME - what to use for inSize here - we don't want to - * interrogate mDigest, as that would result in another RPC... - * and signature size is not related to input size...right? */ - (uint32)inSize, - true); - ssCryptDebug("===sig outputSize(RPC) %u", (unsigned)outSize); - return (size_t)outSize; - } -} - -/* sign */ - -/* first the common routine shared by final and outputSize */ -void SSSignatureContext::sign(CssmData &sig) -{ - /* we have to pass down a modified Context, thus.... */ - Context tempContext = *mContext; - tempContext.AlgorithmType = mSigAlg; - - if(mNullDigest) { - CssmData dData(const_cast(mNullDigest->digestPtr()), - mNullDigest->digestSizeInBytes()); - clientSession().generateSignature(tempContext, - mKeyHandle, - dData, - sig, - mDigestAlg); - } - else { - CssmAutoData d (mDigest->allocator ()); - d.set((*mDigest) ()); - - clientSession().generateSignature(tempContext, - mKeyHandle, - d, - sig, - mDigestAlg); - } -} - -/* this is the one called by CSPFullPluginSession */ -void SSSignatureContext::final(CssmData &sig) -{ - if(mOutBuf.Data) { - /* normal final case in which the actual RPC via SS was done in the - * previous outputSize() call. */ - ssCryptDebug("===final via pre-op and copy"); - copyOutBuf(sig); - return; - } - - ssCryptDebug("===final via RPC"); - sign(sig); -} - -/* verify */ -void -SSSignatureContext::final(const CssmData &sig) -{ - /* we have to pass down a modified Context, thus.... */ - Context tempContext = *mContext; - tempContext.AlgorithmType = mSigAlg; - - if(mNullDigest) { - CssmData dData(const_cast(mNullDigest->digestPtr()), - mNullDigest->digestSizeInBytes()); - clientSession().verifySignature(tempContext, - mKeyHandle, - dData, - sig, - mDigestAlg); - } - else { - CssmData digst = (*mDigest)(); - try { - clientSession().verifySignature(tempContext, - mKeyHandle, - digst, - sig, - mDigestAlg); - } - catch (...) { - mDigest->allocator().free(digst.Data); - throw; - } - mDigest->allocator().free(digst.Data); - } -} - - -// -// SSCryptContext -- Context for Encrypt and Decrypt operations -// -SSCryptContext::SSCryptContext(SSCSPSession &session) - : SSContext(session), mKeyHandle(noKey) -{ - /* nothing for now */ -} - - -SSCryptContext::~SSCryptContext() -{ - /* nothing for now */ -} - -void -SSCryptContext::init(const Context &context, bool encoding) -{ - ssCryptDebug("===init"); - SSContext::init(context, encoding); - - /* reusable; reset accumulator */ - mNullDigest.digestInit(); - - const CssmKey &keyInContext = - context.get(CSSM_ATTRIBUTE_KEY, - CSSMERR_CSP_MISSING_ATTR_KEY); - mKeyHandle = mSession.lookupKey(keyInContext).keyHandle(); -} - -size_t -SSCryptContext::inputSize(size_t outSize) -{ - ssCryptDebug("===inputSize outSize=%u", (unsigned)outSize); - return UINT_MAX; -} - -size_t -SSCryptContext::outputSize(bool final, size_t inSize) -{ - ssCryptDebug("===outputSize final %d inSize=%u", final, (unsigned)inSize); - if(!final) { - /* we buffer until final; no intermediate output */ - return 0; - } - size_t inBufSize = mNullDigest.digestSizeInBytes(); - if(inSize == 0) { - /* This is the implied signal to go for it */ - clearOutBuf(); - if(inBufSize == 0) { - return 0; - } - const CssmData in(const_cast(mNullDigest.digestPtr()), inBufSize); - if (encoding()) { - clientSession().encrypt(*mContext, mKeyHandle, in, mOutBuf); - } - else { - clientSession().decrypt(*mContext, mKeyHandle, in, mOutBuf); - } - /* leave the accumulator as is in case of unexpected sequence */ - ssCryptDebug(" ===outSize(pre-op) %u", (unsigned)mOutBuf.Length); - return mOutBuf.Length; - } - else { - /* out-of-band case, ask CSP via SS */ - uint32 outSize = clientSession().getOutputSize(*mContext, - mKeyHandle, - (uint32)(inBufSize + inSize), - encoding()); - ssCryptDebug(" ===outSize(RPC) %u", (unsigned)outSize); - return (size_t)outSize; - } -} - -void -SSCryptContext::minimumProgress(size_t &in, size_t &out) -{ - in = 1; - out = 0; -} - -void -SSCryptContext::update(void *inp, size_t &inSize, void *outp, size_t &outSize) -{ - ssCryptDebug("===update inSize=%u", (unsigned)inSize); - /* add incoming data to accumulator */ - mNullDigest.digestUpdate(inp, inSize); - outSize = 0; - clearOutBuf(); -} - -void -SSCryptContext::final(CssmData &out) -{ - if(mOutBuf.Data != NULL) { - /* normal final case in which the actual RPC via SS was done in the - * previous outputSize() call. A memcpy is needed here because - * CSPFullPluginSession has just allocated the buf size we need. */ - ssCryptDebug("===final via pre-op and copy"); - copyOutBuf(out); - return; - } - - /* when is this path taken...? */ - ssCryptDebug("===final via RPC"); - size_t inSize = mNullDigest.digestSizeInBytes(); - if(!inSize) return; - - const CssmData in(const_cast(mNullDigest.digestPtr()), inSize); - IFDEBUG(size_t origOutSize = out.length()); - if (encoding()) { - clientSession().encrypt(*mContext, mKeyHandle, in, out); - } - else { - clientSession().decrypt(*mContext, mKeyHandle, in, out); - } - assert(out.length() <= origOutSize); - mNullDigest.digestInit(); -} - -// Digest, using raw CSP -SSDigestContext::SSDigestContext(SSCSPSession &session) - : SSContext(session), mDigest(NULL) -{ - -} - -SSDigestContext::~SSDigestContext() -{ - delete mDigest; -} - -void SSDigestContext::init(const Context &context, bool encoding) -{ - CSSM_ALGORITHMS alg; - - SSContext::init(context, encoding); - alg = context.algorithm(); - mDigest = new CssmClient::Digest(mSession.mRawCsp, alg); -} - -void SSDigestContext::update(const CssmData &data) -{ - mDigest->digest(data); -} - -void SSDigestContext::final(CssmData &out) -{ - (*mDigest)(out); -} - -size_t SSDigestContext::outputSize(bool final, size_t inSize) -{ - if(!final) { - return 0; - } - else { - return (size_t)mDigest->getOutputSize((uint32)inSize); - } -} - -// MACContext - common class for MAC generate, verify -SSMACContext::SSMACContext(SSCSPSession &session) - : SSContext(session), mKeyHandle(noKey) -{ - -} - -void SSMACContext::init(const Context &context, bool encoding) -{ - SSContext::init(context, encoding); - - /* reusable; reset accumulator */ - mNullDigest.digestInit(); - - /* snag key from context */ - const CssmKey &keyInContext = - context.get(CSSM_ATTRIBUTE_KEY, - CSSMERR_CSP_MISSING_ATTR_KEY); - mKeyHandle = mSession.lookupKey(keyInContext).keyHandle(); -} - -void SSMACContext::update(const CssmData &data) -{ - /* add incoming data to accumulator */ - mNullDigest.digestUpdate(data.data(), data.length()); -} - -size_t SSMACContext::outputSize(bool final, size_t inSize) -{ - if(!final) { - ssCryptDebug("===mac outputSize !final\n"); - return 0; - } - if(!encoding()) { - ssCryptDebug("===mac outputSize final, !encoding\n"); - /* don't see why this is even called... */ - return 0; - } - if(inSize == 0) { - /* - * This is the implied signal to go for it. - */ - clearOutBuf(); - genMac(mOutBuf); - ssCryptDebug("===mac outputSize(pre-op) %u", (unsigned)mOutBuf.Length); - return (size_t)mOutBuf.Length; - } - else { - /* out-of-band case, ask CSP via SS */ - uint32 outSize = clientSession().getOutputSize(*mContext, - mKeyHandle, - (uint32)(inSize + mNullDigest.digestSizeInBytes()), - true); - ssCryptDebug("===mac outputSize(RPC) %u", (unsigned)outSize); - return (size_t)outSize; - } -} - -/* generate */ - -/* first the common routine used by final() and outputSize() */ -void SSMACContext::genMac(CssmData &mac) -{ - CssmData allData(const_cast(mNullDigest.digestPtr()), - mNullDigest.digestSizeInBytes()); - clientSession().generateMac(*mContext, mKeyHandle, allData, mac); -} - -void SSMACContext::final(CssmData &mac) -{ - genMac(mac); -} - -/* verify */ -void SSMACContext::final(const CssmData &mac) -{ - CssmData allData(const_cast(mNullDigest.digestPtr()), - mNullDigest.digestSizeInBytes()); - clientSession().verifyMac(*mContext, mKeyHandle, allData, mac); -}