// 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);
}
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);
}
}
+//
+// 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
{ "adhoc", kSecCodeSignatureAdhoc, false },
{ "hard", kSecCodeSignatureForceHard, true },
{ "kill", kSecCodeSignatureForceKill, true },
- { "expires", kSecCodeSignatureForceExpiration, true },
+ { "expires", kSecCodeSignatureForceExpiration, true },
+ { "restrict", kSecCodeSignatureRestrict, true },
+ { "enforcement", kSecCodeSignatureEnforcement, true },
{ NULL }
};