2009-11-29 3 views
11

Мне очень сложно найти ответ на мои вопросы, связанные с кодами.Как получить кодовое имя сертификата приложения

У нас есть приложение для 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

Спасибо за обмен! BTW, я предполагаю, что NSURL * url = [[NSBundle mainBundle] bundleURL] во второй строке может использоваться для проверки действительности всего пакета, включая ресурсы и исполняемые файлы. Правильно ли это? – Stream

+0

Вы когда-нибудь заставляли это работать на 10,5? – Richard

+0

Нет, но я думаю, что для этого немного поздно :) –

0

В приведенном выше ответе, вторая строка должна быть:

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

Если вы используете принятый ответ (содержащий [NSURL URLWithString:...]), то url будет nil, если ваше имя приложения имеет пробел в нем, или если -executablePath возвращает путь, содержащий определенные символы. Это, конечно же, приведет к сбою всей проверки.

(Я сделал это второй ответ, а не комментарий для подсветки синтаксиса.)