| | |
| | | [submodule "extern/license-generator"] |
| | | [submodule "license-generator"] |
| | | path = extern/license-generator |
| | | url = https://github.com/open-license-manager/lcc-license-generator.git |
| | | branch = develop |
| | | branch = develop |
New file |
| | |
| | | Subproject commit 9cb153091edbd55d31e2a1fb1f2e3a2ab5e364b1 |
| | |
| | | #include <stdio.h> |
| | | #include <stdlib.h> |
| | | |
| | | const static char* b64 = |
| | | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
| | | |
| | | // maps A=>0,B=>1.. |
| | | const static unsigned char unb64[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40 |
| | | 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, //50 |
| | | 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, //60 |
| | | 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, //70 |
| | | 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, //80 |
| | | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, //90 |
| | | 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, //100 |
| | | 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, //110 |
| | | 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, //120 |
| | | 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, //130 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240 |
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //250 |
| | | 0, 0, 0, 0, 0, 0, }; // This array has 255 elements |
| | | |
| | | //review api |
| | | char* base64(const void* binaryData, int len, int *flen) { |
| | | const unsigned char* bin = (const unsigned char*) binaryData; |
| | | char* res; |
| | | |
| | | int rc = 0; // result counter |
| | | int byteNo; // I need this after the loop |
| | | |
| | | int modulusLen = len % 3; |
| | | int pad = ((modulusLen & 1) << 1) + ((modulusLen & 2) >> 1); // 2 gives 1 and 1 gives 2, but 0 gives 0. |
| | | |
| | | *flen = 4 * (len + pad) / 3; |
| | | res = (char*) malloc(*flen + 1); // and one for the null |
| | | if (!res) { |
| | | puts("ERROR: base64 could not allocate enough memory."); |
| | | puts("I must stop because I could not get enough"); |
| | | return 0; |
| | | } |
| | | |
| | | for (byteNo = 0; byteNo <= len - 3; byteNo += 3) { |
| | | unsigned char BYTE0 = bin[byteNo]; |
| | | unsigned char BYTE1 = bin[byteNo + 1]; |
| | | unsigned char BYTE2 = bin[byteNo + 2]; |
| | | res[rc++] = b64[BYTE0 >> 2]; |
| | | res[rc++] = b64[((0x3 & BYTE0) << 4) + (BYTE1 >> 4)]; |
| | | res[rc++] = b64[((0x0f & BYTE1) << 2) + (BYTE2 >> 6)]; |
| | | res[rc++] = b64[0x3f & BYTE2]; |
| | | } |
| | | |
| | | if (pad == 2) { |
| | | res[rc++] = b64[bin[byteNo] >> 2]; |
| | | res[rc++] = b64[(0x3 & bin[byteNo]) << 4]; |
| | | res[rc++] = '='; |
| | | res[rc++] = '='; |
| | | } else if (pad == 1) { |
| | | res[rc++] = b64[bin[byteNo] >> 2]; |
| | | res[rc++] = b64[((0x3 & bin[byteNo]) << 4) + (bin[byteNo + 1] >> 4)]; |
| | | res[rc++] = b64[(0x0f & bin[byteNo + 1]) << 2]; |
| | | res[rc++] = '='; |
| | | } |
| | | |
| | | res[rc] = 0; // NULL TERMINATOR! ;) |
| | | return res; |
| | | } |
| | | |
| | | unsigned char* unbase64(const char* ascii, int len, int *flen) { |
| | | const unsigned char *safeAsciiPtr = (const unsigned char*) ascii; |
| | | unsigned char *bin; |
| | | int cb = 0; |
| | | int charNo; |
| | | int pad = 0; |
| | | |
| | | if (len < 2) { // 2 accesses below would be OOB. |
| | | // catch empty string, return NULL as result. |
| | | puts( |
| | | "ERROR: You passed an invalid base64 string (too short). You get NULL back."); |
| | | *flen = 0; |
| | | return 0; |
| | | } |
| | | if (safeAsciiPtr[len - 1] == '=') |
| | | ++pad; |
| | | if (safeAsciiPtr[len - 2] == '=') |
| | | ++pad; |
| | | |
| | | *flen = 3 * len / 4 - pad; |
| | | bin = (unsigned char*) malloc(*flen); |
| | | if (!bin) { |
| | | puts("ERROR: unbase64 could not allocate enough memory."); |
| | | puts("I must stop because I could not get enough"); |
| | | return 0; |
| | | } |
| | | |
| | | for (charNo = 0; charNo <= len - 4 - pad; charNo += 4) { |
| | | int A = unb64[safeAsciiPtr[charNo]]; |
| | | int B = unb64[safeAsciiPtr[charNo + 1]]; |
| | | int C = unb64[safeAsciiPtr[charNo + 2]]; |
| | | int D = unb64[safeAsciiPtr[charNo + 3]]; |
| | | |
| | | bin[cb++] = (A << 2) | (B >> 4); |
| | | bin[cb++] = (B << 4) | (C >> 2); |
| | | bin[cb++] = (C << 6) | (D); |
| | | } |
| | | |
| | | if (pad == 1) { |
| | | int A = unb64[safeAsciiPtr[charNo]]; |
| | | int B = unb64[safeAsciiPtr[charNo + 1]]; |
| | | int C = unb64[safeAsciiPtr[charNo + 2]]; |
| | | |
| | | bin[cb++] = (A << 2) | (B >> 4); |
| | | bin[cb++] = (B << 4) | (C >> 2); |
| | | } else if (pad == 2) { |
| | | int A = unb64[safeAsciiPtr[charNo]]; |
| | | int B = unb64[safeAsciiPtr[charNo + 1]]; |
| | | |
| | | bin[cb++] = (A << 2) | (B >> 4); |
| | | } |
| | | |
| | | return bin; |
| | | } |
| | | #include <stdio.h>
|
| | | #include <stdlib.h>
|
| | |
|
| | | const static char* b64 =
|
| | | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
| | |
|
| | | // maps A=>0,B=>1..
|
| | | const static unsigned char unb64[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40
|
| | | 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, //50
|
| | | 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, //60
|
| | | 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, //70
|
| | | 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, //80
|
| | | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, //90
|
| | | 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, //100
|
| | | 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, //110
|
| | | 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, //120
|
| | | 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, //130
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240
|
| | | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //250
|
| | | 0, 0, 0, 0, 0, 0, }; // This array has 255 elements
|
| | |
|
| | | //review api
|
| | | char* base64(const void* binaryData, int len, int *flen) {
|
| | | const unsigned char* bin = (const unsigned char*) binaryData;
|
| | | char* res;
|
| | |
|
| | | int rc = 0; // result counter
|
| | | int byteNo; // I need this after the loop
|
| | |
|
| | | int modulusLen = len % 3;
|
| | | int pad = ((modulusLen & 1) << 1) + ((modulusLen & 2) >> 1); // 2 gives 1 and 1 gives 2, but 0 gives 0.
|
| | |
|
| | | *flen = 4 * (len + pad) / 3;
|
| | | res = (char*) malloc(*flen + 1); // and one for the null
|
| | | if (!res) {
|
| | | puts("ERROR: base64 could not allocate enough memory.");
|
| | | puts("I must stop because I could not get enough");
|
| | | return 0;
|
| | | }
|
| | |
|
| | | for (byteNo = 0; byteNo <= len - 3; byteNo += 3) {
|
| | | unsigned char BYTE0 = bin[byteNo];
|
| | | unsigned char BYTE1 = bin[byteNo + 1];
|
| | | unsigned char BYTE2 = bin[byteNo + 2];
|
| | | res[rc++] = b64[BYTE0 >> 2];
|
| | | res[rc++] = b64[((0x3 & BYTE0) << 4) + (BYTE1 >> 4)];
|
| | | res[rc++] = b64[((0x0f & BYTE1) << 2) + (BYTE2 >> 6)];
|
| | | res[rc++] = b64[0x3f & BYTE2];
|
| | | }
|
| | |
|
| | | if (pad == 2) {
|
| | | res[rc++] = b64[bin[byteNo] >> 2];
|
| | | res[rc++] = b64[(0x3 & bin[byteNo]) << 4];
|
| | | res[rc++] = '=';
|
| | | res[rc++] = '=';
|
| | | } else if (pad == 1) {
|
| | | res[rc++] = b64[bin[byteNo] >> 2];
|
| | | res[rc++] = b64[((0x3 & bin[byteNo]) << 4) + (bin[byteNo + 1] >> 4)];
|
| | | res[rc++] = b64[(0x0f & bin[byteNo + 1]) << 2];
|
| | | res[rc++] = '=';
|
| | | }
|
| | |
|
| | | res[rc] = 0; // NULL TERMINATOR! ;)
|
| | | return res;
|
| | | }
|
| | |
|
| | | //FIXME! |
| | | unsigned char* unbase64(const char* ascii, int len, int *flen) {
|
| | | const unsigned char *safeAsciiPtr = (const unsigned char*) ascii;
|
| | | unsigned char *bin;
|
| | | int cb = 0;
|
| | | int charNo;
|
| | | int pad = 0;
|
| | |
|
| | | if (len < 2) { // 2 accesses below would be OOB.
|
| | | // catch empty string, return NULL as result.
|
| | | puts(
|
| | | "ERROR: You passed an invalid base64 string (too short). You get NULL back.");
|
| | | *flen = 0;
|
| | | return 0;
|
| | | }
|
| | | if (safeAsciiPtr[len - 1] == '=')
|
| | | ++pad;
|
| | | if (safeAsciiPtr[len - 2] == '=')
|
| | | ++pad;
|
| | |
|
| | | *flen = 3 * len / 4 - pad;
|
| | | bin = (unsigned char*) malloc(*flen);
|
| | | if (!bin) {
|
| | | puts("ERROR: unbase64 could not allocate enough memory.");
|
| | | puts("I must stop because I could not get enough");
|
| | | return 0;
|
| | | }
|
| | |
|
| | | for (charNo = 0; charNo <= len - 4 - pad; charNo += 4) {
|
| | | int A = unb64[safeAsciiPtr[charNo]];
|
| | | int B = unb64[safeAsciiPtr[charNo + 1]];
|
| | | int C = unb64[safeAsciiPtr[charNo + 2]];
|
| | | int D = unb64[safeAsciiPtr[charNo + 3]];
|
| | |
|
| | | bin[cb++] = (A << 2) | (B >> 4);
|
| | | bin[cb++] = (B << 4) | (C >> 2);
|
| | | bin[cb++] = (C << 6) | (D);
|
| | | }
|
| | |
|
| | | if (pad == 1) {
|
| | | int A = unb64[safeAsciiPtr[charNo]];
|
| | | int B = unb64[safeAsciiPtr[charNo + 1]];
|
| | | int C = unb64[safeAsciiPtr[charNo + 2]];
|
| | |
|
| | | bin[cb++] = (A << 2) | (B >> 4);
|
| | | bin[cb++] = (B << 4) | (C >> 2);
|
| | | } else if (pad == 2) {
|
| | | int A = unb64[safeAsciiPtr[charNo]];
|
| | | int B = unb64[safeAsciiPtr[charNo + 1]];
|
| | |
|
| | | bin[cb++] = (A << 2) | (B >> 4);
|
| | | }
|
| | |
|
| | | return bin;
|
| | | }
|
| | |
| | | * Author: devel |
| | | */ |
| | | |
| | | #include "verifier.hpp" |
| | | #include "../os.h" |
| | | #include <stdio.h> |
| | | #include <sstream> |
| | | #include <iostream> |
| | | #include <fstream> |
| | | #include <vector> |
| | | #include <bcrypt.h> |
| | | #include <wincrypt.h> |
| | | #include <iphlpapi.h> |
| | | #include <windows.h> |
| | | #pragma comment(lib, "bcrypt.lib") |
| | | |
| | | #include <public_key.h> |
| | | #include "../../base/logger.h" |
| | | #include "../../base/base64.h" |
| | | #include "../signature_verifier.h" |
| | | |
| | | #define RSA_KEY_BITLEN 1024 |
| | | |
| | | namespace license { |
| | | using namespace std; |
| | | #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) |
| | | |
| | | verifier::verifier() { |
| | | // TODO Auto-generated constructor stub |
| | | static const void formatError(DWORD status, const char* description) { |
| | | char msgBuffer[256]; |
| | | FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &msgBuffer[0], |
| | | sizeof(msgBuffer) - 1, nullptr); |
| | | LOG_DEBUG("error %s : %s %h", description, msgBuffer, status); |
| | | } |
| | | |
| | | verifier::~verifier() { |
| | | // TODO Auto-generated destructor stub |
| | | #pragma pack(push, 1) |
| | | typedef struct { |
| | | BCRYPT_RSAKEY_BLOB rsakey; |
| | | BYTE pkExp[3]; |
| | | BYTE modulus[RSA_KEY_BITLEN / 8]; |
| | | } PUBKEY_BLOB, *P_PUBKEY_BLOB; |
| | | #pragma pack(pop) |
| | | |
| | | static BCRYPT_ALG_HANDLE openSignatureProvider() { |
| | | DWORD status; |
| | | BCRYPT_ALG_HANDLE hSignAlg = nullptr; |
| | | |
| | | return hSignAlg; |
| | | } |
| | | |
| | | static BCRYPT_ALG_HANDLE openHashProvider() { |
| | | DWORD status; |
| | | BCRYPT_ALG_HANDLE hHashAlg = nullptr; |
| | | if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hHashAlg, BCRYPT_SHA256_ALGORITHM, NULL, 0))) { |
| | | throw logic_error("Error opening hash provider"); |
| | | } |
| | | return hHashAlg; |
| | | } |
| | | |
| | | static DWORD hashData(BCRYPT_HASH_HANDLE& hHash, const string& data, PBYTE pbHash, DWORD hashDataLenght) { |
| | | DWORD status; |
| | | bool success = false; |
| | | if (NT_SUCCESS(status = BCryptHashData(hHash, (BYTE*)data.c_str(), (ULONG)data.length(), 0))) { |
| | | status = BCryptFinishHash(hHash, pbHash, hashDataLenght, 0); |
| | | } |
| | | return status; |
| | | } |
| | | |
| | | static size_t read_length(uint8_t*& ptr) { |
| | | uint8_t len = *ptr++; |
| | | size_t result = 0; |
| | | cout << (len & 0x80) << endl; |
| | | if ((len & 0x80) > 0) { |
| | | size_t blen = len & 0x7F; |
| | | for (int i = 0; i < blen; i++) { |
| | | result += (*(ptr++) << (i * 8)); |
| | | } |
| | | } else { |
| | | result = len; |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | static FUNCTION_RETURN read_sequence(uint8_t*& ptr) { |
| | | uint8_t tag = *ptr++; |
| | | if (tag != 0x30) { |
| | | return FUNC_RET_ERROR; |
| | | } |
| | | read_length(ptr); |
| | | return FUNC_RET_OK; |
| | | } |
| | | |
| | | static FUNCTION_RETURN read_integer(uint8_t*& ptr, BYTE* location, const size_t expected_length) { |
| | | uint8_t tag = *ptr++; |
| | | if (tag != 0x02) { |
| | | return FUNC_RET_ERROR; |
| | | } |
| | | size_t length = read_length(ptr); |
| | | // skip the padding byte |
| | | if (*ptr == 0) { |
| | | length--; |
| | | ptr++; |
| | | } |
| | | if (expected_length < length) { |
| | | return FUNC_RET_ERROR; |
| | | } |
| | | for (int i = 0; i < length; i++) { |
| | | location[i] = *(ptr++); |
| | | } |
| | | return FUNC_RET_OK; |
| | | } |
| | | |
| | | static FUNCTION_RETURN readPublicKey(const BCRYPT_ALG_HANDLE sig_alg, BCRYPT_KEY_HANDLE* hKey) { |
| | | FUNCTION_RETURN result = FUNC_RET_ERROR; |
| | | DWORD status; |
| | | PUBKEY_BLOB pubk; |
| | | pubk.rsakey.Magic = BCRYPT_RSAPUBLIC_MAGIC; |
| | | pubk.rsakey.BitLength = RSA_KEY_BITLEN; |
| | | pubk.rsakey.cbPublicExp = 3; |
| | | pubk.rsakey.cbModulus = RSA_KEY_BITLEN / 8; |
| | | pubk.rsakey.cbPrime1 = 0; |
| | | pubk.rsakey.cbPrime2 = 0; |
| | | uint8_t pubKey[] = PUBLIC_KEY; |
| | | uint8_t* pub_key_idx = &pubKey[0]; |
| | | read_sequence(pub_key_idx); |
| | | read_integer(pub_key_idx, (BYTE*)&pubk.modulus, sizeof(pubk.modulus)); |
| | | read_integer(pub_key_idx, (BYTE*)&pubk.pkExp, sizeof(pubk.pkExp)); |
| | | if (NT_SUCCESS(status = BCryptImportKeyPair(sig_alg, nullptr, BCRYPT_RSAPUBLIC_BLOB, hKey, (PUCHAR)&pubk, |
| | | sizeof(pubk), 0))) { |
| | | result = FUNC_RET_OK; |
| | | } else { |
| | | #ifdef _DEBUG |
| | | formatError(status, "error importing public key"); |
| | | #endif |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | static FUNCTION_RETURN verifyHash(const PBYTE pbHash, const DWORD hashDataLenght, const string& signatureBuffer) { |
| | | BCRYPT_KEY_HANDLE phKey = nullptr; |
| | | DWORD status; |
| | | FUNCTION_RETURN result = FUNC_RET_ERROR; |
| | | PBYTE pbSignature = nullptr; |
| | | DWORD dwSigLen; |
| | | BYTE* sigBlob = nullptr; |
| | | BCRYPT_ALG_HANDLE hSignAlg = nullptr; |
| | | |
| | | // FIXME!! |
| | | sigBlob = unbase64(signatureBuffer.c_str(), (int)signatureBuffer.size(), (int*)&dwSigLen); |
| | | |
| | | if (NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hSignAlg, BCRYPT_RSA_ALGORITHM, NULL, 0))) { |
| | | if ((result = readPublicKey(hSignAlg, &phKey)) == FUNC_RET_OK) { |
| | | BCRYPT_PKCS1_PADDING_INFO paddingInfo; |
| | | ZeroMemory(&paddingInfo, sizeof(paddingInfo)); |
| | | paddingInfo.pszAlgId = BCRYPT_SHA256_ALGORITHM; |
| | | if (NT_SUCCESS(status = BCryptVerifySignature(phKey, &paddingInfo, pbHash, hashDataLenght, sigBlob, |
| | | dwSigLen, BCRYPT_PAD_PKCS1))) { |
| | | result = FUNC_RET_OK; |
| | | } else { |
| | | result = FUNC_RET_ERROR; |
| | | #ifdef _DEBUG |
| | | formatError(status, "error verifying signature"); |
| | | #endif |
| | | } |
| | | } else { |
| | | LOG_DEBUG("Error reading public key"); |
| | | } |
| | | } else { |
| | | result = FUNC_RET_NOT_AVAIL; |
| | | #ifdef _DEBUG |
| | | formatError(status, "error opening RSA provider"); |
| | | #endif |
| | | } |
| | | |
| | | if (phKey != nullptr) { |
| | | BCryptDestroyKey(phKey); |
| | | } |
| | | if (hSignAlg != nullptr) { |
| | | BCryptCloseAlgorithmProvider(hSignAlg, 0); |
| | | } |
| | | if (sigBlob) { |
| | | free(sigBlob); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | FUNCTION_RETURN verify_signature(const std::string& stringToVerify, const std::string& signatureB64) { |
| | | BCRYPT_HASH_HANDLE hHash = nullptr; |
| | | PBYTE pbHashObject = nullptr, pbHashData = nullptr; |
| | | |
| | | FUNCTION_RETURN result = FUNC_RET_ERROR; |
| | | const HANDLE hProcessHeap = GetProcessHeap(); |
| | | // BCRYPT_ALG_HANDLE sig_alg = openSignatureProvider(); |
| | | |
| | | BCRYPT_ALG_HANDLE hash_alg = openHashProvider(); |
| | | DWORD status; |
| | | |
| | | // calculate the size of the buffer to hold the hash object |
| | | DWORD cbData = 0, cbHashObject = 0; |
| | | // and the size to keep the hashed data |
| | | DWORD cbHashDataLenght = 0; |
| | | if (NT_SUCCESS(status = BCryptGetProperty(hash_alg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbHashObject, sizeof(DWORD), |
| | | &cbData, 0)) && |
| | | NT_SUCCESS(status = BCryptGetProperty(hash_alg, BCRYPT_HASH_LENGTH, (PBYTE)&cbHashDataLenght, sizeof(DWORD), |
| | | &cbData, 0))) { |
| | | // allocate the hash object on the heap |
| | | pbHashObject = (PBYTE)HeapAlloc(hProcessHeap, 0, cbHashObject); |
| | | pbHashData = (PBYTE)HeapAlloc(hProcessHeap, 0, cbHashDataLenght); |
| | | if (NULL != pbHashObject && nullptr != pbHashData) { |
| | | if (NT_SUCCESS(status = BCryptCreateHash(hash_alg, &hHash, pbHashObject, cbHashObject, NULL, 0, 0))) { |
| | | if (NT_SUCCESS(status = hashData(hHash, stringToVerify, pbHashData, cbHashDataLenght))) { |
| | | result = verifyHash(pbHashData, cbHashDataLenght, signatureB64); |
| | | } else { |
| | | result = FUNC_RET_NOT_AVAIL; |
| | | #ifdef _DEBUG |
| | | formatError(status, "error hashing data"); |
| | | #endif |
| | | } |
| | | } else { |
| | | result = FUNC_RET_NOT_AVAIL; |
| | | #ifdef _DEBUG |
| | | formatError(status, "error creating hash"); |
| | | #endif |
| | | } |
| | | } else { |
| | | result = FUNC_RET_BUFFER_TOO_SMALL; |
| | | LOG_DEBUG("Error allocating memory"); |
| | | } |
| | | } else { |
| | | result = FUNC_RET_NOT_AVAIL; |
| | | #ifdef _DEBUG |
| | | formatError(status, "**** Error returned by BCryptGetProperty"); |
| | | #endif |
| | | } |
| | | |
| | | if (hHash) { |
| | | BCryptDestroyHash(hHash); |
| | | } |
| | | if (pbHashObject) { |
| | | HeapFree(hProcessHeap, 0, pbHashObject); |
| | | } |
| | | if (pbHashData) { |
| | | HeapFree(hProcessHeap, 0, pbHashData); |
| | | } |
| | | if (hash_alg != nullptr) { |
| | | BCryptCloseAlgorithmProvider(hash_alg, 0); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | } /* namespace license */ |
| | |
| | | #if we're here boost has been found |
| | | add_definitions(-DBOOST_ALL_NO_LIB) #Disable Boost Microsoft magic, all dependencies are handled by cmake |
| | | add_definitions(-DBOOST_LIB_DIAGNOSTIC) #Check it is really disabled |
| | | include_directories(${Boost_INCLUDE_DIR}) |
| | | include_directories(${CMAKE_CURRENT_BINARY_DIR}) |
| | | include_directories(${Boost_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) |
| | | link_directories ( ${Boost_LIBRARY_DIR} ) |
| | | |
| | | configure_file ( |
| | |
| | | "${CMAKE_BINARY_DIR}/licensecc_properties_test.h.tmp" |
| | | ) |
| | | |
| | | file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/licensecc_properties_test.h" |
| | | cmake_policy(SET CMP0070 NEW) |
| | | file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/include/$<CONFIG>/licensecc_properties_test.h" |
| | | INPUT "${CMAKE_BINARY_DIR}/licensecc_properties_test.h.tmp") |
| | | |
| | | |
| | | include_directories ( ${CMAKE_BINARY_DIR}/include/$<CONFIG> ) |
| | | add_subdirectory(library) |
| | | add_subdirectory(functional) |
| | |
| | | BOOST_REQUIRE_MESSAGE(fs::create_directories(licenses_base), "test folders created " + licenses_base.string()); |
| | | } |
| | | |
| | | fs::path license_fname(licenses_base / (license_name + ".lic")); |
| | | remove(license_fname.c_str()); |
| | | const fs::path license_fname(licenses_base / (license_name + ".lic")); |
| | | const string license_fname_s = license_fname.string(); |
| | | remove(license_fname_s.c_str()); |
| | | |
| | | stringstream ss; |
| | | ss << LCC_EXE << " license issue"; |
| | |
| | | BOOST_REQUIRE_MESSAGE(fs::create_directories(licenses_base), "test folders created " + licenses_base.string()); |
| | | } |
| | | |
| | | fs::path outputFile(fs::path(PROJECT_TEST_TEMP_DIR) / (test_name + ".tmp")); |
| | | |
| | | remove(outputFile.c_str()); |
| | | const fs::path outputFile(fs::path(PROJECT_TEST_TEMP_DIR) / (test_name + ".tmp")); |
| | | const string output_file_s = outputFile.string(); |
| | | remove(output_file_s.c_str()); |
| | | |
| | | stringstream ss; |
| | | ss << LCC_EXE << " test sign"; |
| | | ss << " --" PARAM_PRIMARY_KEY " " << LCC_PROJECT_PRIVATE_KEY; |
| | | ss << " -d " << data; |
| | | ss << " -o " << outputFile.string(); |
| | | ss << " -o " << output_file_s; |
| | | |
| | | cout << "executing :" << ss.str() << endl; |
| | | const int retCode = std::system(ss.str().c_str()); |