198 lines
5.0 KiB
C++
198 lines
5.0 KiB
C++
//----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 2007 Intel Corporation
|
|
//
|
|
// File: CertHash.cpp
|
|
//
|
|
// Contents: Certificate hash utility
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <windows.h>
|
|
#include <wincrypt.h>
|
|
#include <atlbase.h>
|
|
#include <fstream>
|
|
#include <stdio.h>
|
|
#include <string>
|
|
using namespace std;
|
|
|
|
#include "CertHash.h"
|
|
|
|
//Declaration of the wanted functions in libcrypto.dll
|
|
typedef unsigned char* (*SHA1funcPtr)(const unsigned char* data, size_t dataLength, unsigned char* hash);
|
|
typedef unsigned char* (*SHA256funcPtr)(const unsigned char* data, size_t dataLength, unsigned char* hash);
|
|
typedef unsigned char* (*SHA384funcPtr)(const unsigned char* data, size_t dataLength, unsigned char* hash);
|
|
|
|
CertHash::CertHash(const CertHash& h) : _valid(false)
|
|
{
|
|
_valid = h._valid;
|
|
_dllFailed = h._dllFailed;
|
|
_friendlyName = h._friendlyName;
|
|
_hashAlgorithm = h._hashAlgorithm;
|
|
_hashLength = h._hashLength;
|
|
|
|
_hash = nullptr;
|
|
if(h._hash)
|
|
{
|
|
_hash = new unsigned char[MAX_HASH_LENGTH];
|
|
if (memcpy_s(_hash, MAX_HASH_LENGTH, h._hash, h._hashLength))
|
|
{
|
|
printf("Error: Can't Copy Memory");
|
|
}
|
|
}
|
|
}
|
|
|
|
CertHash::CertHash(const string& fileName, const string& name, const CertHashAlgorithm& hashAlgorithm) : _valid(false), _dllFailed(false)
|
|
{
|
|
_hashLength = 0;
|
|
|
|
_friendlyName = name;
|
|
this->_hashAlgorithm = hashAlgorithm;
|
|
_hash = new unsigned char[MAX_HASH_LENGTH];
|
|
memset(_hash, 0 , MAX_HASH_LENGTH);
|
|
|
|
HCERTSTORE store = NULL;
|
|
PCCERT_CONTEXT pCertContext = NULL;
|
|
CComBSTR str(fileName.c_str());
|
|
|
|
do {
|
|
store = CertOpenStore(
|
|
CERT_STORE_PROV_FILENAME, // the store provider type
|
|
X509_ASN_ENCODING, // if needed, use the usual
|
|
NULL, // use the default HCRYPTPROV
|
|
0, // accept the default for all
|
|
str); // the name of an existing file
|
|
|
|
if (!store)
|
|
break;
|
|
|
|
pCertContext = CertEnumCertificatesInStore(store, NULL);
|
|
if (!pCertContext)
|
|
break;
|
|
|
|
// for sha2 algorithms (sha256 and sha384) use openssl
|
|
if ((USB_CERT_HASH_ALGORITHM_SHA256 == hashAlgorithm) || (USB_CERT_HASH_ALGORITHM_SHA384 == hashAlgorithm))
|
|
{
|
|
HINSTANCE loadLib;
|
|
SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
|
loadLib = LoadLibrary(L"libcrypto.dll");
|
|
// Check to see if the library was loaded successfully
|
|
if (0 != loadLib)
|
|
{
|
|
if (USB_CERT_HASH_ALGORITHM_SHA256 == hashAlgorithm)
|
|
{
|
|
_hashLength = CERT_HASH_SHA256_LENGTH;
|
|
|
|
SHA256funcPtr sha256funcPtr = (SHA256funcPtr)GetProcAddress(loadLib, "SHA256");
|
|
|
|
sha256funcPtr(pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, _hash);
|
|
}
|
|
else if (USB_CERT_HASH_ALGORITHM_SHA384 == hashAlgorithm)
|
|
{
|
|
_hashLength = CERT_HASH_SHA384_LENGTH;
|
|
|
|
SHA384funcPtr sha384funcPtr = (SHA384funcPtr)GetProcAddress(loadLib, "SHA384");
|
|
|
|
sha384funcPtr(pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, _hash);
|
|
}
|
|
|
|
_valid = true;
|
|
FreeLibrary(loadLib);
|
|
}
|
|
else
|
|
{
|
|
_dllFailed = true;
|
|
}
|
|
}
|
|
// for sha1 algorithm windows
|
|
else // sha1 or unsupported hash - use the default (sha1)
|
|
{
|
|
_hashLength = CERT_HASH_SHA1_LENGTH;
|
|
|
|
DWORD cbData = CERT_HASH_SHA1_LENGTH;
|
|
if (!CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, _hash, &cbData))
|
|
break;
|
|
|
|
// do nothing on error...caller must check valid
|
|
_valid = true;
|
|
}
|
|
|
|
} while(0);
|
|
|
|
if (pCertContext)
|
|
CertFreeCertificateContext(pCertContext);
|
|
if (store)
|
|
CertCloseStore(store, 0);
|
|
}
|
|
|
|
CertHash& CertHash::operator=(const CertHash& h)
|
|
{
|
|
_valid = h._valid;
|
|
_dllFailed = h._dllFailed;
|
|
_friendlyName = h._friendlyName;
|
|
_hashAlgorithm = h._hashAlgorithm;
|
|
_hashLength = h._hashLength;
|
|
|
|
_hash = nullptr;
|
|
if (h._hash)
|
|
{
|
|
_hash = new unsigned char[MAX_HASH_LENGTH];
|
|
if (memcpy_s(_hash, MAX_HASH_LENGTH, h._hash, h._hashLength))
|
|
{
|
|
printf("Error: Can't Copy Memory");
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
CertHash::CertHash(const string& hashstring, const string& friendlyName) :_valid(false), _dllFailed(false)
|
|
{
|
|
|
|
_hash = new unsigned char[MAX_HASH_LENGTH];
|
|
_friendlyName = friendlyName;
|
|
|
|
_hashLength = hashstring.length()/2;
|
|
|
|
// check the length of the string
|
|
if(_hashLength == CERT_HASH_SHA1_LENGTH)
|
|
_hashAlgorithm = USB_CERT_HASH_ALGORITHM_SHA1;
|
|
|
|
else if(_hashLength == CERT_HASH_SHA256_LENGTH)
|
|
_hashAlgorithm = USB_CERT_HASH_ALGORITHM_SHA256;
|
|
|
|
else if(_hashLength == CERT_HASH_SHA384_LENGTH)
|
|
_hashAlgorithm = USB_CERT_HASH_ALGORITHM_SHA384;
|
|
|
|
else
|
|
{
|
|
_hashAlgorithm = INVALID_USB_CERT_HASH_ALGORITHM;
|
|
return;
|
|
}
|
|
|
|
|
|
//check if all characters are hex
|
|
for (int i = 0 ; i < hashstring.length(); i++)
|
|
{
|
|
char test = hashstring[i];
|
|
if (!isxdigit(test))
|
|
return;
|
|
}
|
|
|
|
for (int i = 0, j=0; i < hashstring.length(); i=i+2,j++)
|
|
{
|
|
_hash[j] = strtoul((hashstring.substr(i,2)).c_str(), 0, 16);
|
|
}
|
|
|
|
_valid = true;
|
|
|
|
|
|
}
|
|
|
|
CertHash::~CertHash()
|
|
{
|
|
if(_hash)
|
|
{
|
|
delete[] _hash;
|
|
_hash = NULL;
|
|
}
|
|
} |