<# .SYNOPSIS One-liner installer for the check-pqc CLI on Windows. .DESCRIPTION Verifies prerequisites (Node.js >= 18, OpenSSL >= 3.5 with ML-KEM or a network connection for the live probe), installs the npm package globally as @aegyrix/check-pqc, and runs --check-offline to confirm the install. This script does NOT bundle Node or OpenSSL. If you need a self- contained option, use the Docker image instead: docker run --rm ghcr.io/aegyrix/check-pqc:latest example.com .EXAMPLE iwr -useb https://checkpqc.com/install.ps1 | iex .EXAMPLE # Install a pinned version $env:CHECKPQC_VERSION = '0.2.8' iwr -useb https://checkpqc.com/install.ps1 | iex .LINK https://checkpqc.com/cli https://github.com/aegyrix/checkpqc.app #> [CmdletBinding()] param( [string]$Version = $env:CHECKPQC_VERSION, [switch]$Force ) $ErrorActionPreference = 'Stop' $PSDefaultParameterValues['*:ErrorAction'] = 'Stop' # --- helpers -------------------------------------------------------------- function Write-Step { param($m) Write-Host "==> $m" -ForegroundColor Cyan } function Write-Ok { param($m) Write-Host " ✓ $m" -ForegroundColor Green } function Write-Warn { param($m) Write-Host " ! $m" -ForegroundColor Yellow } function Write-Fail { param($m) Write-Host " ✗ $m" -ForegroundColor Red; exit 1 } function Test-Command { param([string]$Name) $null -ne (Get-Command $Name -ErrorAction SilentlyContinue) } function Confirm-Install { param([string]$Message) $answer = Read-Host "$Message Install now? [y/N]" return ($answer -match '^[Yy]') } function Install-NodeDependency { if (Test-Command winget) { winget install OpenJS.NodeJS.LTS return } if (Test-Command scoop) { scoop install nodejs-lts return } if (Test-Command choco) { choco install nodejs-lts -y return } Write-Fail 'No supported package manager found. Install Node.js 18+ from https://nodejs.org/en/download and rerun this script.' } function Install-OpenSSLDependency { if (Test-Command winget) { winget install ShiningLight.OpenSSL.Light return } if (Test-Command choco) { choco install openssl.light -y return } Write-Warn 'No supported package manager found. Install or pre-stage OpenSSL 3.5+ manually for full local/offline proofs.' } # --- banner --------------------------------------------------------------- Write-Host '' Write-Host ' CheckPQC CLI installer' -ForegroundColor White Write-Host ' https://checkpqc.com/cli' -ForegroundColor DarkGray Write-Host '' # --- pre-flight: Node.js -------------------------------------------------- Write-Step 'Checking Node.js (>= 18)' if (-not (Test-Command node)) { Write-Warn 'Node.js is not installed. check-pqc needs Node.js 18+ for the local CLI path.' if (Confirm-Install 'Install Node.js 18+') { Install-NodeDependency } else { Write-Fail 'Install Node.js 18+ and rerun this script.' } } $nodeVersion = (& node --version) -replace '^v','' $nodeMajor = [int]($nodeVersion.Split('.')[0]) if ($nodeMajor -lt 18) { Write-Warn "Node.js $nodeVersion found; check-pqc requires Node 18+." if (Confirm-Install 'Upgrade/install Node.js 18+') { Install-NodeDependency $nodeVersion = (& node --version) -replace '^v','' $nodeMajor = [int]($nodeVersion.Split('.')[0]) if ($nodeMajor -lt 18) { Write-Fail "Node.js $nodeVersion found after install; still need Node 18+." } } else { Write-Fail 'Upgrade Node.js to 18+ and rerun this script.' } } Write-Ok "Node.js $nodeVersion" # --- pre-flight: npm ------------------------------------------------------ if (-not (Test-Command npm)) { Write-Warn 'npm is not on PATH (Node install incomplete?).' if (Confirm-Install 'Install npm by reinstalling/updating Node.js') { Install-NodeDependency } else { Write-Fail 'Install npm and rerun this script.' } } Write-Ok "npm $((& npm --version))" # --- pre-flight: OpenSSL (informational; required for live probes) ------- Write-Step 'Checking OpenSSL (3.5+ with ML-KEM, optional but recommended)' if (Test-Command openssl) { $opensslVersion = (& openssl version) -replace '\s+', ' ' Write-Ok "openssl: $opensslVersion" # Probe for ML-KEM group support (best-effort, non-fatal). $hasMlkem = $false try { $groups = & openssl list -tls-groups 2>$null if ($groups -match '(?i)mlkem') { $hasMlkem = $true } } catch { } if ($hasMlkem) { Write-Ok 'ML-KEM TLS groups available (full live-probe support)' } else { Write-Warn 'OpenSSL present but no ML-KEM groups detected.' Write-Warn 'Live probes will work for SERVER_ONLY/CLIENT_ONLY verdicts.' if (Confirm-Install 'Install or upgrade OpenSSL for full local PQC proofs?') { Install-OpenSSLDependency } else { Write-Warn 'For full PQC capability later, install OpenSSL 3.5+ or use:' Write-Warn ' docker run --rm ghcr.io/aegyrix/check-pqc:offline ' } } } else { Write-Warn 'OpenSSL not found on PATH. Live probes need OpenSSL 3.5+.' Write-Warn 'Offline checks (--check-offline) will still work.' if (Confirm-Install 'Install OpenSSL for full local PQC proofs?') { Install-OpenSSLDependency } } # --- existing install? --------------------------------------------------- if ((Test-Command 'check-pqc') -and -not $Force) { $existing = (& check-pqc --version 2>$null) Write-Step "Existing install detected: $existing" Write-Warn 'Re-run with -Force to reinstall, or upgrade with:' Write-Warn ' npm update -g @aegyrix/check-pqc' if ($Version -and $existing -notmatch [regex]::Escape($Version)) { Write-Step "Pinned version `"$Version`" requested; reinstalling" } else { Write-Host '' Write-Host 'Already installed. Try:' -ForegroundColor White Write-Host ' check-pqc google.com' -ForegroundColor Gray Write-Host ' check-pqc --check-offline' -ForegroundColor Gray return } } # --- install -------------------------------------------------------------- $pkg = if ($Version) { "@aegyrix/check-pqc@$Version" } else { '@aegyrix/check-pqc@latest' } Write-Step "Installing $pkg globally via npm" # Capture both streams; npm writes progress to stderr. $installOutput = & npm install -g $pkg 2>&1 if ($LASTEXITCODE -ne 0) { $installOutput | ForEach-Object { Write-Host " $_" -ForegroundColor DarkGray } Write-Fail "npm install failed (exit $LASTEXITCODE). Try running PowerShell as Administrator, or use a Node version manager (nvm-windows, fnm)." } Write-Ok 'Installed' # --- verify --------------------------------------------------------------- Write-Step 'Verifying install' if (-not (Test-Command 'check-pqc')) { Write-Fail @" check-pqc command not on PATH after install. If you used a per-user Node install, npm's global bin folder may not be on PATH. Add this to your PowerShell profile: `$env:Path += ';' + (npm config get prefix) Then restart your shell. "@ } $installed = (& check-pqc --version 2>$null) -replace '\s+', '' Write-Ok "check-pqc $installed" # Confirm offline capability detection runs cleanly. & check-pqc --check-offline | Out-Null if ($LASTEXITCODE -ne 0 -and $LASTEXITCODE -ne 2) { # Exit 0 = full PQC ready, 2 = partial — both are healthy installs. Write-Warn "check-pqc --check-offline exited $LASTEXITCODE; install OpenSSL 3.5+ for full capability." } # --- next steps ----------------------------------------------------------- Write-Host '' Write-Host ' ✓ Done.' -ForegroundColor Green Write-Host '' Write-Host ' Try a probe:' -ForegroundColor White Write-Host ' check-pqc google.com' -ForegroundColor Gray Write-Host ' check-pqc --json checkpqc.app' -ForegroundColor Gray Write-Host ' check-pqc --check-offline' -ForegroundColor Gray Write-Host '' Write-Host ' Docs: https://checkpqc.com/cli' -ForegroundColor DarkGray Write-Host ' Source: https://github.com/aegyrix/checkpqc.app' -ForegroundColor DarkGray Write-Host ''