Binger, здравствуйте!
1. Пример парсинга CMS: https://github.com/openssl/openssl/blob … /cms_dec.c
2. а) Сначала нужно, прочитать тело сертификата с помощью PKCS#11. Он будет всегда в кодировке DER.
См. примеры SDK. Часть как получить тела всех сертификатов на токене.
rv = functionList->C_OpenSession(slots[i], CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session);
CHECK(" C_OpenSession", rv == CKR_OK, finalize_pkcs11);
rv = functionList->C_FindObjectsInit(session, &findObjectTemplate, 1);
CHECK(" C_FindObjectsInit", rv == CKR_OK, close_session);
certHandles.clear();
certHandles.resize(10000);
rv = functionList->C_FindObjects(session, certHandles.data(), (CK_ULONG)certHandles.size(), &certCount);
CHECK(" C_FindObjects", rv == CKR_OK, close_session);
for (size_t i = 0; i < certCount; ++i) {
CK_ATTRIBUTE certValueAttr = { CKA_VALUE, NULL_PTR, 0 };
std::vector<CK_BYTE> certValue;
rv = functionList->C_GetAttributeValue(session, certHandles[i], &certValueAttr, 1);
CHECK(" C_GetAttributeValue", rv == CKR_OK, close_session);
certValue.resize(certValueAttr.ulValueLen);
certValueAttr.pValue = certValue.data();
rv = functionList->C_GetAttributeValue(session, certHandles[i], &certValueAttr, 1);
CHECK(" C_GetAttributeValue", rv == CKR_OK, close_session);
pemCerts.emplace_back(certToPem(certValue));
}
rv = functionList->C_FindObjectsFinal(session);
CHECK(" C_FindObjectsFinal", rv == CKR_OK, close_session);
б) Сконвертировать его в PEM, а затем в X509*
std::string certToPem(const std::vector<uint8_t>& certBuf) {
if (certBuf.at(0) == 0x30) {
bioPtr cert_bio(BIO_new_mem_buf(certBuf.data(), (int)certBuf.size()), BIO_free_all);
if (!cert_bio) return {};
x509Ptr cert(d2i_X509_bio(cert_bio.get(), nullptr), X509_free);
if (!cert) return {};
bioPtr outBio(BIO_new(BIO_s_mem()), BIO_free_all);
if (!outBio) return {};
int r = PEM_write_bio_X509(outBio.get(), cert.get());
if (!r) return {};
BUF_MEM* mem;
r = BIO_get_mem_ptr(outBio.get(), &mem);
if (r < 1) return {};
return std::string(mem->data, mem->length);
}
return std::string(certBuf.begin(), certBuf.end());
}
X509* certToX509(const std::vector<uint8_t>& certBuf) {
auto pem = certToPem(certBuf);
if (pem.empty()) return nullptr;
bioPtr bio(BIO_new_mem_buf(pem.data(), (int)pem.size()), BIO_free_all);
if (!bio) return nullptr;
return PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr);
}
3. Распарсить CMS. Cм. п.1