Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to obtain codesigned application certificate info

I am having a tough time finding an answer to my codesigning issues.

We have an application for Mac OS written under Cocoa. Finally - we did our codesigning, but i would like to add an extra security check - within the executable itself.

My idea is to validate the fingerprint of the certificate with which the current executable is signed when it is started. If it is missing or invalid (checked against a hardcoded hash within the application) - we shut it down.

So far, i haven't been able how to obtain the certificate used to codesign the executable programatically and check its data.

Does anyone have a clue on how to do this?

Thank you veery much! Martin K.

like image 449
Martin Kovachev Avatar asked Nov 29 '09 13:11

Martin Kovachev


2 Answers

Thanks friend!

I managed to do it for 10.6 with the new functionality but the problem is i am targeting 10.5 and 10.6, at least until some time passes.

I have to throw some more time into libsecurity_codesigning soon so this can be completed for 10.5 also.

But, for people who are looking for ready solutions around here, here is what i ended up with:

SecStaticCodeRef ref = NULL;

NSURL * url = [NSURL URLWithString:[[NSBundle mainBundle] executablePath]]; 

OSStatus status;

// obtain the cert info from the executable
status = SecStaticCodeCreateWithPath((CFURLRef)url, kSecCSDefaultFlags, &ref);

if (ref == NULL) exit(EXIT_STATUS_ON_BAD_CODE_SIGNATURE);
if (status != noErr) exit(EXIT_STATUS_ON_BAD_CODE_SIGNATURE);

SecRequirementRef req = NULL;

// this is the public SHA1 fingerprint of the cert match string
NSString * reqStr = [NSString stringWithFormat:@"%@ %@ = %@%@%@",
    @"certificate",
    @"leaf",
    @"H\"66875745923F01",
    @"F122B387B0F943",
    @"X7D981183151\""
    ];

// create the requirement to check against
status = SecRequirementCreateWithString((CFStringRef)reqStr, kSecCSDefaultFlags, &req);

if (status != noErr) exit(EXIT_STATUS_ON_BAD_CODE_SIGNATURE);
if (req == NULL) exit(EXIT_STATUS_ON_BAD_CODE_SIGNATURE);

status = SecStaticCodeCheckValidity(ref, kSecCSCheckAllArchitectures, req);

if (status != noErr) exit(EXIT_STATUS_ON_BAD_CODE_SIGNATURE);

CFRelease(ref);
CFRelease(req);

LogDebug(@"Code signature was checked and it seems OK");
like image 70
Martin Kovachev Avatar answered Sep 20 '22 07:09

Martin Kovachev


If you're targeting 10.6+ you can use the code signing functions in the Security framework (documentation), in particular SecCodeCheckValidity. Otherwise, the source code to the code signing system is in libsecurity_codesigning.

Since you're using the code signature to authenticate your code you should also validate the designated requirement with SecCodeCopyDesignatedRequirement.

like image 39
vt. Avatar answered Sep 23 '22 07:09

vt.