404 lines
10 KiB
C++
404 lines
10 KiB
C++
#pragma warning(disable : 4512 4511 )
|
|
|
|
#include "windows.h"
|
|
#include "wincrypt.h"
|
|
#include <iostream>
|
|
#include <xstring>
|
|
#include <map>
|
|
#include <vector>
|
|
#include "stdlib.h"
|
|
using namespace std;
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////////////
|
|
PCCERT_CONTEXT GetSignersCert(
|
|
CMSG_SIGNER_INFO const *pSignerInfo,
|
|
HCERTSTORE hExtraStore
|
|
)
|
|
{
|
|
PCCERT_CONTEXT pCertContext = NULL;
|
|
CERT_INFO certInfo;
|
|
|
|
memset(&certInfo, 0, sizeof(CERT_INFO));
|
|
certInfo.SerialNumber = pSignerInfo->SerialNumber;
|
|
certInfo.Issuer = pSignerInfo->Issuer;
|
|
|
|
pCertContext = CertGetSubjectCertificateFromStore(
|
|
hExtraStore,
|
|
X509_ASN_ENCODING,
|
|
&certInfo);
|
|
|
|
return(pCertContext);
|
|
|
|
}
|
|
|
|
|
|
static PCMSG_SIGNER_INFO GetSignerInfo(HCRYPTMSG hMsg, DWORD index)
|
|
{
|
|
|
|
DWORD cbEncodedSigner = 0;
|
|
BYTE *pbEncodedSigner = NULL;
|
|
PCMSG_SIGNER_INFO pSignerInfo = NULL;
|
|
DWORD cbSignerInfo = 0;
|
|
|
|
//
|
|
// get the encoded signer BLOB
|
|
//
|
|
CryptMsgGetParam(hMsg,
|
|
CMSG_ENCODED_SIGNER,
|
|
index,
|
|
NULL,
|
|
&cbEncodedSigner);
|
|
|
|
if (cbEncodedSigner == 0)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (NULL == (pbEncodedSigner = (PBYTE) malloc(cbEncodedSigner)))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (!CryptMsgGetParam(hMsg,
|
|
CMSG_ENCODED_SIGNER,
|
|
index,
|
|
pbEncodedSigner,
|
|
&cbEncodedSigner))
|
|
{
|
|
free(pbEncodedSigner);
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// decode the EncodedSigner info
|
|
//
|
|
if(!CryptDecodeObject(PKCS_7_ASN_ENCODING|CRYPT_ASN_ENCODING,
|
|
PKCS7_SIGNER_INFO,
|
|
pbEncodedSigner,
|
|
cbEncodedSigner,
|
|
0,
|
|
NULL,
|
|
&cbSignerInfo))
|
|
{
|
|
free(pbEncodedSigner);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
if (NULL == (pSignerInfo = (PCMSG_SIGNER_INFO) malloc(cbSignerInfo)))
|
|
{
|
|
free(pbEncodedSigner);
|
|
return NULL;
|
|
}
|
|
|
|
if (!CryptDecodeObject(PKCS_7_ASN_ENCODING|CRYPT_ASN_ENCODING,
|
|
PKCS7_SIGNER_INFO,
|
|
pbEncodedSigner,
|
|
cbEncodedSigner,
|
|
0,
|
|
pSignerInfo,
|
|
&cbSignerInfo))
|
|
{
|
|
free(pbEncodedSigner);
|
|
free(pSignerInfo);
|
|
return NULL;
|
|
}
|
|
|
|
free(pbEncodedSigner);
|
|
return(pSignerInfo);
|
|
}
|
|
|
|
|
|
|
|
extern "C" int __cdecl wmain( int argc, WCHAR **argv )
|
|
{
|
|
HANDLE hUpdateHandle;
|
|
HANDLE hBlobToReplace;
|
|
DWORD dwByteBlobSize;
|
|
vector<BYTE> ByteBlob;
|
|
|
|
hUpdateHandle = BeginUpdateResource( argv[1], FALSE );
|
|
|
|
if ( ( hUpdateHandle == NULL ) || ( hUpdateHandle == INVALID_HANDLE_VALUE ) )
|
|
{
|
|
wcerr << L"Unable to open the file " << argv[1] << L" for resource updating" << ::GetLastError() << endl;
|
|
return 1;
|
|
}
|
|
|
|
hBlobToReplace = CreateFile(
|
|
argv[2],
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
|
|
if ( hBlobToReplace == INVALID_HANDLE_VALUE )
|
|
{
|
|
wcerr << L"Unable to open replacement resource file" << argv[2] << L" for reading, " << ::GetLastError() << endl;
|
|
return 2;
|
|
}
|
|
|
|
ByteBlob.resize( GetFileSize( hBlobToReplace, NULL ) );
|
|
|
|
if ( !ReadFile( hBlobToReplace, &ByteBlob.front(), ByteBlob.size(), &dwByteBlobSize, NULL ) )
|
|
{
|
|
wcerr << L"Unable to read the entire replacement resource, " << ::GetLastError() << endl;
|
|
return 3;
|
|
}
|
|
|
|
if ( !UpdateResource (
|
|
hUpdateHandle,
|
|
RT_MANIFEST,
|
|
MAKEINTRESOURCE(_wtoi(argv[3])),
|
|
MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
|
|
&ByteBlob.front(),
|
|
dwByteBlobSize
|
|
) )
|
|
{
|
|
wcerr << L"Unable to update the resource " << _wtoi(argv[3]) << " because " << ::GetLastError() << endl;
|
|
return 4;
|
|
}
|
|
|
|
|
|
if ( !EndUpdateResource( hUpdateHandle, FALSE ) )
|
|
{
|
|
wcerr << L"Unable to write the changed resource back to the file, " << GetLastError() << endl;
|
|
return 5;
|
|
}
|
|
|
|
CloseHandle( hBlobToReplace );
|
|
|
|
|
|
#if 0
|
|
|
|
PCCTL_CONTEXT pCtlContext = NULL;
|
|
HANDLE hCatalogFile = NULL;
|
|
HANDLE hFileMapping = NULL;
|
|
PVOID pbFileMapping;
|
|
DWORD cbFileMappingSize;
|
|
|
|
hCatalogFile = CreateFileW(
|
|
argv[1],
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL
|
|
);
|
|
|
|
cbFileMappingSize = GetFileSize( hCatalogFile, NULL );
|
|
|
|
|
|
if ( ( hCatalogFile == NULL ) || ( hCatalogFile == INVALID_HANDLE_VALUE ) )
|
|
{
|
|
wcerr << L"Unable to open the file " << argv[1] << L", " << GetLastError() << endl;
|
|
return 2;
|
|
}
|
|
|
|
hFileMapping = CreateFileMappingW(
|
|
hCatalogFile,
|
|
NULL,
|
|
PAGE_READONLY,
|
|
0,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
if ( hFileMapping == NULL )
|
|
{
|
|
wcerr << L"Unable to map from the file handle " << hex << hCatalogFile << endl;
|
|
return 3;
|
|
}
|
|
|
|
pbFileMapping = MapViewOfFile(
|
|
hFileMapping,
|
|
FILE_MAP_READ,
|
|
0,
|
|
0,
|
|
0
|
|
);
|
|
|
|
|
|
pCtlContext = (PCCTL_CONTEXT)CertCreateCTLContext(
|
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
|
(const BYTE*)pbFileMapping,
|
|
cbFileMappingSize
|
|
);
|
|
|
|
if ( pCtlContext == NULL )
|
|
{
|
|
//
|
|
// Urgh..
|
|
//
|
|
wcerr << L"Unable to open the file " << argv[1] << L" as a CTL - " << hex << GetLastError() << endl;
|
|
return 1;
|
|
}
|
|
|
|
PCCERT_CONTEXT pSignerContext = NULL;
|
|
DWORD dwWhichSignerSigned = 0;
|
|
HCERTSTORE hCertStore2 = pCtlContext->hCertStore;
|
|
if ( !CryptMsgGetAndVerifySigner(
|
|
pCtlContext->hCryptMsg,
|
|
0,
|
|
&hCertStore2,
|
|
0,
|
|
&pSignerContext,
|
|
&dwWhichSignerSigned
|
|
) )
|
|
{
|
|
wcerr << L"Unable to validate the signer of this message: " << hex << GetLastError() << endl;
|
|
return 4;
|
|
}
|
|
|
|
vector<WCHAR> wchFriendlyString;
|
|
wchFriendlyString.resize( CertGetNameStringW(
|
|
pSignerContext,
|
|
CERT_NAME_FRIENDLY_DISPLAY_TYPE,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
0
|
|
) );
|
|
|
|
CertGetNameStringW(
|
|
pSignerContext,
|
|
CERT_NAME_FRIENDLY_DISPLAY_TYPE,
|
|
0,
|
|
NULL,
|
|
&wchFriendlyString.front(),
|
|
wchFriendlyString.size()
|
|
);
|
|
|
|
wcerr << L"Signed by " << wstring( wchFriendlyString.begin(), wchFriendlyString.end() ).data() << endl;
|
|
|
|
#endif
|
|
#if 0
|
|
HCERTSTORE hCertStore = NULL;
|
|
HCRYPTMSG hMsgInfo = NULL;
|
|
|
|
//
|
|
// What kind of object is this?
|
|
//
|
|
if ( !CryptQueryObject(
|
|
CERT_QUERY_OBJECT_FILE,
|
|
argv[1],
|
|
CERT_QUERY_CONTENT_FLAG_ALL,
|
|
CERT_QUERY_FORMAT_FLAG_ALL,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&( hCertStore = NULL ),
|
|
&( hMsgInfo = NULL ),
|
|
NULL
|
|
) )
|
|
{
|
|
wcerr << L"Error opening " << argv[1] << L" 0x" << hex << GetLastError() << endl;
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// Now that we have a message, we can ask who all has signed it
|
|
//
|
|
PCMSG_SIGNER_INFO pSignerObject = NULL;
|
|
|
|
if ( hCertStore == NULL )
|
|
{
|
|
hCertStore = CertOpenStore(
|
|
CERT_STORE_PROV_MSG,
|
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
|
NULL,
|
|
NULL,
|
|
(const void*)hMsgInfo
|
|
);
|
|
}
|
|
|
|
if ( ( hCertStore == INVALID_HANDLE_VALUE ) || ( hCertStore == NULL ) )
|
|
{
|
|
wcerr << L"Error opening the in-message certificate store to look up the signer's certificate." << endl;
|
|
return 2;
|
|
}
|
|
|
|
if ( pSignerObject = GetSignerInfo( hMsgInfo, 0 ) )
|
|
{
|
|
PCCERT_CONTEXT pSignerContext = NULL;
|
|
|
|
pSignerContext = GetSignersCert( pSignerObject, hCertStore );
|
|
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
HANDLE hCatalog;
|
|
HANDLE hMapping;
|
|
PVOID pbFileData;
|
|
DWORD dwFileSize;
|
|
|
|
hCatalog = CreateFile( args[0].data(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
|
if ( hCatalog == INVALID_HANDLE_VALUE )
|
|
{
|
|
wcerr << L"Can't open " << args[0].data() << L", " << ::GetLastError() << endl;
|
|
return 1;
|
|
}
|
|
|
|
hMapping = CreateFileMappingW(
|
|
hCatalog,
|
|
NULL,
|
|
PAGE_READONLY,
|
|
0,
|
|
0,
|
|
NULL
|
|
);
|
|
if ( hMapping == NULL )
|
|
{
|
|
wcerr << L"Unable to map " << args[0].data() << L", " << ::GetLastError() << endl;
|
|
return 2;
|
|
}
|
|
|
|
pbFileData = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
|
|
if ( pbFileData == NULL )
|
|
{
|
|
wcerr << L"Mapping view of file failed, " << ::GetLastError() << endl;
|
|
return 3;
|
|
}
|
|
|
|
//
|
|
// Tricky:
|
|
//
|
|
PCCTL_CONTEXT pContext = (PCCTL_CONTEXT)CertCreateContex(
|
|
CERT_STORE_CTL_CONTEXT,
|
|
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
|
|
pbFileData,
|
|
cbFileData,
|
|
CERT_CREATE_CONTEXT_NOCOPY_FLAG,
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// Whoops
|
|
//
|
|
if ( pContext == NULL )
|
|
{
|
|
wcerr << L"Failed opening the catalog like it's a cert context CTL list." << endl;
|
|
return 4;
|
|
}
|
|
|
|
//
|
|
// Let's look at the hMessage member of the cert context created to see
|
|
//
|
|
// CMSG_SIGNER_CERT_INFO_PARAM
|
|
CryptMsgGetParam(
|
|
pContext->hCryptMsg,
|
|
CMSG_SIGNER_CERT_INFO_PARAM,
|
|
|
|
#endif
|
|
return 0;
|
|
}
|