Thanks in advance,
Joe Mueller
GUID action_guid = WINTRUST_ACTION_GENERIC_VERIFY_V2;
WINTRUST_DATA trust_data;
WINTRUST_FILE_INFO file_info;
memset(&file_info, 0, sizeof(file_info));
file_info.cbStruct = sizeof(file_info);
file_info.pcwszFilePath = L"C:\\somefile.dll";
memset(&trust_data, 0, sizeof(trust_data));
// fill in the trust data
trust_data.cbStruct = sizeof(trust_data);
trust_data.dwUIChoice = WTD_UI_NONE;
trust_data.fdwRevocationChecks =
WTD_REVOKE_WHOLECHAIN;
trust_data.dwUnionChoice = WTD_CHOICE_FILE;
trust_data.pFile = &file_info;
HRESULT result;
result = WinVerifyTrust((HWND)
INVALID_HANDLE_VALUE, &action_guid, &trust_data);
if (result != ERROR_SUCCESS) {
printf("Verification failed, code: 0x%
x\n", result);
return NULL;
}
// Authenticode check succeeded, now verify the
certificate used to sign the dll is ours
HANDLE dll_handle = CreateFile("C:\\somefile.dll",
GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_RANDOM_ACCESS, NULL);
if (dll_handle == INVALID_HANDLE_VALUE) {
return NULL;
}
DWORD cert_count;
if (!ImageEnumerateCertificates(dll_handle,
CERT_SECTION_TYPE_ANY, &cert_count, NULL, 0)) {
CloseHandle(dll_handle);
return NULL;
}
// there should only be one certificate associated
with this dll, ours
if (cert_count != 1) {
CloseHandle(dll_handle);
return NULL;
}
// assume most certificates will fit into a 1024
byte buffer
DWORD cert_len = 1024;
LPVOID cert = malloc(sizeof(WIN_CERTIFICATE) +
cert_len);
if (cert == NULL) {
CloseHandle(dll_handle);
return NULL;
}
WIN_CERTIFICATE *cert_p = (WIN_CERTIFICATE*)cert;
cert_p->dwLength = cert_len;
cert_p->wRevision = WIN_CERT_REVISION_1_0;
DWORD actual_cert_len;
// first get the certificate header to see if our
certificate structure is large enough, if not,
// grow it to the proper size
if (!ImageGetCertificateHeader(dll_handle, 0,
cert_p)) {
// problem getting certificate
information, return failure
CloseHandle(dll_handle);
free(cert);
return NULL;
}
if (cert_p->dwLength > cert_len) {
// need to grow buffer
cert_len = cert_p->dwLength;
cert = realloc(cert, cert_len);
if (cert == NULL) {
CloseHandle(dll_handle);
return NULL;
}
cert_p->dwLength = cert_len;
cert_p->wRevision = WIN_CERT_REVISION_1_0;
}
actual_cert_len = cert_len; // preserve
certificate buffer length by using new variable
if (!ImageGetCertificateData(dll_handle, 0,
cert_p, &actual_cert_len)) {
// problem getting certificate, return
failure
CloseHandle(dll_handle);
free(cert);
return NULL;
}
// done with file handle, close it
CloseHandle(dll_handle);
// At this point I have the SignedData certificate
pointed to by cert_p, but now what do I do to compare it's
public key information with my public key???
thanks
Carlos
This posting is provided 'AS IS' with no warranties, and confers no rights.
I counted several queries on how do do this in the
newsgroups, perhaps Microsoft should add this example (or
the other one by Daniel Sie, or both) to MSDN.
I'm posting this in hope that it will help someone else.
Please let me know if you see errors in this solution.
>.
>