|
| 1 | +# QZ Tray Signing Verification Script |
| 2 | + |
| 3 | +Write-Host "`n========================================" -ForegroundColor Cyan |
| 4 | +Write-Host "QZ Tray Signing System Verification" -ForegroundColor Cyan |
| 5 | +Write-Host "========================================`n" -ForegroundColor Cyan |
| 6 | + |
| 7 | +# Check 1: Private key exists |
| 8 | +Write-Host "[1] Checking private key..." -ForegroundColor White |
| 9 | +$privateKey = "server\private-key.pem" |
| 10 | +if (Test-Path $privateKey) { |
| 11 | + $keyContent = Get-Content $privateKey -Raw |
| 12 | + if ($keyContent -match "BEGIN.*PRIVATE KEY") { |
| 13 | + Write-Host " ✓ Private key found and valid" -ForegroundColor Green |
| 14 | + $keySize = $keyContent.Length |
| 15 | + Write-Host " Size: $keySize bytes" -ForegroundColor Gray |
| 16 | + } else { |
| 17 | + Write-Host " ✗ Invalid key format" -ForegroundColor Red |
| 18 | + } |
| 19 | +} else { |
| 20 | + Write-Host " ✗ Private key not found!" -ForegroundColor Red |
| 21 | +} |
| 22 | + |
| 23 | +# Check 2: Certificate exists |
| 24 | +Write-Host "`n[2] Checking X.509 certificate..." -ForegroundColor White |
| 25 | +$cert = "server\qz-certificate.crt" |
| 26 | +if (Test-Path $cert) { |
| 27 | + $certContent = Get-Content $cert -Raw |
| 28 | + if ($certContent -match "BEGIN CERTIFICATE") { |
| 29 | + Write-Host " ✓ Certificate found (X.509 format)" -ForegroundColor Green |
| 30 | + |
| 31 | + # Verify certificate details |
| 32 | + $certInfo = openssl x509 -in $cert -text -noout 2>$null |
| 33 | + if ($certInfo -match "Subject:.*POSDic") { |
| 34 | + Write-Host " ✓ Certificate organization: POSDic" -ForegroundColor Green |
| 35 | + } |
| 36 | + if ($certInfo -match "Signature Algorithm: sha256") { |
| 37 | + Write-Host " ✓ Signature algorithm: SHA256" -ForegroundColor Green |
| 38 | + } |
| 39 | + } else { |
| 40 | + Write-Host " ✗ Invalid certificate format" -ForegroundColor Red |
| 41 | + } |
| 42 | +} else { |
| 43 | + Write-Host " ✗ Certificate not found!" -ForegroundColor Red |
| 44 | +} |
| 45 | + |
| 46 | +# Check 3: Test signing endpoint |
| 47 | +Write-Host "`n[3] Testing signing endpoint..." -ForegroundColor White |
| 48 | +try { |
| 49 | + $testData = @{ |
| 50 | + toSign = "test-data-$(Get-Date -Format 'yyyyMMddHHmmss')" |
| 51 | + } | ConvertTo-Json |
| 52 | + |
| 53 | + $response = Invoke-RestMethod -Uri "https://localhost:3000/api/sign" ` |
| 54 | + -Method POST ` |
| 55 | + -Body $testData ` |
| 56 | + -ContentType "application/json" ` |
| 57 | + -SkipCertificateCheck ` |
| 58 | + -ErrorAction Stop |
| 59 | + |
| 60 | + if ($response.signature) { |
| 61 | + Write-Host " ✓ Signing endpoint working!" -ForegroundColor Green |
| 62 | + Write-Host " Signature length: $($response.signature.Length) chars" -ForegroundColor Gray |
| 63 | + Write-Host " Sample: $($response.signature.Substring(0, [Math]::Min(40, $response.signature.Length)))..." -ForegroundColor Gray |
| 64 | + } else { |
| 65 | + Write-Host " ✗ No signature returned" -ForegroundColor Red |
| 66 | + } |
| 67 | +} catch { |
| 68 | + Write-Host " ✗ Signing endpoint failed: $($_.Exception.Message)" -ForegroundColor Red |
| 69 | + Write-Host " Make sure the server is running (npm run dev)" -ForegroundColor Yellow |
| 70 | +} |
| 71 | + |
| 72 | +# Check 4: Frontend certificate |
| 73 | +Write-Host "`n[4] Checking frontend certificate..." -ForegroundColor White |
| 74 | +$frontendCert = "src\assets\digital-certificate.txt" |
| 75 | +if (Test-Path $frontendCert) { |
| 76 | + $frontContent = Get-Content $frontendCert -Raw |
| 77 | + if ($frontContent -match "BEGIN CERTIFICATE") { |
| 78 | + Write-Host " ✓ Frontend has X.509 certificate" -ForegroundColor Green |
| 79 | + |
| 80 | + # Verify it matches server certificate |
| 81 | + $serverContent = Get-Content $cert -Raw -ErrorAction SilentlyContinue |
| 82 | + if ($frontContent.Trim() -eq $serverContent.Trim()) { |
| 83 | + Write-Host " ✓ Matches server certificate" -ForegroundColor Green |
| 84 | + } else { |
| 85 | + Write-Host " ⚠ Different from server certificate" -ForegroundColor Yellow |
| 86 | + } |
| 87 | + } else { |
| 88 | + Write-Host " ✗ Wrong format (should be X.509)" -ForegroundColor Red |
| 89 | + } |
| 90 | +} else { |
| 91 | + Write-Host " ✗ Frontend certificate not found!" -ForegroundColor Red |
| 92 | +} |
| 93 | + |
| 94 | +# Summary |
| 95 | +Write-Host "`n========================================" -ForegroundColor Cyan |
| 96 | +Write-Host "How Signing Works:" -ForegroundColor Cyan |
| 97 | +Write-Host "========================================" -ForegroundColor Cyan |
| 98 | +Write-Host "" |
| 99 | +Write-Host "1. Frontend loads certificate from:" -ForegroundColor White |
| 100 | +Write-Host " src/assets/digital-certificate.txt" -ForegroundColor Gray |
| 101 | +Write-Host "" |
| 102 | +Write-Host "2. QZ Tray receives print data" -ForegroundColor White |
| 103 | +Write-Host " (receipt HTML, config, etc.)" -ForegroundColor Gray |
| 104 | +Write-Host "" |
| 105 | +Write-Host "3. QZ Tray sends data to backend:" -ForegroundColor White |
| 106 | +Write-Host " POST /api/sign { toSign: '<data>' }" -ForegroundColor Gray |
| 107 | +Write-Host "" |
| 108 | +Write-Host "4. Backend signs with SHA512:" -ForegroundColor White |
| 109 | +Write-Host " crypto.createSign('SHA512')" -ForegroundColor Gray |
| 110 | +Write-Host " Uses: server/private-key.pem" -ForegroundColor Gray |
| 111 | +Write-Host "" |
| 112 | +Write-Host "5. QZ Tray verifies signature:" -ForegroundColor White |
| 113 | +Write-Host " Uses certificate from step 1" -ForegroundColor Gray |
| 114 | +Write-Host " Checks signature matches data" -ForegroundColor Gray |
| 115 | +Write-Host "" |
| 116 | +Write-Host "6. If valid → Print proceeds ✓" -ForegroundColor Green |
| 117 | +Write-Host " If invalid → Print rejected ✗" -ForegroundColor Red |
| 118 | +Write-Host "" |
| 119 | +Write-Host "========================================" -ForegroundColor Cyan |
| 120 | +Write-Host "ALL print jobs are cryptographically signed!" -ForegroundColor Green |
| 121 | +Write-Host "This prevents unauthorized printing." -ForegroundColor Green |
| 122 | +Write-Host "========================================`n" -ForegroundColor Cyan |
| 123 | + |
| 124 | +Read-Host "Press Enter to exit" |
0 commit comments