+static std::string createWhitelistScreen(SecStaticCodeRef code)
+{
+ DiskRep *rep = SecStaticCode::requiredStatic(code)->diskRep();
+ std::string screen;
+ if (CFRef<CFDataRef> info = rep->component(cdInfoSlot)) {
+ // has an Info.plist - hash it
+ SHA1 hash;
+ hash.update(CFDataGetBytePtr(info), CFDataGetLength(info));
+ SHA1::Digest digest;
+ hash.finish(digest);
+ return createWhitelistScreen('I', digest, sizeof(digest));
+ } else if (CFRef<CFDataRef> repSpecific = rep->component(cdRepSpecificSlot)) {
+ // has a rep-specific slot - hash that (this catches disk images cheaply)
+ // got invented after SHA-1 deprecation, so we'll use SHA256, which is the new default
+ CCHashInstance hash(kCCDigestSHA256);
+ hash.update(CFDataGetBytePtr(repSpecific), CFDataGetLength(repSpecific));
+ Byte digest[256/8];
+ hash.finish(digest);
+ return createWhitelistScreen('R', digest, sizeof(digest));
+ } else if (rep->mainExecutableImage()) {
+ // stand-alone Mach-O executables are always candidates
+ return "N";
+ } else {
+ // if everything else fails, hash the (single) file
+ SHA1 hash;
+ hashFileData(rep->mainExecutablePath().c_str(), &hash);
+ SHA1::Digest digest;
+ hash.finish(digest);
+ return createWhitelistScreen('M', digest, sizeof(digest));
+ }
+}
+