X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5dd5f9ec28f304ca377c42fd7f711d6cf12b90e1..5c19dc3ae3bd8e40a9c028b0deddd50ff337692c:/Security/libsecurity_utilities/lib/superblob.h diff --git a/Security/libsecurity_utilities/lib/superblob.h b/Security/libsecurity_utilities/lib/superblob.h deleted file mode 100644 index 785f51ce..00000000 --- a/Security/libsecurity_utilities/lib/superblob.h +++ /dev/null @@ -1,237 +0,0 @@ -// -// SuperBlob - a typed bag of Blobs -// -#ifndef _H_SUPERBLOB -#define _H_SUPERBLOB - -#include -#include - -namespace Security { - - -// -// A SuperBlob is a Blob that contains multiple sub-Blobs of varying type. -// The SuperBlob is contiguous and contains a directory of its sub-blobs. -// A Maker is included. -// -// SuperBlobCore lets you define your own SuperBlob type. To just use a generic -// SuperBlob, use SuperBlob<> below. -// -template -class SuperBlobCore: public Blob<_BlobType, _magic> { -public: - class Maker; friend class Maker; - - typedef _Type Type; - - // echoes from parent BlobCore (the C++ type system is too restrictive here) - typedef BlobCore::Offset Offset; - template BlobType *at(Offset offset) { return BlobCore::at(offset); } - template const BlobType *at(Offset offset) const { return BlobCore::at(offset); } - - void setup(size_t size, unsigned count) - { this->initialize(size); this->mCount = count; } - - struct Index { - Endian type; // type of sub-Blob - Endian offset; // starting offset - }; - - bool validateBlob(size_t maxSize = 0) const; - - unsigned count() const { return mCount; } - - // access by index number - Type type(unsigned n) const { assert(n < mCount); return mIndex[n].type; } - const BlobCore *blob(unsigned n) const - { assert(n < mCount); return mIndex[n].offset ? at(mIndex[n].offset) : NULL; } - template - const BlobType *blob(unsigned n) const { return BlobType::specific(blob(n)); } - - // access by index type (assumes unique types) - const BlobCore *find(Type type) const; - template - const BlobType *find(Type type) const { return BlobType::specific(find(type)); } - -private: - Endian mCount; // number of sub-Blobs following - Index mIndex[0]; // IndexSlot structures - // followed by sub-Blobs, packed and ordered in an undefined way -}; - - -template -inline bool SuperBlobCore<_BlobType, _magic, _Type>::validateBlob(size_t maxSize /* = 0 */) const -{ - unsigned count = mCount; - size_t ixLimit = sizeof(SuperBlobCore) + count * sizeof(Index); // end of index vector - if (!BlobCore::validateBlob(_magic, ixLimit, maxSize)) - return false; - for (const Index *ix = mIndex + count - 1; ix >= mIndex; ix--) { - Offset offset = ix->offset; - if (offset) // if non-null - if (offset < ixLimit // offset not too small - || offset + sizeof(BlobCore) > this->length() // fits Blob header (including length field) - || offset + at(offset)->length() > this->length()) // fits entire blob - return false; - } - return true; -} - - -// -// A generic SuperBlob ready for use. You still need to specify a magic number. -// -template -class SuperBlob : public SuperBlobCore, _magic, _Type> { -}; - - -template -const BlobCore *SuperBlobCore<_BlobType, _magic, _Type>::find(Type type) const -{ - for (unsigned slot = 0; slot < mCount; slot++) - if (mIndex[slot].type == type) - return mIndex[slot].offset ? at(mIndex[slot].offset) : NULL; - return NULL; // not found -} - - -// -// A SuperBlob::Maker simply assembles multiple Blobs into a single, indexed -// super-blob. Just add() sub-Blobs by type and call make() to get -// the result, malloc'ed. A Maker is not resettable. -// Maker can repeatedly make SuperBlobs from the same (cached) inputs. -// It can also tell you how big its output will be, given established contents -// plus (optional) additional sizes of blobs yet to come. -// -template -class SuperBlobCore<_BlobType, _magic, _Type>::Maker { -public: - Maker() { } - - Maker(const Maker &src) - { - for (typename BlobMap::iterator it = mPieces.begin(); it != mPieces.end(); ++it) - mPieces.insert(make_pair(it->first, it->second->clone())); - } - - ~Maker() - { - for (typename BlobMap::iterator it = mPieces.begin(); it != mPieces.end(); ++it) - ::free(it->second); - } - - void add(Type type, BlobCore *blob); // takes ownership of blob - void add(const _BlobType *blobs); // copies all blobs - void add(const Maker &maker); // ditto - - bool contains(Type type) const // see if we have this type already - { return mPieces.find(type) != mPieces.end(); } - BlobCore *get(Type type) const - { - typename BlobMap::const_iterator it = mPieces.find(type); - return (it == mPieces.end()) ? NULL : it->second; - } - - size_t size(size_t size1 = 0, ...) const; // size with optional additional blob sizes - _BlobType *make() const; // create (malloc) and return SuperBlob - _BlobType *operator () () const { return make(); } - -private: - typedef std::map BlobMap; - BlobMap mPieces; -}; - - -// -// Add a Blob to a SuperBlob::Maker. -// This takes ownership of the blob, which must have been malloc'ed. -// Any previous value set for this Type will be freed immediately. -// -template -void SuperBlobCore<_BlobType, _magic, _Type>::Maker::add(Type type, BlobCore *blob) -{ - pair r = mPieces.insert(make_pair(type, blob)); - if (!r.second) { // already there - secdebug("superblob", "Maker %p replaces type=%d", this, type); - ::free(r.first->second); - r.first->second = blob; - } -} - -template -void SuperBlobCore<_BlobType, _magic, _Type>::Maker::add(const _BlobType *blobs) -{ - for (uint32_t ix = 0; ix < blobs->mCount; ix++) - this->add(blobs->mIndex[ix].type, blobs->blob(ix)->clone()); -} - -template -void SuperBlobCore<_BlobType, _magic, _Type>::Maker::add(const Maker &maker) -{ - for (typename BlobMap::const_iterator it = maker.mPieces.begin(); it != maker.mPieces.end(); ++it) - this->add(it->first, it->second->clone()); -} - - -// -// Calculate the size the new SuperBlob would have, given the contents of the Maker -// so far, plus additional blobs with the sizes given. -// -template -size_t SuperBlobCore<_BlobType, _magic, _Type>::Maker::size(size_t size1, ...) const -{ - // count established blobs - size_t count = mPieces.size(); - size_t total = 0; - for (typename BlobMap::const_iterator it = mPieces.begin(); it != mPieces.end(); ++it) - total += it->second->length(); - - // add preview blob sizes to calculation (if any) - if (size1) { - va_list args; - va_start(args, size1); - do { - count++; - total += size1; - size1 = va_arg(args, size_t); - } while (size1); - va_end(args); - } - - return sizeof(SuperBlobCore) + count * sizeof(Index) + total; -} - - -// -// Finish SuperBlob construction and return the new, malloc'ed, SuperBlob. -// This can be done repeatedly. -// -template -_BlobType *SuperBlobCore<_BlobType, _magic, _Type>::Maker::make() const -{ - Offset pc = (Offset)(sizeof(SuperBlobCore) + mPieces.size() * sizeof(Index)); - Offset total = (Offset)size(); - _BlobType *result = (_BlobType *)malloc(total); - if (!result) - UnixError::throwMe(ENOMEM); - result->setup(total, (unsigned)mPieces.size()); - unsigned n = 0; - for (typename BlobMap::const_iterator it = mPieces.begin(); it != mPieces.end(); ++it) { - result->mIndex[n].type = it->first; - result->mIndex[n].offset = pc; - memcpy(result->template at(pc), it->second, it->second->length()); - pc += it->second->length(); - n++; - } - secdebug("superblob", "Maker %p assembles %ld blob(s) into %p (size=%d)", - this, mPieces.size(), result, total); - return result; -} - - -} // Security - -#endif //_H_SUPERBLOB