Ejemplo de código para proveedor de GNC
Descubra cómo indexar los proveedores criptográficos registrados en Dedicated KMS para encontrar el proveedor de GNV instalado con el instalador del cliente de Windows mediante el código de ejemplo proporcionado.
El siguiente código de ejemplo muestra cómo indexar los proveedores criptográficos registrados para encontrar el proveedor de GNC instalado con el instalador del cliente de Windows. El código también muestra cómo crear un par de claves asimétricas y cómo utilizar el par de claves para firmar datos.
Nota
Antes de ejecutar este ejemplo, debe configurar las credenciales de HSM. Para obtener más información, consulte Setting up the HSM Cluster Client in Windows.
#include <windows.h>
#include <stdio.h>
#include <bcrypt.h>
int testReturnStatus = 0;
BCRYPT_KEY_HANDLE GenerateKeyPair(
BCRYPT_ALG_HANDLE hAlg,
ULONG keyLen)
{
NTSTATUS status = -1;
BCRYPT_KEY_HANDLE keyHandle = NULL;
print_debug("Generating Key Pair of size: %lu\n", keyLen);
status = BCryptGenerateKeyPair(hAlg, &keyHandle, keyLen, 0);
if (status)
{
ReportErrorStatus(status, "\t\t\t\t\t\t\t FAIL BCryptGenerateKeyPair");
goto cleanup;
}
/* Finalize RSA keys generated */
status = BCryptFinalizeKeyPair(keyHandle, 0);
if (status)
{
ReportErrorStatus(status, "\t\t\t\t\t\t\t FAIL BCryptFinalizeKeyPair");
goto cleanup;
}
print_debug("Keypair Gen Success\n");
ReportErrorStatus(status, "\t\t PASS\n");
return keyHandle;
cleanup:
if (keyHandle) {
status = BCryptDestroyKey(keyHandle);
keyHandle = NULL;
if (status)
ReportErrorStatus(status, "BCryptDestroyKey");
}
return keyHandle;
}
static NTSTATUS testSignVerify(
PBYTE test,
BCRYPT_KEY_HANDLE signKey,
BCRYPT_KEY_HANDLE verifyKey,
ULONG keyLen,
VOID *pPaddingInfo)
{
NTSTATUS status = -1;
BYTE inbuf[CHUNK_SIZE];
BYTE hash[CHUNK_SIZE];
DWORD hash_size;
PBYTE sign = NULL;
DWORD i;
DWORD insize;
DWORD pcbResult = 0;
ULONG dwFlags = 0;
if (signKey == NULL || verifyKey == NULL) {
status = STATUS_INVALID_HANDLE;
goto cleanup;
}
printf("%s", test);
/* Fill input data; Alternatively can read from file */
for (i = 0; i < CHUNK_SIZE; i++)
inbuf[i] = (BYTE)i + 1;
insize = i;/* Length of inbuf */
if (pPaddingInfo)
dwFlags = BCRYPT_PAD_PKCS1;
// calculate the size of sign data needed
status = BCryptSignHash(signKey,
pPaddingInfo,
hash,
CHUNK_SIZE,
NULL,
0,
&pcbResult,
dwFlags
);
if (status)
{
ReportErrorStatus(status, "\t\t FAIL BCryptSignHash get-size");
goto cleanup;
}
print_debug("required sign data size: %lu\n", pcbResult);
status = CreateHash(BCRYPT_SHA1_ALGORITHM, MS_PRIMITIVE_PROVIDER, inbuf, insize, hash, &hash_size, NULL, 0, 0);
if (status)
goto cleanup;
sign = (PBYTE)HEAPALLOC(pcbResult);
if (sign == NULL) {
status = STATUS_UNSUCCESSFUL;
goto cleanup;
}
status = BCryptSignHash(signKey,
pPaddingInfo,
hash,
hash_size,
sign,
pcbResult,
&pcbResult,
dwFlags
);
if (status)
{
ReportErrorStatus(status, "\t\t FAIL BCryptSignHash");
goto cleanup;
}
print_debug("signed data size: %lu\n", pcbResult);
print_debug("Created Signature from Hash using MS Key Success\n");
/* Verify Signature with Cavium key*/
status = BCryptVerifySignature(verifyKey,
pPaddingInfo,
hash,
hash_size,
sign,
pcbResult,
dwFlags);
if (status)
{
ReportErrorStatus(status, "\t\t FAIL BCryptVerifySignature");
goto cleanup;
}
print_debug("Verifying Signature SUCCESS\n");
ReportErrorStatus(status, "\t\t PASS\n");
cleanup:
if (sign)
HeapFree(GetProcessHeap(), 0, sign);
return status;
}
static void testRSA()
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
LPCWSTR pszAlgId = NULL;
BCRYPT_ALG_HANDLE caviumAlg = NULL;
BCRYPT_ALG_HANDLE msAlg = NULL;
EncDecPriv priv = { 0 };
ULONG keyLen = 2048;
pszAlgId = BCRYPT_RSA_ALGORITHM;
//open Cavium CNG Provider
caviumAlg = OpenAlgorithmProvider(pszAlgId, CAVIUM_PROVIDER_NAME, 0);
if (caviumAlg == NULL)
goto cleanup;
//open Microsoft Primitive Provider
msAlg = OpenAlgorithmProvider(pszAlgId, MS_PRIMITIVE_PROVIDER, 0);
if (msAlg == NULL)
goto cleanup;
// fill priv structure
priv.alg = RSA;
priv.blockSize = 1;
printf("\n\n############################# %ls Unit Testing ########################################\n\n", pszAlgId);
printf("KeyLen\t Test\t\t Info\t\t\t Result\n");
printf("=======================================================================================\n");
for (keyLen = 2048; keyLen <= 4096; keyLen = keyLen + 256) {
printf("\n%lu\n", keyLen);
priv.keyLen = keyLen;
status = testRSACommon(caviumAlg, msAlg, &priv);
#ifdef RUN_MINIMAL_TEST
/* To test functionality with RSA 2048 key size only, break now. */
break; /* This will be suitable if we are running these tests in PR checker kind of build.*/
#endif
}
cleanup:
if (caviumAlg)
CloseAlgorithmProvider(caviumAlg, 0);
if (msAlg)
CloseAlgorithmProvider(msAlg, 0);
return;
}