| | |
| | | /* |
| | | * LicenseSigner.cpp |
| | | * |
| | | * Created on: Apr 6, 2014 |
| | | * Author: devel |
| | | */ |
| | | |
| | | #include "LicenseSigner.h" |
| | | #include "private-key.h" |
| | | #include <stdexcept> |
| | | #include <string.h> |
| | | #include <openssl/evp.h> |
| | | #include <openssl/bio.h> |
| | | #include <openssl/pem.h> |
| | | #include <openssl/err.h> |
| | | #include <iostream> |
| | | #include <cmath> |
| | | |
| | | namespace license { |
| | | using namespace std; |
| | | |
| | | LicenseSigner::LicenseSigner() { |
| | | os_initialize(); |
| | | } |
| | | |
| | | LicenseSigner::LicenseSigner(const std::string& alternatePrimaryKey) { |
| | | os_initialize(); |
| | | } |
| | | |
| | | string LicenseSigner::Opensslb64Encode(size_t slen, unsigned char* signature) { |
| | | /* |
| | | FILE* stream = fmemopen(*buffer, encodedSize+1, "w"); |
| | | */ |
| | | //bio = BIO_new_fp(stdout, BIO_NOCLOSE); |
| | | /*int encodedSize = 4 * ceil(slen / 3); |
| | | char* buffer = (char*) (malloc(encodedSize + 1)); |
| | | memset(buffer,0,encodedSize+1);*/ |
| | | BIO* mem_bio = BIO_new(BIO_s_mem()); |
| | | BIO* b64 = BIO_new(BIO_f_base64()); |
| | | BIO* bio1 = BIO_push(b64, mem_bio); |
| | | BIO_set_flags(bio1, BIO_FLAGS_BASE64_NO_NL); |
| | | BIO_write(bio1, signature, slen); |
| | | BIO_flush(bio1); |
| | | char* charBuf; |
| | | int sz = BIO_get_mem_data(mem_bio, &charBuf); |
| | | string signatureStr; |
| | | signatureStr.assign(charBuf, sz); |
| | | BIO_free_all(bio1); |
| | | return signatureStr; |
| | | } |
| | | |
| | | string LicenseSigner::signString(const string& license) { |
| | | |
| | | size_t slen; |
| | | unsigned char* signature; |
| | | signature = NULL; |
| | | /* Create the Message Digest Context */ |
| | | EVP_MD_CTX* mdctx = EVP_MD_CTX_create(); |
| | | if (!mdctx) { |
| | | throw logic_error("Message digest creation context"); |
| | | } |
| | | const char *private_key = PRIVATE_KEY |
| | | ; |
| | | BIO* bio = BIO_new_mem_buf((void*) (private_key), strlen(private_key)); |
| | | EVP_PKEY *pktmp = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); |
| | | BIO_free(bio); |
| | | /*Initialise the DigestSign operation - SHA-256 has been selected |
| | | * as the message digest function in this example */ |
| | | if (1 != EVP_DigestSignInit(mdctx, NULL, EVP_sha256(), NULL, pktmp)) { |
| | | EVP_MD_CTX_destroy(mdctx); |
| | | } |
| | | /* Call update with the message */ |
| | | if (EVP_DigestSignUpdate(mdctx, license.c_str(), license.length()) != 1) { |
| | | EVP_MD_CTX_destroy(mdctx); |
| | | throw logic_error("Message signing exception"); |
| | | } |
| | | /* Finalise the DigestSign operation */ |
| | | /* First call EVP_DigestSignFinal with a NULL sig parameter to obtain the length of the |
| | | * signature. Length is returned in slen */ |
| | | if (EVP_DigestSignFinal(mdctx, NULL, &slen) != 1) { |
| | | EVP_MD_CTX_destroy(mdctx); |
| | | throw logic_error("Message signature finalization exception"); |
| | | } |
| | | /* Allocate memory for the signature based on size in slen */ |
| | | if (!(signature = (unsigned char *) OPENSSL_malloc( |
| | | sizeof(unsigned char) * slen))) { |
| | | EVP_MD_CTX_destroy(mdctx); |
| | | throw logic_error("Message signature memory allocation exception"); |
| | | } |
| | | /* Obtain the signature */ |
| | | if (1 != EVP_DigestSignFinal(mdctx, signature, &slen)) { |
| | | OPENSSL_free(signature); |
| | | EVP_MD_CTX_destroy(mdctx); |
| | | throw logic_error("Message signature exception"); |
| | | } |
| | | /* |
| | | FILE* stream = fmemopen(*buffer, encodedSize+1, "w"); |
| | | */ |
| | | //bio = BIO_new_fp(stdout, BIO_NOCLOSE); |
| | | /*int encodedSize = 4 * ceil(slen / 3); |
| | | char* buffer = (char*) (malloc(encodedSize + 1)); |
| | | memset(buffer,0,encodedSize+1);*/ |
| | | string signatureStr = Opensslb64Encode(slen, signature); |
| | | /* |
| | | * BIO *bio, *b64; |
| | | char message[] = "Hello World \n"; |
| | | b64 = BIO_new(BIO_f_base64()); |
| | | bio = BIO_new_fp(stdout, BIO_NOCLOSE); |
| | | bio = BIO_push(b64, bio); |
| | | BIO_write(bio, message, strlen(message)); |
| | | BIO_flush(bio); |
| | | BIO_free_all(bio); |
| | | Read Base64 encoded data from standard input and write the decoded data to standard output: |
| | | |
| | | BIO *bio, *b64, *bio_out; |
| | | char inbuf[512]; |
| | | int inlen; |
| | | b64 = BIO_new(BIO_f_base64()); |
| | | bio = BIO_new_fp(stdin, BIO_NOCLOSE); |
| | | bio_out = BIO_new_fp(stdout, BIO_NOCLOSE); |
| | | bio = BIO_push(b64, bio); |
| | | while((inlen = BIO_read(bio, inbuf, 512)) > 0) |
| | | BIO_write(bio_out, inbuf, inlen); |
| | | BIO_free_all(bio); |
| | | */ |
| | | /* Clean up */ |
| | | //free(buffer); |
| | | if (pktmp) |
| | | EVP_PKEY_free(pktmp); |
| | | if (signature) |
| | | OPENSSL_free(signature); |
| | | |
| | | if (mdctx) |
| | | EVP_MD_CTX_destroy(mdctx); |
| | | return signatureStr; |
| | | } |
| | | |
| | | void LicenseSigner::signLicense(FullLicenseInfo& licenseInfo) { |
| | | string license = licenseInfo.printForSign(); |
| | | string signature = signString(license); |
| | | licenseInfo.license_signature = signature; |
| | | } |
| | | |
| | | LicenseSigner::~LicenseSigner() { |
| | | |
| | | } |
| | | |
| | | } /* namespace license */ |
| | | /*
|
| | | * LicenseSigner.cpp (Windows)
|
| | | *
|
| | | * Created on: Apr 6, 2014
|
| | | * Author: devel
|
| | | */
|
| | |
|
| | | #include <stdexcept>
|
| | | #include <string.h>
|
| | | #include <iostream>
|
| | | #include <cmath>
|
| | |
|
| | | #pragma comment(lib, "crypt32.lib")
|
| | |
|
| | | #include <stdio.h>
|
| | | #include <windows.h>
|
| | | #include <Wincrypt.h>
|
| | | #define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
|
| | | #include "../private-key.h"
|
| | |
|
| | | #include "../LicenseSigner.h"
|
| | | #include "../../library/base/logger.h"
|
| | | namespace license {
|
| | | using namespace std;
|
| | |
|
| | | LicenseSigner::LicenseSigner() {
|
| | | os_initialize();
|
| | |
|
| | | if (CryptAcquireContext(
|
| | | &hProv,
|
| | | "license-manager2++",
|
| | | MS_ENHANCED_PROV,
|
| | | PROV_RSA_FULL, //CRYPT_NEWKEYSET
|
| | | 0)) {
|
| | | LOG_DEBUG("CSP context acquired.");
|
| | | }
|
| | | else
|
| | | {
|
| | | LOG_ERROR("Error during CryptAcquireContextc %d.",GetLastError());
|
| | | throw exception();
|
| | | }
|
| | | if (CryptImportKey(
|
| | | hProv,
|
| | | PRIVATE_KEY,
|
| | | sizeof(PRIVATE_KEY),
|
| | | 0,
|
| | | 0,
|
| | | &hPubKey))
|
| | | {
|
| | | LOG_DEBUG("The key has been imported.\n");
|
| | | }
|
| | | else
|
| | | {
|
| | | LOG_ERROR("Private key import failed.\n");
|
| | | throw exception();
|
| | | }
|
| | | |
| | | }
|
| | |
|
| | | LicenseSigner::LicenseSigner(const std::string& alternatePrimaryKey) {
|
| | | os_initialize();
|
| | | }
|
| | |
|
| | | string LicenseSigner::Opensslb64Encode(size_t slen, unsigned char* signature) {
|
| | |
|
| | | return NULL;
|
| | | }
|
| | |
|
| | | string LicenseSigner::signString(const string& license) {
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Declare and initialize variables.
|
| | | BYTE *pbBuffer = (BYTE *)license.c_str();
|
| | | DWORD dwBufferLen = strlen((char *)pbBuffer) + 1;
|
| | | HCRYPTHASH hHash;
|
| | |
|
| | | HCRYPTKEY hKey;
|
| | | BYTE *pbKeyBlob;
|
| | | BYTE *pbSignature;
|
| | | DWORD dwSigLen;
|
| | | DWORD dwBlobLen;
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Acquire a cryptographic provider context handle.
|
| | |
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Get the public at signature key. This is the public key
|
| | | // that will be used by the receiver of the hash to verify
|
| | | // the signature. In situations where the receiver could obtain the
|
| | | // sender's public key from a certificate, this step would not be
|
| | | // needed.
|
| | |
|
| | | if (CryptGetUserKey(
|
| | | hProv,
|
| | | AT_SIGNATURE,
|
| | | &hKey))
|
| | | {
|
| | | printf("The signature key has been acquired. \n");
|
| | | }
|
| | | else
|
| | | {
|
| | | printf("Error during CryptGetUserKey for signkey. %d", GetLastError());
|
| | | }
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Create the hash object.
|
| | |
|
| | | if (CryptCreateHash(
|
| | | hProv,
|
| | | CALG_SHA1,
|
| | | 0,
|
| | | 0,
|
| | | &hHash))
|
| | | {
|
| | | printf("Hash object created. \n");
|
| | | }
|
| | | else
|
| | | {
|
| | | LOG_ERROR("Error during CryptCreateHash.");
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Compute the cryptographic hash of the buffer.
|
| | |
|
| | | if (CryptHashData(
|
| | | hHash,
|
| | | pbBuffer,
|
| | | dwBufferLen,
|
| | | 0))
|
| | | {
|
| | | printf("The data buffer has been hashed.\n");
|
| | | }
|
| | | else
|
| | | {
|
| | | LOG_ERROR("Error during CryptHashData.");
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Determine the size of the signature and allocate memory.
|
| | |
|
| | | dwSigLen = 0;
|
| | | if (CryptSignHash(
|
| | | hHash,
|
| | | AT_SIGNATURE,
|
| | | NULL,
|
| | | 0,
|
| | | NULL,
|
| | | &dwSigLen))
|
| | | {
|
| | | printf("Signature length %d found.\n", dwSigLen);
|
| | | }
|
| | | else
|
| | | {
|
| | | LOG_ERROR("Error during CryptSignHash.");
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Allocate memory for the signature buffer.
|
| | |
|
| | | if (pbSignature = (BYTE *)malloc(dwSigLen))
|
| | | {
|
| | | printf("Memory allocated for the signature.\n");
|
| | | }
|
| | | else
|
| | | {
|
| | | LOG_ERROR("Out of memory.");
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Sign the hash object.
|
| | |
|
| | | if (CryptSignHash(
|
| | | hHash,
|
| | | AT_SIGNATURE,
|
| | | NULL,
|
| | | 0,
|
| | | pbSignature,
|
| | | &dwSigLen))
|
| | | {
|
| | | printf("pbSignature is the hash signature.\n");
|
| | | }
|
| | | else
|
| | | {
|
| | | LOG_ERROR("Error during CryptSignHash.");
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Destroy the hash object.
|
| | |
|
| | | if (hHash)
|
| | | CryptDestroyHash(hHash);
|
| | |
|
| | | printf("The hash object has been destroyed.\n");
|
| | | printf("The signing phase of this program is completed.\n\n");
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // In the second phase, the hash signature is verified.
|
| | | // This would most often be done by a different user in a
|
| | | // separate program. The hash, signature, and the PUBLICKEYBLOB
|
| | | // would be read from a file, an email message, |
| | | // or some other source.
|
| | |
|
| | | // Here, the original pbBuffer, pbSignature, szDescription. |
| | | // pbKeyBlob, and their lengths are used.
|
| | |
|
| | | // The contents of the pbBuffer must be the same data |
| | | // that was originally signed.
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Get the public key of the user who created the digital signature |
| | | // and import it into the CSP by using CryptImportKey. This returns
|
| | | // a handle to the public key in hPubKey.
|
| | |
|
| | | /*if (CryptImportKey(
|
| | | hProv,
|
| | | pbKeyBlob,
|
| | | dwBlobLen,
|
| | | 0,
|
| | | 0,
|
| | | &hPubKey))
|
| | | {
|
| | | printf("The key has been imported.\n");
|
| | | }
|
| | | else
|
| | | {
|
| | | MyHandleError("Public key import failed.");
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Create a new hash object.
|
| | |
|
| | | if (CryptCreateHash(
|
| | | hProv,
|
| | | CALG_MD5,
|
| | | 0,
|
| | | 0,
|
| | | &hHash))
|
| | | {
|
| | | printf("The hash object has been recreated. \n");
|
| | | }
|
| | | else
|
| | | {
|
| | | MyHandleError("Error during CryptCreateHash.");
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Compute the cryptographic hash of the buffer.
|
| | |
|
| | | if (CryptHashData(
|
| | | hHash,
|
| | | pbBuffer,
|
| | | dwBufferLen,
|
| | | 0))
|
| | | {
|
| | | printf("The new hash has been created.\n");
|
| | | }
|
| | | else
|
| | | {
|
| | | MyHandleError("Error during CryptHashData.");
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Validate the digital signature.
|
| | |
|
| | | if (CryptVerifySignature(
|
| | | hHash,
|
| | | pbSignature,
|
| | | dwSigLen,
|
| | | hPubKey,
|
| | | NULL,
|
| | | 0))
|
| | | {
|
| | | printf("The signature has been verified.\n");
|
| | | }
|
| | | else
|
| | | {
|
| | | printf("Signature not validated!\n");
|
| | | }
|
| | | //-------------------------------------------------------------------
|
| | | // Free memory to be used to store signature.
|
| | |
|
| | | if (pbSignature)
|
| | | free(pbSignature);
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Destroy the hash object.
|
| | |
|
| | | if (hHash)
|
| | | CryptDestroyHash(hHash);*/
|
| | |
|
| | | //-------------------------------------------------------------------
|
| | | // Release the provider handle.
|
| | |
|
| | | if (hProv)
|
| | | CryptReleaseContext(hProv, 0);
|
| | | return string("");
|
| | | } // End of main
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | | void LicenseSigner::signLicense(FullLicenseInfo& licenseInfo) {
|
| | | string license = licenseInfo.printForSign();
|
| | | string signature = signString(license);
|
| | | licenseInfo.license_signature = signature;
|
| | | }
|
| | |
|
| | | LicenseSigner::~LicenseSigner() {
|
| | |
|
| | | }
|
| | |
|
| | | } /* namespace license */
|