简体   繁体   English

C ++ macOS-以编程方式检索代码签名证书信息

[英]C++ macOS - Programmatically retrieve code sign certificate information

On Windows, there is a possibility to get a .exe/.dll code sign certificate using CryptQueryObject . 在Windows上,可以使用CryptQueryObject获得.exe / .dll代码签名证书。

Is there any c++ (or objective-c) alternative to retrieve the Subject name and the Serial number of the certificate which has been used to code sign an .app on macOS ? 是否有任何c ++(或Objective-c)替代方案来检索用于对macOS上的.app进行代码签名的证书的主题名称序列号

I don't have problem to code sign my .app using xcode, and when Im in the terminal, Im able to see that my code has been sign with the proper certificate. 我使用xcode对.app进行代码签名没有问题,当Im在终端中时,Im能够看到我的代码已使用适当的证书进行了签名。


EDIT: 编辑:

The idea is to get something like this command line, but in C++. 想法是获得类似此命令行的内容,但使用C ++。

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

This answer might not be optimal for now, and need a lot of refactoring, specially because Im not a macOS developper that why I mix too much c/c++/objective-c. 这个答案目前可能不是最佳选择,并且需要大量重构,特别是因为Im不是macOS开发人员,所以我为什么要混合太多c / c ++ / objective-c。

Please feel free to edit this code , specially if there is a memory leak, I dont know what I have the CFRelease in this. 请随时编辑此代码 ,特别是如果存在内存泄漏,我不知道我在其中包含CFRelease。

So based on different sources, I made a solution that programmatically extract the subject common name (CN) and serial number of the certificate from a macOS bundle/app/executable. 因此,基于不同的来源,我制定了一个解决方案,以编程方式从macOS软件包/应用程序/可执行文件中提取证书的主题公用名(CN)和序列号。 Here are the source I based my code on: 这是我基于代码的来源:

Here the code: 这里的代码:

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM