X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5dd5f9ec28f304ca377c42fd7f711d6cf12b90e1..5c19dc3ae3bd8e40a9c028b0deddd50ff337692c:/Security/libsecurity_cdsa_utilities/lib/context.h diff --git a/Security/libsecurity_cdsa_utilities/lib/context.h b/Security/libsecurity_cdsa_utilities/lib/context.h deleted file mode 100644 index f5eb57d7..00000000 --- a/Security/libsecurity_cdsa_utilities/lib/context.h +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Copyright (c) 2000-2006,2011-2012,2014 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -// -// context - CSSM cryptographic context objects -// -#ifndef _H_CONTEXT -#define _H_CONTEXT - -#include -#include -#include -#include -#include // to serialize/copy access credentials -#include - -namespace Security { - - -// -// Context is a POD overlay for the CSSM_CONTEXT type. It does -// add allocation functions and lots of good stuff. -// Note that if you're outside CSSM proper, you are not supposed to -// memory-manage Context structures on your own. Be a good boy and -// call the CSSM API functions. -// We also provide a POD overlay for CSSM_CONTEXT_ATTRIBUTE, with -// the obvious semantics. -// -class Context : public PodWrapper { -public: - Context(CSSM_CONTEXT_TYPE type, CSSM_ALGORITHMS algorithmId); - - uint32 attributesInUse() const { return NumberOfAttributes; } - CSSM_CONTEXT_TYPE type() const { return ContextType; } - CSSM_ALGORITHMS algorithm() const { return AlgorithmType; } - CSSM_CSP_HANDLE cspHandle() const { return CSPHandle; } - - void deleteAttribute(CSSM_ATTRIBUTE_TYPE type); - size_t copyAttributes(CSSM_CONTEXT_ATTRIBUTE * &attrs, uint32 &count, Allocator &alloc) const; - - void copyFrom(const Context &source, Allocator &alloc) - { source.copyAttributes(ContextAttributes, NumberOfAttributes, alloc); } - -public: - class Attr : public PodWrapper { - public: - Attr() { } - Attr(const CSSM_CONTEXT_ATTRIBUTE &attr) { (CSSM_CONTEXT_ATTRIBUTE &)*this = attr; } - - template - Attr(CSSM_ATTRIBUTE_TYPE typ, T &value, size_t size = 0) - { - AttributeType = typ; - // attribute component pointers are stupidly non-const; allow const input - Attribute.String = const_cast(reinterpret_cast(&value)); - AttributeLength = (uint32_t) (size ? size : sizeof(T)); - } - - Attr(CSSM_ATTRIBUTE_TYPE typ, uint32 value) - { - AttributeType = typ; - Attribute.Uint32 = value; - AttributeLength = 0; - } - - CSSM_ATTRIBUTE_TYPE type() const { return AttributeType; } - uint32 baseType() const { return AttributeType & CSSM_ATTRIBUTE_TYPE_MASK; } - - operator char * () const - { assert(baseType() == CSSM_ATTRIBUTE_DATA_STRING); return Attribute.String; } - operator CssmData & () const - { assert(baseType() == CSSM_ATTRIBUTE_DATA_CSSM_DATA); - return CssmData::overlay(*Attribute.Data); } - operator CssmCryptoData & () const - { assert(baseType() == CSSM_ATTRIBUTE_DATA_CRYPTO_DATA); - return CssmCryptoData::overlay(*Attribute.CryptoData); } - operator CssmKey & () const - { assert(baseType() == CSSM_ATTRIBUTE_DATA_KEY); return CssmKey::overlay(*Attribute.Key); } - operator AccessCredentials & () const - { assert(baseType() == CSSM_ATTRIBUTE_DATA_ACCESS_CREDENTIALS); - return AccessCredentials::overlay(*Attribute.AccessCredentials); } - operator uint32 () const - { assert(baseType() == CSSM_ATTRIBUTE_DATA_UINT32); return Attribute.Uint32; } - operator CSSM_DL_DB_HANDLE &() const - { - assert(baseType() == CSSM_ATTRIBUTE_DATA_DL_DB_HANDLE); - if (Attribute.DLDBHandle == NULL) - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_DL_DB_HANDLE); - return *Attribute.DLDBHandle; - } - operator CssmDate & () const - { assert(baseType() == CSSM_ATTRIBUTE_DATA_DATE); - return CssmDate::overlay(*Attribute.Date); } - // @@@ etc. etc. - add yours today! - - void operator = (uint32 value) { Attribute.Uint32 = value; } - template - void operator = (T *ptr) { Attribute.String = reinterpret_cast(ptr); } - - IFDUMP(void dump() const;) // debug dump this Attr to stdout (one line) - }; - - // Attributes by position - Attr *attributes() const { return Attr::overlay(ContextAttributes); } - Attr &operator [] (unsigned int ix) - { assert(ix < NumberOfAttributes); return static_cast(ContextAttributes[ix]); } - const Attr &operator [] (unsigned int ix) const - { assert(ix < NumberOfAttributes); return static_cast(ContextAttributes[ix]); } - - // general attribute retrieval by type - Attr *find(CSSM_ATTRIBUTE_TYPE theType) const - { return find(theType, ContextAttributes, NumberOfAttributes); } - - template - Elem &get(CSSM_ATTRIBUTE_TYPE type, CSSM_RETURN err) const - { - if (Attr *attr = find(type)) - return static_cast(*attr); - else - CssmError::throwMe(err); - } - - template - Elem *get(CSSM_ATTRIBUTE_TYPE type) const - { - if (Attr *attr = find(type)) - // @@@ Invoking conversion operator to Elem & on *attr and taking address of result. - return &static_cast(*attr); - else - return NULL; - } - - uint32 getInt(CSSM_ATTRIBUTE_TYPE type, CSSM_RETURN err) const - { - if (Attr *attr = find(type)) - return static_cast(*attr); - else - CssmError::throwMe(err); - } - - uint32 getInt(CSSM_ATTRIBUTE_TYPE type) const - { - if (Attr *attr = find(type)) - return static_cast(*attr); - else - return 0; - } - - bool getInt(CSSM_ATTRIBUTE_TYPE type, uint32 &value) const - { - if (Attr *attr = find(type)) { - value = static_cast(*attr); - return true; - } else - return false; - } - -public: - template - void replace(CSSM_ATTRIBUTE_TYPE type, const T &newValue) const - { - if (Attr *attr = find(type)) - *attr = Attr(type, newValue); - else - CssmError::throwMe(CSSMERR_CSSM_ATTRIBUTE_NOT_IN_CONTEXT); - } - -public: - void *operator new (size_t size, Allocator &alloc) throw(std::bad_alloc) - { return alloc.malloc(size); } - void operator delete (void *addr, size_t, Allocator &alloc) throw() - { return alloc.free(addr); } - static void destroy(Context *context, Allocator &alloc) throw() - { alloc.free(context->ContextAttributes); alloc.free(context); } - -public: - // Post-IPC context fixup. - // This can only be called on a Built Context after IPC transmission. - void postIPC(void *base, CSSM_CONTEXT_ATTRIBUTE *ipcAttributes); - -public: - class Builder; - - // dump to stdout, multiline format - IFDUMP(void dump(const char *title = NULL, - const CSSM_CONTEXT_ATTRIBUTE *attrs = NULL) const;) - -protected: - // find an attribute in a plain array of attribute structures (no context) - static Attr *find(CSSM_ATTRIBUTE_TYPE theType, - const CSSM_CONTEXT_ATTRIBUTE *attrs, unsigned int count); -}; - - -namespace DataWalkers { - - -template -void walk(Action &operate, CSSM_CONTEXT_ATTRIBUTE &attr) -{ - operate(attr); - if (attr.Attribute.String) // non-NULL pointer (imprecise but harmless) - switch (attr.AttributeType & CSSM_ATTRIBUTE_TYPE_MASK) { - case CSSM_ATTRIBUTE_DATA_CSSM_DATA: - walk(operate, attr.Attribute.Data); break; - case CSSM_ATTRIBUTE_DATA_CRYPTO_DATA: - walk(operate, attr.Attribute.CryptoData); break; - case CSSM_ATTRIBUTE_DATA_KEY: - walk(operate, attr.Attribute.Key); break; - case CSSM_ATTRIBUTE_DATA_STRING: - walk(operate, attr.Attribute.String); break; - case CSSM_ATTRIBUTE_DATA_DATE: - walk(operate, attr.Attribute.Date); break; - case CSSM_ATTRIBUTE_DATA_RANGE: - walk(operate, attr.Attribute.Range); break; - case CSSM_ATTRIBUTE_DATA_ACCESS_CREDENTIALS: - walk(operate, attr.Attribute.AccessCredentials); break; - case CSSM_ATTRIBUTE_DATA_VERSION: - walk(operate, attr.Attribute.Version); break; - case CSSM_ATTRIBUTE_DATA_DL_DB_HANDLE: - walk(operate, attr.Attribute.DLDBHandle); break; - case CSSM_ATTRIBUTE_NONE: - case CSSM_ATTRIBUTE_DATA_UINT32: - break; - default: - secdebug("walkers", "invalid attribute (%ux) in context", (unsigned)attr.AttributeType); - break; - } -} - -template -void walk(Action &operate, Context::Attr &attr) -{ - walk(operate, static_cast(attr)); -} - -} // end namespace DataWalkers - - -// -// Context::Builder - make context attributes the fun way. -// -// A Context (aka CSSM_CONTEXT) has a pointer to an array of context attributes, -// most of which contain pointers to other stuff with pointers to God Knows Where. -// Instead of allocating this all over the heap, a Context::Builder performs -// a two-pass algorithm that places all that stuff into a single heap node. -// Specifically, the builder will allocate and create a vector of CSSM_CONTEXT_ATTRIBUTE -// structures and all their subordinate heap storage. -// A Builder does not deal in Context objects and does not care what you do with your -// CSSM_CONTEXT_ATTRIBUTE array once it's delivered. Since it's a single heap node, -// you can just free() it using the appropriate allocator when you're done with it. -// -// Theory of operation: -// Builder works in two phases, called scan and build. During scan, you call setup() -// with the desired data to be placed into the attribute vector. When done, call make() -// to switch to build phase. Then call put() with the SAME sequence of values as in phase 1. -// Finally, call done() to receive the pointer-and-count values. -// @@@ Add comment about IPC use. -// -using namespace DataWalkers; - -class Context::Builder { -protected: -public: - Builder(Allocator &alloc) : allocator(alloc) - { slotCount = 0; attributes = NULL; } - ~Builder() { allocator.free(attributes); } - - Allocator &allocator; - - // switch to build phase - size_t make(); - // deliver result - void done(CSSM_CONTEXT_ATTRIBUTE * &attributes, uint32 &count); - -public: - // - // Phase 1 (scan) dispatch. Call once for each attribute needed. - // - template - void setup(T p, CSSM_RETURN invalidError = CSSM_OK) - { - if (p) { - slotCount++; - walk(sizer, unconst_ref_cast(p)); - } else if (invalidError) - CssmError::throwMe(invalidError); - } - - void setup(uint32 n, CSSM_RETURN invalidError = CSSM_OK) - { - if (n) - slotCount++; - else if (invalidError) - CssmError::throwMe(invalidError); - } - - void setup(CSSM_SIZE n, CSSM_RETURN invalidError = CSSM_OK) - { - if (n) - slotCount++; - else if (invalidError) - CssmError::throwMe(invalidError); - } - - void setup(const CSSM_KEY *k, CSSM_RETURN invalidError = CSSM_OK) - { - if (!invalidError) { - if (k) { - slotCount++; - walk(sizer, unconst_ref_cast(k)); - } - return; // no additional validation performed - } - // perform a basic sanity check of the input CSSM_KEY - if (!(k) || (k->KeyHeader.HeaderVersion > CSSM_KEYHEADER_VERSION)) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_REFERENCE); - } - // must not point to an odd address or NULL - if (!(k->KeyData.Data) || ((uint64_t)k->KeyData.Data & (uint64_t)1)) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_POINTER); - } - // simplistic key data length check - if ((k->KeyData.Length < 4) || (k->KeyData.Length > 32768)) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT); - } - slotCount++; - walk(sizer, unconst_ref_cast(k)); - } - - // dynamic attribute type - void setup(const CSSM_CONTEXT_ATTRIBUTE &attr) - { slotCount++; walk(sizer, const_cast(attr)); } - void setup(const Context::Attr &attr) { setup(static_cast(attr)); } - - // - // Phase 2 (copy) dispatch. Call once for each attribute, in same order as setup(). - // - template - void put(CSSM_ATTRIBUTE_TYPE type, const T *p) - { - if (p) { - assert(slot < slotCount); // check overflow - Attr &attribute = attributes[slot++]; - attribute.AttributeType = type; - attribute.AttributeLength = (uint32)size(p); //@@@ needed? how/when/what for? - T *tmp = const_cast(p); - attribute = walk(copier, tmp); - } - } - void put(CSSM_ATTRIBUTE_TYPE type, uint32 value) - { - if (value) { - assert(slot < slotCount); // check overflow - Attr &attribute = attributes[slot++]; - attribute.AttributeType = type; - attribute.AttributeLength = 0; //@@@ unclear what that should be - attribute = value; // no heap data (immediate value) - } - } - void put(const CSSM_CONTEXT_ATTRIBUTE &attr) - { - assert(slot < slotCount); - Attr &attribute = attributes[slot++]; - attribute = attr; // shallow copy - walk(copier, attribute); // deep copy - } - void put(const Context::Attr &attr) { put(static_cast(attr)); } - -private: - // pass 1 state: collect sizes and counts - unsigned slotCount; // count of attribute slots in use - SizeWalker sizer; // memory size calculator - - // pass 2 state: build the data set - Context::Attr *attributes; // attribute vector and start of block - CopyWalker copier; // data copy engine - uint32 slot; // writer slot position -}; - -} // end namespace Security - -#endif //_H_CONTEXT