164 lines
5.6 KiB
Plaintext
164 lines
5.6 KiB
Plaintext
{*******************************************************}
|
|
{ }
|
|
{ Tocsg.Cert }
|
|
{ }
|
|
{ Copyright (C) 2025 kku }
|
|
{ }
|
|
{*******************************************************}
|
|
|
|
unit Tocsg.Cert;
|
|
|
|
interface
|
|
|
|
uses
|
|
Winapi.Windows;
|
|
|
|
//const
|
|
// CERT_QUERY_OBJECT_FILE = $00000001;
|
|
// CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED = $00000020;
|
|
// CERT_QUERY_FORMAT_FLAG_BINARY = $00000002;
|
|
// CMSG_SIGNER_INFO_PARAM = 6;
|
|
// CERT_NAME_SIMPLE_DISPLAY_TYPE = 4;
|
|
// CERT_X500_NAME_STR = 3;
|
|
// CERT_FIND_SUBJECT_CERT = $0000000B;
|
|
//
|
|
// X509_ASN_ENCODING = $00000001; // X.509 인증서 인코딩
|
|
// PKCS_7_ASN_ENCODING = $00010000; // PKCS#7 서명 인코딩
|
|
// ENCODING_TYPE = (X509_ASN_ENCODING or PKCS_7_ASN_ENCODING);
|
|
//
|
|
//type
|
|
// HCERTSTORE = Pointer;
|
|
// HCRYPTMSG = Pointer;
|
|
// PCCERT_CONTEXT = ^CERT_CONTEXT;
|
|
//
|
|
//function CryptQueryObject(dwObjectType: DWORD; pvObject: PChar;
|
|
// dwExpectedContentTypeFlags, dwExpectedFormatTypeFlags: DWORD;
|
|
// dwFlags: DWORD; var pdwMsgAndCertEncodingType, pdwContentType,
|
|
// pdwFormatType: DWORD; var phCertStore: HCERTSTORE;
|
|
// var phMsg: HCRYPTMSG; ppvContext: Pointer): BOOL; stdcall;
|
|
// external 'Crypt32.dll';
|
|
//
|
|
//function CryptMsgGetParam(hCryptMsg: HCRYPTMSG; dwParamType, dwIndex: DWORD;
|
|
// pvData: Pointer; var pcbData: DWORD): BOOL; stdcall;
|
|
// external 'Crypt32.dll';
|
|
//
|
|
//function CertNameToStr(dwCertEncodingType: DWORD; pName: PCERT_NAME_BLOB;
|
|
// dwStrType: DWORD; psz: PChar; csz: DWORD): DWORD; stdcall;
|
|
// external 'Crypt32.dll' name 'CertNameToStrW';
|
|
//
|
|
//function CertFindCertificateInStore(hCertStore: HCERTSTORE;
|
|
// dwCertEncodingType: DWORD; dwFindFlags: DWORD;
|
|
// dwFindType: DWORD; pvFindPara: Pointer;
|
|
// pPrevCertContext: PCCERT_CONTEXT): PCCERT_CONTEXT; stdcall;
|
|
// external 'Crypt32.dll';
|
|
//
|
|
//function CertFreeCertificateContext(pCertContext: PCCERT_CONTEXT): BOOL; stdcall;
|
|
// external 'Crypt32.dll';
|
|
//
|
|
//function CertCloseStore(hCertStore: HCERTSTORE; dwFlags: DWORD): BOOL; stdcall;
|
|
// external 'Crypt32.dll';
|
|
//
|
|
//function CryptMsgClose(hCryptMsg: HCRYPTMSG): BOOL; stdcall;
|
|
// external 'Crypt32.dll';
|
|
|
|
function IsFileSigned(const FileName: string): Boolean;
|
|
|
|
implementation
|
|
|
|
function IsFileSigned(const FileName: string): Boolean;
|
|
var
|
|
WinTrustData: WINTRUST_DATA;
|
|
WinTrustFileInfo: WINTRUST_FILE_INFO;
|
|
GuidAction: TGUID;
|
|
begin
|
|
Result := False;
|
|
// GUID 설정 (WINTRUST_ACTION_GENERIC_VERIFY_V2)
|
|
GuidAction := WINTRUST_ACTION_GENERIC_VERIFY_V2;
|
|
// WINTRUST_FILE_INFO 초기화
|
|
ZeroMemory(@WinTrustFileInfo, SizeOf(WinTrustFileInfo));
|
|
WinTrustFileInfo.cbStruct := SizeOf(WinTrustFileInfo);
|
|
WinTrustFileInfo.pcwszFilePath := PWideChar(WideString(FileName));
|
|
WinTrustFileInfo.hFile := 0;
|
|
WinTrustFileInfo.pgKnownSubject := nil;
|
|
// WINTRUST_DATA 초기화
|
|
ZeroMemory(@WinTrustData, SizeOf(WinTrustData));
|
|
WinTrustData.cbStruct := SizeOf(WinTrustData);
|
|
WinTrustData.dwUIChoice := WTD_UI_NONE; // UI 없음
|
|
WinTrustData.fdwRevocationChecks := WTD_REVOKE_NONE; // 인증서 폐기 목록(CRL) 체크 안 함
|
|
WinTrustData.dwUnionChoice := WTD_CHOICE_FILE; // 파일 검사
|
|
WinTrustData.pFile := @WinTrustFileInfo; // 검사할 파일 정보
|
|
WinTrustData.dwStateAction := 0;
|
|
WinTrustData.hWVTStateData := 0;
|
|
WinTrustData.pwszURLReference := nil;
|
|
WinTrustData.dwProvFlags := WTD_SAFER_FLAG;
|
|
// 서명 확인
|
|
Result := WinVerifyTrust(0, GuidAction, @WinTrustData) = ERROR_SUCCESS;
|
|
end;
|
|
|
|
//function GetCertificateInfo(const FileName: string): string;
|
|
//var
|
|
// hFile: THandle;
|
|
// hFileMapping: THandle;
|
|
// pbFile: Pointer;
|
|
// hStore: HCERTSTORE;
|
|
// hMsg: HCRYPTMSG;
|
|
// CertContext: PCCERT_CONTEXT;
|
|
// Encoding, ContentType, FormatType: DWORD;
|
|
// SignerInfo: PCMSG_SIGNER_INFO;
|
|
// dwSignerInfo: DWORD;
|
|
// IssuerName, SubjectName: array[0..1023] of Char;
|
|
//begin
|
|
// Result := '서명 정보 없음';
|
|
//
|
|
// // 파일 열기
|
|
// if not CryptQueryObject(CERT_QUERY_OBJECT_FILE, PChar(FileName),
|
|
// CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
|
|
// CERT_QUERY_FORMAT_FLAG_BINARY, 0, Encoding,
|
|
// ContentType, FormatType, hStore, hMsg, nil) then
|
|
// begin
|
|
// Exit;
|
|
// end;
|
|
//
|
|
// // 서명자 정보 크기 확인
|
|
// if not CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, nil, dwSignerInfo) then
|
|
// begin
|
|
// Exit;
|
|
// end;
|
|
//
|
|
// // 서명자 정보 가져오기
|
|
// GetMem(SignerInfo, dwSignerInfo);
|
|
// try
|
|
// if not CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, SignerInfo, dwSignerInfo) then
|
|
// begin
|
|
// Exit;
|
|
// end;
|
|
//
|
|
// // 인증서 찾기
|
|
// CertContext := CertFindCertificateInStore(hStore, ENCODING_TYPE,
|
|
// 0, CERT_FIND_SUBJECT_CERT, @SignerInfo^.Issuer, nil);
|
|
//
|
|
// if Assigned(CertContext) then
|
|
// begin
|
|
// // 발급자 정보
|
|
// CertNameToStr(CERT_X500_NAME_STR, @CertContext^.pCertInfo^.Issuer,
|
|
// CERT_NAME_SIMPLE_DISPLAY_TYPE, IssuerName, SizeOf(IssuerName));
|
|
//
|
|
// // 서명자 정보
|
|
// CertNameToStr(CERT_X500_NAME_STR, @CertContext^.pCertInfo^.Subject,
|
|
// CERT_NAME_SIMPLE_DISPLAY_TYPE, SubjectName, SizeOf(SubjectName));
|
|
//
|
|
// Result := Format('발급자: %s' + sLineBreak + '서명자: %s', [IssuerName, SubjectName]);
|
|
// end;
|
|
// finally
|
|
// FreeMem(SignerInfo);
|
|
// if Assigned(CertContext) then
|
|
// CertFreeCertificateContext(CertContext);
|
|
// if hStore <> nil then
|
|
// CertCloseStore(hStore, 0);
|
|
// if hMsg <> nil then
|
|
// CryptMsgClose(hMsg);
|
|
// end;
|
|
//end;
|
|
|
|
end.
|