Blame

a5cd20 Samuli Seppänen 2025-03-19 09:33:21 1
# Introduction 
2
3
Generic build instructions for tap-windows6 [are available](https://github.com/OpenVPN/tap-windows6/blob/master/README.rst) in it's Git repo. This page contains additional information that is more generic and not really suitable for inclusion in the main documentation.
4
5
# Requirements
6
7
Getting the [Authenticode signatures](https://msdn.microsoft.com/en-us/library/windows/hardware/ff686697%28v=vs.85%29.aspx) 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:
8
9
1. The Certificate path needs to be complete. This can be achieved by including [cross-certificate of your CA](https://msdn.microsoft.com/en-us/library/windows/hardware/dn170454%28v=vs.85%29.aspx) (e.g. Digicert) in the signed files. At least for Digicert non-EV and EV code-signing certificates have different CAs.
10
1. The signature needs to be timestamped, or the driver will stop functioning when the code-signing certificate expires.
11
12
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.
13
14
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](https://docs.microsoft.com/en-us/windows-hardware/drivers/dashboard/attestation-signing-a-kernel-driver-for-public-release) in MS jargon. These signatures can be created in [Windows Dev Center](https://developer.microsoft.com/en-us/windows) once you've cleared all the bureaucratic obstacles like signing in to development programs and registering your EV hardware token with your account.
15
16
Note that while it is technically possible to put two signatures in one driver (attestation signed + cross-signed), the resulting driver will not install cleanly.
17
18
Here are the general prequisites for building and signing, regardless of signature type:
19
20
* On build computer
21
* [tap-windows6](https://github.com/OpenVPN/tap-windows6) source directory is up-to-date
22
* [Enterprise Windows Drive Kit](https://docs.microsoft.com/en-us/windows-hardware/drivers/develop/using-the-enterprise-wdk) ISO image is installed and mounted as a system drive
23
* tap-windows6 build system is configured properly (paths.py etc.)
24
* Clone [Windows-driver-samples](https://github.com/Microsoft/Windows-driver-samples/)
25
* Optionally copy the "setup\devcon" directory to the tap-windows6 directory
26
* On signing computer
27
* An EV token is visible in the Windows Certificate Store
28
* A correct cross-certificate from your CA is installed into the tap-windows6 directory
29
* sign\Sign-Tap6.conf.ps1 is configured properly
30
31
On top of the generic requirements listed above there are a few extra requirements when doing attestation signing for Windows 10:
32
33
* You need to register your EV dongle with your organization's account in the Windows Dev Center ([direct link](https://developer.microsoft.com/en-us/dashboard/account/managecertificates)).
34
* INF file syntax needs to be valid, as MS backend servers will check it at submission time. Use the latest version of !InfVerif (see footer in Hardware Dev Center) to validate the syntax before submission.
35
36
In the documentation below it is assumed that all Windows commands are executed from within a Powershell session.
37
38
# Setting up the SMB share
39
40
If the building and signing computers are separate you are *strongly encouraged* to share the build directory on the build computer with the signing computer, e.g. using SMB); this removes the need for doing error-prone file copying, archive extraction, etc. In the instructions below it is assumed that this is the case.
41
42
You can create new shares on the build computer in various ways. Here's an example on how to do it with Puppet using Powershell DSC resources:
43
44
```
45
dsc_windowsfeature { 'File server':
46
dsc_ensure => 'present',
47
dsc_name => 'FS-FileServer',
48
}
49
50
dsc_xsmbshare { 'tap-windows6-build-directory':
51
dsc_ensure => 'present',
52
dsc_name => 'tap6build',
53
dsc_description => 'tap-windows6 build directory',
54
dsc_path => 'C:\\Users\\build\\opt\\tap-windows6',
55
dsc_folderenumerationmode => 'AccessBased',
56
dsc_fullaccess => 'tapbuilder\build',
57
}
58
```
59
60
This code can be mapped almost 1:1 to Powershell DSC. Alternatively you can use raw Powershell commands [Add-Windowsfeature](https://ss64.com/ps/add-windowsfeature.html) and [New-Smbshare](https://docs.microsoft.com/en-us/powershell/module/smbshare/new-smbshare?view=win10-ps) to do the same. Or just create the share via Windows GUI somehow. Remember to open port 445 in the firewall.
61
62
Once the share is up, mount it on a Powershell session:
63
64
```
65
$ net use W: \\tapbuilder.example.org\tap6build /user:build 'password-here'
66
```
67
68
Note that this mount is session-specific, so you need to do it from the session you use to sign the files from.
69
70
# Building
71
72
The building and signing process is automated to a large degree and documented in detail in tap-windows6's [README.rst file](https://github.com/OpenVPN/tap-windows6/blob/master/README.rst). The instructions work equally well in two scenarios:
73
74
* A single computer is use to build and sign
75
* Build and signing computers are separate, but the build directory is shared with SMB
76
77
If tap-windows6 build directory is shared via SMB you will get warnings about running scripts from the Internet. Unfortunately it is not possible to make this problem go away, even with the [Unblock-File](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/unblock-file?view=powershell-6) !CmdLet when working with SMB shares, unless you modify the global Powershell execution policy with [Set-ExecutionPolicy](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy) !CmdLet.
78
79
It is generally a bad idea to support Windows Vista. But if you must, please look [here](/SigningForWindowsVista).
80
81
# Hints
82
83
## Modifying the Visual Studio project files
84
85
Many tap-windows6 build settings come from the Visual studio project file, src\tap-windows6.vcxproj. That file is generated by buildtap.py from src\tap-windows6.vcxproj.in.
86
87
There does not seem to be any easily available reference for vcxproj files. This means that the safest and possibly the only realistic way to modify them is by using Visual Studio itself. The Visual Studio + WDK installation process is fairly well documented [here](https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk), but for sake of completeness the requirements are:
88
89
* Visual Studio 2019 Community
90
* Install workload "Desktop Development with C++"
91
* Install component "Windows 10 SDK"
92
* Windows Driver Kit (WDK)
93
* Version must match that of "Windows 10 SDK"
94
* Copy of tap-windows6.vcxproj under src
95
* This file can be generated elsewhere with buildtap.py and copied over to the Visual Studio computer
96
97
After you've installed the above components launch Visual Studio 2019 and open tap-windows6.vcxproj file. Then you can modify the project properties as you want using the GUI. Your changes will not affect tap-windows6.vcxproj, but will create a new file called tap-windows6.vcxproj.user. Its contents look something like this:
98
99
```
100
<?xml version="1.0" encoding="utf-8"?>
101
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
102
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
103
<SignMode>TestSign</SignMode>
104
</PropertyGroup>
105
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
106
<SignMode>Off</SignMode>
107
</PropertyGroup>
108
</Project>
109
```
110
111
Once you've figured out what the GUI does you can port those changes to tap-windows6.vcxproj.in and they will get applied to all subsequent builds.
112
113
114
## Installing certificates
115
116
Installing a PFX file to the Currentuser certificate store using Powershell:
117
```
118
Import-PfxCertificate –FilePath <path-to-pfx> cert:\CurrentUser\My -Password (ConvertTo-SecureString -String <pfx-password> -Force –AsPlainText)
119
```
120
If you're not accustomed to Powershell you can just use *mmc.exe* and the certificate snap-ins to install the certificate.
121
122
## Querying the certificate store
123
124
To list all certificates in *Currentuser\My* store using Powershell:
125
```
126
Get-ChildItem cert:\CurrentUser\My
127
```
128
Or alternatively:
129
```
130
Set-Location cert:\CurrentUser\My
131
dir
132
```
133
The *dir* command is just an alias for *Get-!ChildItem*
134
135
## Creating catalog files with inf2cat
136
137
To create a catalog file for a 32-bit driver:
138
```
139
Inf2Cat.exe /driver:<full-path-to-driver-directory> /os:Vista_x86,Server2008_X86,7_X86
140
```
141
To create a catalog file for a 64-bit driver:
142
```
143
Inf2Cat.exe /driver:<full-path-to-driver-directory> /os:Vista_X64,Server2008_X64,Server2008R2_X64,7_X64
144
```
145
Example:
146
```
147
Inf2Cat.exe /driver:C:\Users\John\tap6\amd64 /os:Vista_X64,Server2008_X64,Server2008R2_X64,7_X64
148
```
149
150
**NOTE:** According to Microsoft Inf2Cat requires a full path to the driver directory.
151
152
## Signing files with signtool.exe
153
154
**NOTE:** signtool seems to expect absoluete paths to certificate files. Below only the filenames are given for clarity.
155
156
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:
157
```
158
signtool.exe sign /v /ac <cross-certificate> /t <timestamp-url> /f <pfx-file> /p <pfx-password> <file>
159
```
160
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:
161
```
162
signtool.exe sign /v /ac <cross-certificate> /t <timestamp-url> /a <file>
163
```
164
Sign a driver using a certificate under *Currentuser\My*, selecting the right certificate based on a substring of the certificate's subjectname:
165
```
166
signtool.exe sign /v /ac <cross-certificate> /t <timestamp-url> /s My /n <subjectname> <file>
167
```
168
Example of adding two signatures and timestamps. This requires a relatively recent signtool.exe (e.g. from Windows Kit 10):
169
```
170
# Create primary (SHA1) signature (certificate in a pfx file)
171
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
172
173
# Add secondary (SHA2) signature (certificate in the certificate store)
174
signtool.exe sign /v /s My /n OpenVPN /ac digicert-high-assurance-ev.crt /as /fd SHA256 tap6/amd64/tap0901.cat
175
signtool.exe timestamp /tr http://timestamp.digicert.com /td SHA256 /tp 1 tap6/amd64/tap0901.cat
176
```
177
178
Signing a file (e.g. the installer) directly with Signtool using a certificate from local PFX file.
179
```
180
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
181
```
182
183
## Validating signatures
184
185
Verifying the Authenticode signature of a file using Powershell:
186
187
```
188
Get-AuthenticodeSignature <path-to-file>
189
```
190
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*.
191
192
Using signtool.exe to verify a driver's signature probably gives more reliable results than the Get-!AuthenticodeSignature Cmdlet:
193
```
194
signtool.exe verify /v /kp /c <drivername>.cat <drivername>.sys
195
```
196
197
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.
198
199
# External links
200
201
**General information**
456ccd Samuli Seppänen 2025-03-19 09:49:08 202
* [Questions and Answers: Windows 10 Driver Signing](http://www.osr.com/blog/2015/07/24/questions-answers-windows-10-driver-signing/)
a5cd20 Samuli Seppänen 2025-03-19 09:33:21 203
* [Attestation signing a kernel driver for public release](https://docs.microsoft.com/en-us/windows-hardware/drivers/dashboard/attestation-signing-a-kernel-driver-for-public-release)
456ccd Samuli Seppänen 2025-03-19 09:49:08 204
* [Practical Windows Code and Driver Signing](http://www.davidegrayson.com/signing/)
a5cd20 Samuli Seppänen 2025-03-19 09:33:21 205
* [Authenticode Digital Signatures](https://msdn.microsoft.com/en-us/library/windows/hardware/ff686697%28v=vs.85%29.aspx)
206
* [Cross-Certificates for Kernel Mode Code Signing](https://msdn.microsoft.com/en-us/library/windows/hardware/dn170454%28v=vs.85%29.aspx)
207
* [Bug 1079858 - Deal with deprecation of SHA1 (SHA-1) Authenticode signatures for Windows signing](https://bugzilla.mozilla.org/show_bug.cgi?id=1079858) (from Mozilla.org)
208
**Practical guides**
209
* [Steps for Signing a Device Driver Package](https://technet.microsoft.com/en-us/library/dd919238%28v=ws.10%29.aspx)
210
* [Signed Driver Walkthrough](https://github.com/pbatard/libwdi/wiki/Signed-Driver-Walkthrough) (from libwdi project)
a03235 Samuli Seppänen 2025-03-19 09:34:05 211
* [Microsoft's Kernel-Mode Code Signing Walkthrough](http://www.microsoft.com/whdc/driver/install/drvsign/kmcs-walkthrough.mspx) (in doc format)
a5cd20 Samuli Seppänen 2025-03-19 09:33:21 212
**References**
213
* [Inf2Cat](https://msdn.microsoft.com/en-us/library/windows/hardware/ff553618%28v=vs.85%29.aspx)
214
* [Signtool](https://msdn.microsoft.com/en-us/library/windows/desktop/aa387764%28v=vs.85%29.aspx)
215
* [Get-AuthenticodeSignature](https://technet.microsoft.com/en-us/library/hh849805.aspx)
216
* [Set-AuthenticodeSignature](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-authenticodesignature?view=powershell-6)
217
* [Import-PfxCertificate](https://technet.microsoft.com/en-us/library/hh848625.aspx)