-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: code sign builds * chore: upgrade setup-msbuild actions * feat: make code signing optional, but default to true
- Loading branch information
Showing
4 changed files
with
235 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<# | ||
.SYNOPSIS | ||
Generates a self-signed Code Signing certificate. | ||
.DESCRIPTION | ||
This script generates a self-signed Code Signing certificate for the specified company name, | ||
exports it to a PFX file, and then removes the certificate from the certificate store. | ||
.PARAMETER CompanyName | ||
The name of the company for which the certificate is being generated. This name is used for the Common Name (CN) and Organization (O) fields in the certificate subject. | ||
.PARAMETER ExportPath | ||
The file path where the PFX file containing the self-signed certificate will be exported. The default value is "cert.pfx". | ||
.PARAMETER CertPassword | ||
The password to secure the exported PFX file. This parameter is mandatory and must be provided as a SecureString. | ||
.PARAMETER YearsValid | ||
The number of years the certificate will be valid for. The default value is 2 years. | ||
.EXAMPLE | ||
$SecurePassword = ConvertTo-SecureString -String "P@ssw0rd" -AsPlainText -Force | ||
.\GenerateCert.ps1 -CompanyName "ExampleCompany" -ExportPath ".\ExampleCert.pfx" -CertPassword $SecurePassword | ||
This example generates a certificate for "ExampleCompany", exports it to ".\ExampleCert.pfx", using the password "P@ssw0rd". | ||
#> | ||
|
||
param( | ||
[Parameter(Mandatory=$true, HelpMessage="The name of the company for which the certificate is being generated. Used in the CN and O fields of the certificate subject.")] | ||
[ValidateNotNullOrEmpty()] | ||
[string]$CompanyName, | ||
|
||
[Parameter(HelpMessage="The file path where the PFX file will be exported. Default is 'cert.pfx'.")] | ||
[string]$ExportPath = "cert.pfx", | ||
|
||
[Parameter(Mandatory=$true, HelpMessage="The password for the exported PFX file. Must be a SecureString.")] | ||
[ValidateScript({ | ||
if (([Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($_))).Length -eq 0) { | ||
throw "Certificate password must not be empty." | ||
} | ||
return $true | ||
})] | ||
[SecureString]$CertPassword, | ||
|
||
[ValidateRange(1, 10)] | ||
[int]$YearsValid = 2 | ||
) | ||
|
||
# Check if ExportPath already exists and ask for overwrite confirmation | ||
if (Test-Path $ExportPath) { | ||
$overwrite = Read-Host "File '$ExportPath' already exists. Do you want to overwrite it? (Y/N)" | ||
if ($overwrite -ne 'Y') { | ||
Write-Host "Operation cancelled by user." | ||
exit | ||
} | ||
} | ||
|
||
$certSubject = "CN=$CompanyName CA, O=$CompanyName, C=US" | ||
$certStoreLocation = "Cert:\CurrentUser\My" | ||
|
||
# Generate a self-signed certificate | ||
$cert = New-SelfSignedCertificate ` | ||
-Type CodeSigningCert -Subject $certSubject ` | ||
-TextExtension @("2.5.29.19={text}false") ` | ||
-KeyUsage DigitalSignature ` | ||
-KeyLength 2048 ` | ||
-NotAfter (Get-Date).AddYears($YearsValid) ` | ||
-CertStoreLocation $certStoreLocation ` | ||
-KeyExportPolicy Exportable | ||
|
||
# Export the certificate to a PFX file | ||
$certPath = "$certStoreLocation\" + $cert.Thumbprint | ||
Export-PfxCertificate -Cert $certPath -FilePath $ExportPath -Password $CertPassword | ||
|
||
# Remove the certificate from the store after export | ||
Get-ChildItem -Path $certPath | Remove-Item | ||
|
||
Write-Host "Certificate generated and exported to $ExportPath" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
<# | ||
.SYNOPSIS | ||
Signs a binary file with a digital certificate. | ||
.DESCRIPTION | ||
This script signs a specified binary file using a digital certificate. The certificate can be provided either as a file path or as a Base64-encoded string. A password for the certificate is required. | ||
.PARAMETER CertPath | ||
The file path to the digital certificate (.pfx file). If this parameter is not provided and CertBase64 is used, a temporary certificate file will be created. | ||
.PARAMETER CertBase64 | ||
The Base64-encoded string of the digital certificate. If provided, it will be decoded and saved as a temporary .pfx file for signing. This parameter is ignored if CertPath is provided. | ||
.PARAMETER CertPassword | ||
The password for the digital certificate's private key. This parameter is mandatory and must be provided as a SecureString. | ||
.PARAMETER BinaryPath | ||
The file path to the binary that will be signed. This parameter is mandatory. | ||
.EXAMPLE | ||
PS> .\SignCode.ps1 -CertPath "C:\path\to\your\certificate.pfx" -CertPassword (ConvertTo-SecureString -String "YourPassword" -AsPlainText -Force) -BinaryPath "C:\path\to\your\binary.exe" | ||
Signs the binary "binary.exe" using the certificate specified at "certificate.pfx". | ||
.EXAMPLE | ||
PS> $certBase64 = Get-Content "C:\path\to\your\certificateBase64.txt" -Raw | ||
PS> .\SignCode.ps1 -CertBase64 $certBase64 -CertPassword (ConvertTo-SecureString -String "YourPassword" -AsPlainText -Force) -BinaryPath "C:\path\to\your\binary.exe" | ||
Signs the binary "binary.exe" using a Base64-encoded digital certificate read from a text file. | ||
.NOTES | ||
This script uses signtool.exe, which must be available in your system's PATH. The script assumes the use of SHA256 for signing and timestamps the signature using http://timestamp.digicert.com. | ||
#> | ||
|
||
param( | ||
[Parameter(Mandatory=$false)] | ||
[string]$CertPath, | ||
|
||
[Parameter(Mandatory=$false)] | ||
[string]$CertBase64, | ||
|
||
[Parameter(Mandatory=$true)] | ||
[System.Security.SecureString]$CertPassword, | ||
|
||
[Parameter(Mandatory=$true)] | ||
[string]$BinaryPath | ||
) | ||
|
||
function Find-SignTool { | ||
$possiblePaths = @( | ||
"${env:ProgramFiles(x86)}\Windows Kits\10\bin\*\x64", | ||
"${env:ProgramFiles(x86)}\Windows Kits\10\bin\10.0.*\x64", | ||
"${env:ProgramFiles(x86)}\Microsoft SDKs\Windows\v7.1A\Bin", | ||
"${env:ProgramFiles}\Microsoft SDKs\Windows\v8.1A\Bin\x64" | ||
) | ||
|
||
foreach ($path in $possiblePaths) { | ||
$signtool = Get-ChildItem -Path $path -Filter signtool.exe -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 | ||
if ($null -ne $signtool) { | ||
return $signtool.FullName | ||
} | ||
} | ||
|
||
throw "signtool.exe not found. Please ensure the Windows SDK is installed." | ||
} | ||
|
||
$signtoolPath = Find-SignTool | ||
|
||
if ($CertBase64 -and !$CertPath) { | ||
$certContent = [System.Convert]::FromBase64String($CertBase64) | ||
$CertPath = "tempCert.pfx" | ||
[IO.File]::WriteAllBytes($CertPath, $certContent) | ||
} | ||
|
||
if (-not (Test-Path $CertPath)) { | ||
throw "Certificate path is invalid or certificate is not provided." | ||
} | ||
|
||
if (-not (Test-Path $BinaryPath)) { | ||
throw "Binary path is invalid." | ||
} | ||
|
||
$certPasswordPlainText = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($CertPassword)) | ||
|
||
& $signtoolPath sign /fd SHA256 /a /f $CertPath /p $certPasswordPlainText /tr http://timestamp.digicert.com /td SHA256 $BinaryPath | ||
|
||
if ($LASTEXITCODE -ne 0) { | ||
throw "Signing failed with exit code $LASTEXITCODE." | ||
} |