Skip to content

Instantly share code, notes, and snippets.

@rbmm
Created September 21, 2023 16:26
Show Gist options
  • Save rbmm/781af2f747d96c0fd06f41548671294c to your computer and use it in GitHub Desktop.
Save rbmm/781af2f747d96c0fd06f41548671294c to your computer and use it in GitHub Desktop.
void DumpKeyCrc(NCRYPT_KEY_HANDLE hKey)
{
ULONG cb;
UCHAR blob[0x400];
if (0 <= NCryptExportKey(hKey, 0, BCRYPT_RSAPUBLIC_BLOB, 0, blob, sizeof(blob), &cb, 0))
{
DbgPrint("crc=%08X\r\n", RtlComputeCrc32(0, blob, cb));
}
}
void DumpKeyCrc(BCRYPT_KEY_HANDLE hKey)
{
ULONG cb;
UCHAR blob[0x400];
if (0 <= BCryptExportKey(hKey, 0, BCRYPT_RSAPUBLIC_BLOB, blob, sizeof(blob), &cb, 0))
{
DbgPrint("crc=%08X\r\n", RtlComputeCrc32(0, blob, cb));
}
}
void OnReader(_In_ PCWSTR ReaderName, _In_ NCRYPT_PROV_HANDLE hProvider, _In_ PUCHAR pbCertEncoded)
{
BCRYPT_PKCS1_PADDING_INFO pi = { BCRYPT_SHA1_ALGORITHM };
BYTE hash[20], sig[0x200];
BCryptGenRandom(0, hash, sizeof(hash), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
DbgPrint("Reader: \"%S\"\r\n", ReaderName);
int len = 0;
PWSTR pszScope = 0;
while (0 < (len = _snwprintf(pszScope, len, L"\\\\.\\%s\\", ReaderName)))
{
if (pszScope)
{
NCryptKeyName* pKeyName;
PVOID pEnumState = 0;
while(S_OK == NCryptEnumKeys(hProvider, pszScope, &pKeyName, &pEnumState, NCRYPT_SILENT_FLAG))
{
union {
NCRYPT_KEY_HANDLE hKey;
BCRYPT_KEY_HANDLE hBKey;
};
if (NOERROR == NCryptOpenKey(hProvider, &hKey, pKeyName->pszName, pKeyName->dwLegacyKeySpec, pKeyName->dwFlags))
{
DumpKeyCrc(hKey);
PCWSTR pszPin = L"0";
ULONG cbCertEncoded, cbSig = 0;
NTSTATUS status;
// you use wcslen(pszPin)*sizeof(WCHAR), windows built-in +1
NOERROR == (status = NCryptSetProperty(hKey, NCRYPT_PIN_PROPERTY, (PBYTE)pszPin, (ULONG)(1 + wcslen(pszPin))*sizeof(WCHAR), 0)) &&
NOERROR == (status = NCryptSignHash(hKey, &pi, hash, sizeof(hash), sig, sizeof(sig), &cbSig, BCRYPT_PAD_PKCS1));
DbgPrint("NCryptSignHash=%x,[%x]\n", status, cbSig);
status = NCryptGetProperty(hKey, NCRYPT_CERTIFICATE_PROPERTY,
pbCertEncoded, MINSHORT, &cbCertEncoded, 0);
NCryptFreeObject(hKey);
if (NOERROR == status)
{
if (PCCERT_CONTEXT pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING, pbCertEncoded, cbCertEncoded))
{
BOOL b = CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING,
&pCertContext->pCertInfo->SubjectPublicKeyInfo, 0, 0, &hBKey);
CertFreeCertificateContext(pCertContext);
if (b)
{
DumpKeyCrc(hBKey);
status = BCryptVerifySignature(hBKey, &pi, hash, sizeof(hash),
sig, cbSig, BCRYPT_PAD_PKCS1);
BCryptDestroyKey(hBKey);
DbgPrint("VerifySignature=%x\r\n", status);
}
}
}
}
NCryptFreeBuffer(pKeyName);
}
break;
}
pszScope = (PWSTR)alloca(++len * sizeof(WCHAR));
}
}
void TestCards()
{
if (PBYTE pbCertEncoded = new BYTE[MINSHORT])
{
NCRYPT_PROV_HANDLE hProvider;
if (S_OK == NCryptOpenStorageProvider(&hProvider, MS_SMART_CARD_KEY_STORAGE_PROVIDER, 0))
{
SCARDCONTEXT hContext;
if (NOERROR == SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0, &hContext))
{
PWSTR mszReaders = 0;
DWORD cchReaders = SCARD_AUTOALLOCATE;
if (NOERROR == SCardListReadersW(hContext, 0, (PWSTR)&mszReaders, &cchReaders))
{
PVOID pvMem = mszReaders;
while (*mszReaders)
{
OnReader(mszReaders, hProvider, pbCertEncoded);
mszReaders += wcslen(mszReaders) + 1;
}
SCardFreeMemory(hContext, pvMem);
}
SCardReleaseContext(hContext);
}
NCryptFreeObject(hProvider);
}
delete [] pbCertEncoded;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment