Статус: Участник
Группы: Участники
Зарегистрирован: 27.05.2016(UTC) Сообщений: 10  Откуда: Spb Сказал(а) «Спасибо»: 2 раз
|
Добрый день, знатоки. Прошу вас помочь, нубу ) Я новичок в CryptoAPI, хотел бы получить от вас умный совет. Стоит задача: проверить подпись и найти сертификат (поверить, если он в exe или dll). Модули подписаны сертификатом. Подпись легко проверил через WinTrast. Нужно найти сертификат. Написал следующую функцию. На входе имя файла, серийные номер сертификата, издатель Насколько, я понимаю, сертификат встроен в модуль после выполнения (ну я так сделал): signtool.exe sign /f "Corp Software.pfx" /p pass -t http://timestamp.verisign.com/scripts/timstamp.dll "$(TargetPath)" Модули подписаны сертификатом: Серийный номер: 612D7BF3000000000012 Субъект: E = development@comp.ru CN = COMP Software OU = IT O = EPSA L = SPb S = SPb C = RU Издатель(Issuer): CN = comp-GWSRV-CA DC = comp DC = local Корневой сертификат издателя (CA в домене): Серийный номер: 155AE3A6B2F0D28B47F017A4436019BF Субъект: CN = comp-GWSRV-CA DC = comp DC = local Издатель(Issuer): CN = comp-GWSRV-CA DC = comp DC = local На самоподписанных сертификатах все работаетНапример, когда: Серийный номер: C191A06AD69C89944FDE4D6DB7A86949 Кому выдан: CN = My Corporation Кем выдан: CN = My Corporation Все будет замечательно. Но, если передаю, например:Серийный номер: 612D7BF3000000000012 Издатель(Issuer): CN = comp-GWSRV-CA,DC = comp,DC = local (запятые ставлю) Не находит. Пробовал различные комбинации - не находит ( Что не так?На входе: путь к файлу (dll или exe), Серийный номер, Кем выдан На выходе: ERROR_SUCCESS - если найден. Код:
LRESULT CLCertVerifyCertificateW(LPCWSTR pszFilePath, LPCWSTR pszSerialNumber, LPCWSTR pszIssuer){
if(!pszFilePath || !pszSerialNumber || !pszIssuer) return ERROR_BAD_ARGUMENTS;
BOOL lResult=ERROR_ACCESS_DENIED;
HCRYPTPROV hCryptProvider=NULL;
DWORD dwEncoding=0x00;
DWORD dwContent=0x00;
DWORD dwFormatType=0x00;
HCRYPTMSG hCryptMsg=NULL;
HCERTSTORE hCertStore=NULL;
PCCERT_CONTEXT pSignerCert=NULL;
CERT_ID cert_id={0x00};
LPBYTE pbtIssure=NULL;
DWORD dwIssureLen=0x00;
LPBYTE pbtSerialNumber=NULL;
DWORD dwSerialNumberLen=0x00;
WCHAR pszAlphaHex[0x03]={0x00};
PWCHAR pszSerialNumberTmp=NULL;
LPBYTE pbtSerialNumberTmp=NULL;
// Get context to use for Crypt
if(::CryptAcquireContextW(&hCryptProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)){
// Open file store
if(::CryptQueryObject(CERT_QUERY_OBJECT_FILE, pszFilePath, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY, 0x00, &dwEncoding, &dwContent, &dwFormatType, &hCertStore, &hCryptMsg, NULL)){
// Prepare cert info for search in app file
// Convert Issuer
if(::CertStrToNameW(dwEncoding, pszIssuer, CERT_NAME_STR_COMMA_FLAG | CERT_X500_NAME_STR | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG, NULL, NULL, &dwIssureLen, NULL)){
pbtIssure=new BYTE[dwIssureLen]();
if(pbtIssure){
if(::CertStrToNameW(dwEncoding, pszIssuer, CERT_NAME_STR_COMMA_FLAG | CERT_X500_NAME_STR | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG, NULL, pbtIssure, &dwIssureLen, NULL)){
cert_id.IssuerSerialNumber.Issuer.pbData=pbtIssure;
cert_id.IssuerSerialNumber.Issuer.cbData=dwIssureLen;
// Convert SerialNumber (from hex string to byte with reverse order)
dwSerialNumberLen=wcslen(pszSerialNumber);
if(dwSerialNumberLen && !(dwSerialNumberLen%0x02)){
pszSerialNumberTmp=(PWCHAR)(pszSerialNumber+dwSerialNumberLen);
dwSerialNumberLen=dwSerialNumberLen/0x02;
pbtSerialNumber=new BYTE[dwSerialNumberLen]();
if(pbtSerialNumber){
pbtSerialNumberTmp=pbtSerialNumber;
while(pszSerialNumber<pszSerialNumberTmp){
pszSerialNumberTmp-=0x02;
memcpy(pszAlphaHex, pszSerialNumberTmp, 0x04);
*pbtSerialNumberTmp=(BYTE)std::stoi(pszAlphaHex, 0x0, 0x10);
pbtSerialNumberTmp++;
}
cert_id.dwIdChoice=CERT_ID_ISSUER_SERIAL_NUMBER;
cert_id.IssuerSerialNumber.SerialNumber.pbData=pbtSerialNumber;
cert_id.IssuerSerialNumber.SerialNumber.cbData=dwSerialNumberLen;
// Search certificate in this store
pSignerCert=::CertFindCertificateInStore(hCertStore, dwEncoding, 0x00, CERT_FIND_CERT_ID, &cert_id, NULL);
if(pSignerCert) lResult=ERROR_SUCCESS;
}
}
}
}
}
}
}
// Cleanup
if(pbtSerialNumber) delete pbtSerialNumber;
if(pbtIssure) delete pbtIssure;
if(pSignerCert) ::CertFreeCertificateContext(pSignerCert);
if(hCryptMsg) ::CryptMsgClose(hCryptMsg);
if(hCertStore) ::CertCloseStore(hCertStore, 0x00);
if(hCryptProvider) ::CryptReleaseContext(hCryptProvider, 0x00);
return lResult;
}
Отредактировано пользователем 27 мая 2016 г. 9:51:48(UTC)
| Причина: Не указана
|