X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b1ab9ed8d0e0f1c3b66d7daa8fd5564444c56195..4d3cab3d35f4c42d2870204fa61908caab38d33e:/libsecurity_codesigning/lib/codedirectory.cpp diff --git a/libsecurity_codesigning/lib/codedirectory.cpp b/libsecurity_codesigning/lib/codedirectory.cpp index 0bcb9801..06f67a32 100644 --- a/libsecurity_codesigning/lib/codedirectory.cpp +++ b/libsecurity_codesigning/lib/codedirectory.cpp @@ -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 } };