]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_codesigning/lib/codedirectory.cpp
Security-55471.14.tar.gz
[apple/security.git] / libsecurity_codesigning / lib / codedirectory.cpp
index 0bcb980192b6cc4a746533cdddd8c8094a1b220a..06f67a3239df23a7643a0b82de087df036a9b5fb 100644 (file)
@@ -143,19 +143,18 @@ void CodeDirectory::checkIntegrity() const
        // now check interior offsets for validity
        if (!stringAt(identOffset))
                MacOSError::throwMe(errSecCSSignatureFailed); // identifier out of blob range
-       if (!contains(hashOffset - uint64_t(hashSize) * nSpecialSlots, hashSize * (uint64_t(nSpecialSlots) + nCodeSlots)))
+       if (!contains(hashOffset - int64_t(hashSize) * nSpecialSlots, hashSize * (int64_t(nSpecialSlots) + nCodeSlots)))
                MacOSError::throwMe(errSecCSSignatureFailed); // hash array out of blob range
        if (const Scatter *scatter = this->scatterVector()) {
                // the optional scatter vector is terminated with an element having (count == 0)
                unsigned int pagesConsumed = 0;
-               while (scatter->count) {
+               for (;; scatter++) {
                        if (!contains(scatter, sizeof(Scatter)))
                                MacOSError::throwMe(errSecCSSignatureFailed);
+                       if (scatter->count == 0)
+                               break;
                        pagesConsumed += scatter->count;
-                       scatter++;
                }
-               if (!contains(scatter, sizeof(Scatter)))                        // (even sentinel must be in range)
-                       MacOSError::throwMe(errSecCSSignatureFailed);
                if (!contains((*this)[pagesConsumed-1], hashSize))      // referenced too many main hash slots
                        MacOSError::throwMe(errSecCSSignatureFailed);
        }
@@ -217,8 +216,6 @@ DynamicHash *CodeDirectory::hashFor(HashAlgorithm hashType)
        switch (hashType) {
        case kSecCodeSignatureHashSHA1:                                         alg = kCCDigestSHA1; break;
        case kSecCodeSignatureHashSHA256:                                       alg = kCCDigestSHA256; break;
-       case kSecCodeSignatureHashPrestandardSkein160x256:      alg = kCCDigestSkein160; break;
-       case kSecCodeSignatureHashPrestandardSkein256x512:      alg = kCCDigestSkein256; break;
        default:
                MacOSError::throwMe(errSecCSSignatureUnsupported);
        }
@@ -252,6 +249,33 @@ size_t CodeDirectory::generateHash(DynamicHash *hasher, const void *data, size_t
 }
 
 
+//
+// Turn a hash of canonical type into a hex string
+//
+std::string CodeDirectory::hexHash(const unsigned char *hash) const
+{
+       size_t size = this->hashSize;
+       char result[2*size+1];
+       for (unsigned n = 0; n < size; n++)
+               sprintf(result+2*n, "%02.2x", hash[n]);
+       return result;
+}
+
+
+//
+// Generate a screening code string from a (complete) CodeDirectory.
+// This can be used to make a lightweight pre-screening code from (just) a CodeDirectory.
+//
+std::string CodeDirectory::screeningCode() const
+{
+       if (slotIsPresent(-cdInfoSlot))         // has Info.plist
+               return "I" + hexHash((*this)[-cdInfoSlot]); // use Info.plist hash
+       if (pageSize == 0)                                      // good-enough proxy for "not a Mach-O file"
+               return "M" + hexHash((*this)[0]); // use hash of main executable
+       return "N";                                                     // no suitable screening code
+}
+
+
 }      // CodeSigning
 }      // Security
 
@@ -265,6 +289,8 @@ const SecCodeDirectoryFlagTable kSecCodeDirectoryFlagTable[] = {
        { "adhoc",              kSecCodeSignatureAdhoc,                 false },
        { "hard",               kSecCodeSignatureForceHard,             true },
        { "kill",               kSecCodeSignatureForceKill,             true },
-       { "expires",    kSecCodeSignatureForceExpiration, true },
+       { "expires",            kSecCodeSignatureForceExpiration,       true },
+       { "restrict",           kSecCodeSignatureRestrict,              true },
+       { "enforcement",        kSecCodeSignatureEnforcement,           true },
        { NULL }
 };