]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_codesigning/lib/codedirectory.h
Security-59306.11.20.tar.gz
[apple/security.git] / OSX / libsecurity_codesigning / lib / codedirectory.h
index 381d6660b2691629158f3dc741d22e8e06b3a2e8..eae6649fe4022f43018d88287466a122135be1e1 100644 (file)
@@ -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<uint32_t> teamIDOffset;  // offset of optional teamID string
        Endian<uint32_t> spare3;                // unused (most be zero)
        Endian<uint64_t> codeLimit64;   // limit to main image signature range, 64 bits
-       
+       Endian<uint64_t> execSegBase;   // offset of executable segment
+       Endian<uint64_t> execSegLimit;  // limit of executable segment
+       Endian<uint64_t> execSegFlags;  // exec segment flags
+
+       Endian<uint32_t> runtime;                       // Runtime version encoded as an unsigned int
+       Endian<uint32_t> 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<unsigned char>(hashOffset) + hashSize * slot;
+
+               if (preEncrypt) {
+                       if (version >= supportsPreEncrypt && preEncryptOffset != 0) {
+                               assert(slot >= 0);
+                               return at<unsigned char>(preEncryptOffset) + hashSize * slot;
+                       } else {
+                               return NULL;
+                       }
+               } else {
+                       return at<unsigned char>(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<unsigned char>(hashOffset) + hashSize * slot;
+               CodeDirectory *cd = const_cast<CodeDirectory *>(this);
+               return const_cast<const unsigned char *>(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<const char>(teamIDOffset) : NULL; }
        char *teamID() { return version >= supportsTeamID && teamIDOffset ? at<char>(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;