Created
September 21, 2023 16:26
-
-
Save rbmm/781af2f747d96c0fd06f41548671294c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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