Files
jobtrackingapp/automation/tests/Synthetic-Signer.ps1
T

26 lines
2.0 KiB
PowerShell

#Requires -Version 7.2
# Disposable test key only. Production signing uses the owner's nonexportable certificate.
param([ValidateSet('Setup','Sign')][string]$Action, [string]$Root, [string]$RequestPath, [string]$ApprovalPath)
$ErrorActionPreference = 'Stop'
$rsa = [Security.Cryptography.RSA]::Create(2048)
try {
if ($Action -eq 'Setup') {
$request = [Security.Cryptography.X509Certificates.CertificateRequest]::new('CN=DISPOSABLE SYNTHETIC ONLY', $rsa,
[Security.Cryptography.HashAlgorithmName]::SHA256,[Security.Cryptography.RSASignaturePadding]::Pkcs1)
$cert = $request.CreateSelfSigned([DateTimeOffset]::UtcNow.AddMinutes(-1),[DateTimeOffset]::UtcNow.AddHours(2))
[IO.File]::WriteAllBytes((Join-Path $Root 'owner.cer'),$cert.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert))
[IO.File]::WriteAllText((Join-Path $Root 'synthetic-private.pem'),$rsa.ExportPkcs8PrivateKeyPem())
$cert.Dispose()
} else {
$rsa.ImportFromPem([IO.File]::ReadAllText((Join-Path $Root 'synthetic-private.pem')))
$hash = [Convert]::ToHexString([Security.Cryptography.SHA256]::HashData([IO.File]::ReadAllBytes($RequestPath))).ToLowerInvariant()
$payload = @{requestSha256=$hash;approved=$true;ownerSid='OWNER';decision='Synthetic owner approves exact request';disposition='Approve';
issuedUtc=[DateTimeOffset]::UtcNow.ToString('o');expiresUtc=[DateTimeOffset]::UtcNow.AddHours(1).ToString('o')} | ConvertTo-Json -Compress
$bytes = [Text.Encoding]::UTF8.GetBytes($payload)
$signature = $rsa.SignData($bytes,[Security.Cryptography.HashAlgorithmName]::SHA256,[Security.Cryptography.RSASignaturePadding]::Pkcs1)
[IO.Directory]::CreateDirectory([IO.Path]::GetDirectoryName($ApprovalPath)) | Out-Null
@{payloadBase64=[Convert]::ToBase64String($bytes);signatureBase64=[Convert]::ToBase64String($signature)} |
ConvertTo-Json -Compress | Set-Content -LiteralPath $ApprovalPath -Encoding utf8NoBOM
}
} finally { $rsa.Dispose() }