Validate authenticode signature using the certificate Subject (#12474)

* Use cerificate subject to verify authenticode signature

* Use function instead of script variables

* Switch all places to using Get-MicrosoftPublisher

* Remove SignatureThumbprint

* Use common subject for the Edge driver
This commit is contained in:
Pavel Iakovenko
2025-06-30 21:33:57 -04:00
committed by GitHub
parent 0790ef6e2a
commit 7eede67cd0
25 changed files with 72 additions and 103 deletions

View File

@@ -19,6 +19,7 @@ Export-ModuleMember -Function @(
Export-ModuleMember -Function @(
'Install-Binary'
'Invoke-DownloadWithRetry'
'Get-MicrosoftPublisher'
'Get-ToolsetContent'
'Get-TCToolPath'
'Get-TCToolVersionPath'

View File

@@ -21,8 +21,8 @@ function Install-Binary {
.PARAMETER ExtraInstallArgs
Additional arguments that will be passed to the installer. Cannot be used together with InstallArgs.
.PARAMETER ExpectedSignature
The expected signature of the binary. If specified, the binary's signature is checked before installation.
.PARAMETER ExpectedSubject
The expected signature subject of the binary. If specified, the binary's signature is checked before installation.
.PARAMETER ExpectedSHA256Sum
The expected SHA256 sum of the binary. If specified, the binary's SHA256 sum is checked before installation.
@@ -35,7 +35,7 @@ function Install-Binary {
This is only displayed when the installation fails.
.EXAMPLE
Install-Binary -Url "https://go.microsoft.com/fwlink/p/?linkid=2083338" -Type EXE -InstallArgs ("/features", "+", "/quiet") -ExpectedSignature "A5C7D5B7C838D5F89DDBEDB85B2C566B4CDA881F"
Install-Binary -Url "https://go.microsoft.com/fwlink/p/?linkid=2083338" -Type EXE -InstallArgs ("/features", "+", "/quiet") -ExpectedSubject "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
#>
Param
@@ -48,7 +48,7 @@ function Install-Binary {
[String] $Type,
[String[]] $InstallArgs,
[String[]] $ExtraInstallArgs,
[String[]] $ExpectedSignature,
[String] $ExpectedSubject,
[String] $ExpectedSHA256Sum,
[String] $ExpectedSHA512Sum,
[String] $InstallerLogPath
@@ -78,11 +78,11 @@ function Install-Binary {
$filePath = Invoke-DownloadWithRetry -Url $Url -Path "${env:TEMP_DIR}\$fileName"
}
if ($PSBoundParameters.ContainsKey('ExpectedSignature')) {
if ($ExpectedSignature) {
Test-FileSignature -Path $filePath -ExpectedThumbprint $ExpectedSignature
if ($PSBoundParameters.ContainsKey('ExpectedSubject')) {
if ($ExpectedSubject) {
Test-FileSignature -Path $filePath -ExpectedSubject $ExpectedSubject
} else {
throw "ExpectedSignature parameter is specified, but no signature is provided."
throw "ExpectedSubject parameter is specified, but no value is provided."
}
}
@@ -975,28 +975,28 @@ function Test-FileSignature {
Tests the file signature of a given file.
.DESCRIPTION
The Test-FileSignature function checks the signature of a file against the expected thumbprints.
The Test-FileSignature function checks the signature of a file against the expected subject.
It uses the Get-AuthenticodeSignature cmdlet to retrieve the signature information of the file.
If the signature status is not valid or the thumbprint does not match the expected thumbprints, an exception is thrown.
If the signature status is not valid or the subject of the signing certificate does not match the expected subject, an exception is thrown.
.PARAMETER Path
Specifies the path of the file to test.
.PARAMETER ExpectedThumbprint
Specifies the expected thumbprints to match against the file's signature.
.PARAMETER ExpectedSubject
Specifies the expected subject to match against the file's signature.
.EXAMPLE
Test-FileSignature -Path "C:\Path\To\File.exe" -ExpectedThumbprint "A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6Q7R8S9T0"
Test-FileSignature -Path "C:\Path\To\File.exe" -ExpectedSubject "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
This example tests the signature of the file "C:\Path\To\File.exe" against the expected thumbprint "A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6Q7R8S9T0".
This example tests the signature of the file "C:\Path\To\File.exe" against the expected subject "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US".
#>
param(
[Parameter(Mandatory = $true, Position = 0)]
[string] $Path,
[Parameter(Mandatory = $true)]
[string[]] $ExpectedThumbprint
[Parameter(Mandatory = $true, Position = 1)]
[string] $ExpectedSubject
)
$signature = Get-AuthenticodeSignature $Path
@@ -1005,19 +1005,15 @@ function Test-FileSignature {
throw "Signature status is not valid. Status: $($signature.Status)"
}
foreach ($thumbprint in $ExpectedThumbprint) {
if ($signature.SignerCertificate.Thumbprint.Contains($thumbprint)) {
Write-Output "Signature for $Path is valid"
$signatureMatched = $true
return
}
if ($signature.SignerCertificate.EnhancedKeyUsageList.FriendlyName -notcontains "Code Signing") {
throw "Certificate is not for code signing. Key usage: $($signature.SignerCertificate.EnhancedKeyUsageList)"
}
if ($signatureMatched) {
Write-Output "Signature for $Path is valid"
} else {
throw "Signature thumbprint do not match expected."
if ($signature.SignerCertificate.Subject -ne $ExpectedSubject) {
throw "Certificate subject does not match. Subject: $($signature.SignerCertificate.Subject)"
}
Write-Output "Signature for $Path is valid"
}
function Update-Environment {
@@ -1055,3 +1051,12 @@ function Update-Environment {
}
}
}
function Get-MicrosoftPublisher {
<#
.SYNOPSIS
Returns well-known subject for the Microsoft signing certificate
#>
return "CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
}

View File

@@ -32,8 +32,7 @@ Function Install-VisualStudio {
[Parameter(Mandatory)] [String] $Channel,
[String] $InstallChannel = "",
[Parameter(Mandatory)] [String[]] $RequiredComponents,
[String] $ExtraArgs = "",
[Parameter(Mandatory)] [String[]] $SignatureThumbprint
[String] $ExtraArgs = ""
)
@@ -51,7 +50,7 @@ Function Install-VisualStudio {
$bootstrapperFilePath = Invoke-DownloadWithRetry $BootstrapperUrl
# Verify that the bootstrapper is signed by Microsoft
Test-FileSignature -Path $bootstrapperFilePath -ExpectedThumbprint $SignatureThumbprint
Test-FileSignature -Path $bootstrapperFilePath -ExpectedSubject $(Get-MicrosoftPublisher)
try {
$responseData = @{