| | |
| | | *
|
| | | */
|
| | |
|
| | | #include "CryptoHelperWindows.h"
|
| | | #include <sstream>
|
| | | #include <vector>
|
| | | #include <string>
|
| | | #include "CryptoHelperWindows.h"
|
| | | // The RSA public-key key exchange algorithm
|
| | | #define ENCRYPT_ALGORITHM CALG_RSA_SIGN
|
| | | // The high order WORD 0x0200 (decimal 512)
|
| | |
| | | CryptoHelperWindows::CryptoHelperWindows() {
|
| | | m_hCryptProv = NULL;
|
| | | m_hCryptKey = NULL;
|
| | | if (!CryptAcquireContext(&m_hCryptProv, "license++sign", MS_ENHANCED_PROV,
|
| | | PROV_RSA_FULL, 0)) {
|
| | | if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL, PROV_RSA_FULL, 0)) {
|
| | | // If the key container cannot be opened, try creating a new
|
| | | // container by specifying a container name and setting the
|
| | | // CRYPT_NEWKEYSET flag.
|
| | | printf("Error in AcquireContext 0x%08x \n", GetLastError());
|
| | | if (NTE_BAD_KEYSET == GetLastError()) {
|
| | | if (!CryptAcquireContext(&m_hCryptProv, "license++sign",
|
| | | MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
|
| | | printf("Error in AcquireContext 0x%08x \n", GetLastError());
|
| | | throw logic_error("");
|
| | | DWORD lastError = GetLastError();
|
| | | printf("Error in CryptAcquireContext (1) 0x%08x \n", lastError);
|
| | | if (NTE_BAD_KEYSET == lastError) {
|
| | | if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
|
| | | printf("Warn in CryptAcquireContext: acquiring new user keyset failed 0x%08x, trying less secure mackine keyset \n", GetLastError());
|
| | | //maybe access to protected storage disabled. Try with machine keys (less secure)
|
| | | if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET)) {
|
| | | printf("Error in CryptAcquireContext (2) 0x%08x \n", GetLastError());
|
| | | if (!CryptAcquireContext(&m_hCryptProv, "license_sign", NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET)) {
|
| | | printf("Error in CryptAcquireContext (3): acquiring new keyset(machine) failed 0x%08x \n", GetLastError());
|
| | | throw logic_error("");
|
| | | }
|
| | | }
|
| | | }
|
| | | } else {
|
| | | printf(" Error in AcquireContext 0x%08x \n", GetLastError());
|
| | | printf(" Error in CryptAcquireContext (4) 0x%08x \n", lastError);
|
| | | throw logic_error("");
|
| | | }
|
| | | }
|
| | |
| | | m_hCryptKey = NULL;
|
| | | // Call the CryptGenKey method to get a handle
|
| | | // to a new exportable key-pair.
|
| | | if (!CryptGenKey(m_hCryptProv,
|
| | | ENCRYPT_ALGORITHM,
|
| | | if (!CryptGenKey(m_hCryptProv, ENCRYPT_ALGORITHM,
|
| | | KEYLENGTH | CRYPT_EXPORTABLE, &m_hCryptKey)) {
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(
|
| | | string("Error generating keys ") + to_string(static_cast<long long>(dwErrCode)));
|
| | | string("Error generating keys ")
|
| | | + to_string(static_cast<long long>(dwErrCode)));
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | HRESULT hr = S_OK;
|
| | | DWORD dwErrCode;
|
| | | DWORD dwBlobLen;
|
| | | BYTE *pbKeyBlob = NULL;
|
| | | BYTE *pbKeyBlob = nullptr;
|
| | | stringstream ss;
|
| | | // If the handle to key container is NULL, fail.
|
| | | if (m_hCryptKey == NULL)
|
| | |
| | | // This call here determines the length of the key
|
| | | // blob.
|
| | | if (!CryptExportKey(m_hCryptKey,
|
| | | NULL, PUBLICKEYBLOB, 0,
|
| | | NULL, &dwBlobLen)) {
|
| | | NULL, PUBLICKEYBLOB, 0, nullptr, &dwBlobLen)) {
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(
|
| | | string("Error calculating size of public key ")
|
| | | + to_string(static_cast<long long>(dwErrCode)));
|
| | | }
|
| | | // Allocate memory for the pbKeyBlob.
|
| | | if ((pbKeyBlob = new BYTE[dwBlobLen]) == NULL) {
|
| | | if ((pbKeyBlob = new BYTE[dwBlobLen]) == nullptr) {
|
| | | throw logic_error(string("Out of memory exporting public key "));
|
| | | }
|
| | | // Do the actual exporting into the key BLOB.
|
| | |
| | | delete pbKeyBlob;
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(
|
| | | string("Error exporting public key ") + to_string(static_cast<long long>(dwErrCode)));
|
| | | string("Error exporting public key ")
|
| | | + to_string(static_cast<long long>(dwErrCode)));
|
| | | } else {
|
| | | ss << "\t";
|
| | | for (unsigned int i = 0; i < dwBlobLen; i++) {
|
| | |
| | | // This call here determines the length of the key
|
| | | // blob.
|
| | | if (!CryptExportKey(m_hCryptKey,
|
| | | NULL, PRIVATEKEYBLOB, 0,
|
| | | NULL, &dwBlobLen)) {
|
| | | NULL, PRIVATEKEYBLOB, 0, nullptr, &dwBlobLen)) {
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(
|
| | | string("Error calculating size of private key ")
|
| | | + to_string(static_cast<long long>(dwErrCode)));
|
| | | }
|
| | | // Allocate memory for the pbKeyBlob.
|
| | | if ((pbKeyBlob = new BYTE[dwBlobLen]) == NULL) {
|
| | | if ((pbKeyBlob = new BYTE[dwBlobLen]) == nullptr) {
|
| | | throw logic_error(string("Out of memory exporting private key "));
|
| | | }
|
| | |
|
| | |
| | | delete pbKeyBlob;
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(
|
| | | string("Error exporting private key ") + to_string(static_cast<long long>(dwErrCode)));
|
| | | string("Error exporting private key ")
|
| | | + to_string(static_cast<long long>(dwErrCode)));
|
| | | } else {
|
| | | ss << "\t";
|
| | | for (unsigned int i = 0; i < dwBlobLen; i++) {
|
| | |
| | | return ss.str();
|
| | | }
|
| | |
|
| | | void CryptoHelperWindows::printHash(HCRYPTHASH* hHash) const {
|
| | | void CryptoHelperWindows::printHash(HCRYPTHASH *hHash) const {
|
| | | BYTE *pbHash;
|
| | | DWORD dwHashLen;
|
| | | DWORD dwHashLenSize = sizeof(DWORD);
|
| | | char* hashStr;
|
| | | char *hashStr;
|
| | | unsigned int i;
|
| | |
|
| | | if (CryptGetHashParam(*hHash, HP_HASHSIZE, (BYTE *) &dwHashLen,
|
| | | if (CryptGetHashParam(*hHash, HP_HASHSIZE, (BYTE*) &dwHashLen,
|
| | | &dwHashLenSize, 0)) {
|
| | | pbHash = (BYTE*) malloc(dwHashLen);
|
| | | hashStr = (char*) malloc(dwHashLen * 2 + 1);
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | const string CryptoHelperWindows::signString(const void* privateKey,
|
| | | size_t pklen, const string& license) const {
|
| | | BYTE *pbBuffer = (BYTE *) license.c_str();
|
| | | const DWORD dwBufferLen = (DWORD)strlen((char *)pbBuffer);
|
| | | const string CryptoHelperWindows::signString(const void *privateKey,
|
| | | size_t pklen, const string &license) const {
|
| | | BYTE *pbBuffer = (BYTE*) license.c_str();
|
| | | const DWORD dwBufferLen = (DWORD) strlen((char*) pbBuffer);
|
| | | HCRYPTHASH hHash;
|
| | |
|
| | | HCRYPTKEY hKey;
|
| | |
| | | //-------------------------------------------------------------------
|
| | | // Acquire a cryptographic provider context handle.
|
| | |
|
| | | if (!CryptImportKey(m_hCryptProv, (const BYTE *) privateKey, (DWORD) pklen, 0, 0,
|
| | | &hKey)) {
|
| | | if (!CryptImportKey(m_hCryptProv, (const BYTE*) privateKey, (DWORD) pklen,
|
| | | 0, 0, &hKey)) {
|
| | | throw logic_error(
|
| | | string("Error in importing the PrivateKey ")
|
| | | + to_string(static_cast<long long>(GetLastError())));
|
| | |
| | | // Determine the size of the signature and allocate memory.
|
| | |
|
| | | dwSigLen = 0;
|
| | | if (CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, NULL, &dwSigLen)) {
|
| | | if (CryptSignHash(hHash, AT_SIGNATURE, nullptr, 0, nullptr, &dwSigLen)) {
|
| | | printf("Signature length %d found.\n", dwSigLen);
|
| | | } else {
|
| | | throw logic_error(string("Error during CryptSignHash."));
|
| | |
| | | //-------------------------------------------------------------------
|
| | | // Allocate memory for the signature buffer.
|
| | |
|
| | | if (pbSignature = (BYTE *) malloc(dwSigLen)) {
|
| | | if (pbSignature = (BYTE*) malloc(dwSigLen)) {
|
| | | printf("Memory allocated for the signature.\n");
|
| | | } else {
|
| | | throw logic_error(string("Out of memory."));
|
| | |
| | | //-------------------------------------------------------------------
|
| | | // Sign the hash object.
|
| | |
|
| | | if (CryptSignHash(hHash, AT_SIGNATURE,
|
| | | NULL, 0, pbSignature, &dwSigLen)) {
|
| | | if (CryptSignHash(hHash, AT_SIGNATURE, nullptr, 0, pbSignature,
|
| | | &dwSigLen)) {
|
| | | printf("pbSignature is the signature length. %d\n", dwSigLen);
|
| | | } else {
|
| | | throw logic_error(string("Error during CryptSignHash."));
|
| | |
| | | CryptDestroyKey(hKey);
|
| | |
|
| | | CryptBinaryToString(pbSignature, dwSigLen,
|
| | | CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, NULL, &strLen);
|
| | | CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, nullptr, &strLen);
|
| | | vector<char> buffer(strLen);
|
| | | CryptBinaryToString(pbSignature, dwSigLen,
|
| | | CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF, &buffer[0], &strLen);
|