如何验证系统中安装的客户端证书

时间:2016-09-09 03:59:50

标签: macos winapi ssl openssl cryptoapi

我正在尝试在我的应用中实现多平台设备/客户端证书chck。 我想为Windows和Mac实现,所以c ++中的常见实现只有很少的平台特定代码。 我也集成了OpenSSL。

我在Windows个人存储中安装了客户端证书,在登录密钥链中安装了Mac。

我有一个CA链作为.pem文件的形式。

我想使用openssl从Pem文件获取叶子CA,而不是使用颁发者名称并使用特定于平台的代码从设备获取匹配的客户端证书。 我想获得clinet证书的上下文并使用openssl来验证CA链

这里的问题是, 1.如何从PEM获取叶子 2.如何在Windos / mac中检索已安装客户端证书的公共部分?

此致 Birajendu

1 个答案:

答案 0 :(得分:0)

这是一段代码

X509_STORE      *openssl_store = NULL;
X509_STORE_CTX  *vrfy_ctx = NULL;

OpenSSL_add_all_algorithms();

if (!(openssl_store=X509_STORE_new())) {
    printf("Error creating X509_STORE_CTX object");
    return false;
}
vrfy_ctx = X509_STORE_CTX_new();
if (NULL == vrfy_ctx) {
    printf("X509_STORE_CTX_new failed");
    return false;
}

if (1 != X509_STORE_load_locations(openssl_store, tmpCertFile.c_str(), NULL)) {
    printf("Error loading CA cert or chain file");
    return false;
}

HCERTSTORE hStore = NULL;
BYTE *pCert = NULL; 
DWORD dwCert = 0;
PCCERT_CONTEXT pCertContext = NULL;

//Open Personal Certificate Store
hStore = CertOpenSystemStore(0, TEXT("MY"));
if (hStore == NULL) {
    printf("CertOpenSystemStore failed, error : %d", GetLastError());
    return false;
} 

//Enumerate Certificate Store
while (pCertContext = CertEnumCertificatesInStore(hStore, pCertContext)) {

    const unsigned char *cert_data = pCertContext->pbCertEncoded;

    X509 *cert = d2i_X509(NULL, &cert_data, pCertContext->cbCertEncoded);

    X509_STORE_CTX_init(vrfy_ctx, openssl_store, cert, NULL);
    int ret = X509_verify_cert(vrfy_ctx);
    X509_STORE_CTX_cleanup(vrfy_ctx);

    if (1 == ret) {
        printf("Matching client certificate found");
        return true;
    }

    if (cert) {
        X509_free(cert);
    }
}
if (hStore) {
    CertCloseStore(hStore, CERT_CLOSE_STORE_CHECK_FLAG);
}