[[TOC(inline, depth=1)]] = Introduction = Generic build instructions for tap-windows6 [https://github.com/OpenVPN/tap-windows6/blob/master/README.rst 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 [https://msdn.microsoft.com/en-us/library/windows/hardware/ff686697%28v=vs.85%29.aspx 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 [https://msdn.microsoft.com/en-us/library/windows/hardware/dn170454%28v=vs.85%29.aspx 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. 1. 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, 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). The build computer should have WinDDK 7600.* installed, because currently buildtap.py does not work on anything newer. = Building with support for Windows Vista = If the driver has to support Windows Vista or very old Windows 7 versions it has to have two signatures: 1. Primary signature created with a normal (non-EV) SHA1 code-signing certificate. The SHA1 signature needs to be the primary as Vista can apparently understand only one signature. 1. 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 also further requirements due to the two signatures: * Build computer should have a SHA1 code-signing certificate in the certificate store under ''Currentuser\My'' or as a PFX file. The primary signature will be created by tap-windows6 build system. * 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/signing procedure in this case is rather convoluted. '''On build computer''' Copy your kernel-mode SHA1 code-signing certificate and the intermediate cross-signing certificate to the ''tap-windows6'' directory. Run ''buildtap.py'' to build and to sign with SHA1 {{{ $ python buildtap.py -b --sign }}} '''NOTE:''' using the "-c" switch will wipe out any pre-built tapinstall.exe's in the ''tapinstall'' directory, so be careful with it. Copy the following files to the ''code-signing computer'': * tap6.tar.gz * 32-bit tapinstall.exe (renamed to tapinstall32.exe) * 64-bit tapinstall.exe (renamed to tapinstall64.exe) '''On code-signing computer''' Clone the [https://github.com/mattock/sign-tap6/ Sign-Tap6] repository. Ensure your SHA2 EV code-signing certificate is visible in the Windows certificate store, and copy the matching cross-certificate to the sign-tap6 directory. All commands except the actual signing should be done from Git Bash or similar. Copy ''tap6.tar.gz'' to the ''sign-tap6'' directory and extract it: {{{ $ tar -zxf tap6.tar.gz }}} Copy tapinstall.exe's to the ''tap6'' directory: {{{ $ cp tapinstall32.exe tap6/i386/tapinstall.exe $ cp tapinstall64.exe tap6/amd64/tapinstall.exe }}} Next append secondary signatures with ''Sign-Tap6.ps1'' in an ''administrator Powershell session''. For example: {{{ $ Sign-Tap6.ps1 -SourceDir tap6 -Append }}} Now wrap the dual-signed files into a tarball (e.g. using Git Bash): {{{ $ tar -zcf tap6-dual-signed.tar.gz tap6 }}} Copy the dual-signed tarball back to the ''build computer''. '''On build computer''' Extract contents of ''tap6-dual-signed.tar.gz'' to the ''tap-windows6'' directory: {{{ $ rm -rf dist tap6 $ tar -zxf tap6-dual-signed.tar.gz $ mv tap6 dist }}} Next you will need to run ''buildtap.py'' using the same parameters as before, except that you must not ''clean'' (-c) or ''build'' (-b). You should only ''package'' (-p) the dist directory into an installer. If you have a user-mode ''SHA2'' certificate available on the ''build computer'', then it is easiest to sign with that, e.g. {{{ $ python buildtap.py -p --sign --certfile= --certpw= --crosscert= --timestamp=http://timestamp.digicert.com --ti=tapinstall }}} Alternatively copy the installer produced by ''buildtap.py'' to the ''code-signing computer'' for the additional signature, as described below. '''On code-signing computer''' Append a signature to the tap-windows--.exe using ''Sign-Tap6.ps1''. Make sure you use 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 [https://github.com/mattock/sign-tap6/ Sign-Tap6.ps1]. If this process sounds complicated, that'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. = Building for Windows 7 and later = 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 build process is somewhat easier than with dual signatures. There are only a couple small differences: * buildtap.py should not use the --sign switch or any of its parameters * The -Append switch must not be used in Sign-Tap6 * '''The -Force switch must be used in Sign-Tap6:''' without it the file hashes in the .cat files will be incorrect and driver will not install. * An older version of signtool.exe can be used on the code-signing computer as appending of signatures is not necessary = Useful commands = == Installing certificates == Installing a PFX file to the Currentuser certificate store using Powershell: {{{ Import-PfxCertificate –FilePath cert:\CurrentUser\My -Password (ConvertTo-SecureString -String -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: /os:Vista_x86,Server2008_X86,7_X86 }}} To create a catalog file for a 64-bit driver: {{{ Inf2Cat.exe /driver: /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 == '''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 /t /f /p }}} 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 /t /a }}} 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 /t /s My /n }}} 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 /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 }}} 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 http://timestamp.digicert.com tap-windows-9.22.1-I601.exe }}} == Validating signatures == Verifying the Authenticode signature of a file using Powershell: {{{ Get-AuthenticodeSignature }}} 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 .cat .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. = External links = '''General information''' * [http://www.osr.com/blog/2015/07/24/questions-answers-windows-10-driver-signing/ Questions and Answers: Windows 10 Driver Signing] * [http://www.davidegrayson.com/signing/ Practical Windows Code and Driver Signing] * [https://msdn.microsoft.com/en-us/library/windows/hardware/ff686697%28v=vs.85%29.aspx Authenticode Digital Signatures] * [https://msdn.microsoft.com/en-us/library/windows/hardware/dn170454%28v=vs.85%29.aspx Cross-Certificates for Kernel Mode Code Signing] * [https://bugzilla.mozilla.org/show_bug.cgi?id=1079858 Bug 1079858 - Deal with deprecation of SHA1 (SHA-1) Authenticode signatures for Windows signing] (from Mozilla.org) '''Practical guides''' * [https://technet.microsoft.com/en-us/library/dd919238%28v=ws.10%29.aspx Steps for Signing a Device Driver Package] * [https://github.com/pbatard/libwdi/wiki/Signed-Driver-Walkthrough Signed Driver Walkthrough] (from libwdi project) * [http://www.microsoft.com/whdc/driver/install/drvsign/kmcs-walkthrough.mspx Microsoft's Kernel-Mode Code Signing Walkthrough] (in doc format) '''References''' * [https://msdn.microsoft.com/en-us/library/windows/hardware/ff553618%28v=vs.85%29.aspx Inf2Cat] * [https://msdn.microsoft.com/en-us/library/windows/desktop/aa387764%28v=vs.85%29.aspx Signtool] * [https://technet.microsoft.com/en-us/library/hh849805.aspx Get-AuthenticodeSignature] * [https://technet.microsoft.com/en-us/library/hh848625.aspx Import-PfxCertificate]