-
Notifications
You must be signed in to change notification settings - Fork 762
Example to use OpenSC with Microsoft CNG and CryptoAPI
Veronika Hanulíková edited this page May 3, 2024
·
2 revisions
It is possible to use the Smartcard via OpenSC with the Microsoft CNG library. CNG can be used together with CryptoAPI.
With the CNG its easy to use the smartcard like a normal pkcs12 container or something similar.
#include <Windows.h>
#include <wincrypt.h>
#include <functional>
#include <memory>
#include <vector>
template <typename T>
using raii_ptr = std::unique_ptr<T, std::function<void(T *)>>;
// Read the x509 from connected smartcard
int main() {
NCRYPT_PROV_HANDLE provider = NULL;
raii_ptr<NCRYPT_PROV_HANDLE> hProvider(&provider,
[](NCRYPT_PROV_HANDLE *handle) {
if (handle)
NCryptFreeObject(*handle);
});
NCryptOpenStorageProvider(hProvider.get(), MS_SMART_CARD_KEY_STORAGE_PROVIDER,
0);
NCryptKeyName *pKeyName = nullptr;
PVOID pState = nullptr;
auto status = NCryptEnumKeys(*hProvider, 0, &pKeyName, &pState, 0);
if (status == NTE_NO_MORE_ITEMS)
return 0;
if (status != ERROR_SUCCESS && status != ERROR_SUCCESS) {
printf("Error: NCryptEnumKeys : 0x%x\n", status);
return 0;
}
printf("Ok: NCryptEnumKeys : 0x%x\n", status);
NCRYPT_KEY_HANDLE key = NULL;
raii_ptr<NCRYPT_KEY_HANDLE> hKey(&key, [](NCRYPT_KEY_HANDLE *handle) {
if (handle)
NCryptFreeObject(*handle);
});
status = NCryptOpenKey(*hProvider, hKey.get(), pKeyName->pszName,
pKeyName->dwLegacyKeySpec, 0);
wprintf(L"Ok: NCryptOpenKey : 0x%x, Key Name: %s\n", status,
pKeyName->pszName);
wprintf(L"Using key : %s\n", pKeyName->pszName);
DWORD size = 0;
NCryptGetProperty(*hKey, NCRYPT_CERTIFICATE_PROPERTY, nullptr, 0, &size, 0);
std::vector<BYTE> cert;
cert.resize(size);
NCryptGetProperty(*hKey, NCRYPT_CERTIFICATE_PROPERTY, &cert[0], size, &size,
0);
DWORD nDestinationSize;
if (CryptBinaryToString(reinterpret_cast<const BYTE *>(&cert[0]), cert.size(),
CRYPT_STRING_BASE64, nullptr, &nDestinationSize)) {
LPTSTR pszDestination = static_cast<LPTSTR>(HeapAlloc(
GetProcessHeap(), HEAP_NO_SERIALIZE, nDestinationSize * sizeof(TCHAR)));
if (pszDestination) {
if (CryptBinaryToString(reinterpret_cast<const BYTE *>(&cert[0]),
cert.size(), CRYPT_STRING_BASE64, pszDestination,
&nDestinationSize)) {
printf(pszDestination);
}
HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pszDestination);
}
}
return 0;
}
Warning: Due to attempts to plant malicious links to our wiki, it is no longer open to anyone to edit. If you want to contribute to this, wiki, please open a pull request here: https://github.com/OpenSC/Wiki.