Как получить кодовое имя сертификата приложения
Мне сложно найти ответ на мои вопросы, касающиеся кодов.
У нас есть приложение для Mac OS, написанное под Cocoa. Наконец, мы выполнили нашу кодовую регистрацию, но я хотел бы добавить дополнительную проверку безопасности - внутри самого исполняемого файла.
Моя идея - проверить отпечаток сертификата, с которым текущий исполняемый файл подписан, когда он запущен. Если он отсутствует или недействителен (проверен на жестко запрограммированный хэш в приложении) - мы закрываем его.
До сих пор я не смог получить сертификат, используемый для кодирования исполняемого файла программно и проверки его данных.
Кто-нибудь знает, как это сделать?
Спасибо, очень много!
Мартин К.
Ответы
Ответ 1
Спасибо другу!
Мне удалось сделать это для 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");
Ответ 2
Если вы используете таргетинг 10.6+, вы можете использовать функции подписи кода в структуре безопасности (документация), в частности SecCodeCheckValidity. В противном случае исходный код системы подписи кода находится в libsecurity_codesigning.
Поскольку вы используете подпись кода для аутентификации своего кода, вы также должны проверить указанное требование с помощью SecCodeCopyDesignatedRequirement.
Ответ 3
В ответе выше, вторая строка должна быть:
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] executablePath]];
Если вы используете принятый ответ (содержащий [NSURL URLWithString:...]
), то url
будет отсутствовать, если ваше имя приложения имеет пробел в нем или если -executablePath
возвращает путь, содержащий определенные символы. Это, конечно же, приведет к сбою всей проверки.
(Я сделал это вторым ответом, а не комментарием для подсветки синтаксиса.)