UNPKG

authenticode

Version:

Get authenticode information from Windows runnables

75 lines (63 loc) 2.3 kB
import { promisify } from 'util' import { execFile } from 'child_process' // https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.signaturestatus export enum SignatureStatus { Valid = 0, UnknownError = 1, NotSigned = 2, HashMismatch = 3, NotTrusted = 4, NotSupportedFileFormat = 5, Incompatible = 6, } export enum SignatureType { None = 0, Authenticode = 1, Catalog = 2, } // https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509certificate2?redirectedfrom=MSDN&view=netcore-3.1 export interface SignerCertificate { Subject: string } // https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.signature export interface BaseSignature { IsOSBinary: unknown Path: string SignatureType: SignatureType SignerCertificate: unknown Status: SignatureStatus StatusMessage: string TimeStamperCertificate: unknown } const statusWithSignature = [SignatureStatus.Valid, SignatureStatus.HashMismatch, SignatureStatus.NotTrusted] as const export interface PresentSignature extends BaseSignature { Status: typeof statusWithSignature[number] SignerCertificate: SignerCertificate } export type Signature = BaseSignature | PresentSignature export interface SignatureSummary { status: string type: string subject: string | null } export async function getAuthenticode(path: string): Promise<Signature> { const escapedPath = path.replace('"', '`"') const command = `Get-AuthenticodeSignature "${escapedPath}" | ConvertTo-Json -Compress` const encodedCommand = Buffer.from(command, 'utf16le').toString('base64') const { stdout } = await promisify(execFile)('powershell.exe', [ '-NoProfile', '-EncodedCommand', encodedCommand ]) return JSON.parse(stdout) } function signatureIsPresent(signature: Signature): signature is PresentSignature { return (statusWithSignature as readonly SignatureStatus[]).includes(signature.Status) } export function summary(signature: Signature): SignatureSummary { return { status: SignatureStatus[signature.Status] ?? String(signature.Status), type: SignatureType[signature.SignatureType] ?? String(signature.SignatureType), subject: signatureIsPresent(signature) ? signature.SignerCertificate.Subject : null, } }