C MACOS-编程检索代码符号证书信息

C++ macOS - Programmatically retrieve code sign certificate information

本文关键字:符号 证书 信息 代码 检索 MACOS- 编程      更新时间:2023-10-16

在Windows上,有可能使用CryptqueryObject获得.EXE/.DLL代码符号证书。

是否有任何C (或Objective-C(替代方案可以检索主题名称和证书的序列号已用于代码签名的证书在macos上?

我没有问题可以使用xcode签名我的.App,当我在终端中IM时,我能够看到我的代码已使用正确的证书签名。


编辑:

这个想法是要获得类似此命令行的东西,但是在C 中。

codesign -v --extract-certificates MyApp.app/ 
| openssl x509 -inform DER -in codesign0 -text 
| grep "Serial" -A 1

这个答案现在可能不是最佳的,并且需要大量的重构,特别是因为我不是Macos的开发器,为什么我将太多C/C /Objective-C。P>

请随时编辑此代码,特别是如果有内存泄漏,我不知道我在此中有什么。

因此,我根据不同的来源制定了一种解决方案,该解决方案可以从MacOS捆绑包/应用程序/可执行文件中编程地提取主题通用名称(CN(和证书的序列号。这是我基于我的代码的来源:

  • Apple CodeSign源代码提取提取物
  • 如何读取SeccerTificateref Data
  • 的示例
  • 如何使用OpenSSL读取字节证书的示例

在这里代码:

#include <Foundation/Foundation.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
#include <openssl/bio.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
int main(int argc, const char * argv[]) {    
    NSURL* url = [NSURL URLWithString:@"/Path/To/Your/Codesign/MyApp.app"];
    CFURLRef path = (__bridge CFURLRef)url;
    SecStaticCodeRef codeRef;
    SecStaticCodeCreateWithPath(path, kSecCSDefaultFlags, &codeRef);      
    SecCSFlags flags = kSecCSInternalInformation
    | kSecCSSigningInformation
    | kSecCSRequirementInformation
    | kSecCSInternalInformation;
    CFDictionaryRef api;
    SecCodeCopySigningInformation(codeRef, flags, &api);
    CFArrayRef certChain = (CFArrayRef)CFDictionaryGetValue(api, kSecCodeInfoCertificates);
    // Get the first certificate from the .app 
    // use the CFIndex count = CFArrayGetCount(certChain); 
    // If you want to process all certificates in a loop (same to codesign source code).
    SecCertificateRef cert = SecCertificateRef(CFArrayGetValueAtIndex(certChain, 0));
    CFDataRef der = SecCertificateCopyData(cert);
    // Use solution from the example or using NSData*.
    //const unsigned char* data = CFDataGetBytePtr(der);    
    //int len = CFDataGetLength(der);
    NSData* data = (__bridge NSData*)der;    
    BIO* bio = BIO_new_mem_buf((void *)[data bytes], (int)[data length]);
    X509* certssl = NULL;
    X509_NAME* subName = NULL;
    X509_NAME_ENTRY* entry = NULL;
    unsigned char* subjectStr;    
    // Read certificate from the BIO 
    // Note that SecCertificateRef is in DER format
    if ( !( certssl = d2i_X509_bio(bio, NULL)))
        return -1;    
    // Get Subject common name (CN)
    if( !( subName= X509_get_subject_name(certssl)))
        return -1;   
    if( !( entry = X509_NAME_get_entry(subName, X509_NAME_get_index_by_NID(subName, NID_commonName, -1))))
        return -1;   
    ASN1_STRING_to_UTF8(&subjectStr, X509_NAME_ENTRY_get_data(entry));    
    // Extract the certificate's serial number.
    ASN1_INTEGER* asn1_serial = X509_get_serialNumber(certssl);
    if (asn1_serial == NULL)
        return -1;    
    // Convert serial number into a char buffer.
    BIGNUM* bnser = ASN1_INTEGER_to_BN(asn1_serial, NULL);
    char* serialStr = BN_bn2hex(bnser);    
    X509_free(certssl);
    BIO_free_all(bio);
    return 0;
}