X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5dd5f9ec28f304ca377c42fd7f711d6cf12b90e1..5c19dc3ae3bd8e40a9c028b0deddd50ff337692c:/Security/libsecurity_cdsa_utilities/lib/cssmdata.h diff --git a/Security/libsecurity_cdsa_utilities/lib/cssmdata.h b/Security/libsecurity_cdsa_utilities/lib/cssmdata.h deleted file mode 100644 index eee84a0a..00000000 --- a/Security/libsecurity_cdsa_utilities/lib/cssmdata.h +++ /dev/null @@ -1,560 +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@ - */ - - -// -// cssmdata.h -- Manager different CssmData types -// -#ifndef _H_CDSA_UTILITIES_CSSMDATA -#define _H_CDSA_UTILITIES_CSSMDATA - -#include -#include -#include -#include -#include - -namespace Security { - - -// -// User-friendlier CSSM_DATA thingies. -// CssmData is a PODWrapper for CSSM_DATA, but is also used throughout -// the security code as a "byte blob" representation. -// -class CssmData : public PodWrapper { -public: - CssmData() { Data = 0; Length = 0; } - - size_t length() const { return Length; } - void *data() const { return Data; } - void *end() const { return Data + Length; } - - // - // Create a CssmData from any pointer-to-byte-sized-object and length. - // - CssmData(void *data, size_t length) - { Data = reinterpret_cast(data); Length = length; } - CssmData(char *data, size_t length) - { Data = reinterpret_cast(data); Length = length; } - CssmData(unsigned char *data, size_t length) - { Data = reinterpret_cast(data); Length = length; } - CssmData(signed char *data, size_t length) - { Data = reinterpret_cast(data); Length = length; } - - CssmData(CFDataRef cf) - { Data = const_cast(CFDataGetBytePtr(cf)); Length = CFDataGetLength(cf); } - - // the void * form accepts too much; explicitly deny all other types - private: template CssmData(T *, size_t); public: - - // explicitly construct from a data-oid source - template - explicit CssmData(const T &obj) - { Data = (UInt8 *)obj.data(); Length = obj.length(); } - - // - // Do allow generic "wrapping" of any data structure, but make it conspicuous - // since it's not necessarily the Right Thing (alignment and byte order wise). - // Also note that the T & form removes const-ness, since there is no ConstCssmData. - // - template - static CssmData wrap(const T &it) - { return CssmData(const_cast(reinterpret_cast(&it)), sizeof(it)); } - - template - static CssmData wrap(T *data, size_t length) - { return CssmData(const_cast(static_cast(data)), length); } - - // - // Automatically convert a CssmData to any pointer-to-byte-sized-type. - // - operator signed char * () const { return reinterpret_cast(Data); } - operator unsigned char * () const { return reinterpret_cast(Data); } - operator char * () const { return reinterpret_cast(Data); } - operator void * () const { return reinterpret_cast(Data); } - - // - // If you want to interpret the contents of a CssmData blob as a particular - // type, you have to be more explicit to show that you know what you're doing. - // See wrap() above. - // - template - T *interpretedAs() const { return reinterpret_cast(Data); } - - template - T *interpretedAs(CSSM_RETURN error) const - { return interpretedAs(sizeof(T), error); } - - template - T *interpretedAs(size_t len, CSSM_RETURN error) const - { - if (data() == NULL || length() != len) CssmError::throwMe(error); - return interpretedAs(); - } - -public: - void length(size_t newLength) // shorten only - { assert(newLength <= Length); Length = newLength; } - - void *at(off_t offset) const - { assert(offset >= 0 && (CSSM_SIZE)offset <= Length); return Data + offset; } - void *at(off_t offset, size_t size) const // length-checking version - { assert(offset >= 0 && (CSSM_SIZE)offset + size <= Length); return Data + offset; } - - template T *at(off_t offset) const { return reinterpret_cast(at(offset)); } - template T *at(off_t offset, size_t size) const - { return reinterpret_cast(at(offset, size)); } - - unsigned char byte(off_t offset) const { return *at(offset); } - unsigned char &byte(off_t offset) { return *at(offset); } - - void *use(size_t taken) // logically remove some bytes - { assert(taken <= Length); void *r = Data; Length -= taken; Data += taken; return r; } - - void clear() - { Data = NULL; Length = 0; } - - string toString () const; // convert to string type (no trailing null) - string toHex() const; // hex string of binary blob - string toOid() const; // standard OID string encoding (1.2.3...) - void fromHex(const char *digits); // fill myself with hex data (no allocation) - - operator bool () const { return Data != NULL; } - bool operator ! () const { return Data == NULL; } - bool operator < (const CssmData &other) const; - bool operator == (const CssmData &other) const - { return length() == other.length() && !memcmp(data(), other.data(), length()); } - bool operator != (const CssmData &other) const - { return !(*this == other); } - - // Extract fixed-format data from a CssmData. Fixes any alignment trouble for you. - template - void extract(T &destination, CSSM_RETURN error = CSSM_ERRCODE_INVALID_DATA) const - { - if (length() != sizeof(destination) || data() == NULL) - CssmError::throwMe(error); - memcpy(&destination, data(), sizeof(destination)); - } -}; - - -inline bool CssmData::operator < (const CssmData &other) const -{ - if (Length != other.Length) // If lengths are not equal the shorter data is smaller. - return Length < other.Length; - if (Length == 0) // If lengths are both zero ignore the Data. - return false; - if (Data == NULL || other.Data == NULL) // arbitrary (but consistent) ordering - return Data < other.Data; - return memcmp(Data, other.Data, Length) < 0; // Do a lexicographic compare on equal sized Data. -} - - -// -// CSSM_OIDs are CSSM_DATAs but will probably have different wrapping characteristics. -// -typedef CssmData CssmOid; - - -// -// A convenient way to make a CssmData from a (const) string. -// Note that the underlying string is not memory-managed, so it -// should either be static or of sufficient (immutable) lifetime. -// -class StringData : public CssmData { -public: - StringData(const char *s) : CssmData(const_cast(s), strlen(s)) { } - StringData(const std::string &s) : CssmData(const_cast(s.c_str()), s.size()) { } -}; - - -// -// A CssmData bundled up with a data buffer it refers to -// -template -struct DataBuffer : public CssmData { - unsigned char buffer[size]; - DataBuffer() : CssmData(buffer, size) { } -}; - - -// -// Comparing CssmDatas for equality. -// Note: No ordering is established here. -// Both CSSM_DATAs have to exist. -// -bool operator == (const CSSM_DATA &d1, const CSSM_DATA &d2); -inline bool operator != (const CSSM_DATA &d1, const CSSM_DATA &d2) -{ return !(d1 == d2); } - - -// -// The following pseudo-code describes what (at minimum) is required for a class -// to be a "PseudoData". PseudoData arguments ("DataOids") are used in templates. -// -// class PseudoData { -// void *data() const ... -// size_t length() const ... -// operator const CssmData &() const ... -// } -// -// All this can be satisfied, of course, by inheriting from CssmData. -// - - -// -// A common virtual parent for CssmData-like objects that actively manage the -// allocation status of their data blob. Note that this is about allocating -// the data(), not the CssmData structure itself. -// The ManagedData layer provides for little active memory management, since -// the underlying strategies are potentially very disparate. It does however -// have a well defined interface for *yielding up* its data for copying or transfer. -// -class CssmManagedData { -public: - CssmManagedData(Allocator &alloc) : allocator(alloc) { } - virtual ~CssmManagedData(); - - Allocator &allocator; - - virtual operator const CssmData & () const { return get(); } - template T *data() const { return reinterpret_cast(data()); } - void *data() const { return get().data(); } - size_t length() const { return get().length(); } - - virtual CssmData &get() const throw() = 0; // get shared copy, no ownership change - virtual CssmData release() = 0; // give up copy, ownership is transferred - virtual void reset() = 0; // give up copy, data is discarded -}; - - -inline bool operator == (const CssmManagedData &d1, const CssmData &d2) -{ return d1.get() == d2; } - -inline bool operator == (const CssmData &d1, const CssmManagedData &d2) -{ return d1 == d2.get(); } - -inline bool operator == (const CssmManagedData &d1, const CssmManagedData &d2) -{ return d1.get() == d2.get(); } - -inline bool operator != (const CssmManagedData &d1, const CssmData &d2) -{ return d1.get() != d2; } - -inline bool operator != (const CssmData &d1, const CssmManagedData &d2) -{ return d1 != d2.get(); } - -inline bool operator != (const CssmManagedData &d1, const CssmManagedData &d2) -{ return d1.get() != d2.get(); } - - -// -// A CssmOwnedData is a CssmManagedData that unilaterally owns its data storage. -// It has its CssmData object provided during construction. -// -class CssmOwnedData : public CssmManagedData { -public: - CssmOwnedData(Allocator &alloc, CssmData &mine) : CssmManagedData(alloc), referent(mine) { } - - CssmOwnedData(Allocator &alloc, CSSM_DATA &mine) - : CssmManagedData(alloc), referent(CssmData::overlay(mine)) { referent.clear(); } - - // - // Basic retrievals (this echoes features of CssmData) - // - operator void * () const { return referent; } - operator char * () const { return referent; } - operator signed char * () const { return referent; } - operator unsigned char * () const { return referent; } - - operator bool () const { return referent; } - bool operator ! () const { return !referent; } - - size_t length() const { return referent.length(); } - - - // - // Basic allocators - // - void *malloc(size_t len) - { - // pseudo-atomic reallocation semantics - CssmAutoPtr alloc(allocator, allocator.malloc(len)); - reset(); - return referent = CssmData(alloc.release(), len); - } - - void *realloc(size_t newLen) - { - // Allocator::realloc() should be pseudo-atomic (i.e. throw on error) - return referent = CssmData(allocator.realloc(referent.data(), newLen), newLen); - } - - void length(size_t len) { realloc(len); } - - - // - // Manipulate existing data - // - void *append(const void *addData, size_t addLength) - { - size_t oldLength = length(); - realloc(oldLength + addLength); - return memcpy(referent.at(oldLength), addData, addLength); - } - - void *append(const CssmData &data) - { return append(data.data(), data.length()); } - - - // - // set() replaces current data with new, taking over ownership to the extent possible. - // - template - void set(T *data, size_t length) - { - // assume that data was allocated by our allocator -- we can't be sure - reset(); - referent = CssmData(data, length); - } - - void set(CssmManagedData &source); - void set(const CSSM_DATA &source) { set(source.Data, source.Length); } - // NOTE: General template set() cannot be used because all subclasses of CssmManagedData - // need to receive the special handling above. Use set(*.data(), *.length()) instead. - - - // - // copy() replaces current data with new, making a copy and leaving - // the source intact. - // - template - void copy(const T *data, size_t length) - { - CssmAutoPtr newData(allocator, memcpy(allocator.malloc(length), data, length)); - reset(); - referent = CssmData(newData.release(), length); - } - - void copy(const CssmData &source) - { if (&source != &referent) copy(source.data(), source.length()); } - void copy(const CSSM_DATA &source) - { if (&source != &referent) copy(source.Data, source.Length); } - void copy(CssmManagedData &source) { copy(source.get()); } - template - void copy(const Data &source) { copy(source.data(), source.length()); } - - - // - // Assignment conservatively uses copy if allocator unknown, set if known - // - void operator = (CssmManagedData &source) { set(source); } - void operator = (CssmOwnedData &source) { set(source); } - void operator = (const CSSM_DATA &source) { copy(source); } - - CssmData &get() const throw(); - -public: - void fromOid(const char *oid); // fill from text OID form (1.2.3...) - -protected: - CssmData &referent; -}; - - -// -// A CssmAutoData is a CssmOwnedData that includes its CssmData object. -// This is the very simple case: The object includes ownership, data object, -// and data storage. -// -class CssmAutoData : public CssmOwnedData { -public: - CssmAutoData(Allocator &alloc) : CssmOwnedData(alloc, mData) { } - - template - CssmAutoData(Allocator &alloc, const Data &source) : CssmOwnedData(alloc, mData) - { *this = source; } - - CssmAutoData(CssmAutoData &source) : CssmOwnedData(source.allocator, mData) - { set(source); } - - explicit CssmAutoData(CssmManagedData &source) : CssmOwnedData(source.allocator, mData) - { set(source); } - - CssmAutoData(Allocator &alloc, const void *data, size_t length) - : CssmOwnedData(alloc, mData) { copy(data, length); } - - ~CssmAutoData() { allocator.free(mData); } - - CssmData release(); - void reset(); - - // assignment (not usefully inherited) - void operator = (CssmManagedData &source) { set(source); } - void operator = (CssmOwnedData &source) { set(source); } - void operator = (CssmAutoData &source) { set(source); } - template - void operator = (const Data &source) { copy(source); } - -private: - CssmData mData; -}; - - -// -// A CssmRemoteData is a CssmOwnedData that uses an external CssmData object. -// Its release operation clears an internal ownership flag but does not clear -// the CssmData values so they can be used to return values to an outside scope. -// -class CssmRemoteData : public CssmOwnedData { -public: - CssmRemoteData(Allocator &alloc, CssmData &mine) - : CssmOwnedData(alloc, mine), iOwnTheData(true) { } - - CssmRemoteData(Allocator &alloc, CSSM_DATA &mine) - : CssmOwnedData(alloc, mine), iOwnTheData(true) { } - - ~CssmRemoteData() - { if (iOwnTheData) allocator.free(referent); } - - CssmData release(); - void reset(); - - // assignment (not usefully inherited) - void operator = (CssmManagedData &source) { set(source); } - void operator = (CssmOwnedData &source) { set(source); } - void operator = (CssmAutoData &source) { set(source); } - template - void operator = (const Data &source) { copy(source); } - -private: - bool iOwnTheData; -}; - - -// -// CssmPolyData -// -// Used by functions that take a CssmData and would like to allow it to be -// initialized with a static string, int or other basic type. The function *must* -// copy the Data of the CssmPolyData when doing so if it is to be used -// after the function returns. (For example by creating a CssmDataContainer from it). -class CssmPolyData : public CssmData { - template - uint8 *set(const T &it) - { return const_cast(reinterpret_cast(&it)); } -public: - template - CssmPolyData(const char_T *s) : CssmData(const_cast(s), strlen(s)) {} - CssmPolyData(const string &s) : CssmData(const_cast(s.c_str()), s.size()) {} - CssmPolyData(const CSSM_DATA &data) : CssmData(data.Data, data.Length) {} - - // Don't use a template constructor (for T &) here - it would eat way too much - CssmPolyData(const bool &t) : CssmData(set(t), sizeof(t)) { } - CssmPolyData(const uint32 &t) : CssmData(set(t), sizeof(t)) { } - CssmPolyData(const sint32 &t) : CssmData(set(t), sizeof(t)) { } - CssmPolyData(const sint64 &t) : CssmData(set(t), sizeof(t)) { } - CssmPolyData(const double &t) : CssmData(set(t), sizeof(t)) { } - CssmPolyData(const unsigned long &t) : CssmData(set(t), sizeof(t)) { } - CssmPolyData(const CSSM_GUID &t) : CssmData(set(t), sizeof(t)) { } - CssmPolyData(const StringPtr s) : CssmData (reinterpret_cast(s + 1), uint32 (s[0])) {} -}; - -class CssmDateData : public CssmData -{ -public: - CssmDateData(const CSSM_DATE &date); -private: - uint8 buffer[8]; -}; - - -// -// Non POD refcounted CssmData wrapper that own the data it refers to. -// -class CssmDataContainer : public CssmData, public RefCount -{ -public: - CssmDataContainer(Allocator &inAllocator = Allocator::standard()) : - CssmData(), mAllocator(inAllocator) {} - template - CssmDataContainer(const T *data, size_t length, Allocator &inAllocator = Allocator::standard()) : - CssmData(inAllocator.malloc(length), length), mAllocator(inAllocator) - { if (length) ::memcpy(Data, data, length); } - void clear() { if (Data) { mAllocator.free(Data); Data = NULL; Length = 0; } } - void invalidate () {Data = NULL; Length = 0;} - ~CssmDataContainer() { if (Data) mAllocator.free(Data); } - void append(const CssmPolyData &data) - { - size_t newLength = Length + data.Length; - Data = reinterpret_cast(mAllocator.realloc(Data, newLength)); - memcpy(Data + Length, data.Data, data.Length); - Length = newLength; - } - CssmDataContainer(const CssmDataContainer &other) - : mAllocator(other.mAllocator) - { - Data = reinterpret_cast(mAllocator.malloc(other.Length)); - memcpy(Data, other.Data, other.Length); - Length = other.Length; - } - CssmDataContainer & operator = (const CSSM_DATA &other) - { - clear(); - Data = reinterpret_cast(mAllocator.malloc(other.Length)); - memcpy(Data, other.Data, other.Length); - Length = other.Length; - return *this; - } - -public: - Allocator &mAllocator; - -private: - operator CssmDataContainer * () const; // prohibit conversion-to-my-pointer -}; - -// -// CSSM_OIDs are CSSM_DATAs but will probably have different wrapping characteristics. -// -typedef CssmDataContainer CssmOidContainer; - -template -class CssmBuffer : public RefPointer -{ -public: - CssmBuffer() : RefPointer(new Container()) {} // XXX This should may just set ptr to NULL. - template - CssmBuffer(const T *data, size_t length, Allocator &inAllocator = Allocator::standard()) : - RefPointer(new Container(data, length, inAllocator)) {} - CssmBuffer(const CSSM_DATA &data, Allocator &inAllocator = Allocator::standard()) : - RefPointer(new Container(data.Data, data.Length, inAllocator)) {} - CssmBuffer(const CssmBuffer& other) : RefPointer(other) {} - CssmBuffer(Container *p) : RefPointer(p) {} - bool operator < (const CssmBuffer &other) const { return (**this) < (*other); } -}; - - -} // end namespace Security - -#endif // _H_CDSA_UTILITIES_CSSMDATA