Code: Select all
#define WIN32_LEAN_AND_MEAN
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "SignApiService.cpp"
#include
#include
#include
#include
#pragma comment(lib, "ncrypt.lib")
#pragma comment(lib, "winhttp.lib")
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "libcurl.lib") // 0) {
buffer[bytesRead] = 0;
response.append(buffer, bytesRead);
}
} while (result && bytesRead > 0);
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return response;
}
SECURITY_STATUS WINAPI KSPSetKeyProperty(
NCRYPT_HANDLE hObject,
LPCWSTR pszProperty,
PBYTE pbInput,
DWORD cbInput,
DWORD dwFlags)
{
if (!hObject || !pszProperty) return NTE_INVALID_PARAMETER;
KeyContext* ctx = reinterpret_cast(hObject);
// Accept public key from C# application
if (_wcsicmp(pszProperty, L"Public Key") == 0) {
if (pbInput && cbInput > 0) {
ctx->publicKey.assign(pbInput, pbInput + cbInput);
ctx->hasPublicKey = true;
return ERROR_SUCCESS;
}
}
// You can add other settable properties here if needed
return NTE_NOT_SUPPORTED;
}
extern "C" __declspec(dllexport)
SECURITY_STATUS WINAPI KSPOpenStorageProvider(
NCRYPT_PROV_HANDLE* phProvider,
LPCWSTR pszProviderName,
DWORD dwFlags)
{
// Simple debug message
OutputDebugStringW(L"=== EKENG KSP: NCryptOpenStorageProvider called ===");
// Check parameters
if (!phProvider) {
OutputDebugStringW(L"Invalid parameter: phProvider is NULL");
return NTE_INVALID_PARAMETER;
}
// For now, just return a simple success
*phProvider = (NCRYPT_PROV_HANDLE)1;
OutputDebugStringW(L"=== EKENG KSP: NCryptOpenStorageProvider SUCCESS ===");
return ERROR_SUCCESS;
}
SECURITY_STATUS WINAPI KSPCreatePersistedKey(
NCRYPT_PROV_HANDLE hProvider,
NCRYPT_KEY_HANDLE* phKey,
LPCWSTR pszAlgId,
LPCWSTR pszKeyName,
DWORD dwLegacyKeySpec,
DWORD dwFlags)
{
UNREFERENCED_PARAMETER(hProvider);
UNREFERENCED_PARAMETER(pszAlgId);
UNREFERENCED_PARAMETER(dwLegacyKeySpec);
if (!phKey || !pszKeyName) return NTE_INVALID_PARAMETER;
// DEBUG: See what's actually being passed
// We only support **ephemeral** keys – no real persistence
if (dwFlags & NCRYPT_PERSIST_FLAG) {
return NTE_NOT_SUPPORTED;
}
// Extract phone number from the name (EKENG_REMOTE_
)
std::wstring wName = pszKeyName; // This becomes "EKENG_REMOTE_37433360309"
std::string phone = "unknown";
const std::wstring prefix = KEY_PREFIX; // L"EKENG_REMOTE_"
// DEBUG: Print what we received
std::wcout name, pbOutput, cbOutput, pcbResult);
}
if (_wcsicmp(pszProperty, L"Algorithm Name") == 0) {
return CopyWideString(ctx->algorithm, pbOutput, cbOutput, pcbResult);
}
// ✅ Provide public key from cache if requested
if (_wcsicmp(pszProperty, L"Public Key") == 0 && ctx->hasPublicKey) {
*pcbResult = static_cast(ctx->publicKey.size());
if (!pbOutput) return ERROR_SUCCESS;
if (cbOutput < ctx->publicKey.size()) return NTE_BUFFER_TOO_SMALL;
memcpy(pbOutput, ctx->publicKey.data(), ctx->publicKey.size());
return ERROR_SUCCESS;
}
else if (_wcsicmp(pszProperty, L"Public Key") == 0) {
// Return error if public key not set
return NTE_NO_KEY;
}
return NTE_NOT_SUPPORTED;
}
SECURITY_STATUS WINAPI KSPSignHash(
NCRYPT_KEY_HANDLE hKey,
VOID* pPaddingInfo,
PBYTE pbHashValue,
DWORD cbHashValue,
PBYTE pbSignature,
DWORD cbSignature,
DWORD* pcbResult,
DWORD dwFlags)
{
UNREFERENCED_PARAMETER(pPaddingInfo);
UNREFERENCED_PARAMETER(dwFlags);
if (!hKey || !pcbResult) return NTE_INVALID_PARAMETER;
KeyContext* ctx = reinterpret_cast(hKey);
if (ctx->phoneNumber.empty()) return NTE_INVALID_PARAMETER;
if (!ctx->bFinalized) {
return NTE_INVALID_PARAMETER; // or NTE_NOT_READY
}
try {
std::string digestB64 = Base64Encode(pbHashValue, cbHashValue);
// NOTE: The heavy-weight polling is now **inside** SignatureService.
// You can cache the auth token globally to avoid re-auth each call.
SignatureService svc(60, 2000);
SignatureResponse resp = svc.SignMID(
ctx->phoneNumber,
digestB64,
"pkcs1",
"Sign this piece");
if (!resp.GetException().empty()) {
return NTE_INTERNAL_ERROR;
}
std::vector sigBin = Base64Decode(resp.GetSignature());
DWORD sigSize = static_cast(sigBin.size());
*pcbResult = sigSize;
if (!pbSignature) return ERROR_SUCCESS; // size query
if (cbSignature < sigSize) return NTE_BUFFER_TOO_SMALL;
memcpy(pbSignature, sigBin.data(), sigSize);
return ERROR_SUCCESS;
}
catch (...) {
OutputDebugStringA("KSPSignHash: unexpected exception");
return NTE_INTERNAL_ERROR;
}
}
SECURITY_STATUS WINAPI KSPVerifySignature(
NCRYPT_KEY_HANDLE hKey,
VOID* pPaddingInfo,
PBYTE pbHash,
DWORD cbHash,
PBYTE pbSignature,
DWORD cbSignature,
DWORD dwFlags)
{
// Implement signature verification using your remote service
return NTE_NOT_SUPPORTED; // Temporary
}
SECURITY_STATUS WINAPI KSPEncrypt(
NCRYPT_KEY_HANDLE hKey,
PBYTE pbInput,
DWORD cbInput,
VOID* pPaddingInfo,
PBYTE pbOutput,
DWORD cbOutput,
DWORD* pcbResult,
DWORD dwFlags)
{
// Implement encryption if needed
return NTE_NOT_SUPPORTED;
}
// KSP: Free Provider
SECURITY_STATUS WINAPI KSPFreeProvider(NCRYPT_PROV_HANDLE hProvider, DWORD dwFlags)
{
UNREFERENCED_PARAMETER(hProvider);
UNREFERENCED_PARAMETER(dwFlags);
return ERROR_SUCCESS;
}
// KSP: Free Buffer
SECURITY_STATUS WINAPI KSPFreeBuffer(PVOID pvInput)
{
if (pvInput) {
free(pvInput);
}
return ERROR_SUCCESS;
}
// === FUNCTION TABLE: MUST BE DECLARED BEFORE GetKeyStorageInterface ===
static NCRYPT_KEY_STORAGE_FUNCTION_TABLE g_KspFunctionTable = {
NCRYPT_KEY_STORAGE_INTERFACE_VERSION,
KSPOpenStorageProvider, // OpenProvider
KSPOpenKey, // OpenKey
KSPCreatePersistedKey, // CreatePersistedKey
KSPGetProperty, // GetKeyProperty
KSPSetKeyProperty, // SetKeyProperty
KSPFinalizeKey, // FinalizeKey
KSPDeleteKey, // DeleteKey
KSPFreeKey, // FreeKey
KSPFreeBuffer, // FreeBuffer
KSPFreeProvider, // FreeProvider
KSPEncrypt, // Encrypt
KSPSignHash, // SignHash
Mobile version