Thursday, March 5, 2009

Using code-signing in OS X

OS X 10.5 includes code-signing support. Unlike Windows, code-signing in 10.5 doesn't really affect the user experience, but that will almost certainly change in future versions. The only code-signing aware features in OS X are the firewall and parental control systems. Both of these systems use the code-signature to identify an application independently of its location on disk and of its version, therefore, firewall preferences can be saved accross upgrades.

OS X 10.5 allows you to sign your applications and verify their on disk and runtime signatures. Here's the catch; Apple only support doing this via the codesign utility.

But what if I want to make use of code-signing in my application, for instance, checking the validity of a process I'm about to do IPC with? If you are like me, you don't like the idea of executing codesign directly and picking up the return code, you'd prefer an API. Well one exists and its really nice. Here is the code to verify the runtime signature of a process:

SecCodeRef code = 0;
SecCodeCreateWithPID(pid, kSecCSDefaultFlags, &code);
SecCodeCheckValidity(code, kSecCSDefaultFlags, 0);

Obviously, you'll have to check return codes and such, but 3 lines for code-signature validation is pretty nice. But all it checks is that the code hasn't been tampered with, no identity checks here. Adding your own extra requirements (like an identity check) is also easy (see man csreq for details on requirement strings):

SecRequirementRef requirement = 0;
SecCodeRef code = 0;
SecRequirementCreateWithString("certificate root H=\"abcdef12345\"", kSecCSDefaultFlags, &requirement);
SecCodeCreateWithPID(pid, kSecCSDefaultFlags, &code);
SecCodeCheckValidity(code, kSecCSDefaultFlags, requirement);

For brevity, I lied about being able to pass a char* to create the requirement (it should be a CFString) and I didn't check my return codes. Replace "abcdef12345" with your public key's SHA1 and you can verify that the code is signed by you. Pretty nice. Much better than the 100 or so lines of CryptUI code I had to write to do the same thing. As always though, there is a downside, the API is private, and codesign doesn't work on the preview builds of Snow Leopard, which makes me think they may have changed the something. Bummer.

Still, if you're interested download libsecurity_codesigning from the Darwin source code page and enjoy.

No comments: