| | |
| | | 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", MS_ENHANCED_PROV,
|
| | | 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());
|
| | | 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("");
|
| | | }
|
| | | }
|
| | | else
|
| | | {
|
| | | } else {
|
| | | printf(" Error in AcquireContext 0x%08x \n", GetLastError());
|
| | | throw logic_error("");
|
| | | }
|
| | | }
|
| | |
|
| | | }
|
| | |
|
| | |
|
| | | /**
|
| | | This method calls the CryptGenKey function to get a handle to an
|
| | |
| | | exportable key-pair. The key-pair is generated with the RSA public-key
|
| | | key exchange algorithm using Microsoft Enhanced Cryptographic Provider.
|
| | | */
|
| | | void CryptoHelperWindows::generateKeyPair()
|
| | | {
|
| | | void CryptoHelperWindows::generateKeyPair() {
|
| | | HRESULT hr = S_OK;
|
| | | DWORD dwErrCode;
|
| | | // If the handle to key container is NULL, fail.
|
| | |
| | | // to a new exportable key-pair.
|
| | | if (!CryptGenKey(m_hCryptProv,
|
| | | ENCRYPT_ALGORITHM,
|
| | | KEYLENGTH | CRYPT_EXPORTABLE,
|
| | | &m_hCryptKey))
|
| | | {
|
| | | KEYLENGTH | CRYPT_EXPORTABLE, &m_hCryptKey)) {
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(string("Error generating keys ") + to_string(dwErrCode));
|
| | | throw logic_error(
|
| | | string("Error generating keys ") + to_string(dwErrCode));
|
| | | }
|
| | | }
|
| | |
|
| | | /* This method calls the CryptExportKey function to get the Public key
|
| | | in a string suitable for C source inclusion.
|
| | | */
|
| | | const string CryptoHelperWindows::exportPublicKey() const
|
| | | {
|
| | | const string CryptoHelperWindows::exportPublicKey() const {
|
| | | HRESULT hr = S_OK;
|
| | | DWORD dwErrCode;
|
| | | DWORD dwBlobLen;
|
| | |
| | | throw logic_error("call GenerateKey first.");
|
| | | // This call here determines the length of the key
|
| | | // blob.
|
| | | if (!CryptExportKey(
|
| | | m_hCryptKey,
|
| | | NULL,
|
| | | PUBLICKEYBLOB,
|
| | | 0,
|
| | | NULL,
|
| | | &dwBlobLen))
|
| | | {
|
| | | if (!CryptExportKey(m_hCryptKey,
|
| | | NULL, PUBLICKEYBLOB, 0,
|
| | | NULL, &dwBlobLen)) {
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(string("Error calculating size of public key ") + to_string(dwErrCode));
|
| | | throw logic_error(
|
| | | string("Error calculating size of public key ")
|
| | | + to_string(dwErrCode));
|
| | | }
|
| | | // Allocate memory for the pbKeyBlob.
|
| | | if ((pbKeyBlob = new BYTE[dwBlobLen]) == NULL)
|
| | | {
|
| | | if ((pbKeyBlob = new BYTE[dwBlobLen]) == NULL) {
|
| | | throw logic_error(string("Out of memory exporting public key "));
|
| | | }
|
| | | // Do the actual exporting into the key BLOB.
|
| | | if (!CryptExportKey(
|
| | | m_hCryptKey,
|
| | | NULL,
|
| | | PUBLICKEYBLOB,
|
| | | 0,
|
| | | pbKeyBlob,
|
| | | &dwBlobLen))
|
| | | {
|
| | | if (!CryptExportKey(m_hCryptKey,
|
| | | NULL, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen)) {
|
| | | delete pbKeyBlob;
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(string("Error exporting public key ") + to_string(dwErrCode));
|
| | | }
|
| | | else
|
| | | {
|
| | | throw logic_error(
|
| | | string("Error exporting public key ") + to_string(dwErrCode));
|
| | | } else {
|
| | | ss << "\t";
|
| | | for (unsigned int i = 0; i < dwBlobLen; i++){
|
| | | if (i != 0){
|
| | |
| | | }
|
| | |
|
| | | CryptoHelperWindows::~CryptoHelperWindows() {
|
| | | if (m_hCryptProv)
|
| | | {
|
| | | if (m_hCryptProv) {
|
| | | CryptReleaseContext(m_hCryptProv, 0);
|
| | | m_hCryptProv = NULL;
|
| | | }
|
| | |
| | | // in a byte array. The byte array is allocated on the heap and the size
|
| | | // of this is returned to the caller. The caller is responsible for releasing // this memory using a delete call.
|
| | | //--------------------------------------------------------------------
|
| | | const string CryptoHelperWindows::exportPrivateKey() const
|
| | | {
|
| | | const string CryptoHelperWindows::exportPrivateKey() const {
|
| | | HRESULT hr = S_OK;
|
| | | DWORD dwErrCode;
|
| | | DWORD dwBlobLen;
|
| | |
| | | throw logic_error(string("call GenerateKey first."));
|
| | | // This call here determines the length of the key
|
| | | // blob.
|
| | | if (!CryptExportKey(
|
| | | m_hCryptKey,
|
| | | NULL,
|
| | | PRIVATEKEYBLOB,
|
| | | 0,
|
| | | NULL,
|
| | | &dwBlobLen))
|
| | | {
|
| | | if (!CryptExportKey(m_hCryptKey,
|
| | | NULL, PRIVATEKEYBLOB, 0,
|
| | | NULL, &dwBlobLen)) {
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(string("Error calculating size of private key ") + to_string(dwErrCode));
|
| | | throw logic_error(
|
| | | string("Error calculating size of private key ")
|
| | | + to_string(dwErrCode));
|
| | | }
|
| | | // Allocate memory for the pbKeyBlob.
|
| | | if ((pbKeyBlob = new BYTE[dwBlobLen]) == NULL)
|
| | | {
|
| | | if ((pbKeyBlob = new BYTE[dwBlobLen]) == NULL) {
|
| | | throw logic_error(string("Out of memory exporting private key "));
|
| | | }
|
| | |
|
| | | // Do the actual exporting into the key BLOB.
|
| | | if (!CryptExportKey(
|
| | | m_hCryptKey,
|
| | | NULL,
|
| | | PRIVATEKEYBLOB,
|
| | | 0,
|
| | | pbKeyBlob,
|
| | | &dwBlobLen))
|
| | | {
|
| | | if (!CryptExportKey(m_hCryptKey,
|
| | | NULL, PRIVATEKEYBLOB, 0, pbKeyBlob, &dwBlobLen)) {
|
| | | delete pbKeyBlob;
|
| | | dwErrCode = GetLastError();
|
| | | throw logic_error(string("Error exporting private key ") + to_string(dwErrCode));
|
| | | }
|
| | | else
|
| | | {
|
| | | throw logic_error(
|
| | | string("Error exporting private key ") + to_string(dwErrCode));
|
| | | } else {
|
| | | ss << "\t";
|
| | | for (unsigned int i = 0; i < dwBlobLen; i++){
|
| | | if (i != 0){
|
| | |
| | | char* hashStr;
|
| | | int i;
|
| | |
|
| | | if (CryptGetHashParam(*hHash, HP_HASHSIZE, (BYTE *)&dwHashLen, &dwHashLenSize, 0))
|
| | | {
|
| | | if (CryptGetHashParam(*hHash, HP_HASHSIZE, (BYTE *) &dwHashLen,
|
| | | &dwHashLenSize, 0)) {
|
| | | pbHash = (BYTE*)malloc(dwHashLen);
|
| | | hashStr = (char*)malloc(dwHashLen * 2 + 1);
|
| | | if (CryptGetHashParam(*hHash, HP_HASHVAL, pbHash, &dwHashLen, 0)) {
|
| | |
| | | }
|
| | | }
|
| | |
|
| | | const string CryptoHelperWindows::signString(const void* privateKey, size_t pklen,
|
| | | const string& license) const{
|
| | | const string CryptoHelperWindows::signString(const void* privateKey,
|
| | | size_t pklen, const string& license) const {
|
| | | BYTE *pbBuffer = (BYTE *)license.c_str();
|
| | | DWORD dwBufferLen = strlen((char *)pbBuffer);
|
| | | HCRYPTHASH hHash;
|
| | |
| | | DWORD dwBlobLen;
|
| | | DWORD strLen;
|
| | |
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Acquire a cryptographic provider context handle.
|
| | |
|
| | | if (!CryptImportKey(m_hCryptProv, (const BYTE *) privateKey, pklen, 0, 0, &hKey))
|
| | | {
|
| | | throw logic_error(string("Error in importing the PrivateKey ") + to_string(GetLastError()));
|
| | | if (!CryptImportKey(m_hCryptProv, (const BYTE *) privateKey, pklen, 0, 0,
|
| | | &hKey)) {
|
| | | throw logic_error(
|
| | | string("Error in importing the PrivateKey ")
|
| | | + to_string(GetLastError()));
|
| | | }
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Create the hash object.
|
| | |
|
| | | if (CryptCreateHash(
|
| | | m_hCryptProv,
|
| | | CALG_SHA1,
|
| | | 0,
|
| | | 0,
|
| | | &hHash))
|
| | | {
|
| | | if (CryptCreateHash(m_hCryptProv, CALG_SHA1, 0, 0, &hHash)) {
|
| | | printf("Hash object created. \n");
|
| | | }
|
| | | else
|
| | | {
|
| | | } else {
|
| | | CryptDestroyKey(hKey);
|
| | | throw logic_error(string("Error during CryptCreateHash."));
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Compute the cryptographic hash of the buffer.
|
| | |
|
| | | if (CryptHashData(hHash,pbBuffer,dwBufferLen, 0))
|
| | | {
|
| | | if (CryptHashData(hHash, pbBuffer, dwBufferLen, 0)) {
|
| | | #ifdef _DEBUG
|
| | | printf("Length of data to be hashed: %d \n", dwBufferLen);
|
| | | printHash(&hHash);
|
| | | #endif
|
| | | }
|
| | | else
|
| | | {
|
| | | } else {
|
| | | throw logic_error(string("Error during CryptHashData."));
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // 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, NULL, 0, NULL, &dwSigLen)) {
|
| | | printf("Signature length %d found.\n", dwSigLen);
|
| | | }
|
| | | else
|
| | | {
|
| | | } 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
|
| | | {
|
| | | } 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,
|
| | | NULL, 0, pbSignature, &dwSigLen)) {
|
| | | printf("pbSignature is the signature length. %d\n", dwSigLen);
|
| | | }
|
| | | else
|
| | | {
|
| | | } else {
|
| | | throw logic_error(string("Error during CryptSignHash."));
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Destroy the hash object.
|
| | |
|
| | |
|
| | | CryptDestroyHash(hHash);
|
| | | CryptDestroyKey(hKey);
|
| | |
| | |
|
| | | /*if (hProv)
|
| | | CryptReleaseContext(hProv, 0);*/
|
| | | if (pbSignature)
|
| | | if (pbSignature) {
|
| | | free(pbSignature);
|
| | | }
|
| | | return string(&buffer[0]);
|
| | | }
|
| | | } /* namespace license */
|