Last active
February 1, 2019 01:46
-
-
Save tuxuser/d2bb11378b2b27a5a95d148ca48f3c8a 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
#include <stdio.h> | |
#include <windows.h> | |
#include <bcrypt.h> | |
#define NT_SUCCESS(x) (x == 0) | |
#define STATUS_SUCCESS ((NTSTATUS)0) | |
#define STATUS_ERROR ((NTSTATUS)1) | |
NTSTATUS SaveFile(PUCHAR dataBlob, ULONG dataSz, LPCWSTR filePath) | |
{ | |
BOOL bErrorFlag = FALSE; | |
DWORD dwBytesWritten = 0; | |
HANDLE hFile = NULL; | |
hFile = CreateFileW(filePath, | |
GENERIC_WRITE, | |
0, | |
NULL, // default security | |
CREATE_NEW, // create new file only | |
FILE_ATTRIBUTE_NORMAL, // normal file | |
NULL); // no attr. template | |
if (hFile == INVALID_HANDLE_VALUE) | |
{ | |
printf(":: ERROR :: UNABLE TO OPEN FiLE \"%ls\" FOR WRITE\n", filePath); | |
return STATUS_ERROR; | |
} | |
printf(":: WRiTiNG %u BYTES TO %ls\n", dataSz, filePath); | |
bErrorFlag = WriteFile( | |
hFile, // open file handle | |
dataBlob, // start of data to write | |
dataSz, // number of bytes to write | |
&dwBytesWritten, // number of bytes that were written | |
NULL); // no overlapped structure | |
if (FALSE == bErrorFlag) | |
{ | |
printf(":: ERROR :: ERROR WRiTiNG FiLE \"%ls\"\n", filePath); | |
return STATUS_ERROR; | |
} | |
else if (dwBytesWritten != dataSz) | |
{ | |
// This is an error because a synchronous write that results in | |
// success (WriteFile returns TRUE) should write all data as | |
// requested. This would not necessarily be the case for | |
// asynchronous writes. | |
printf(":: ERROR :: dwBytesWritten != dwBytesToWrite \"%ls\"\n", filePath); | |
return STATUS_ERROR; | |
} | |
printf(":: WROTE %u BYTES SUCCESSFULLY\n", dataSz); | |
CloseHandle(hFile); | |
return STATUS_SUCCESS; | |
} | |
NTSTATUS ExportRsaKey(BCRYPT_KEY_HANDLE hKey, LPCWSTR pszBlobType) | |
{ | |
NTSTATUS ret = 0; | |
ULONG resultLength = 0; | |
ULONG requiredSize = 0; | |
ULONG writtenSize = 0; | |
DWORD keyStrength = 0; | |
ret = BCryptGetProperty(hKey, BCRYPT_KEY_STRENGTH, (PBYTE)&keyStrength, sizeof(keyStrength), &resultLength, 0); | |
if (!NT_SUCCESS(ret)) | |
{ | |
printf(":: ERROR :: FAiLED TO GET KEYSTRENGTH :: CODE :: %u\n", GetLastError()); | |
return ret; | |
} | |
ret = BCryptExportKey(hKey, NULL, pszBlobType, NULL, 0, &requiredSize, 0); | |
if (!NT_SUCCESS(ret)) | |
{ | |
printf(":: ERROR :: FAiLED TO GET KEYSiZE :: CODE :: %u\n", GetLastError()); | |
return ret; | |
} | |
PUCHAR pKeyBlob = (PUCHAR)malloc(requiredSize); | |
ret = BCryptExportKey(hKey, NULL, pszBlobType, pKeyBlob, requiredSize, &writtenSize, 0); | |
if (!NT_SUCCESS(ret)) | |
{ | |
printf(":: ERROR :: FAiLED TO EXPORT KEY :: CODE :: %u\n", GetLastError()); | |
free(pKeyBlob); | |
return ret; | |
} | |
LPWSTR filePath = (LPWSTR)malloc(255); | |
wsprintfW(filePath, L"RSA_%u_%ls.bin", keyStrength, pszBlobType); | |
ret = SaveFile(pKeyBlob, writtenSize, filePath); | |
free(pKeyBlob); | |
if (!NT_SUCCESS(ret)) | |
{ | |
printf(":: ERROR :: FAiLED TO SAVE KEY :: CODE :: %u\n", GetLastError()); | |
return ret; | |
} | |
return STATUS_SUCCESS; | |
} | |
NTSTATUS ExportRsaKeys(BCRYPT_KEY_HANDLE hKey) | |
{ | |
NTSTATUS ret = STATUS_SUCCESS; | |
ret = ExportRsaKey(hKey, BCRYPT_RSAPUBLIC_BLOB); | |
if (!NT_SUCCESS(ret)) return ret; | |
ExportRsaKey(hKey, BCRYPT_RSAPRIVATE_BLOB); | |
if (!NT_SUCCESS(ret)) return ret; | |
ExportRsaKey(hKey, BCRYPT_RSAFULLPRIVATE_BLOB); | |
if (!NT_SUCCESS(ret)) return ret; | |
ExportRsaKey(hKey, LEGACY_RSAPRIVATE_BLOB); | |
if (!NT_SUCCESS(ret)) return ret; | |
ExportRsaKey(hKey, LEGACY_RSAPUBLIC_BLOB); | |
if (!NT_SUCCESS(ret)) return ret; | |
return STATUS_SUCCESS; | |
} | |
NTSTATUS ExportRsaKeyInfo(BCRYPT_KEY_HANDLE hKey) | |
{ | |
return STATUS_SUCCESS; | |
} | |
NTSTATUS GenerateRsaKey(int bitLength) | |
{ | |
NTSTATUS ret = 0; | |
BCRYPT_ALG_HANDLE hProvider = NULL; | |
BCRYPT_KEY_HANDLE hKey = NULL; | |
printf(":: OPENiNG ALGORiTHM PROViDER\n"); | |
ret = BCryptOpenAlgorithmProvider(&hProvider, BCRYPT_RSA_ALGORITHM, MS_PRIMITIVE_PROVIDER, 0); | |
if (!NT_SUCCESS(ret)) | |
{ | |
printf(":: ERROR :: FAiLED TO OPEN RSA PROViDER :: Code: %u\n", GetLastError()); | |
return ret; | |
} | |
printf(":: GENERATiNG KEYPAiR\n"); | |
ret = BCryptGenerateKeyPair(hProvider, &hKey, bitLength, 0); | |
if (!NT_SUCCESS(ret)) | |
{ | |
printf(":: ERROR :: FAiLED TO GENERATE KEYPAiR :: Code: %u\n", GetLastError()); | |
return ret; | |
} | |
/* | |
ret = BCryptSetProperty(hKey, BCRYPT_PADDING_SCHEMES, BCRYPT_SUPPORTED_PAD_PSS, 1, 0); | |
if (!NT_SUCCESS(ret)) | |
{ | |
printf(":: ERROR :: FAiLED TO SET PADDiNG SCHEME :: CODE: %u\n", GetLastError()); | |
return ret; | |
} | |
*/ | |
printf(":: FiNALiZING KEYPAiR\n"); | |
ret = BCryptFinalizeKeyPair(hKey, 0); | |
if (!NT_SUCCESS(ret)) | |
{ | |
printf(":: ERROR :: FAiLED to FiNALiZE KEYPAiR :: Code: %u\n", GetLastError()); | |
return ret; | |
} | |
ret = ExportRsaKeys(hKey); | |
if (!NT_SUCCESS(ret)) | |
{ | |
printf(":: ERROR :: FAiLED to EXPORT RSA KEYS :: Code: %u\n", GetLastError()); | |
return ret; | |
} | |
ret = ExportRsaKeyInfo(hKey); | |
if (!NT_SUCCESS(ret)) | |
{ | |
printf(":: ERROR :: FAiLED to EXPORT RSA KEY INFO :: Code: %u\n", GetLastError()); | |
return ret; | |
} | |
printf(":: CLEANUP"); | |
ret = BCryptDestroyKey(hKey); | |
if (!NT_SUCCESS(ret)) | |
{ | |
printf(":: ERROR :: CLEANUP FAiLED :: DESTROYiNG KEY :: Code: %u\n", GetLastError()); | |
return ret; | |
} | |
ret = BCryptCloseAlgorithmProvider(hProvider, 0); | |
if (!NT_SUCCESS(ret)) | |
{ | |
printf(":: ERROR :: CLEANUP FAiLED :: DESTROYiNG PROViDER :: Code: %u\n", GetLastError()); | |
return ret; | |
} | |
return STATUS_SUCCESS; | |
} | |
int main() | |
{ | |
GenerateRsaKey(512); | |
GenerateRsaKey(1024); | |
GenerateRsaKey(2048); | |
GenerateRsaKey(3072); | |
GenerateRsaKey(4096); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment