wiki:BuildingTapWindows6

Version 14 (modified by Samuli Seppänen, 8 years ago) (diff)

--

Introduction

The 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.

Codesigning

Basic process

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. In practice tap-windows6 driver needs two signatures:

  1. Primary signature created with a normal (non-EV) SHA1 code-signing certificate. This is required by Windows Vista, which does not seem to understand SHA2 signatures at all, and which can apparently only handle one signature. Very outdated Windows 7 installations may have similar issues.
  2. Secondary signature created with an Extended Validation (EV) SHA2 code-signing certificate. An EV certificate is required on Windows 10 for kernel drivers.

There are two additional requirements for both of these signatures:

  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 validity of the signature, or if the only important thing is the hash algorithm of the actual certificate. When the cross-certificates expires (in 5-15 years), an actual Microsoft signature is required in all drivers. This means that all drivers need to be submitted to Microsoft for signing (see links below for more information).

Due to the above, the build environment for tap-windows6 needs to setup just right:

  • Build computer should have WinDDK 7600.* installed, because currently buildtap.py does not work on anything newer. Build computer should have a SHA1 code-signing certificate in the certificate store under Currentuser\My
  • Code-signing computer should have Windows Kit 10 installed: this kit includes a version of Signtool.exe which supports appending signatures to files. The SHA2 EV code-signing certificate needs to be visible in the certificate store under Currentuser\My.

The actual build procedure is a bit convoluted:

  1. Run buildtap.py on the build computer, signing it with the SHA1 certificate. Make sure to include the correct cross-certificate and to timestamp the signature. Creating the installer (buildtap.py -p) does not make any sense right here.
  2. Copy tap6.tar.gz to the signing computer
  3. Unpack tap6.tar.gz on the signing computer
  4. Append signatures to tapinstall.exe and tap0901.cat files. The Sign-Tap6 tool is a convenient way to do this. Ensure you're using the correct cross-certificate and that you timestamp the signature.
  5. Copy the dual-signed files back to the build computer
  6. Copy the contents of the dual-signed tap6 directory to dist in tap-windows6 build root.
  7. Run buildtap.py again using the same parameters as before, but ensure you do not clean (-c) or build (-b). You should only package (-p) the dist directory into an installer.
  8. Copy the installer to the code-signing computer, and append a signature to it using the EV SHA2 certificate. Right now, this process has not been automated, but the command-line is fairly easy to construct manually by looking at Sign-Tap6.ps1.

If this process sounds complicated, it's because it is. At some point would make sense to adapt buildtap.py to add both signatures automatically, which would simplify the process dramatically. However, that would require porting buildtap.py to Windows Kit 10, which would require a non-trivial amount of work.

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
dir

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 

Example:

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

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 http://timestamp.digicert.com /fd SHA1 tap6/amd64/tap0901.cat

# 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/tap0901.cat
signtool.exe timestamp /tr http://timestamp.digicert.com /td SHA256 /tp 1 tap6/amd64/tap0901.cat

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 tap0901.cat 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.

General information

Practical guides

References