buildtools/sign_files.ps1 (101 lines of code) (raw):
<#
.Synopsis
Authenticode-sign the set of provided files in-place.
.DESCRIPTION
Authenticode-sign the set of provided files in-place.
You can pass either a file (or files e.g. -Files file1, file2 - mind the limits of PS command line though)
or a folder with filter and recurse conditions (e.g. -Path folder -Filters *.dll,*.exe -Recurse).
#>
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true, ParameterSetName="Files")]
[string[]]$Files,
[Parameter(Mandatory=$true, ParameterSetName="Path")]
[string]$Path,
[Parameter(ParameterSetName="Path")]
[string[]]$Filters,
[Parameter(ParameterSetName="Path")]
[switch]$Recurse
)
Begin
{
$ErrorActionPreference = "Stop"
$unsignedS3bucket = $Env:UNSIGNED_BUCKET
$signedS3bucket = $Env:SIGNED_BUCKET
$FilesToSign = @()
if ($PSCmdlet.ParameterSetName -eq "Files")
{
$FilesToSign = $Files
}
else
{
if ($Recurse)
{
$FilesToSign = Get-ChildItem -Path $Path -Include $Filters -File -Recurse | Select-Object -ExpandProperty FullName
}
else
{
$FilesToSign = Get-ChildItem -Path $Path\* -Include $Filters -File | Select-Object -ExpandProperty FullName
}
}
if ($FilesToSign.Count -eq 0)
{
return "Nothing to sign"
}
filter ValidateJob()
{
$job = $_
if ($job.State -eq "Failed")
{
throw $job.JobStateInfo.Reason.ErrorRecord
}
}
$sw = [Diagnostics.Stopwatch]::StartNew()
$signFile =
{
param($file)
$key = Split-Path $file -leaf
$key = "XRayDotNetSignerProfile/AuthenticodeSigner-SHA256-RSA/$key"
$retryCount = 0
$maxRetryCount = 10
Write-Host "Signing File: ", $file
do {
$versionId = aws s3api put-object --bucket $unsignedS3bucket --key $key --body $file --query VersionId --acl bucket-owner-full-control
$retryCount++
} while ($LASTEXITCODE -ne 0 -and $retryCount -le $maxRetryCount)
if ($LASTEXITCODE -ne 0)
{
throw "Upload failed for: $file Reason: " + $Error[0].Exception.Message
}
$retryCount = 0
do {
$jobId = aws s3api get-object-tagging --bucket $unsignedS3bucket --key $key --version-id $versionId --query 'TagSet[?Key==`signer-job-id`].Value | [0]'
$jobId = $jobId.Trim('"')
$retryCount++
} while ($jobId -eq "null" -and $retryCount -le $maxRetryCount)
if ($jobId -eq "null")
{
throw "Exceeded retries to check if the object has finished signing for: $file"
}
$retryCount = 0
do {
aws s3api get-object --bucket $signedS3bucket --key $key-$jobId $file
$retryCount++
} while ($LASTEXITCODE -ne 0 -and $retryCount -le $maxRetryCount)
if ($LASTEXITCODE -ne 0)
{
throw "Download failed for: $file Reason: " + $Error[0].Exception.Message
}
}
Get-Job | Remove-Job
Write-Host "Signing", $FilesToSign.Count, "file(s)..."
foreach ($file in $FilesToSign)
{
$null = Invoke-Command -ScriptBlock $signFile -ArgumentList $file
}
Get-Job | Wait-Job | ValidateJob
$sw.Stop()
$totalSec += $sw.Elapsed.TotalSeconds
Write-Host "Done. Overall execution time : $totalSec sec."
}