|
# script parameters |
|
param( |
|
[ValidateSet("Sign", "UntrustCertificates")] |
|
[string] $Mode = "Sign", |
|
|
|
[string] $InfFile, |
|
[string] $CommonName = "linux.local", |
|
[switch] $Force |
|
) |
|
|
|
$ErrorActionPreference = "Stop" |
|
|
|
# check if this script is run as administrator |
|
If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) |
|
{ |
|
Write-Error "You are not an Administrator. This script needs to be run by an Adminsitrator!" |
|
} |
|
|
|
# check if InfFile exists |
|
if(-NOT (Test-Path -Path $InfFile)) |
|
{ |
|
Write-Error "$InfFile not found!" |
|
} |
|
|
|
# utility functions |
|
function Step |
|
{ |
|
param([string] $Desc, [System.Management.Automation.ScriptBlock] $Code) |
|
|
|
Write-Output "[*] $Desc"; |
|
Invoke-Command -ScriptBlock $Code |
|
} |
|
|
|
function Get-CertificateThumbprint |
|
{ |
|
param([string] $FilePath) |
|
|
|
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 |
|
$cert.Import($(Resolve-Path $FilePath)) |
|
|
|
return $cert.Thumbprint |
|
} |
|
|
|
|
|
# Get Kits root |
|
try { |
|
$InstalledRoots = Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots" |
|
$WinKits = $InstalledRoots.KitsRoot10 |
|
$ToolsPrefix = "$($WinKits)\bin\10.0.18362.0\x64" |
|
} catch { |
|
Write-Error "Could not locate the Windows Driver Kit. Head to https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk and download the WDK" |
|
} |
|
|
|
function RunKit |
|
{ |
|
param([Parameter(Mandatory=$true)][string] $ToolName, [string[]] $Arguments) |
|
|
|
Write-Output "Running $($ToolsPrefix)\$($ToolName)" |
|
$Proc = Start-Process -FilePath "$($ToolsPrefix)\$($ToolName)" -ArgumentList $Arguments -NoNewWindow -PassThru -Wait |
|
|
|
if ($Proc.ExitCode -NE 0) |
|
{ |
|
Write-Error "Process failed with exit code: $($Proc.ExitCode)" |
|
} |
|
} |
|
|
|
# Script vars |
|
$CatFile = [io.path]::GetFileNameWithoutExtension($InfFile) + ".cat" |
|
$CertFile = [io.path]::GetFileNameWithoutExtension($InfFile) + ".cer" |
|
|
|
# Scripts |
|
function DoSign |
|
{ |
|
# verify that the Inf file contains a "Catalog" entry |
|
if (-NOT (Select-String -Path $InfFile -Pattern "CatalogFile" -CaseSensitive -SimpleMatch -Quiet)) |
|
{ |
|
Write-Error "Could not find the 'CatalogFile' entry inside the INF file! Make sure it points to a certificate with the same Name." |
|
} |
|
|
|
Step -Desc "Create Catalog file" -Code { |
|
New-FileCatalog -Path $InfFile -CatalogFilePath $CatFile -CatalogVersion 2.0 |
|
} |
|
|
|
if (-NOT (Test-Path -Path $CertFile) -OR $Force) |
|
{ |
|
Step -Desc "Create a Test Certificate" -Code { |
|
# see https://docs.microsoft.com/en-us/windows-hardware/drivers/install/creating-test-certificates |
|
# This will create a self-signed certificate and store it in the Personal certificate stora on the local machine. |
|
RunKit -ToolName "makecert.exe" -Arguments "-r -sr LocalMachine -ss My -pe -n CN=$($CommonName) -eku 1.3.6.1.5.5.7.3.3 $CertFile" |
|
} |
|
|
|
Step -Desc "Import the Test Certificate into the Local Computer Trusted Root CAs and Trusted Publishers stores" -Code { |
|
Import-Certificate -FilePath $CertFile -CertStoreLocation Cert:\LocalMachine\Root |
|
Import-Certificate -FilePath $CertFile -CertStoreLocation Cert:\LocalMachine\TrustedPublisher |
|
} |
|
} |
|
else |
|
{ |
|
Write-Output "Certificate already exists. Using $CertFile. If you still want to create a new one, use the -Force option" |
|
} |
|
|
|
Step -Desc "Sign the Catalog with the Test Certificate" -Code { |
|
# see https://docs.microsoft.com/en-us/windows-hardware/drivers/install/test-signing-a-catalog-file |
|
RunKit -ToolName "signtool.exe" -Arguments "sign /v /sm /s My /n $($CommonName) /t http://timestamp.digicert.com $($CatFile)" |
|
} |
|
|
|
Write-Output "Successfully singed the driver and added the certificate to the trusted store." |
|
} |
|
|
|
function DoUntrustCertificates |
|
{ |
|
Step -Desc "Remove the Test Certificate from the Local Computer Trusted Root CAs and Trusted Publishers stores" -Code { |
|
$thumbprint = Get-CertificateThumbprint -FilePath $CertFile |
|
|
|
Remove-Item -Path ("Cert:\LocalMachine\My\$($thumbprint)") |
|
Remove-Item -Path ("Cert:\LocalMachine\Root\$($thumbprint)") |
|
Remove-Item -Path ("Cert:\LocalMachine\TrustedPublisher\$($thumbprint)") |
|
} |
|
|
|
Write-Output "Sucessfully removed all certificates from the trusted certificate stores." |
|
} |
|
|
|
# entry |
|
Write-Output "Selected Mode: $Mode" |
|
|
|
Switch($Mode) |
|
{ |
|
"Sign" { DoSign } |
|
"UntrustCertificates" { DoUntrustCertificates } |
|
} |