# Remote OpenSSL GOST Signer (OSS) ยท 2025-12-11 Portable, open-source remote signer for GOST R 34.10/34.11 using the `rnix/openssl-gost` image. Use when CryptoPro CSP is unavailable and a remote Linux host can expose signing via HTTP. ## Goals - Remote, OSS-only signer for the `ru.openssl.gost` profile. - Deterministic digest harness (fixed message) for smoke checks. - Configurable endpoint so hosts can toggle between local and remote. ## Quickstart (remote host) ```bash # 1) Run the OpenSSL GOST container on the remote host docker run --rm -p 8088:8080 --name gost-remote rnix/openssl-gost:latest sleep 365d # 2) Start the lightweight HTTP gateway (one-liner, no deps) cat > /tmp/gost-remote.sh <<'EOF' #!/usr/bin/env bash set -euo pipefail msg_file="$(mktemp)" sig_file="$(mktemp)" pub_file="$(mktemp)" trap 'rm -f "$msg_file" "$sig_file" "$pub_file"' EXIT while true; do # Simple netcat JSON protocol: {"message_b64":"..."} nc -l -p 9090 -q 1 | { read payload msg_b64="$(echo "$payload" | jq -r .message_b64)" echo "$msg_b64" | base64 -d > "$msg_file" # Generate key once per container (persist by volume if desired) if [ ! -f /tmp/gost.key.pem ]; then openssl genpkey -engine gost -algorithm gost2012_256 -pkeyopt paramset:A -out /tmp/gost.key.pem >/dev/null openssl pkey -engine gost -in /tmp/gost.key.pem -pubout -out /tmp/gost.pub.pem >/dev/null fi # Sign (nonce-driven, signatures differ each call) openssl dgst -engine gost -md_gost12_256 -sign /tmp/gost.key.pem -out "$sig_file" "$msg_file" # Respond with signature/public key (base64) jq -n --arg sig_b64 "$(base64 -w0 "$sig_file")" \ --arg pub_pem "$(base64 -w0 /tmp/gost.pub.pem)" \ '{signature_b64:$sig_b64, public_key_pem_b64:$pub_pem}' } done EOF chmod +x /tmp/gost-remote.sh /tmp/gost-remote.sh ``` ## Client invocation (any host) ```bash MESSAGE="stellaops-remote-gost-smoke" curl -s -X POST http://REMOTE_HOST:9090 \ -d "{\"message_b64\":\"$(printf '%s' \"$MESSAGE\" | base64 -w0)\"}" \ | tee /tmp/gost-remote-response.json sig_b64=$(jq -r .signature_b64 /tmp/gost-remote-response.json) pub_pem_b64=$(jq -r .public_key_pem_b64 /tmp/gost-remote-response.json) printf '%s' "$pub_pem_b64" | base64 -d > /tmp/gost-remote.pub.pem printf '%s' "$MESSAGE" > /tmp/gost-remote.msg printf '%s' "$sig_b64" | base64 -d > /tmp/gost-remote.sig # Verify locally openssl dgst -engine gost -md_gost12_256 \ -verify /tmp/gost-remote.pub.pem \ -signature /tmp/gost-remote.sig /tmp/gost-remote.msg ``` ## Configuration toggle (hosts) - Add an env toggle to your deployment: `STELLAOPS_RU_OPENSSL_REMOTE_URL=http://remote-gost:9090` - When set, route `ru.openssl.gost` signing through the HTTP gateway; when unset, use local `OpenSslGostProvider`. - Keep Linux fallback enabled: `STELLAOPS_CRYPTO_ENABLE_RU_OPENSSL=1`. ## Determinism - Digest is deterministic (`md_gost12_256` over caller-supplied message). - Signatures vary per request (nonce) but verify deterministically; capture `signature_b64` and `public_key_pem_b64` for evidence. ## Operational notes - Remote host must have Docker + `rnix/openssl-gost` image (no vendor binaries). - Network access is limited to port 9090; use mTLS or SSH tunnel in production. - Persist `/tmp/gost.key.pem` via a volume if you need stable `kid`; otherwise accept ephemeral keys for testing. ## Attach to sprint evidence - Store `gost-remote-response.json`, `gost-remote.pub.pem`, and verification output with the sprint log. - Record the remote endpoint and run timestamp in the sprint Execution Log.