How to obtain codesigned application certificate i

2019-01-14 08:43发布

问题:

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.

回答1:

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");


回答2:

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.



回答3:

In the answer above, the second line should be:

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

If you use the accepted answer (containing [NSURL URLWithString:...]), then url will be nil if your app's name has a space in it or if -executablePath returns a path containing certain characters. This will, of course, cause the whole validation to fail.

(I made this a second answer rather than a comment for the syntax-highlighting.)