Verify command

The verify command checks the validity of signed files, ensuring their integrity and confirming that the signatures are trusted. It can verify multiple files efficiently with wildcard support.

Usage

SignotaurTool.exe verify [options] [files]

Files Parameter

  • A list of file paths to verify. You can specify individual file paths or use wildcards to match multiple files. This parameter supports the following wildcard patterns:

    • *: Matches zero or more characters within a file name. For example, *.exe will match all executable files in the specified directory.
    • ?: Matches a single character. For instance, file?.dll will match file1.dll, file2.dll, but not file12.dll.
    • **: Indicates a recursive search across all subdirectories. For example, **/*.exe will match all .exe files found in the current directory and all its subdirectories.
    • !: Identifies an exclude pattern. This must be at the start of the pattern. It must be used in conjunction with a normal include pattern. For instance, the two patterns *.dll and !*.Test.dll will match all .dll files found in the current directory excluded all test dlls, that is file1.dll, file2.dll, but not file1.Test.dll.
  • Examples:

    • *.exe: Matches all executable files in the specified directory.
    • C:\Projects\**\*.dll: Matches all dynamic link library files in the C:\Projects directory and any of its subdirectories.
    • C:\MyFiles\file?.exe: Matches any executable files that start with "file" followed by a single character.
    • !*.pdb: Matches all debug files in the specified directory from the current match.
  • Notes:

    • Ensure that the directory paths are correctly specified, as the function will attempt to find matching files based on the directory provided in conjunction with the wildcards.
    • For verifying a large number of files, you can use the --file-list option to specify the path to a file containing the list of file paths.

ClickOnce and VSTO Content Pattern Filtering

When verifying ClickOnce (.application) or VSTO (.vsto) files, you can specify which dependency files should be verified using content patterns. Use a colon (:) to separate the root file pattern from the content patterns. See ClickOnce and VSTO Verification.

Options

  • --fl, --file-list <FileName>

    Specifies the path to a file containing a list of file paths to verify. Each line in the file should contain one file path. The tool will interpret each path just as it does for the Files parameter. For ClickOnce/VSTO files, you can use the content pattern syntax (:) to filter dependencies (e.g., MyApp.application:*.dll:*.exe).

  • -b, --base-directory <Directory>

    Sets the base directory for resolving relative file paths.

  • --ir, --ignore-untrusted-root

    Ignores untrusted root errors when verifying a file signed with a self-signed certificate. Use this option with caution as it bypasses trust validation for the root certificate.

  • -m, --max-degree-of-parallelism <MDOP>

    Specifies the maximum number of concurrent file verification operations. Default is 4. A higher value can speed up processing for large file sets.

  • --cf, --continue-on-fail

    Continues verifying subsequent files even if an error occurs while verifying a file. This option is useful for batch verification scenarios.

  • --encoding <Encoding>

    Specifies the output encoding. Set to one of UTF8, UTF16, OEMCodePage or CodePage### where ### is the number of the code page to use. Defaults to UTF8.

  • --theme <Theme>

    Specifies the console colour theme. Options are: General (default, suitable for most consoles), Dark (optimized for dark backgrounds), Light (optimized for light backgrounds), or None (disables colours). The default is General.

  • --nc, --no-colour, --no-color

    Disables coloured output entirely. This is useful for CI/CD environments, log files, or systems that don't support ANSI colour codes. Alternatively, you can set the NO_COLOR environment variable to any non-empty value to achieve the same effect (following the no-color.org standard).

  • `--nb

    Hides the banner in the output, which may be useful for scripting or logging purposes where you want a clean output.

  • -v, --verbose

    Enables verbose logging for the verification process, providing detailed output, which can be useful for debugging.

  • --rm, --revocation-mode <Mode>

    Specify the revocation check mode when verifying the certificate chain. By default, the verification process may try to check the certificate status against online Certificate Revocation Lists (CRLs) or Online Certificate Status Protocol (OCSP) responders. If these URLs are inaccessible or slow to respond — possibly due to firewall restrictions, then changing the revocation mode can improve verification performance. The parameter accepts the following <Mode> values:

    • Online (default): Performs live revocation checks.
    • Offline: Skips online checks and uses cached data.
    • NoCheck: Disables all revocation validation (not recommended for production).
  • --sl|--strict-lifetime

    Strictly enforce signature validity to the certificate’s validity period when a timestamp is present.

  • --uf, --unsupported-file-types <Action>

    Controls what happens when a file type is not recognised during verification. Known file types (Authenticode, CMS, NuGet, VSIX, ClickOnce, RDP) are always verified with the correct method automatically.

    • Fail (default): Error on unrecognised file types.
    • Ignore: Skip unrecognised files.
    • UseCMSSigning: Verify unrecognised files as CMS/PKCS#7.
    • UseAuthenticodeSigning: Verify unrecognised files as Authenticode.

Examples

  1. Verify files with default settings:

    SignotaurTool.exe verify file1.exe file2.dll
    
  2. Verify files with a file list:

    SignotaurTool.exe verify --fl filelist.txt
    
  3. Verify a CMS-signed .mobileconfig profile (automatically detected):

    SignotaurTool.exe verify profile.mobileconfig
    
  4. Verify a signed NuGet package (automatically detected):

    SignotaurTool.exe verify MyPackage.1.0.0.nupkg
    
  5. Verify a signed Visual Studio extension (automatically detected):

    SignotaurTool.exe verify MyExtension.vsix
    
  6. Verify a signed Remote Desktop connection file (automatically detected):

    SignotaurTool.exe verify connection.rdp
    
  7. Verify a CMS-signed file with a non-standard extension:

    SignotaurTool.exe verify --uf UseCMSSigning config.xml
    
  8. Verify a CMS-signed file with a self-signed certificate:

    SignotaurTool.exe verify --ignore-untrusted-root profile.mobileconfig
    

Supported File Types

Authenticode

The verify command supports Authenticode verification of the following file types: .appx, .appxbundle, .cab, .cat, .cdxml, .dll, .eappx, .eappxbundle, .emsix, .emsixbundle, .exe, .msi, .msix, .msixbundle, .msm, .msp, .mst, .ocx, .ps1, .ps1xml, .psd1, .psm1, .stl, .sys, .vbs, .vxd, .winmd. Additional PE file types may also be verified automatically.

CMS/PKCS#7

The following file types are automatically verified using CMS/PKCS#7: .mobileconfig (Apple configuration profiles), .mobileprovision (Apple/iOS provisioning profiles), .provisionprofile (macOS provisioning profiles).

Unrecognised CMS-signed files can be verified by specifying --uf UseCMSSigning.

NuGet Packages

NuGet packages (.nupkg) are automatically verified using NuGet-specific signature verification. This checks the CMS signature integrity, package hash, signing certificate, timestamp, and certificate chain.

VSIX (Visual Studio Extensions)

VSIX packages (.vsix) are automatically verified using OPC XML digital signature verification. This validates the package signature, per-part digests, signing certificate, timestamp (if present), and certificate chain.

RDP Files

.rdp files signed by Signotaur or by Microsoft's rdpsign.exe are automatically verified. The verifier strips Microsoft's 12-byte header, decodes the embedded CMS signature, recomputes the canonical scope bytes from the file's current content, and checks the CMS signature, certificate chain, and (optional) timestamp. Tampering with any of the fields listed in signscope:s: causes verification to fail with BadDigest. See RDP file signing for more detail.

ClickOnce or VSTO Verification

See ClickOnce and VSTO Signing for detailed information about content filtering and application-specific options. If the input includes a .application file (ClickOnce deployment manifest), or a .vsto file (Visual Studio Tools for Office add-in manifest), the verify command automatically detects and verifies all related application files and manifests. See ClickOnce and VSTO Signing.

Exit Codes

The following exit codes indicate the result of the operation performed by SignotaurTool.exe verify. The most common failures are 16 NoSignature (the file is unsigned), 20 UntrustedRoot (chain not anchored to a trusted root — suppress with --ignore-untrusted-root), 48 BadDigest (the signature does not match the file contents), and 21 CertificateExpired / 23 CertificateRevoked. Codes 16–58 reach the verify command via the Windows WinVerifyTrust API for Authenticode files (.exe, .dll, .msi, .cat, etc.) and via the managed verifiers for CMS, NuGet, VSIX, and RDP files; any HRESULT the Windows API can return is mappable here.

  • 0 (Success): All files were verified successfully.
  • 1 (NotFound): One or more specified files were not found (ERROR_FILE_NOT_FOUND).
  • 2 (Aborted): The verification was cancelled (E_ABORT).
  • 3 (AccessDenied): A file could not be opened for reading (E_ACCESSDENIED).
  • 4 (Failure): General failure — for example, an unsupported file type when no fallback action is configured, or an unspecified error (E_FAIL).
  • 5 (InvalidHandle): An invalid handle was used by the underlying cryptographic API (E_HANDLE).
  • 6 (InvalidArgument): At least one input file must be supplied (E_INVALIDARG).
  • 7 (NoInterface): A required cryptographic interface is not supported (E_NOINTERFACE).
  • 8 (NotImplemented): A required feature is not implemented by the underlying cryptographic provider (E_NOTIMPL).
  • 9 (OutOfMemory): The system could not allocate memory for verification (E_OUTOFMEMORY).
  • 10 (InvalidPointer): An invalid memory pointer was used by the underlying cryptographic API (E_POINTER).
  • 11 (UnexpectedFailure): A catastrophic failure occurred in the underlying cryptographic provider (E_UNEXPECTED).
  • 12 (AdditionalCertNotFound): A certificate referenced by the signature could not be located while building the chain (CRYPT_E_NOT_FOUND).
  • 13 (FileListError): An error occurred while processing a --file-list file.
  • 14 (SharingViolation): An input file is locked by another process (ERROR_SHARING_VIOLATION).
  • 15 (UnknownResult): The cryptographic API returned an HRESULT that the client does not recognise.
  • 16 (NoSignature): The file is not signed (TRUST_E_NOSIGNATURE).
  • 17 (ExplicitDistrust): The signature is present but the certificate is explicitly distrusted (TRUST_E_EXPLICIT_DISTRUST).
  • 18 (SubjectNotTrusted): The signing subject is not trusted for the requested action (TRUST_E_SUBJECT_NOT_TRUSTED).
  • 19 (InvalidPolicy): The certificate policy is invalid or not allowed (CERT_E_INVALID_POLICY).
  • 20 (UntrustedRoot): The certificate chain terminates in a root that is not trusted (CERT_E_UNTRUSTEDROOT). Suppress with --ignore-untrusted-root.
  • 21 (CertificateExpired): The signing certificate has expired (CERT_E_EXPIRED).
  • 22 (Malformed): The certificate is malformed (CERT_E_MALFORMED).
  • 23 (CertificateRevoked): The certificate has been revoked (CERT_E_REVOKED).
  • 24 (FileError): A file error occurred while reading the signed file (CRYPT_E_FILE_ERROR).
  • 25 (ProviderUnknown): Unknown trust provider (TRUST_E_PROVIDER_UNKNOWN).
  • 26 (SubjectFormUnknown): Unknown trust subject form (TRUST_E_SUBJECT_FORM_UNKNOWN).
  • 27 (ActionUnknown): Unknown trust action (TRUST_E_ACTION_UNKNOWN).
  • 28 (TrustFailure): Generic trust verification failed (TRUST_E_FAIL).
  • 29 (CertificateIssuerChaining): A parent certificate is not correctly issued by a higher authority (CERT_E_ISSUERCHAINING).
  • 30 (CertificateValidityPeriodNesting): Validity periods in the chain do not nest correctly (CERT_E_VALIDITYPERIODNESTING).
  • 31 (CertificateRole): A certificate is being used in an invalid role (CERT_E_ROLE).
  • 32 (CertificatePathLenConst): A path-length constraint in the chain has been exceeded (CERT_E_PATHLENCONST).
  • 33 (CertificateCritical): A certificate has an unrecognised critical extension (CERT_E_CRITICAL).
  • 34 (CertificatePurpose): The certificate is being used for an invalid purpose (CERT_E_PURPOSE).
  • 35 (CertificateUntrustedTestRoot): The chain terminates in an untrusted test root (CERT_E_UNTRUSTEDTESTROOT).
  • 36 (CertificateRevocationFailure): The revocation check could not continue (CERT_E_REVOCATION_FAILURE).
  • 37 (CertificateCNNoMatch): The certificate's common name does not match (CERT_E_CN_NO_MATCH).
  • 38 (CertificateWrongUsage): The certificate is not valid for the requested usage (CERT_E_WRONG_USAGE).
  • 39 (CertificateUntrustedCA): The issuing certificate authority is not trusted (CERT_E_UNTRUSTEDCA).
  • 40 (CertificateInvalidName): The certificate name is invalid (CERT_E_INVALID_NAME).
  • 41 (CertificateChaining): A certificate chain could not be built to a trusted root authority (CERT_E_CHAINING).
  • 42 (SecuritySettings): The cryptographic operation was blocked by security policy or settings (CRYPT_E_SECURITY_SETTINGS).
  • 44 (TrustSystemError): A system-level trust error occurred (TRUST_E_SYSTEM_ERROR).
  • 45 (TrustNoSignerCert): No signer certificate was found in the signature (TRUST_E_NO_SIGNER_CERT).
  • 46 (CannotInstallProvider): The certificate's signature could not be verified (TRUST_E_PROVIDER_UNKNOWN_ACTION).
  • 47 (TimeStampError): An inline timestamp signature or its certificate is invalid (TRUST_E_TIME_STAMP).
  • 48 (BadDigest): The signature digest did not match the file contents (TRUST_E_BAD_DIGEST).
  • 49 (InvalidBasicConstraints): A certificate's basic constraints extension is invalid or missing (TRUST_E_BASIC_CONSTRAINTS).
  • 50 (CounterSignerError): The countersignature or timestamp signature could not be verified (TRUST_E_COUNTER_SIGNER).
  • 51 (NoRevocationCheck): The revocation function was unable to check revocation (CRYPT_E_NO_REVOCATION_CHECK).
  • 52 (RevocationOffline): The revocation server was offline (CRYPT_E_REVOCATION_OFFLINE).
  • 54 (BadFormat): The file is not in the expected format for its detected type (ERROR_BAD_FORMAT).
  • 55 (BadAsn1Tag): The signature contained an invalid ASN.1 tag (CRYPT_E_ASN1_BADTAG).
  • 56 (BadEncode): The signature could not be decoded (CRYPT_E_BAD_ENCODE).
  • 57 (BadMessage): The signature is not a valid cryptographic message (CRYPT_E_BAD_MSG).
  • 58 (BadAsn1Corrupt): The signature contained corrupt ASN.1 data (CRYPT_E_ASN1_CORRUPT).

Typically a more specific message will be displayed before an error exit code is returned.