Skip to content

Check the signature of a file using the WinVerifyTrust API

License

Notifications You must be signed in to change notification settings

xan105/node-win-verify-trust

Repository files navigation

About

Check the signature of a file using the WinVerifyTrust API.
Retrieve some certificate information.

📦 Scoped @xan105 packages are for my own personal use but feel free to use them.

Example

Dead simple:

import { isSigned } from "@xan105/win-verify-trust";

const trusted = await isSigned("/path/to/file");
console.log(trusted) //boolean

Verbose:

import { verifyTrust } from "@xan105/win-verify-trust";

const { trusted, message } = await verifyTrust("/path/to/file");
console.log(trusted, message) 
//true
//"The file is signed and the signature was verified"

Once you know a file is signed and the signature was verified.
You may want to check some info of the cert:

import { getCertificate } from "@xan105/win-verify-trust";

const certificate = await getCertificate("steam_api64.dll");
console.log(certificate) 
/*
{
  signer: {
    issuer: 'DigiCert SHA2 Assured ID Code Signing CA',
    subject: 'Valve',
    serialNumber: '054f466ceccbe9d6bee81f5435e64d47',
    digestAlgo: 'sha1'
  },
  timestamp: {
    issuer: 'Symantec Time Stamping Services CA - G2',
    subject: 'Symantec Time Stamping Services Signer - G4',
    serialNumber: '0ecff438c8febf356e04d86a981b1a50',
    digestAlgo: 'sha1'
  }
}
*/

💡 You can pass an optional arg to isSigned()
to also check that the cert was signed for the specified signer subject:

import { isSigned } from "@xan105/win-verify-trust";

const trusted = await isSigned("steam_api64.dll", "valve");
console.log(trusted) //boolean

Installation

npm install @xan105/win-verify-trust

Force compiling:

npm install @xan105/win-verify-trust --build-from-source

You will need C/C++ build tools and Python 3.x (node-gyp) to build this module.
🚀 x86, x64 and arm64 prebuilt binary provided.

API

⚠️ This module is only available as an ECMAScript module (ESM).

Named export

verifyTrust(filePath: string): Promise<object>

Performs a trust verification action on the specified file using the WinVerifyTrust API.

Return value

Returns an object as

{
  trusted: boolean,
  message: string
}

Where trusted indicates if the file is signed and the signature was verified.
And message the details of the trust status (verbose).

eg: "No signature was present in the subject"

Remarks

❌ This function will throw if the target file doesn't exist, or file ext isn't allowed, or it timeout.
⚠️ Allowed ext are: ".exe", ".cab", ".dll", ".ocx", ".msi", ".msix", ".xpi", ".ps1".

getCertificate(filePath: string): Promise<object>

Retrieve some certificate information.
Once you know a file is signed and the signature was verified after having used verifyTrust() you may want to check some certificate information.

Return value

Returns an object as

{
  programName?: string,
  publisherLink?: string,
  infoLink?: string,
  signer: {
    issuer?: string,
    subject?: string,
    serialNumber?: string,
    digestAlgo?: string
  },
  timestamp?: {
    issuer?: string,
    subject?: string,
    serialNumber?: string,
    digestAlgo?: string
  }
}

Where signer contains information from the signer certificate and timestamp from the timestamp certificate.

programName is the program name, publisherLink and infoLink are publisher information.

Remarks

❌ This function will throw on error.
⚠️ Allowed ext are: ".exe", ".cab", ".dll", ".ocx", ".msi", ".msix", ".xpi", ".ps1".

💡 Invoking this function on an unsigned target will result in an ETIMEOUT error. You should use verifyTrust() first.

isSigned(filePath: string, name?: string | null): Promise<boolean>

Check if the specified file is signed and trusted.
Optionally also check that the signer certificate was issued for the specified subject name (case-insensitive).

This is a shorthand of verifyTrust() and getCertificate().
This function doesn't throw.