如何获取应用程序的代码签名证书信息

13

我在解决代码签名问题上遇到了一些困难。

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

我的想法是,在启动可执行文件时验证当前可执行文件所使用证书的指纹。如果缺失或无效(与应用程序内硬编码的哈希值进行比对),则关闭应用程序。

到目前为止,我还不知道如何以编程方式获取用于代码签名的证书并检查其数据。

有人知道如何做吗?

非常感谢! Martin K.

2个回答

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

谢谢分享!顺便问一下,我假设第二行中的NSURL * url = [[NSBundle mainBundle] bundleURL]可以用来检查整个包括资源和可执行文件的有效性。这正确吗? - Vadim
不,但我认为现在有点晚了 :) - Martin Kovachev

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接