X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/fa7225c82381bac4432a6edf16f53b5370238d85..b54c578e17e9bcbd74aa30ea75e25e955b9a6205:/OSX/libsecurity_codesigning/lib/codedirectory.h?ds=sidebyside diff --git a/OSX/libsecurity_codesigning/lib/codedirectory.h b/OSX/libsecurity_codesigning/lib/codedirectory.h index 381d6660..eae6649f 100644 --- a/OSX/libsecurity_codesigning/lib/codedirectory.h +++ b/OSX/libsecurity_codesigning/lib/codedirectory.h @@ -65,7 +65,7 @@ namespace CodeSigning { #define kSecCS_ENTITLEMENTFILE "CodeEntitlements" // entitlement configuration #define kSecCS_REPSPECIFICFILE "CodeRepSpecific" // DiskRep-specific use slot #define kSecCS_TOPDIRECTORYFILE "CodeTopDirectory" // Top-level directory list - +#define kSecCS_ENTITLEMENTDERFILE "CodeEntitlementDER" // DER entitlement representation // // Special hash slot values. In a CodeDirectory, these show up at negative slot @@ -93,6 +93,7 @@ enum { cdTopDirectorySlot = 4, // Application specific slot cdEntitlementSlot = 5, // embedded entitlement configuration cdRepSpecificSlot = 6, // for use by disk rep + cdEntitlementDERSlot = 7, // DER representation of entitlements // (add further primary slot numbers here) cdSlotCount, // total number of special slots (+1 for slot 0) @@ -112,6 +113,7 @@ enum { cdAlternateCodeDirectoryLimit = 0x1005, // 5+1 hashes should be enough for everyone... cdSignatureSlot = 0x10000, // CMS signature cdIdentificationSlot, // identification blob (detached signatures only) + cdTicketSlot, // ticket embedded in signature (DMG only) // (add further virtual slot numbers here) }; @@ -198,16 +200,24 @@ public: Endian teamIDOffset; // offset of optional teamID string Endian spare3; // unused (most be zero) Endian codeLimit64; // limit to main image signature range, 64 bits - + Endian execSegBase; // offset of executable segment + Endian execSegLimit; // limit of executable segment + Endian execSegFlags; // exec segment flags + + Endian runtime; // Runtime version encoded as an unsigned int + Endian preEncryptOffset; // offset of pre-encrypt hash slots + // works with the version field; see comments above - static const uint32_t currentVersion = 0x20300; // "version 2.3" + static const uint32_t currentVersion = 0x20500; // "version 2.5" static const uint32_t compatibilityLimit = 0x2F000; // "version 3 with wiggle room" static const uint32_t earliestVersion = 0x20001; // earliest supported version static const uint32_t supportsScatter = 0x20100; // first version to support scatter option static const uint32_t supportsTeamID = 0x20200; // first version to support team ID option static const uint32_t supportsCodeLimit64 = 0x20300; // first version to support codeLimit64 - + static const uint32_t supportsExecSegment = 0x20400; // first version to support exec base and limit + static const uint32_t supportsPreEncrypt = 0x20500; // first version to support pre-encrypt hashes and runtime version + void checkIntegrity() const; // throws if inconsistent or unsupported version typedef uint32_t HashAlgorithm; // types of internal glue hashes @@ -224,18 +234,28 @@ public: // main hash array access SpecialSlot maxSpecialSlot() const; - unsigned char *operator [] (Slot slot) + unsigned char *getSlotMutable (Slot slot, bool preEncrypt) { assert(slot >= int(-nSpecialSlots) && slot < int(nCodeSlots)); - return at(hashOffset) + hashSize * slot; + + if (preEncrypt) { + if (version >= supportsPreEncrypt && preEncryptOffset != 0) { + assert(slot >= 0); + return at(preEncryptOffset) + hashSize * slot; + } else { + return NULL; + } + } else { + return at(hashOffset) + hashSize * slot; + } } - - const unsigned char *operator [] (Slot slot) const + + const unsigned char *getSlot (Slot slot, bool preEncrypt) const { - assert(slot >= int(-nSpecialSlots) && slot < int(nCodeSlots)); - return at(hashOffset) + hashSize * slot; + CodeDirectory *cd = const_cast(this); + return const_cast(cd->getSlotMutable(slot, preEncrypt)); } - + // // The main page hash array can be "scattered" across the code file // by specifying an array of Scatter elements, terminated with an @@ -257,10 +277,18 @@ public: const char *teamID() const { return version >= supportsTeamID && teamIDOffset ? at(teamIDOffset) : NULL; } char *teamID() { return version >= supportsTeamID && teamIDOffset ? at(teamIDOffset) : NULL; } - + + uint64_t execSegmentBase() const { return (version >= supportsExecSegment) ? execSegBase.get() : 0; } + uint64_t execSegmentLimit() const { return (version >= supportsExecSegment) ? execSegLimit.get() : 0; } + uint64_t execSegmentFlags() const { return (version >= supportsExecSegment) ? execSegFlags.get() : 0; } + + const unsigned char *preEncryptHashes() const { return getSlot(0, true); } + + uint32_t runtimeVersion() const {return (version >= supportsPreEncrypt) ? runtime.get() : 0; } + public: - bool validateSlot(const void *data, size_t size, Slot slot) const; // validate memory buffer against page slot - bool validateSlot(UnixPlusPlus::FileDesc fd, size_t size, Slot slot) const; // read and validate file + bool validateSlot(const void *data, size_t size, Slot slot, bool preEncrypted) const; // validate memory buffer against page slot + bool validateSlot(UnixPlusPlus::FileDesc fd, size_t size, Slot slot, bool preEncrypted) const; // read and validate file bool slotIsPresent(Slot slot) const; class Builder; @@ -268,7 +296,7 @@ public: public: static DynamicHash *hashFor(HashAlgorithm hashType); // create a DynamicHash subclass for (hashType) digests DynamicHash *getHash() const { return hashFor(this->hashType); } // make one for me - CFDataRef cdhash() const; + CFDataRef cdhash(bool truncate = true) const; static void multipleHashFileData(UnixPlusPlus::FileDesc fd, size_t limit, HashAlgorithms types, void (^action)(HashAlgorithm type, DynamicHash* hasher)); bool verifyMemoryContent(CFDataRef data, const Byte* digest) const;