In Objective C, how do I get a checksum for an OSX folder and its contents (which may also have several subfolders)? Preferably, I'd like to get the sha512 value.
In Bash, I can do this like so:
find /tmp/examplefolder -type f -print | xargs cat | shasum -a 512
...however, one can replace the shasum
command with their own version and undo what I'm trying to do.
BACKGROUND:
I'm using the native OSX webkit widget for the GUI of my OSX application. This pulls from file://
out of a folder called MyApp.app/Resources/html
. To resist some virus maliciously hacking MyApp.app
, I plan to have an info.plist
with a sha512 value in it (that will be encrypted of course). When the application boots, it will calculate the sha512 value of MyApp.app/Resources/html
, then encrypt it in the same way as my info.plist
value, and then compare the two values to see if they are identical. If not, then the application has been compromised. I'll alert the user with a dialog box and shut down the application.
Questions Answered
Q1. Won't it have to be encrypted in some way to prevent tampering with the saved value in Info.plist? – mipadi
A1. Yes, before storing in Info.plist, it will be encrypted. I said that above. I can handle the encryption step using the Crypto library.
Q2. Files in the app (resource directory) do not have write permissions. If you encrypt to where will you save the encryption key? – zaph
A2. At the time of compilation, in the compilation steps, I will have a Bash script calculate the sha512 checksum, encrypt it, and update the Info.plist.
Q3. If files in the application can't be written to, what's the point of the checksum at all? – mipadi
A3. My application won't write back to the Resources/html folder. It will store session state using the typical user settings strategy that Apple encourages for all applications. Instead, what I fear is a virus that infects the Resources/html folder, replacing it with bad stuff, and causes the application to appear to be normal but is doing something harmful in the background. This is where the checksum can help -- it can help prevent tampering after application installation.
Q4. I assumed the asker was not using code signing (for some reason), since code signing does already cover this. – mipadi
A4. If you're asking why I don't just rely on code signing -- it's because after the application is marked as trusted, the virus can get into the Resources/html folder and cause havoc. This is why I need the checksum mechanism on application boot.
You could use the FileManager
method:
- (NSDirectoryEnumerator<NSURL *> *)enumeratorAtURL:(NSURL *)url includingPropertiesForKeys:(NSArray<NSString *> *)keys options:(NSDirectoryEnumerationOptions)mask errorHandler:(BOOL (^)(NSURL *url, NSError *error))handler
See the Apple documentation for example code.
or
- (NSArray<NSString *> *)subpathsOfDirectoryAtPath:(NSString *)path error:(NSError *)error
to enumerator all files in the path.
Create a SHA512 instance with Common Crypto function:
CC_SHA512_Init(CC_SHA256_CTX *c)
for each file enumerated update:
CC_SHA512_Update(CC_SHA256_CTX *c, const void *data, CC_LONG len)
complete with:
CC_SHA512_Final(unsigned char *md, CC_SHA256_CTX *c)
There is no need to encrypt the SHA512 output since SHA is a one-way function.