如何获取已签署的应用程序证书信息

时间:2009-11-29 13:11:45

标签: cocoa security macos certificate codesign

我很难找到代码签名问题的答案。

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

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

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

有没有人知道如何做到这一点?

非常感谢你! 马丁K。

3 个答案:

答案 0 :(得分:10)

谢谢朋友!

我设法使用新功能以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");

答案 1 :(得分:4)

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

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

答案 2 :(得分:0)

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

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

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

(我把它作为第二个答案,而不是语法高亮的评论。)