diff --git a/Actions/AL-Go-Helper.ps1 b/Actions/AL-Go-Helper.ps1 index fb8f11a4a..4313b64e8 100644 --- a/Actions/AL-Go-Helper.ps1 +++ b/Actions/AL-Go-Helper.ps1 @@ -2306,3 +2306,15 @@ function GetProjectsFromRepository { } return $projects } + +function Get-PackageVersion($PackageName) { + $alGoPackages = Get-Content -Path "$PSScriptRoot\Packages.json" | ConvertFrom-Json + + # Check if the package is in the list of packages + if ($alGoPackages.PSobject.Properties.name -match $PackageName) { + return $alGoPackages.$PackageName + } + else { + throw "Package $PackageName is not in the list of packages" + } +} \ No newline at end of file diff --git a/Actions/Packages.json b/Actions/Packages.json new file mode 100644 index 000000000..d2a594537 --- /dev/null +++ b/Actions/Packages.json @@ -0,0 +1,3 @@ +{ + "sign": "0.9.1-beta.24123.2" +} \ No newline at end of file diff --git a/Actions/Sign/Sign.ps1 b/Actions/Sign/Sign.ps1 index 30251f63e..0982fbeb5 100644 --- a/Actions/Sign/Sign.ps1 +++ b/Actions/Sign/Sign.ps1 @@ -21,16 +21,19 @@ try { DownloadAndImportBcContainerHelper $telemetryScope = CreateScope -eventId 'DO0083' -parentTelemetryScopeJson $ParentTelemetryScopeJson - Write-Host "::group::Install AzureSignTool" - dotnet tool install --global AzureSignTool --version 4.0.1 - Write-Host "::endgroup::" - $Files = Get-ChildItem -Path $PathToFiles -File | Select-Object -ExpandProperty FullName - Write-Host "Signing files:" + if (-not $Files) { + Write-Host "No files to sign. Exiting." + return + } + + Write-Host "::group::Files to be signed" $Files | ForEach-Object { Write-Host "- $_" } + Write-Host "::endgroup::" + # Get parameters for signing $AzureCredentials = ConvertFrom-Json $AzureCredentialsJson $settings = $env:Settings | ConvertFrom-Json if ($settings.keyVaultName) { @@ -42,23 +45,22 @@ try { else { throw "KeyVaultName is not specified in AzureCredentials nor in settings. Please specify it in one of them." } + $description = "Signed with AL-Go for GitHub" + $descriptionUrl = "$ENV:GITHUB_SERVER_URL/$ENV:GITHUB_REPOSITORY" - RetryCommand -Command { Param( $AzureKeyVaultName, $AzureCredentials, $digestAlgorithm, $TimestampService, $Certificate, $Files) - Write-Host "::group::Register NavSip" - Register-NavSip - Write-Host "::endgroup::" - - AzureSignTool sign --file-digest $digestAlgorithm ` - --azure-key-vault-url "https://$AzureKeyVaultName.vault.azure.net/" ` - --azure-key-vault-client-id $AzureCredentials.clientId ` - --azure-key-vault-tenant-id $AzureCredentials.tenantId ` - --azure-key-vault-client-secret $AzureCredentials.clientSecret ` - --azure-key-vault-certificate $Certificate ` - --timestamp-rfc3161 "$TimestampService" ` - --timestamp-digest $digestAlgorithm ` - $Files - } -MaxRetries 3 -ArgumentList $AzureKeyVaultName, $AzureCredentials, $digestAlgorithm, $TimestampService, $Settings.keyVaultCodesignCertificateName, $Files - + Write-Host "::group::Signing files" + Invoke-SigningTool -KeyVaultName $AzureKeyVaultName ` + -CertificateName $settings.keyVaultCodesignCertificateName ` + -ClientId $AzureCredentials.clientId ` + -ClientSecret $AzureCredentials.clientSecret ` + -TenantId $AzureCredentials.tenantId ` + -FilesToSign $PathToFiles ` + -Description $description ` + -DescriptionUrl $descriptionUrl ` + -TimestampService $TimestampService ` + -DigestAlgorithm $digestAlgorithm ` + -Verbosity "Information" + Write-Host "::endgroup::" TrackTrace -telemetryScope $telemetryScope } catch { diff --git a/Actions/Sign/Sign.psm1 b/Actions/Sign/Sign.psm1 index cf2bb6aa6..0f65de4b3 100644 --- a/Actions/Sign/Sign.psm1 +++ b/Actions/Sign/Sign.psm1 @@ -1,44 +1,101 @@ -function GetNavSipFromArtifacts -( - [string] $NavSipDestination -) -{ - $artifactTempFolder = Join-Path $([System.IO.Path]::GetTempPath()) ([System.IO.Path]::GetRandomFileName()) - - try { - Download-Artifacts -artifactUrl (Get-BCArtifactUrl -type Sandbox -country core) -basePath $artifactTempFolder | Out-Null - Write-Host "Downloaded artifacts to $artifactTempFolder" - $navsip = Get-ChildItem -Path $artifactTempFolder -Filter "navsip.dll" -Recurse - Write-Host "Found navsip at $($navsip.FullName)" - Copy-Item -Path $navsip.FullName -Destination $NavSipDestination -Force | Out-Null - Write-Host "Copied navsip to $NavSipDestination" - } - finally { - Remove-Item -Path $artifactTempFolder -Recurse -Force - } +<# + .SYNOPSIS + Installs the dotnet signing tool. + .DESCRIPTION + Installs the dotnet signing tool. +#> +function Install-SigningTool() { + . (Join-Path -Path $PSScriptRoot -ChildPath "..\AL-Go-Helper.ps1" -Resolve) + + # Create folder in temp directory with a unique name + $tempFolder = Join-Path -Path ([System.IO.Path]::GetTempPath()) "SigningTool-$(Get-Random)" + + # Get version of the signing tool + $version = Get-PackageVersion -PackageName "sign" + + # Install the signing tool in the temp folder + Write-Host "Installing signing tool version $version in $tempFolder" + New-Item -ItemType Directory -Path $tempFolder | Out-Null + dotnet tool install sign --version $version --tool-path $tempFolder | Out-Null + + # Return the path to the signing tool + $signingTool = Join-Path -Path $tempFolder "sign.exe" -Resolve + return $signingTool } <# -.SYNOPSIS -Register the navsip.dll in the system32 folder + .SYNOPSIS + Signs files in a given path using a certificate from Azure Key Vault. + .DESCRIPTION + Signs files in a given path using a certificate from Azure Key Vault. + .PARAMETER KeyVaultName + The name of the Azure Key Vault where the certificate is stored. + .PARAMETER CertificateName + The name of the certificate in the Azure Key Vault. + .PARAMETER ClientId + The client ID of the service principal used to authenticate with Azure Key Vault. + .PARAMETER ClientSecret + The client secret of the service principal used to authenticate with Azure Key Vault. + .PARAMETER TenantId + The tenant ID of the service principal used to authenticate with Azure Key Vault. + .PARAMETER FilesToSign + The path to the file(s) to be signed. Supports wildcards. + .PARAMETER Description + The description to be included in the signature. + .PARAMETER DescriptionUrl + The URL to be included in the signature. + .PARAMETER TimestampService + The URL of the timestamp server. + .PARAMETER DigestAlgorithm + The digest algorithm to use for signing and timestamping. + .PARAMETER Verbosity + The verbosity level of the signing tool. + .EXAMPLE + Invoke-SigningTool -KeyVaultName "my-key-vault" -CertificateName "my-certificatename" -ClientId "my-client-id" -ClientSecret "my-client-secret" -TenantId "my-tenant-id" + -FilesToSign "C:\path\to\files\*.app" -Description "Signed with AL-Go for GitHub" -DescriptionUrl "github.com/myorg/myrepo" #> -function Register-NavSip() { - $navSipDestination = "C:\Windows\System32" - $navSipDllPath = Join-Path $navSipDestination "navsip.dll" - try { - if (-not (Test-Path $navSipDllPath)) { - GetNavSipFromArtifacts -NavSipDestination $navSipDllPath - } - - Write-Host "Unregistering dll $navSipDllPath" - RegSvr32 /u /s $navSipDllPath - Write-Host "Registering dll $navSipDllPath" - RegSvr32 /s $navSipDllPath - } - catch { - Write-Host "Failed to copy navsip to $navSipDestination" - } +function Invoke-SigningTool() { + param( + [Parameter(Mandatory = $true)] + [string] $KeyVaultName, + [Parameter(Mandatory = $true)] + [string] $CertificateName, + [Parameter(Mandatory = $true)] + [string] $ClientId, + [Parameter(Mandatory = $true)] + [string] $ClientSecret, + [Parameter(Mandatory = $true)] + [string] $TenantId, + [Parameter(Mandatory = $true)] + [string] $FilesToSign, + [Parameter(Mandatory = $true)] + [string] $Description, + [Parameter(Mandatory = $true)] + [string] $DescriptionUrl, + [Parameter(Mandatory = $false)] + [string] $TimestampService = "http://timestamp.digicert.com", + [Parameter(Mandatory = $false)] + [string] $DigestAlgorithm = "sha256", + [Parameter(Mandatory = $false)] + [string] $Verbosity = "Information" + ) + + $signingToolExe = Install-SigningTool + # Sign files + . $signingToolExe code azure-key-vault ` + --azure-key-vault-url "https://$KeyVaultName.vault.azure.net/" ` + --azure-key-vault-certificate $CertificateName ` + --azure-key-vault-client-id $ClientId ` + --azure-key-vault-client-secret $ClientSecret ` + --azure-key-vault-tenant-id $TenantId ` + --description $Description ` + --description-url $DescriptionUrl ` + --file-digest $DigestAlgorithm ` + --timestamp-digest $DigestAlgorithm ` + --timestamp-url $TimestampService ` + --verbosity $Verbosity ` + $FilesToSign } -Export-ModuleMember Register-NavSip +Export-ModuleMember -Function Invoke-SigningTool \ No newline at end of file