[Windows] Refactor helpers that verify hashsum and signature (#8886)

This commit is contained in:
Vasilii Polikarpov
2023-11-30 09:22:14 +01:00
committed by GitHub
parent abb81511d4
commit 92e22bd8c6
17 changed files with 151 additions and 109 deletions

View File

@@ -12,10 +12,9 @@ $downloadUrl = ($assets.browser_download_url -ilike "*aliyun-cli-windows-*-amd64
$packagePath = Invoke-DownloadWithRetry $downloadUrl $packagePath = Invoke-DownloadWithRetry $downloadUrl
#region Supply chain security - Alibaba Cloud CLI #region Supply chain security - Alibaba Cloud CLI
$fileHash = (Get-FileHash -Path $packagePath -Algorithm SHA256).Hash
$hashUrl = ($assets.browser_download_url -ilike "*SHASUMS256.txt*") | Select-Object -First 1 $hashUrl = ($assets.browser_download_url -ilike "*SHASUMS256.txt*") | Select-Object -First 1
$externalHash = (Invoke-RestMethod -Uri $hashURL).ToString().Split("`n").Where({ $_ -ilike "*$installerFileName*" }).Split(' ')[0] $externalHash = (Invoke-RestMethod -Uri $hashURL).ToString().Split("`n").Where({ $_ -ilike "*$installerFileName*" }).Split(' ')[0]
Use-ChecksumComparison $fileHash $externalHash Test-FileChecksum $packagePath -ExpectedSHA256Sum $externalHash
#endregion #endregion
Write-Host "Expand aliyun-cli archive" Write-Host "Expand aliyun-cli archive"

View File

@@ -35,7 +35,7 @@ function Install-AndroidSDKPackages {
[Parameter(Mandatory = $true)] [Parameter(Mandatory = $true)]
[AllowEmptyCollection()] [AllowEmptyCollection()]
[AllowNull()] [AllowNull()]
[string[]]$Packages [string[]] $Packages
) )
# The sdkmanager.bat script is used to install Android SDK packages. # The sdkmanager.bat script is used to install Android SDK packages.
@@ -63,11 +63,7 @@ $androidToolset = (Get-ToolsetContent).android
$cmdlineToolsUrl = $androidToolset.commandline_tools_url $cmdlineToolsUrl = $androidToolset.commandline_tools_url
$cmdlineToolsArchPath = Invoke-DownloadWithRetry $cmdlineToolsUrl $cmdlineToolsArchPath = Invoke-DownloadWithRetry $cmdlineToolsUrl
#region Supply chain security Test-FileChecksum $cmdlineToolsArchPath -ExpectedSHA256Sum $androidToolset.hash
$localFileHash = (Get-FileHash -Path $cmdlineToolsArchPath -Algorithm SHA256).Hash
Use-ChecksumComparison -LocalFileHash $localFileHash -DistributorFileHash $androidToolset.hash
#endregion
Expand-7ZipArchive -Path $cmdlineToolsArchPath -DestinationPath "${SDKInstallRoot}\cmdline-tools" Expand-7ZipArchive -Path $cmdlineToolsArchPath -DestinationPath "${SDKInstallRoot}\cmdline-tools"

View File

@@ -25,7 +25,7 @@ if ($userPath) {
# Verify and run choco installer # Verify and run choco installer
$signatureThumbprint = "83AC7D88C66CB8680BCE802E0F0F5C179722764B" $signatureThumbprint = "83AC7D88C66CB8680BCE802E0F0F5C179722764B"
$InstallScriptPath = Invoke-DownloadWithRetry 'https://chocolatey.org/install.ps1' $InstallScriptPath = Invoke-DownloadWithRetry 'https://chocolatey.org/install.ps1'
Test-FileSignature -FilePath $InstallScriptPath -ExpectedThumbprint $signatureThumbprint Test-FileSignature -Path $InstallScriptPath -ExpectedThumbprint $signatureThumbprint
Invoke-Expression $InstallScriptPath Invoke-Expression $InstallScriptPath
# Turn off confirmation # Turn off confirmation

View File

@@ -21,6 +21,6 @@ Add-MachinePathItem $CloudFoundryCliPath
# Validate cf signature # Validate cf signature
$CloudFoundrySignatureThumbprint = "4C69EDD13930ED01B83DD1D17B09C434DC1F2177" $CloudFoundrySignatureThumbprint = "4C69EDD13930ED01B83DD1D17B09C434DC1F2177"
Test-FileSignature -FilePath "$CloudFoundryCliPath\cf.exe" -ExpectedThumbprint $CloudFoundrySignatureThumbprint Test-FileSignature -Path "$CloudFoundryCliPath\cf.exe" -ExpectedThumbprint $CloudFoundrySignatureThumbprint
Invoke-PesterTests -TestFile "CLI.Tools" -TestName "CloudFoundry CLI" Invoke-PesterTests -TestFile "CLI.Tools" -TestName "CloudFoundry CLI"

View File

@@ -22,7 +22,7 @@ function Get-SDKVersionsToInstall (
$currentReleases = $currentReleases.'releases' | Where-Object { !$_.'release-version'.Contains('-') } $currentReleases = $currentReleases.'releases' | Where-Object { !$_.'release-version'.Contains('-') }
$sdks = @() $sdks = @()
ForEach ($release in $currentReleases) { foreach ($release in $currentReleases) {
$sdks += $release.'sdk' $sdks += $release.'sdk'
$sdks += $release.'sdks' $sdks += $release.'sdks'
} }
@@ -30,7 +30,7 @@ function Get-SDKVersionsToInstall (
return $sdks.version ` return $sdks.version `
| Sort-Object { [Version] $_ } -Unique ` | Sort-Object { [Version] $_ } -Unique `
| Group-Object { $_.Substring(0, $_.LastIndexOf('.') + 2) } ` | Group-Object { $_.Substring(0, $_.LastIndexOf('.') + 2) } `
| Foreach-Object { $_.Group[-1] } | ForEach-Object { $_.Group[-1] }
} }
function Invoke-Warmup ( function Invoke-Warmup (
@@ -62,9 +62,7 @@ function InstallSDKVersion (
#region Supply chain security #region Supply chain security
$distributorFileHash = (Invoke-RestMethod -Uri "https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/$dotnetVersion/releases.json").releases.sdks.Where({ $_.version -eq $SdkVersion }).files.Where({ $_.name -eq 'dotnet-sdk-win-x64.zip' }).hash $distributorFileHash = (Invoke-RestMethod -Uri "https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/$dotnetVersion/releases.json").releases.sdks.Where({ $_.version -eq $SdkVersion }).files.Where({ $_.name -eq 'dotnet-sdk-win-x64.zip' }).hash
$localFileHash = (Get-FileHash -Path $ZipPath -Algorithm 'SHA512').Hash Test-FileChecksum $ZipPath -ExpectedSHA512Sum $distributorFileHash
Use-ChecksumComparison -LocalFileHash $localFileHash -DistributorFileHash $distributorFileHash
#endregion #endregion
} else { } else {
Write-Host "Sdk version $sdkVersion already installed" Write-Host "Sdk version $sdkVersion already installed"
@@ -87,29 +85,23 @@ function InstallAllValidSdks() {
$installationUrl = "https://dot.net/v1/${installationName}" $installationUrl = "https://dot.net/v1/${installationName}"
Invoke-DownloadWithRetry -Url $installationUrl -Path ".\$installationName" Invoke-DownloadWithRetry -Url $installationUrl -Path ".\$installationName"
ForEach ($dotnetVersion in $dotnetVersions) foreach ($dotnetVersion in $dotnetVersions) {
{
$sdkVersionsToInstall = Get-SDKVersionsToInstall -DotnetVersion $dotnetVersion $sdkVersionsToInstall = Get-SDKVersionsToInstall -DotnetVersion $dotnetVersion
foreach ($sdkVersion in $sdkVersionsToInstall) {
ForEach ($sdkVersion in $sdkVersionsToInstall)
{
InstallSDKVersion -SdkVersion $sdkVersion -DotnetVersion $dotnetVersion -Warmup $warmup InstallSDKVersion -SdkVersion $sdkVersion -DotnetVersion $dotnetVersion -Warmup $warmup
} }
} }
} }
function InstallTools() function InstallTools() {
{
$dotnetTools = (Get-ToolsetContent).dotnet.tools $dotnetTools = (Get-ToolsetContent).dotnet.tools
ForEach ($dotnetTool in $dotnetTools) foreach ($dotnetTool in $dotnetTools) {
{
dotnet tool install $($dotnetTool.name) --tool-path "C:\Users\Default\.dotnet\tools" --add-source https://api.nuget.org/v3/index.json | Out-Null dotnet tool install $($dotnetTool.name) --tool-path "C:\Users\Default\.dotnet\tools" --add-source https://api.nuget.org/v3/index.json | Out-Null
} }
} }
function RunPostInstallationSteps() function RunPostInstallationSteps() {
{
# Add dotnet to PATH # Add dotnet to PATH
Add-MachinePathItem "C:\Program Files\dotnet" Add-MachinePathItem "C:\Program Files\dotnet"

View File

@@ -28,7 +28,7 @@ Expand-7ZipArchive -Path $archivePath -DestinationPath $edgeDriverPath
#Validate the EdgeDriver signature #Validate the EdgeDriver signature
$signatureThumbprint = "CB9C4FBEA1D87D2D468AC5A9CAAB0163F6AD8401" $signatureThumbprint = "CB9C4FBEA1D87D2D468AC5A9CAAB0163F6AD8401"
Test-FileSignature -FilePath "$edgeDriverPath\msedgedriver.exe" -ExpectedThumbprint $signatureThumbprint Test-FileSignature -Path "$edgeDriverPath\msedgedriver.exe" -ExpectedThumbprint $signatureThumbprint
Write-Host "Setting the environment variables..." Write-Host "Setting the environment variables..."
[Environment]::SetEnvironmentVariable("EdgeWebDriver", $EdgeDriverPath, "Machine") [Environment]::SetEnvironmentVariable("EdgeWebDriver", $EdgeDriverPath, "Machine")

View File

@@ -50,7 +50,7 @@ Expand-7ZipArchive -Path $GeckoDriverArchPath -DestinationPath $GeckoDriverPath
# Validate Gecko WebDriver signature # Validate Gecko WebDriver signature
$GeckoDriverSignatureThumbprint = "1326B39C3D5D2CA012F66FB439026F7B59CB1974" $GeckoDriverSignatureThumbprint = "1326B39C3D5D2CA012F66FB439026F7B59CB1974"
Test-FileSignature -FilePath "$GeckoDriverPath/geckodriver.exe" -ExpectedThumbprint $GeckoDriverSignatureThumbprint Test-FileSignature -Path "$GeckoDriverPath/geckodriver.exe" -ExpectedThumbprint $GeckoDriverSignatureThumbprint
Write-Host "Setting the environment variables..." Write-Host "Setting the environment variables..."
Add-MachinePathItem -PathItem $GeckoDriverPath Add-MachinePathItem -PathItem $GeckoDriverPath

View File

@@ -64,12 +64,7 @@ function Install-JavaJDK {
# Download and extract java binaries to temporary folder # Download and extract java binaries to temporary folder
$downloadUrl = $asset.binary.package.link $downloadUrl = $asset.binary.package.link
$archivePath = Invoke-DownloadWithRetry $downloadUrl $archivePath = Invoke-DownloadWithRetry $downloadUrl
Test-FileChecksum $archivePath -ExpectedSHA256Sum $asset.binary.package.checksum
#region Supply chain security - JDK
$fileHash = (Get-FileHash -Path $archivePath -Algorithm SHA256).Hash
$externalHash = $asset.binary.package.checksum
Use-ChecksumComparison $fileHash $externalHash
#endregion
# We have to replace '+' sign in the version to '-' due to the issue with incorrect path in Android builds https://github.com/actions/runner-images/issues/3014 # We have to replace '+' sign in the version to '-' due to the issue with incorrect path in Android builds https://github.com/actions/runner-images/issues/3014
$fullJavaVersion = $asset.version.semver -replace '\+', '-' $fullJavaVersion = $asset.version.semver -replace '\+', '-'
@@ -123,7 +118,7 @@ Install-ChocoPackage maven -ArgumentList "--version=$versionToInstall"
Install-ChocoPackage gradle Install-ChocoPackage gradle
# Add maven env variables to Machine # Add maven env variables to Machine
[string]$m2 = ([Environment]::GetEnvironmentVariable("PATH", "Machine")).Split(";") -match "maven" [string] $m2 = ([Environment]::GetEnvironmentVariable("PATH", "Machine")).Split(";") -match "maven"
$m2_repo = 'C:\ProgramData\m2' $m2_repo = 'C:\ProgramData\m2'
New-Item -Path $m2_repo -ItemType Directory -Force | Out-Null New-Item -Path $m2_repo -ItemType Directory -Force | Out-Null
@@ -138,8 +133,7 @@ $sha256sum = '79479DDE416B082F38ECD1F2F7C6DEBD4D0C2249AF80FD046D1CE05D628F2EC6'
$coberturaPath = "C:\cobertura-2.1.1" $coberturaPath = "C:\cobertura-2.1.1"
$archivePath = Invoke-DownloadWithRetry $uri $archivePath = Invoke-DownloadWithRetry $uri
$fileHash = (Get-FileHash -Path $archivePath -Algorithm SHA256).Hash Test-FileChecksum $archivePath -ExpectedSHA256Sum $sha256sum
Use-ChecksumComparison $fileHash $sha256sum
Expand-7ZipArchive -Path $archivePath -DestinationPath "C:\" Expand-7ZipArchive -Path $archivePath -DestinationPath "C:\"
[Environment]::SetEnvironmentVariable("COBERTURA_HOME", $coberturaPath, "Machine") [Environment]::SetEnvironmentVariable("COBERTURA_HOME", $coberturaPath, "Machine")

View File

@@ -14,9 +14,8 @@ $kotlinDownloadUrl = Resolve-GithubReleaseAssetUrl `
$kotlinArchivePath = Invoke-DownloadWithRetry $kotlinDownloadUrl $kotlinArchivePath = Invoke-DownloadWithRetry $kotlinDownloadUrl
#region Supply chain security #region Supply chain security
$fileHash = (Get-FileHash -Path $kotlinArchivePath -Algorithm SHA256).Hash
$externalHash = Get-HashFromGitHubReleaseBody -RepoOwner "JetBrains" -RepoName "kotlin" -FileName "$kotlinBinaryName-*.zip" -Version $kotlinVersion -WordNumber 2 $externalHash = Get-HashFromGitHubReleaseBody -RepoOwner "JetBrains" -RepoName "kotlin" -FileName "$kotlinBinaryName-*.zip" -Version $kotlinVersion -WordNumber 2
Use-ChecksumComparison $fileHash $externalHash Test-FileChecksum $kotlinArchivePath -ExpectedSHA256Sum $externalHash
#endregion #endregion
Write-Host "Expand Kotlin archive" Write-Host "Expand Kotlin archive"

View File

@@ -14,10 +14,9 @@ $null = New-Item -Path $destFilePath -ItemType Directory -Force
$packagePath = Invoke-DownloadWithRetry -Url $kindDownloadLink -Path "$destFilePath\kind.exe" $packagePath = Invoke-DownloadWithRetry -Url $kindDownloadLink -Path "$destFilePath\kind.exe"
#region Supply chain security - Kind #region Supply chain security - Kind
$fileHash = (Get-FileHash -Path $packagePath -Algorithm SHA256).Hash
$hashUrl = ($assets.browser_download_url -match "kind-windows-amd64.sha256sum") | Select-Object -First 1 $hashUrl = ($assets.browser_download_url -match "kind-windows-amd64.sha256sum") | Select-Object -First 1
$externalHash = (Invoke-RestMethod -Uri $hashURL).ToString().Split("`n").Where({ $_ -ilike "*kind-windows-amd64*" }).Split(' ')[0] $externalHash = (Invoke-RestMethod -Uri $hashURL).ToString().Split("`n").Where({ $_ -ilike "*kind-windows-amd64*" }).Split(' ')[0]
Use-ChecksumComparison $fileHash $externalHash Test-FileChecksum $packagePath -ExpectedSHA256Sum $externalHash
#endregion #endregion
Add-MachinePathItem $destFilePath Add-MachinePathItem $destFilePath

View File

@@ -21,10 +21,9 @@ function Install-Msys2 {
Write-Host "Finished download" Write-Host "Finished download"
#region Supply chain security - Kind #region Supply chain security - Kind
$fileHash = (Get-FileHash -Path $msys2File -Algorithm SHA256).Hash
$hashUrl = ($assets.browser_download_url -match "msys2-checksums.txt") | Select-Object -First 1 $hashUrl = ($assets.browser_download_url -match "msys2-checksums.txt") | Select-Object -First 1
$externalHash = (Invoke-RestMethod -Uri $hashURL).ToString().Split("`n").Where({ $_ -ilike "*msys2-x86_64*" }).Split(' ')[0] $externalHash = (Invoke-RestMethod -Uri $hashURL).ToString().Split("`n").Where({ $_ -ilike "*msys2-x86_64*" }).Split(' ')[0]
Use-ChecksumComparison $fileHash $externalHash Test-FileChecksum $msys2File -ExpectedSHA256Sum $externalHash
#endregion #endregion
# extract tar.xz to C:\ # extract tar.xz to C:\

View File

@@ -7,8 +7,8 @@
function Install-PyPy function Install-PyPy
{ {
param( param(
[String]$PackagePath, [String] $PackagePath,
[String]$Architecture [String] $Architecture
) )
# Create PyPy toolcache folder # Create PyPy toolcache folder
@@ -102,16 +102,13 @@ foreach($toolsetVersion in $toolsetVersions.versions)
$tempPyPyPackagePath = Invoke-DownloadWithRetry $latestMajorPyPyVersion.download_url $tempPyPyPackagePath = Invoke-DownloadWithRetry $latestMajorPyPyVersion.download_url
#region Supply chain security #region Supply chain security
$localFileHash = (Get-FileHash -Path $tempPyPyPackagePath -Algorithm SHA256).Hash
$distributorFileHash = $null $distributorFileHash = $null
foreach ($node in $checksums) {
ForEach($node in $checksums) { if ($node.InnerText -ilike "*${filename}*") {
if($node.InnerText -ilike "*${filename}*") {
$distributorFileHash = $node.InnerText.ToString().Split("`n").Where({ $_ -ilike "*${filename}*" }).Split(' ')[0] $distributorFileHash = $node.InnerText.ToString().Split("`n").Where({ $_ -ilike "*${filename}*" }).Split(' ')[0]
} }
} }
Test-FileChecksum $tempPyPyPackagePath -ExpectedSHA256Sum $distributorFileHash
Use-ChecksumComparison -LocalFileHash $localFileHash -DistributorFileHash $distributorFileHash
#endregion #endregion
Install-PyPy -PackagePath $tempPyPyPackagePath -Architecture $toolsetVersions.arch Install-PyPy -PackagePath $tempPyPyPackagePath -Architecture $toolsetVersions.arch

View File

@@ -13,10 +13,8 @@ $env:CARGO_HOME = "C:\Users\Default\.cargo"
$rustupPath = Invoke-DownloadWithRetry "https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe" $rustupPath = Invoke-DownloadWithRetry "https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe"
#region Supply chain security #region Supply chain security
$localFileHash = (Get-FileHash -Path (Join-Path ${env:TEMP} 'rustup-init.exe') -Algorithm SHA256).Hash
$distributorFileHash = (Invoke-RestMethod -Uri 'https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe.sha256').Trim() $distributorFileHash = (Invoke-RestMethod -Uri 'https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe.sha256').Trim()
Test-FileChecksum (Join-Path ${env:TEMP} 'rustup-init.exe') -ExpectedSHA256Sum $distributorFileHash
Use-ChecksumComparison -LocalFileHash $localFileHash -DistributorFileHash $distributorFileHash
#endregion #endregion
# Install Rust by running rustup-init.exe (disabling the confirmation prompt with -y) # Install Rust by running rustup-init.exe (disabling the confirmation prompt with -y)

View File

@@ -16,10 +16,9 @@ $DestinationPath = Join-Path $StackToolcachePath "x64"
$StackArchivePath = Invoke-DownloadWithRetry $DownloadUrl $StackArchivePath = Invoke-DownloadWithRetry $DownloadUrl
#region Supply chain security - Stack #region Supply chain security - Stack
$fileHash = (Get-FileHash -Path $StackArchivePath -Algorithm SHA256).Hash
$hashUrl = $StackReleasesJson.assets | Where-Object { $_.name.EndsWith("$DownloadFilePattern.sha256") } | Select-Object -ExpandProperty "browser_download_url" -First 1 $hashUrl = $StackReleasesJson.assets | Where-Object { $_.name.EndsWith("$DownloadFilePattern.sha256") } | Select-Object -ExpandProperty "browser_download_url" -First 1
$externalHash = (Invoke-RestMethod -Uri $hashURL).ToString().Split("`n").Where({ $_ -ilike "*$DownloadFilePattern*" }).Split(' ')[0] $externalHash = (Invoke-RestMethod -Uri $hashURL).ToString().Split("`n").Where({ $_ -ilike "*$DownloadFilePattern*" }).Split(' ')[0]
Use-ChecksumComparison $fileHash $externalHash Test-FileChecksum $StackArchivePath -ExpectedSHA256Sum $externalHash
#endregion #endregion
Write-Host "Expand stack archive" Write-Host "Expand stack archive"

View File

@@ -38,8 +38,8 @@ Export-ModuleMember -Function @(
'Get-VisualStudioInstance' 'Get-VisualStudioInstance'
'Get-VisualStudioComponents' 'Get-VisualStudioComponents'
'Get-WindowsUpdateStates' 'Get-WindowsUpdateStates'
'Use-ChecksumComparison'
'Get-HashFromGitHubReleaseBody' 'Get-HashFromGitHubReleaseBody'
'Test-FileChecksum'
'Test-FileSignature' 'Test-FileSignature'
'Update-Environment' 'Update-Environment'
) )

View File

@@ -75,20 +75,18 @@ function Install-Binary {
if ($PSBoundParameters.ContainsKey('ExpectedSignature')) { if ($PSBoundParameters.ContainsKey('ExpectedSignature')) {
if ($ExpectedSignature) { if ($ExpectedSignature) {
Test-FileSignature -FilePath $filePath -ExpectedThumbprint $ExpectedSignature Test-FileSignature -Path $filePath -ExpectedThumbprint $ExpectedSignature
} else { } else {
throw "ExpectedSignature parameter is specified, but no signature is provided." throw "ExpectedSignature parameter is specified, but no signature is provided."
} }
} }
if ($ExpectedSHA256Sum) { if ($ExpectedSHA256Sum) {
$fileHash = (Get-FileHash -Path $filePath -Algorithm SHA256).Hash Test-FileChecksum $filePath -ExpectedSHA256Sum $ExpectedSHA256Sum
Use-ChecksumComparison $fileHash $ExpectedSHA256Sum
} }
if ($ExpectedSHA512Sum) { if ($ExpectedSHA512Sum) {
$fileHash = (Get-FileHash -Path $filePath -Algorithm SHA512).Hash Test-FileChecksum $filePath -ExpectedSHA512Sum $ExpectedSHA512Sum
Use-ChecksumComparison $fileHash $ExpectedSHA512Sum
} }
if ($ExtraInstallArgs -and $InstallArgs) { if ($ExtraInstallArgs -and $InstallArgs) {
@@ -388,7 +386,7 @@ function Get-TCToolVersionPath {
# Take latest installed version in case if toolset version contains wildcards # Take latest installed version in case if toolset version contains wildcards
$foundVersion = Get-Item $versionPath ` $foundVersion = Get-Item $versionPath `
| Sort-Object -Property { [version]$_.name } -Descending ` | Sort-Object -Property { [version] $_.name } -Descending `
| Select-Object -First 1 | Select-Object -First 1
if (-not $foundVersion) { if (-not $foundVersion) {
@@ -414,11 +412,11 @@ function Expand-7ZipArchive {
Param Param
( (
[Parameter(Mandatory = $true)] [Parameter(Mandatory = $true)]
[string]$Path, [string] $Path,
[Parameter(Mandatory = $true)] [Parameter(Mandatory = $true)]
[string]$DestinationPath, [string] $DestinationPath,
[ValidateSet("x", "e")] [ValidateSet("x", "e")]
[char]$ExtractMethod = "x" [char] $ExtractMethod = "x"
) )
Write-Host "Expand archive '$PATH' to '$DestinationPath' directory" Write-Host "Expand archive '$PATH' to '$DestinationPath' directory"
@@ -455,7 +453,7 @@ function Get-AndroidPackages {
#> #>
Param Param
( (
[string]$SDKRootPath [string] $SDKRootPath
) )
if (-not $SDKRootPath) { if (-not $SDKRootPath) {
@@ -503,9 +501,9 @@ function Get-AndroidPlatformPackages {
#> #>
Param Param
( (
[string]$SDKRootPath, [string] $SDKRootPath,
[Alias("minVersion")] [Alias("minVersion")]
[int]$minimumVersion = 0 [int] $minimumVersion = 0
) )
if (-not $SDKRootPath) { if (-not $SDKRootPath) {
@@ -545,9 +543,9 @@ function Get-AndroidBuildToolPackages {
#> #>
Param Param
( (
[string]$SDKRootPath, [string] $SDKRootPath,
[Alias("minVersion")] [Alias("minVersion")]
[version]$minimumVersion = "0.0.0" [version] $minimumVersion = "0.0.0"
) )
if (-not $SDKRootPath) { if (-not $SDKRootPath) {
@@ -582,7 +580,7 @@ function Get-AndroidInstalledPackages {
Param Param
( (
[string]$SDKRootPath [string] $SDKRootPath
) )
if (-not $SDKRootPath) { if (-not $SDKRootPath) {
@@ -750,7 +748,7 @@ function Resolve-GithubReleaseAssetUrl {
} }
# Sort releases by version # Sort releases by version
$releases = $releases | Sort-Object -Descending { [version]$_.version } $releases = $releases | Sort-Object -Descending { [version] $_.version }
# Select releases matching version # Select releases matching version
if ($Version -eq "latest") { if ($Version -eq "latest") {
@@ -789,35 +787,18 @@ function Resolve-GithubReleaseAssetUrl {
return ($matchedUrl -as [string]) return ($matchedUrl -as [string])
} }
function Use-ChecksumComparison {
param (
[Parameter(Mandatory = $true)]
[string]$LocalFileHash,
[Parameter(Mandatory = $true)]
[string]$DistributorFileHash
)
Write-Verbose "Performing checksum verification"
if ($LocalFileHash -ne $DistributorFileHash) {
throw "Checksum verification failed. Expected hash: $DistributorFileHash; Actual hash: $LocalFileHash."
} else {
Write-Verbose "Checksum verification passed"
}
}
function Get-HashFromGitHubReleaseBody { function Get-HashFromGitHubReleaseBody {
param ( param (
[string]$RepoOwner, [string] $RepoOwner,
[string]$RepoName, [string] $RepoName,
[Parameter(Mandatory = $true)] [Parameter(Mandatory = $true)]
[string]$FileName, [string] $FileName,
[string]$Url, [string] $Url,
[string]$Version = "latest", [string] $Version = "latest",
[boolean]$IsPrerelease = $false, [boolean] $IsPrerelease = $false,
[int]$SearchInCount = 100, [int] $SearchInCount = 100,
[string]$Delimiter = '|', [string] $Delimiter = '|',
[int]$WordNumber = 1 [int] $WordNumber = 1
) )
if ($Url) { if ($Url) {
@@ -846,15 +827,104 @@ function Get-HashFromGitHubReleaseBody {
} }
return $result return $result
} }
function Test-FileSignature {
param( function Test-FileChecksum {
[Parameter(Mandatory = $true)] <#
[string]$FilePath, .SYNOPSIS
[Parameter(Mandatory = $true)] Verifies the checksum of a file.
[string[]]$ExpectedThumbprint
.DESCRIPTION
The Test-FileChecksum function verifies the SHA256 or SHA512 checksum of a file against an expected value.
If the checksum does not match the expected value, the function throws an error.
.PARAMETER Path
The path to the file for which to verify the checksum.
.PARAMETER ExpectedSHA256Sum
The expected SHA256 checksum. If this parameter is provided, the function will calculate the SHA256 checksum of the file and compare it to this value.
.PARAMETER ExpectedSHA512Sum
The expected SHA512 checksum. If this parameter is provided, the function will calculate the SHA512 checksum of the file and compare it to this value.
.EXAMPLE
Test-FileChecksum -Path "C:\temp\file.txt" -ExpectedSHA256Sum "ABC123"
Verifies that the SHA256 checksum of the file at C:\temp\file.txt is ABC123.
.EXAMPLE
Test-FileChecksum -Path "C:\temp\file.txt" -ExpectedSHA512Sum "DEF456"
Verifies that the SHA512 checksum of the file at C:\temp\file.txt is DEF456.
#>
param (
[Parameter(Mandatory = $true, Position = 0)]
[string] $Path,
[Parameter(Mandatory = $false)]
[String] $ExpectedSHA256Sum,
[Parameter(Mandatory = $false)]
[String] $ExpectedSHA512Sum
) )
$signature = Get-AuthenticodeSignature $FilePath Write-Verbose "Performing checksum verification"
if ($ExpectedSHA256Sum -and $ExpectedSHA512Sum) {
throw "Only one of the ExpectedSHA256Sum and ExpectedSHA512Sum parameters can be provided"
}
if (-not (Test-Path $Path)) {
throw "File not found: $Path"
}
if ($ExpectedSHA256Sum) {
$fileHash = (Get-FileHash -Path $Path -Algorithm SHA256).Hash
$expectedHash = $ExpectedSHA256Sum
}
if ($ExpectedSHA512Sum) {
$fileHash = (Get-FileHash -Path $Path -Algorithm SHA512).Hash
$expectedHash = $ExpectedSHA512Sum
}
if ($fileHash -ne $expectedHash) {
throw "Checksum verification failed: expected $expectedHash, got $fileHash"
} else {
Write-Verbose "Checksum verification passed"
}
}
function Test-FileSignature {
<#
.SYNOPSIS
Tests the file signature of a given file.
.DESCRIPTION
The Test-FileSignature function checks the signature of a file against the expected thumbprints.
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.
.PARAMETER Path
Specifies the path of the file to test.
.PARAMETER ExpectedThumbprint
Specifies the expected thumbprints to match against the file's signature.
.EXAMPLE
Test-FileSignature -Path "C:\Path\To\File.exe" -ExpectedThumbprint "A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6Q7R8S9T0"
This example tests the signature of the file "C:\Path\To\File.exe" against the expected thumbprint "A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6Q7R8S9T0".
#>
param(
[Parameter(Mandatory = $true, Position = 0)]
[string] $Path,
[Parameter(Mandatory = $true)]
[string[]] $ExpectedThumbprint
)
$signature = Get-AuthenticodeSignature $Path
if ($signature.Status -ne "Valid") { if ($signature.Status -ne "Valid") {
throw "Signature status is not valid. Status: $($signature.Status)" throw "Signature status is not valid. Status: $($signature.Status)"
@@ -862,14 +932,14 @@ function Test-FileSignature {
foreach ($thumbprint in $ExpectedThumbprint) { foreach ($thumbprint in $ExpectedThumbprint) {
if ($signature.SignerCertificate.Thumbprint.Contains($thumbprint)) { if ($signature.SignerCertificate.Thumbprint.Contains($thumbprint)) {
Write-Output "Signature for $FilePath is valid" Write-Output "Signature for $Path is valid"
$signatureMatched = $true $signatureMatched = $true
return return
} }
} }
if ($signatureMatched) { if ($signatureMatched) {
Write-Output "Signature for $FilePath is valid" Write-Output "Signature for $Path is valid"
} else { } else {
throw "Signature thumbprint do not match expected." throw "Signature thumbprint do not match expected."
} }

View File

@@ -41,7 +41,7 @@ Function Install-VisualStudio {
$bootstrapperFilePath = Invoke-DownloadWithRetry $BootstrapperUrl $bootstrapperFilePath = Invoke-DownloadWithRetry $BootstrapperUrl
# Verify that the bootstrapper is signed by Microsoft # Verify that the bootstrapper is signed by Microsoft
Test-FileSignature -FilePath $bootstrapperFilePath -ExpectedThumbprint $SignatureThumbprint Test-FileSignature -Path $bootstrapperFilePath -ExpectedThumbprint $SignatureThumbprint
try { try {
Write-Host "Enable short name support on Windows needed for Xamarin Android AOT, defaults appear to have been changed in Azure VMs" Write-Host "Enable short name support on Windows needed for Xamarin Android AOT, defaults appear to have been changed in Azure VMs"