X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/72a12576750f52947eb043106ba5c12c0d07decf..b1ab9ed8d0e0f1c3b66d7daa8fd5564444c56195:/libsecurity_cdsa_plugin/lib/csputilities.cpp diff --git a/libsecurity_cdsa_plugin/lib/csputilities.cpp b/libsecurity_cdsa_plugin/lib/csputilities.cpp new file mode 100644 index 00000000..467cdd5f --- /dev/null +++ b/libsecurity_cdsa_plugin/lib/csputilities.cpp @@ -0,0 +1,152 @@ +/* + * 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. + */ + + +// +// csputilities - utility classes for CSP implementation +// +#include +#include +#include +#include + +using LowLevelMemoryUtilities::increment; + + +// +// Writer objects +// +CSPFullPluginSession::Writer::Writer(CssmData *v, uint32 n, CssmData *rem) +: vec(v), firstVec(v), lastVec(v + n - 1), remData(rem) +{ + if (vec == NULL || n == 0) + CssmError::throwMe(CSSMERR_CSP_INVALID_OUTPUT_VECTOR); // CDSA p.253, amended + useData(vec); + written = 0; +} + +void CSPFullPluginSession::Writer::allocate(size_t needed, Allocator &alloc) +{ + if (!needed) + return; // No output buffer space needed so we're done. + else if (vec == firstVec && !*vec) { // initial null vector element, wants allocation there + *vec = makeBuffer(needed, alloc); + lastVec = vec; // ignore all subsequent buffers in vector + useData(vec); + } else { + // how much output space do we have left? + size_t size = currentSize; + for (CssmData *v = vec + 1; v <= lastVec; v++) + size += v->length(); + if (size >= needed) + return; // we're fine + if (remData) { + if (!*remData) { // have overflow, can allocate + *remData = makeBuffer(needed - size, alloc); + return; // got it + } + if (size + remData->length() >= needed) + return; // will fit into overflow + } + // not enough buffer space, and can't allocate + CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR); + } +} + +void CSPFullPluginSession::Writer::nextBlock(void * &ptr, size_t &size) +{ + ptr = currentBuffer; + size = currentSize; +} + +void CSPFullPluginSession::Writer::use(size_t used) +{ + assert(used <= currentSize); + written += used; + if (used < currentSize) { + currentBuffer = increment(currentBuffer, used); + currentSize -= used; + } else { + if (vec < lastVec) { + useData(vec++); // use next vector buffer + } else if (vec == lastVec && remData) { + useData(remData); // use remainder buffer + vec++; // mark used +#if !defined(NDEBUG) && 0 + } else if (vec == lastVec) { + vec++; + } else if (vec > lastVec) { + assert(false); // 2nd try to overflow end +#endif /* !NDEBUG */ + } else { + currentBuffer = NULL; // no more output buffer + currentSize = 0; + } + } +} + +void CSPFullPluginSession::Writer::put(void *addr, size_t size) +{ + while (size > 0) { + void *p; size_t sz; + nextBlock(p, sz); + if (size < sz) + sz = size; // cap transfer + memcpy(p, addr, sz); + use(sz); + addr = increment(addr, sz); + size -= sz; + } +} + +size_t CSPFullPluginSession::Writer::close() +{ + return written; +} + + +// +// Common algorithm utilities +// +void CSPFullPluginSession::setKey(CssmKey &key, + const Context &context, CSSM_KEYCLASS keyClass, + CSSM_KEYATTR_FLAGS attrs, CSSM_KEYUSE use) +{ + // general setup + memset(&key.KeyHeader, 0, sizeof(key.KeyHeader)); + key.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; + key.KeyHeader.CspId = plugin.myGuid(); + key.KeyHeader.AlgorithmId = context.algorithm(); + key.KeyHeader.KeyClass = keyClass; + key.KeyHeader.KeyUsage = use; + key.KeyHeader.KeyAttr = attrs; + + CssmDate *theDate = context.get(CSSM_ATTRIBUTE_START_DATE); + if(theDate) { + key.KeyHeader.StartDate = *theDate; + } + theDate = context.get(CSSM_ATTRIBUTE_END_DATE); + if(theDate) { + key.KeyHeader.EndDate = *theDate; + } + + // defaults (change as needed) + key.KeyHeader.WrapAlgorithmId = CSSM_ALGID_NONE; + + // clear key data (standard says, "Always allocate this, ignore prior contents.") + key = CssmData(); +}