2009-11-29 136 views
11

我很难找到解决我的代码签名问题的答案。如何获得签名的应用程序证书信息

我们有一个在Cocoa下编写的Mac OS应用程序。最后 - 我们做了我们的代码签名,但我想在可执行文件本身中添加额外的安全检查。

我的想法是验证当前可执行文件启动时签发的证书的指纹。如果它丢失或无效(在应用程序中针对硬编码哈希进行检查) - 我们将其关闭。

到目前为止,我还没有能够以编程方式获取用于编码可执行文件的证书并检查其数据。

有没有人有关于如何做到这一点的线索?

非常感谢你! Martin K.

回答

4

如果您的目标是10.6+,则可以使用安全框架(documentation)中的代码签名功能,特别是SecCodeCheckValidity。否则,代码签名系统的源代码位于libsecurity_codesigning

由于您使用代码签名来验证您的代码,您还应该使用SecCodeCopyDesignatedRequirement验证指定的要求。

8

感谢朋友!

我设法做到了10.6的新功能,但问题是我的目标是10.5和10.6,至少在一段时间过后。

我不得不再花费一些时间到libsecurity_codesigning中,这样10.5也可以完成。

但是,对于谁是寻找现成的解决方案在这里的人,这里是我结束了:

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

感谢您的分享! 顺便说一句,我假设第二行中的NSURL * url = [[NSBundle mainBundle] bundleURL]可以用来检查整个bundle的有效性,包括Resources和Executables。这是对的吗? – Stream 2010-03-12 21:25:53

+0

你有没有得到这个工作在10.5? – Richard 2011-02-03 17:09:52

+0

不,但我认为现在有点迟了:) – 2012-03-13 16:09:16

0

在上面的答案,第二行应该是:

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

如果您使用接受的答案(包含[NSURL URLWithString:...]),那么url将为零,如果您的应用程序的名称中有空格或-executablePath返回包含某些字符的路径。这当然会导致整个验证失败。

(我对此做了第二个回答,而不是语法突出显示的评论。)

相关问题