Version 33 (modified by Samuli Seppänen, 3 years ago) (diff)

Update tap-windows6 cross-signing documentation


Generic build instructions for tap-windows6 are available in it's Git repo. This page contains additional information that is more generic and not really suitable for inclusion in the main documentation.

Generic requirements

Getting the Authenticode signatures right so that all Windows versions detect them can be quite tricky. This seems to be particularly true for kernel-mode driver packages. The Authenticode signatures have a few requirements:

  1. The Certificate path needs to be complete. This can be achieved by including cross-certificate of your CA (e.g. Digicert) in the signed files. At least for Digicert non-EV and EV code-signing certificates have different CAs.
  2. The signature needs to be timestamped, or the driver will stop functioning when the code-signing certificate expires.

It is not clear if signtool's digest algorithm (/fd SHA|SHA256) affects the acceptability of the signature in Windows 7 and beyond, or if the only important thing is the hash algorithm of the actual certificate.

Cross-signing is possible for Windows 7/8/8.1/Server 2012r2 as long as the certification authority's cross-certificate is valid. Beyond that point an actual Microsoft signature is required in all drivers. Windows 10 already requires these Microsoft signatures - they're called attestation signatures in MS jargon. These signatures can be created in Windows Dev Center once you've cleared all the bureaucratic obstacles like signing in to development programs and registering your EV hardware token with your account.

Building with support for Windows Vista

NOTE: It is generally a bad idea to support Windows Vista. But if you must, please look here.

Building and signing for Windows 7/8/8.1/Server 2012r2

Any relatively recent Windows 7 installation supports SHA2 Authenticode signatures. This means that the laborious and fragile dual-signature process can be avoided. You only need the EV SHA2 kernel-mode code-signing certificate, which probably comes in the form of a dongle that integrates with Windows certificate store. The tap-windows6 installer may optionally signed with a different, non-EV SHA2 code-signing certificate.

The prequisites for cross-signing:

  • On build computer
    • tap-windows6 source directory is up-to-date
    • Enterprise Windows Drive Kit ISO image is installed and mounted as a system drive
    • tap-windows6 build system is configured properly (mostly file paths)
    • A user- or kernel mode authenticode certificate is present for signing the tap-windows6 installer
  • On signing computer
    • An EV token is visible in the Windows Certificate Store
    • Sign-Tap6 source directory is up-to-date
    • A correct cross-certificate from your CA is installed into the sign-tap6 directory
    • Sign-Tap6 is configured properly
  • Your workstation
    • You are able to transfer files (e.g. via SSH) from and to the build and signing computers

It is also assumed that all Windows commands are executed from within a Powershell session. The signing process is as follows

On build computer

$ cd tap-windows6
$ python -c -b

On workstation

Copy the tap6.tar.gz from the build computer to the signing computer.

On signing computer

$ cd sign-tap6
$ tar -zxf tap6.tar.gz
$ Sign-Tap6.ps1 -SourceDir tap6 -Force
$ Move-Item tap6 tap6-signed
$ tar -zcf tap6-signed.tar.gz tap6-signed

The EV dongle will probably prompt you twice per architecture (x86, x64, arm64) as it signs the catalog file and tapinstall.exe for each. Note that the -Force switch is required or the file hashes in the .cat files will be incorrect and the driver will not install.

On workstation

Copy tap6-signed.tar.gz from signing computer to the build computer for packaging.

On build computer

Useful commands

Installing certificates

Installing a PFX file to the Currentuser certificate store using Powershell:

Import-PfxCertificate –FilePath <path-to-pfx> cert:\CurrentUser\My -Password (ConvertTo-SecureString -String <pfx-password> -Force –AsPlainText)

If you're not accustomed to Powershell you can just use mmc.exe and the certificate snap-ins to install the certificate.

Querying the certificate store

To list all certificates in Currentuser\My store using Powershell:

Get-ChildItem cert:\CurrentUser\My

Or alternatively:

Set-Location cert:\CurrentUser\My

The dir command is just an alias for Get-ChildItem

Creating catalog files with inf2cat

To create a catalog file for a 32-bit driver:

Inf2Cat.exe /driver:<full-path-to-driver-directory> /os:Vista_x86,Server2008_X86,7_X86

To create a catalog file for a 64-bit driver:

Inf2Cat.exe /driver:<full-path-to-driver-directory> /os:Vista_X64,Server2008_X64,Server2008R2_X64,7_X64 


Inf2Cat.exe /driver:C:\Users\John\tap6\amd64 /os:Vista_X64,Server2008_X64,Server2008R2_X64,7_X64 

NOTE: According to Microsoft Inf2Cat requires a full path to the driver directory.

Signing files with signtool.exe

NOTE: signtool seems to expect absoluete paths to certificate files. Below only the filenames are given for clarity.

Sign a file using a (non-EV) certificate stored in a pfx file. Note that this process is not suitable for EV certificates, which are probably all stored in some sort of dongle and thus only visible through the Windows Certificate Store:

signtool.exe sign /v /ac <cross-certificate> /t <timestamp-url> /f <pfx-file> /p <pfx-password> <file>

Sign a driver with the "best" certificate found from the certificate store. This should work if there is only code-signing certificate in the store:

signtool.exe sign /v /ac <cross-certificate> /t <timestamp-url> /a <file>

Sign a driver using a certificate under Currentuser\My, selecting the right certificate based on a substring of the certificate's subjectname:

signtool.exe sign /v /ac <cross-certificate> /t <timestamp-url> /s My /n <subjectname> <file>

Example of adding two signatures and timestamps. This requires a relatively recent signtool.exe (e.g. from Windows Kit 10):

# Create primary (SHA1) signature (certificate in a pfx file)
signtool.exe sign /v /f digicert-sha1.pfx /p <pfx-password> /ac digicert-assured-id.crt /t /fd SHA1 tap6/amd64/

# Add secondary (SHA2) signature (certificate in the certificate store)
signtool.exe sign /v /s My /n OpenVPN /ac digicert-high-assurance-ev.crt /as /fd SHA256 tap6/amd64/
signtool.exe timestamp /tr /td SHA256 /tp 1 tap6/amd64/

Signing a file (e.g. the installer) directly with Signtool using a certificate from local PFX file.

signtool.exe sign /v /ac digicert-assured-id.crt /f digicert-user-mode-2019.pfx /p password /t tap-windows-9.22.1-I601.exe

Validating signatures

Verifying the Authenticode signature of a file using Powershell:

Get-AuthenticodeSignature <path-to-file>

Note that even if the above command says that the file's certificate is valid, there is absolutely no guarantee that various Windows versions will accept it. It is unclear whether the Cmdlet checks the entire certificate path or not: it does hang for long periods of time occasionally doing something.

Using signtool.exe to verify a driver's signature probably gives more reliable results than the Get-AuthenticodeSignature Cmdlet:

signtool.exe verify /v /kp /c <drivername>.cat <drivername>.sys

Signatures can also be validated by looking at "File properties" of the file. The publisher should show up correctly in some places (not necessarily all), there should be a timestamp counter-certificate, and an unbroken certification path should be present.

External links

General information

Practical guides