Created
April 24, 2018 07:00
-
-
Save iarovyi/c31b34959c1cadaea462327dcdc0df1a to your computer and use it in GitHub Desktop.
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
<# | |
I) Sign executable: | |
.\Signing-Utilities.ps1 -CommaSeparatedFilesToSign "D:\FilesToSign\one.exe,D:\FilesToSign\two.exe" | |
II) Upload or update signing key: | |
Initialize-AWSDefaults -ProfileName !!!!!!!!!!!!!!!!! -Region eu-west-1 #Different profile for production | |
. .\Signing-Utilities.ps1 | |
UploadSigningKey -SigningKeyPath "C:\Users\s.larovyi\Desktop\KMS\testKey.pfx" -Password "secret" | |
List of saved values: https://eu-west-1.console.aws.amazon.com/ec2/v2/home?region=eu-west-1#Parameters:sort=Name | |
#> | |
param( | |
[string]$CommaSeparatedFilesToSign = "" | |
) | |
function CreateSecret([string]$Name, [string]$Value, [string]$Description = " "){ | |
function NewKmsKey($Name, $Value, $Description, $Alias, [bool]$SandboxOnly = $false){ | |
#policy that allows the root deployments access to the key | |
$iamUsers = @{ 'dev' = '!!!!!!!!!!!!!!!!!'; 'sandbox' = '!!!!!!!!!!!!!!!!!'; 'production' = '!!!!!!!!!!!!!!!!!' }; | |
$roles = @{ | |
'sandbox' = '!!!!!!!!!!!!!!!!!'; | |
'xx' = '!!!!!!!!!!!!!!!!!'; | |
'teamcity' = 'teamcity-build-agent'; | |
'teamcityServiceAccount' = 'serviceAccount-TeamCity'; | |
}; | |
$decryptRole = if($SandboxOnly){ $roles.sandbox }else{ $roles.xx } | |
$iamUser = if($SandboxOnly){ $iamUsers.sandbox }else{ $iamUsers.production } | |
Write-Host "Using $($iamUser) user and $($decryptRole) role" | |
$policy = ' | |
{ | |
"Version": "2012-10-17", | |
"Id": "key-default-1", | |
"Statement": [ | |
{ | |
"Sid": "Enable IAM User Permissions", | |
"Effect": "Allow", | |
"Principal": { | |
"AWS": "arn:aws:iam::'+ $iamUser +':root" | |
}, | |
"Action": "kms:*", | |
"Resource": "*" | |
}, | |
{ | |
"Sid": "Allow Decryption", | |
"Effect": "Allow", | |
"Principal": { | |
"AWS": "arn:aws:iam::'+ $iamUser +':role/' + $decryptRole + '" | |
}, | |
"Action": "kms:Decrypt", | |
"Resource": "*" | |
} | |
] | |
}'; | |
#"AWS": "arn:aws:iam::'+ $iamUsers.production +':role/' + $roles.teamcity + '", | |
#"AWS": "arn:aws:iam::'+ $iamUsers.production +':role/' + $roles.teamcityServiceAccount + '" | |
Write-Host "Policy for new KMS Key: $($policy)" | |
#create kms key, assign an alias and add the value to ssm | |
$newKey = New-KMSKey -Description $Description -Policy $policy | %{ | |
#http://docs.aws.amazon.com/powershell/latest/reference/items/New-KMSAlias.html | |
New-KMSAlias -AliasName "alias/$($Alias.Trim().ToLower())" -TargetKeyId $_.KeyId | |
Write-SSMParameter -KeyId $_.KeyId -Description $Description -Name $Name.Trim().ToLower() -Type SecureString -Value $Value.Trim() | |
} | |
} | |
#Initialize-AWSDefaults -ProfileName !!!!!!!!!!!!!!!!! -Region eu-west-1 | |
$isSandboxProfile = (Get-AWSCredentials -ListProfiles).IndexOf("!!!!!!!!!!!!!!!!!") -ne -1; | |
NewKmsKey -Name $Name -Value $Value -Description $Description -Alias $Name -SandboxOnly $isSandboxProfile | |
} | |
function GetSecret ([string]$Name) { | |
return (Get-SSMParameterValue -Name $Name.Trim().ToLower() -Region eu-west-1 -WithDecryption $true).Parameters[0].Value; | |
} | |
function HasSecret([string]$Name){ | |
function GetKmsKey($Name) { Get-KMSKey -KeyId "alias/$($Name.Trim().ToLower())" } | |
return (GetKmsKey $Name) -ne $null; | |
} | |
function DeleteSecret([string]$Name){ | |
$realName = $Name.Trim().ToLower(); | |
$alias = "alias/$($realName)"; | |
Remove-SSMParameter -Name $realName -Force | |
Write-Host $alias | |
Remove-KMSAlias -AliasName $alias -Force | |
} | |
function UploadSecretFile([string]$Name, [string]$Path, [string]$Description = " "){ | |
$bytes = Get-Content $Path -Encoding Byte | |
$value = [System.Convert]::ToBase64String($bytes); | |
CreateSecret -Name $Name -Value $value -Description $Description | |
} | |
function DownloadSecretFile([string]$Name, [string] $PathToSave){ | |
$stringValue = GetSecret -Name $Name; | |
$bytes = [System.Convert]::FromBase64String($stringValue); | |
[System.IO.File]::WriteAllBytes($PathToSave,$bytes) | |
} | |
function ConvertBinaryFileToTextFile([string]$BinaryFile, [string] $TextFile){ | |
$bytes = Get-Content $BinaryFile -Encoding Byte | |
$value = [System.Convert]::ToBase64String($bytes); | |
$value | Out-File -Filepath $TextFile | |
} | |
function ConvertTextFileToBinaryFile([string] $TextFile, [string]$BinaryFile){ | |
$stringValue = Get-Content $TextFile | |
$bytes = [System.Convert]::FromBase64String($stringValue); | |
[System.IO.File]::WriteAllBytes($BinaryFile,$bytes) | |
} | |
function Sign([string]$ExecutablePath, [string]$SigningKeyPath, [string]$Password){ | |
if ([string]::IsNullOrEmpty($Password)) { throw [System.IO.InvalidDataException] "Empty certificate password" } | |
if (!(Test-Path $ExecutablePath)) { throw [System.ArgumentException] "Executable path is incorrect: '${$ExecutablePath}'" } | |
if (!(Test-Path $SigningKeyPath)) { throw [System.ArgumentException] "Signing key path is incorrect: '${$SigningKeyPath}'" } | |
if ([IO.Path]::GetExtension($SigningKeyPath) -ne ".pfx"){ throw [System.ArgumentException] "Signing key file should be 'pfx' file: '${$SigningKeyPath}'" } | |
$Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($SigningKeyPath, $Password) | |
if($Cert -eq $null) | |
{ | |
throw [System.IO.InvalidDataException] "Incorrect certificate" | |
} | |
Set-AuthenticodeSignature -FilePath $ExecutablePath -Certificate $Cert -ErrorAction Stop | |
Write-Host "File '$($ExecutablePath)' has been signed with '$($SigningKeyPath)'. You may see some not important error in console if you use test certificate."; | |
} | |
function SignFiles([string] $CommaSeparatedFilesToSign){ | |
$files = $CommaSeparatedFilesToSign -split ',' | |
$signingKeyPath = join-path (Resolve-Path .\).Path "key.pfx"; | |
$password = GetSecret -Name "SigningKeyPassword"; | |
DownloadSecretFile -Name "SigningKey" -PathToSave $signingKeyPath | |
try { | |
foreach($fileToSign in $files){ | |
Sign -ExecutablePath $fileToSign -SigningKeyPath $signingKeyPath -Password $password | |
} | |
} | |
finally { | |
Remove-Item $signingKeyPath | |
} | |
} | |
function UploadSigningKey ([string]$SigningKeyPath, [string]$Password) { | |
$fileKey = "SigningKey"; | |
$passwordKey = "SigningKeyPassword"; | |
if (HasSecret -Name $fileKey) { | |
DeleteSecret -Name $fileKey | |
DeleteSecret -Name $passwordKey | |
} | |
UploadSecretFile -Name $fileKey -Path $SigningKeyPath -Description "signing key" | |
CreateSecret -Name $passwordKey -Value $Password -Description "signing key password" | |
} | |
Write-Host "Signing files: '$($CommaSeparatedFilesToSign)' with Version $(3) of 'Signing-Utilities.ps1'" | |
Write-Host "Roles assigned to machine:" | |
(Get-AWSCredentials -ListProfiles) | Write-Host | |
#Initialize-AWSDefaults -ProfileName !!!!!!!!!!!!!!!!! -Region eu-west-1 | |
#Write-Host "Log in as !!!!!!!!!!!!!!!!!" | |
if (![string]::IsNullOrEmpty($CommaSeparatedFilesToSign)) { | |
SignFiles -CommaSeparatedFilesToSign $CommaSeparatedFilesToSign | |
} else { | |
Write-Host "No files specified for signing" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment