Add post-quantum cryptography support with PqSoftCryptoProvider
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
wine-csp-build / Build Wine CSP Image (push) Has been cancelled
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
wine-csp-build / Build Wine CSP Image (push) Has been cancelled
- Implemented PqSoftCryptoProvider for software-only post-quantum algorithms (Dilithium3, Falcon512) using BouncyCastle. - Added PqSoftProviderOptions and PqSoftKeyOptions for configuration. - Created unit tests for Dilithium3 and Falcon512 signing and verification. - Introduced EcdsaPolicyCryptoProvider for compliance profiles (FIPS/eIDAS) with explicit allow-lists. - Added KcmvpHashOnlyProvider for KCMVP baseline compliance. - Updated project files and dependencies for new libraries and testing frameworks.
This commit is contained in:
173
ops/wine-csp/Dockerfile
Normal file
173
ops/wine-csp/Dockerfile
Normal file
@@ -0,0 +1,173 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
# Wine CSP Service - GOST cryptographic operations via Wine-hosted CryptoPro CSP
|
||||
#
|
||||
# WARNING: For TEST VECTOR GENERATION ONLY - not for production signing
|
||||
#
|
||||
# Build:
|
||||
# docker buildx build -f ops/wine-csp/Dockerfile -t wine-csp:latest .
|
||||
#
|
||||
# Run:
|
||||
# docker run -p 5099:5099 -e WINE_CSP_MODE=limited wine-csp:latest
|
||||
|
||||
# ==============================================================================
|
||||
# Stage 1: Build .NET application for Windows x64
|
||||
# ==============================================================================
|
||||
ARG SDK_IMAGE=mcr.microsoft.com/dotnet/sdk:10.0-preview-bookworm-slim
|
||||
FROM ${SDK_IMAGE} AS build
|
||||
|
||||
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1 \
|
||||
DOTNET_NOLOGO=1 \
|
||||
DOTNET_ROLL_FORWARD=LatestMajor \
|
||||
SOURCE_DATE_EPOCH=1704067200
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
# Copy solution files and NuGet configuration
|
||||
COPY Directory.Build.props Directory.Build.rsp NuGet.config ./
|
||||
|
||||
# Copy local NuGet packages if available
|
||||
COPY local-nugets/ ./local-nugets/
|
||||
|
||||
# Copy Wine CSP Service source
|
||||
COPY src/__Tools/WineCspService/ ./src/__Tools/WineCspService/
|
||||
|
||||
# Copy GostCryptography fork dependency
|
||||
COPY third_party/forks/AlexMAS.GostCryptography/ ./third_party/forks/AlexMAS.GostCryptography/
|
||||
|
||||
# Restore and publish for Windows x64 (runs under Wine)
|
||||
RUN --mount=type=cache,target=/root/.nuget/packages \
|
||||
dotnet restore src/__Tools/WineCspService/WineCspService.csproj && \
|
||||
dotnet publish src/__Tools/WineCspService/WineCspService.csproj \
|
||||
-c Release \
|
||||
-r win-x64 \
|
||||
--self-contained true \
|
||||
-o /app/publish \
|
||||
/p:PublishSingleFile=true \
|
||||
/p:EnableCompressionInSingleFile=true \
|
||||
/p:DebugType=none \
|
||||
/p:DebugSymbols=false
|
||||
|
||||
# ==============================================================================
|
||||
# Stage 2: Runtime with Wine and CryptoPro CSP support
|
||||
# ==============================================================================
|
||||
FROM ubuntu:22.04 AS runtime
|
||||
|
||||
# OCI Image Labels
|
||||
LABEL org.opencontainers.image.title="StellaOps Wine CSP Service" \
|
||||
org.opencontainers.image.description="GOST cryptographic test vector generation via Wine-hosted CryptoPro CSP" \
|
||||
org.opencontainers.image.vendor="StellaOps" \
|
||||
org.opencontainers.image.source="https://git.stella-ops.org/stellaops/router" \
|
||||
com.stellaops.component="wine-csp" \
|
||||
com.stellaops.security.production-signing="false" \
|
||||
com.stellaops.security.test-vectors-only="true"
|
||||
|
||||
# Wine CSP service configuration
|
||||
ARG WINE_CSP_PORT=5099
|
||||
ARG APP_USER=winecsp
|
||||
ARG APP_UID=10001
|
||||
ARG APP_GID=10001
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive \
|
||||
# Wine configuration
|
||||
WINEDEBUG=-all \
|
||||
WINEPREFIX=/home/${APP_USER}/.wine \
|
||||
WINEARCH=win64 \
|
||||
# Service configuration
|
||||
WINE_CSP_PORT=${WINE_CSP_PORT} \
|
||||
ASPNETCORE_URLS=http://+:${WINE_CSP_PORT} \
|
||||
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1 \
|
||||
# CSP configuration
|
||||
WINE_CSP_MODE=limited \
|
||||
WINE_CSP_INSTALLER_PATH=/opt/cryptopro/csp-installer.msi \
|
||||
WINE_CSP_LOG_LEVEL=Information \
|
||||
# Display for Wine (headless)
|
||||
DISPLAY=:99
|
||||
|
||||
# Install Wine and dependencies
|
||||
# Using WineHQ stable repository for consistent Wine version
|
||||
RUN set -eux; \
|
||||
dpkg --add-architecture i386; \
|
||||
apt-get update; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg2 \
|
||||
software-properties-common \
|
||||
wget \
|
||||
xvfb \
|
||||
cabextract \
|
||||
p7zip-full \
|
||||
procps; \
|
||||
# Add WineHQ repository key
|
||||
mkdir -pm755 /etc/apt/keyrings; \
|
||||
wget -O /etc/apt/keyrings/winehq-archive.key \
|
||||
https://dl.winehq.org/wine-builds/winehq.key; \
|
||||
# Add WineHQ repository
|
||||
wget -NP /etc/apt/sources.list.d/ \
|
||||
https://dl.winehq.org/wine-builds/ubuntu/dists/jammy/winehq-jammy.sources; \
|
||||
apt-get update; \
|
||||
# Install Wine stable
|
||||
apt-get install -y --no-install-recommends \
|
||||
winehq-stable; \
|
||||
# Install winetricks for runtime dependencies
|
||||
wget -O /usr/local/bin/winetricks \
|
||||
https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks; \
|
||||
chmod +x /usr/local/bin/winetricks; \
|
||||
# Cleanup
|
||||
apt-get clean; \
|
||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
# Create non-root user for Wine service
|
||||
# Note: Wine requires writable home directory for prefix
|
||||
RUN groupadd -r -g ${APP_GID} ${APP_USER} && \
|
||||
useradd -r -u ${APP_UID} -g ${APP_GID} -m -d /home/${APP_USER} -s /bin/bash ${APP_USER} && \
|
||||
mkdir -p /app /opt/cryptopro /var/log/wine-csp /var/run/wine-csp && \
|
||||
chown -R ${APP_UID}:${APP_GID} /app /home/${APP_USER} /opt/cryptopro /var/log/wine-csp /var/run/wine-csp
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy application from build stage
|
||||
COPY --from=build --chown=${APP_UID}:${APP_GID} /app/publish/ ./
|
||||
|
||||
# Copy supporting scripts
|
||||
COPY --chown=${APP_UID}:${APP_GID} ops/wine-csp/entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
COPY --chown=${APP_UID}:${APP_GID} ops/wine-csp/healthcheck.sh /usr/local/bin/healthcheck.sh
|
||||
COPY --chown=${APP_UID}:${APP_GID} ops/wine-csp/install-csp.sh /usr/local/bin/install-csp.sh
|
||||
RUN chmod +x /usr/local/bin/entrypoint.sh /usr/local/bin/healthcheck.sh /usr/local/bin/install-csp.sh
|
||||
|
||||
# Switch to non-root user for Wine prefix initialization
|
||||
USER ${APP_UID}:${APP_GID}
|
||||
|
||||
# Initialize Wine prefix (creates .wine directory with Windows environment)
|
||||
# This must run as the app user to set correct ownership
|
||||
# Using xvfb-run for headless Wine initialization
|
||||
RUN set -eux; \
|
||||
# Start virtual framebuffer and initialize Wine
|
||||
xvfb-run --auto-servernum --server-args="-screen 0 1024x768x24" \
|
||||
wine64 wineboot --init; \
|
||||
wineserver --wait; \
|
||||
# Install Visual C++ 2019 runtime via winetricks (required for .NET)
|
||||
xvfb-run --auto-servernum --server-args="-screen 0 1024x768x24" \
|
||||
winetricks -q vcrun2019 || true; \
|
||||
wineserver --wait; \
|
||||
# Set Windows version to Windows 10 for compatibility
|
||||
wine64 reg add "HKCU\\Software\\Wine\\Version" /v Windows /d "win10" /f || true; \
|
||||
wineserver --wait; \
|
||||
# Cleanup Wine temp files
|
||||
rm -rf /home/${APP_USER}/.cache/winetricks /tmp/.X* /tmp/winetricks* || true
|
||||
|
||||
EXPOSE ${WINE_CSP_PORT}
|
||||
|
||||
# Health check using custom script that probes /health endpoint
|
||||
# Extended start_period due to Wine initialization time
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \
|
||||
CMD /usr/local/bin/healthcheck.sh
|
||||
|
||||
# Volumes for persistence and CSP installer
|
||||
# - Wine prefix: stores CSP installation, certificates, keys
|
||||
# - CSP installer: mount customer-provided CryptoPro MSI here
|
||||
# - Logs: service logs
|
||||
VOLUME ["/home/${APP_USER}/.wine", "/opt/cryptopro", "/var/log/wine-csp"]
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
CMD ["wine64", "/app/WineCspService.exe"]
|
||||
227
ops/wine-csp/entrypoint.sh
Normal file
227
ops/wine-csp/entrypoint.sh
Normal file
@@ -0,0 +1,227 @@
|
||||
#!/bin/bash
|
||||
# Wine CSP Service Entrypoint
|
||||
#
|
||||
# Initializes Wine environment and starts the WineCspService under Wine.
|
||||
# For TEST VECTOR GENERATION ONLY - not for production signing.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Configuration
|
||||
# ------------------------------------------------------------------------------
|
||||
WINE_CSP_PORT="${WINE_CSP_PORT:-5099}"
|
||||
WINE_CSP_MODE="${WINE_CSP_MODE:-limited}"
|
||||
WINE_CSP_INSTALLER_PATH="${WINE_CSP_INSTALLER_PATH:-/opt/cryptopro/csp-installer.msi}"
|
||||
WINE_CSP_LOG_LEVEL="${WINE_CSP_LOG_LEVEL:-Information}"
|
||||
WINE_PREFIX="${WINEPREFIX:-$HOME/.wine}"
|
||||
DISPLAY="${DISPLAY:-:99}"
|
||||
|
||||
# Marker files
|
||||
CSP_INSTALLED_MARKER="${WINE_PREFIX}/.csp_installed"
|
||||
WINE_INITIALIZED_MARKER="${WINE_PREFIX}/.wine_initialized"
|
||||
|
||||
# Log prefix for structured logging
|
||||
log() {
|
||||
echo "[$(date -u '+%Y-%m-%dT%H:%M:%SZ')] [entrypoint] $*"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo "[$(date -u '+%Y-%m-%dT%H:%M:%SZ')] [entrypoint] [ERROR] $*" >&2
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Virtual Framebuffer Management
|
||||
# ------------------------------------------------------------------------------
|
||||
start_xvfb() {
|
||||
if ! pgrep -x Xvfb > /dev/null; then
|
||||
log "Starting Xvfb virtual framebuffer on display ${DISPLAY}"
|
||||
Xvfb "${DISPLAY}" -screen 0 1024x768x24 &
|
||||
sleep 2
|
||||
fi
|
||||
}
|
||||
|
||||
stop_xvfb() {
|
||||
if pgrep -x Xvfb > /dev/null; then
|
||||
log "Stopping Xvfb"
|
||||
pkill -x Xvfb || true
|
||||
fi
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Wine Initialization
|
||||
# ------------------------------------------------------------------------------
|
||||
initialize_wine() {
|
||||
if [[ -f "${WINE_INITIALIZED_MARKER}" ]]; then
|
||||
log "Wine prefix already initialized"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "Initializing Wine prefix at ${WINE_PREFIX}"
|
||||
|
||||
start_xvfb
|
||||
|
||||
# Initialize Wine prefix
|
||||
wine64 wineboot --init 2>/dev/null || true
|
||||
wineserver --wait
|
||||
|
||||
# Set Windows version for CryptoPro compatibility
|
||||
wine64 reg add "HKCU\\Software\\Wine\\Version" /v Windows /d "win10" /f 2>/dev/null || true
|
||||
wineserver --wait
|
||||
|
||||
# Create marker
|
||||
touch "${WINE_INITIALIZED_MARKER}"
|
||||
log "Wine prefix initialized successfully"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# CryptoPro CSP Installation
|
||||
# ------------------------------------------------------------------------------
|
||||
install_cryptopro() {
|
||||
# Check if already installed
|
||||
if [[ -f "${CSP_INSTALLED_MARKER}" ]]; then
|
||||
log "CryptoPro CSP already installed"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if installer is available
|
||||
if [[ ! -f "${WINE_CSP_INSTALLER_PATH}" ]]; then
|
||||
log "CryptoPro CSP installer not found at ${WINE_CSP_INSTALLER_PATH}"
|
||||
log "Service will run in limited mode without CSP"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "Installing CryptoPro CSP from ${WINE_CSP_INSTALLER_PATH}"
|
||||
|
||||
start_xvfb
|
||||
|
||||
# Run the CSP installation script
|
||||
if /usr/local/bin/install-csp.sh; then
|
||||
touch "${CSP_INSTALLED_MARKER}"
|
||||
log "CryptoPro CSP installed successfully"
|
||||
else
|
||||
log_error "CryptoPro CSP installation failed"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Service Configuration
|
||||
# ------------------------------------------------------------------------------
|
||||
configure_service() {
|
||||
log "Configuring Wine CSP service"
|
||||
log " Mode: ${WINE_CSP_MODE}"
|
||||
log " Port: ${WINE_CSP_PORT}"
|
||||
log " Log Level: ${WINE_CSP_LOG_LEVEL}"
|
||||
|
||||
# Configure Wine debug output based on log level
|
||||
case "${WINE_CSP_LOG_LEVEL}" in
|
||||
Trace|Debug)
|
||||
export WINEDEBUG="warn+all"
|
||||
;;
|
||||
Information)
|
||||
export WINEDEBUG="-all"
|
||||
;;
|
||||
Warning|Error|Critical)
|
||||
export WINEDEBUG="-all"
|
||||
;;
|
||||
*)
|
||||
export WINEDEBUG="-all"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Set ASP.NET Core environment
|
||||
export ASPNETCORE_URLS="http://+:${WINE_CSP_PORT}"
|
||||
export ASPNETCORE_ENVIRONMENT="${ASPNETCORE_ENVIRONMENT:-Production}"
|
||||
export Logging__LogLevel__Default="${WINE_CSP_LOG_LEVEL}"
|
||||
|
||||
# Check if CSP is available
|
||||
if [[ -f "${CSP_INSTALLED_MARKER}" ]]; then
|
||||
export WINE_CSP_CSP_AVAILABLE="true"
|
||||
log "CryptoPro CSP is available"
|
||||
else
|
||||
export WINE_CSP_CSP_AVAILABLE="false"
|
||||
log "Running without CryptoPro CSP (limited mode)"
|
||||
fi
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Startup Validation
|
||||
# ------------------------------------------------------------------------------
|
||||
validate_environment() {
|
||||
log "Validating environment"
|
||||
|
||||
# Check Wine is available
|
||||
if ! command -v wine64 &> /dev/null; then
|
||||
log_error "wine64 not found in PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check application exists
|
||||
if [[ ! -f "/app/WineCspService.exe" ]]; then
|
||||
log_error "WineCspService.exe not found at /app/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify Wine prefix is writable
|
||||
if [[ ! -w "${WINE_PREFIX}" ]]; then
|
||||
log_error "Wine prefix ${WINE_PREFIX} is not writable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Environment validation passed"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Signal Handlers
|
||||
# ------------------------------------------------------------------------------
|
||||
cleanup() {
|
||||
log "Received shutdown signal, cleaning up..."
|
||||
|
||||
# Stop Wine server gracefully
|
||||
wineserver -k 15 2>/dev/null || true
|
||||
sleep 2
|
||||
wineserver -k 9 2>/dev/null || true
|
||||
|
||||
stop_xvfb
|
||||
|
||||
log "Cleanup complete"
|
||||
exit 0
|
||||
}
|
||||
|
||||
trap cleanup SIGTERM SIGINT SIGQUIT
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Main Entry Point
|
||||
# ------------------------------------------------------------------------------
|
||||
main() {
|
||||
log "=========================================="
|
||||
log "Wine CSP Service Entrypoint"
|
||||
log "=========================================="
|
||||
log "WARNING: For TEST VECTOR GENERATION ONLY"
|
||||
log "=========================================="
|
||||
|
||||
validate_environment
|
||||
initialize_wine
|
||||
|
||||
# Only attempt CSP installation in full mode
|
||||
if [[ "${WINE_CSP_MODE}" == "full" ]]; then
|
||||
install_cryptopro
|
||||
fi
|
||||
|
||||
configure_service
|
||||
|
||||
# Start Xvfb for the main process
|
||||
start_xvfb
|
||||
|
||||
log "Starting WineCspService..."
|
||||
log "Listening on port ${WINE_CSP_PORT}"
|
||||
|
||||
# Execute the command passed to the container (or default)
|
||||
if [[ $# -gt 0 ]]; then
|
||||
exec "$@"
|
||||
else
|
||||
exec wine64 /app/WineCspService.exe
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
24
ops/wine-csp/healthcheck.sh
Normal file
24
ops/wine-csp/healthcheck.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# Wine CSP Service Health Check
|
||||
#
|
||||
# Probes the /health endpoint to determine if the service is healthy.
|
||||
# Returns 0 (healthy) or 1 (unhealthy).
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
WINE_CSP_PORT="${WINE_CSP_PORT:-5099}"
|
||||
HEALTH_ENDPOINT="http://127.0.0.1:${WINE_CSP_PORT}/health"
|
||||
TIMEOUT_SECONDS=8
|
||||
|
||||
# Perform health check
|
||||
response=$(wget -q -O - --timeout="${TIMEOUT_SECONDS}" "${HEALTH_ENDPOINT}" 2>/dev/null) || exit 1
|
||||
|
||||
# Verify response contains expected status
|
||||
if echo "${response}" | grep -q '"status":"Healthy"'; then
|
||||
exit 0
|
||||
elif echo "${response}" | grep -q '"status":"Degraded"'; then
|
||||
# Degraded is acceptable (e.g., CSP not installed but service running)
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
215
ops/wine-csp/install-csp.sh
Normal file
215
ops/wine-csp/install-csp.sh
Normal file
@@ -0,0 +1,215 @@
|
||||
#!/bin/bash
|
||||
# CryptoPro CSP Installation Script for Wine
|
||||
#
|
||||
# Installs customer-provided CryptoPro CSP MSI under Wine environment.
|
||||
# This script is called by entrypoint.sh when CSP installer is available.
|
||||
#
|
||||
# IMPORTANT: CryptoPro CSP is commercial software. The installer MSI must be
|
||||
# provided by the customer with appropriate licensing. StellaOps does not
|
||||
# distribute CryptoPro CSP.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Configuration
|
||||
# ------------------------------------------------------------------------------
|
||||
WINE_CSP_INSTALLER_PATH="${WINE_CSP_INSTALLER_PATH:-/opt/cryptopro/csp-installer.msi}"
|
||||
WINE_PREFIX="${WINEPREFIX:-$HOME/.wine}"
|
||||
DISPLAY="${DISPLAY:-:99}"
|
||||
|
||||
# Expected CSP installation paths (under Wine prefix)
|
||||
CSP_PROGRAM_FILES="${WINE_PREFIX}/drive_c/Program Files/Crypto Pro"
|
||||
CSP_MARKER="${WINE_PREFIX}/.csp_installed"
|
||||
CSP_VERSION_FILE="${WINE_PREFIX}/.csp_version"
|
||||
|
||||
# Installation timeout (5 minutes)
|
||||
INSTALL_TIMEOUT=300
|
||||
|
||||
# Log prefix
|
||||
log() {
|
||||
echo "[$(date -u '+%Y-%m-%dT%H:%M:%SZ')] [install-csp] $*"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo "[$(date -u '+%Y-%m-%dT%H:%M:%SZ')] [install-csp] [ERROR] $*" >&2
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Pre-Installation Checks
|
||||
# ------------------------------------------------------------------------------
|
||||
check_prerequisites() {
|
||||
log "Checking installation prerequisites"
|
||||
|
||||
# Check installer exists
|
||||
if [[ ! -f "${WINE_CSP_INSTALLER_PATH}" ]]; then
|
||||
log_error "CSP installer not found: ${WINE_CSP_INSTALLER_PATH}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify file is an MSI
|
||||
if ! file "${WINE_CSP_INSTALLER_PATH}" | grep -qi "microsoft installer"; then
|
||||
log_error "File does not appear to be an MSI installer"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check Wine is available
|
||||
if ! command -v wine64 &> /dev/null; then
|
||||
log_error "wine64 not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check Wine prefix exists
|
||||
if [[ ! -d "${WINE_PREFIX}" ]]; then
|
||||
log_error "Wine prefix not initialized: ${WINE_PREFIX}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "Prerequisites check passed"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Installation
|
||||
# ------------------------------------------------------------------------------
|
||||
install_csp() {
|
||||
log "Starting CryptoPro CSP installation"
|
||||
log "Installer: ${WINE_CSP_INSTALLER_PATH}"
|
||||
|
||||
# Create installation log directory
|
||||
local log_dir="${WINE_PREFIX}/csp_install_logs"
|
||||
mkdir -p "${log_dir}"
|
||||
|
||||
local install_log="${log_dir}/install_$(date -u '+%Y%m%d_%H%M%S').log"
|
||||
|
||||
# Run MSI installer silently
|
||||
# /qn = silent mode, /norestart = don't restart, /l*v = verbose logging
|
||||
log "Running msiexec installer (this may take several minutes)..."
|
||||
|
||||
timeout "${INSTALL_TIMEOUT}" wine64 msiexec /i "${WINE_CSP_INSTALLER_PATH}" \
|
||||
/qn /norestart /l*v "${install_log}" \
|
||||
AGREETOLICENSE=Yes \
|
||||
2>&1 | tee -a "${install_log}" || {
|
||||
local exit_code=$?
|
||||
log_error "MSI installation failed with exit code: ${exit_code}"
|
||||
log_error "Check installation log: ${install_log}"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Wait for Wine to finish
|
||||
wineserver --wait
|
||||
|
||||
log "MSI installation completed"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Post-Installation Verification
|
||||
# ------------------------------------------------------------------------------
|
||||
verify_installation() {
|
||||
log "Verifying CryptoPro CSP installation"
|
||||
|
||||
# Check for CSP program files
|
||||
if [[ -d "${CSP_PROGRAM_FILES}" ]]; then
|
||||
log "Found CSP directory: ${CSP_PROGRAM_FILES}"
|
||||
else
|
||||
log_error "CSP program directory not found"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check for key CSP DLLs
|
||||
local csp_dll="${WINE_PREFIX}/drive_c/windows/system32/cpcspi.dll"
|
||||
if [[ -f "${csp_dll}" ]]; then
|
||||
log "Found CSP DLL: ${csp_dll}"
|
||||
else
|
||||
log "Warning: CSP DLL not found at expected location"
|
||||
# This might be OK depending on CSP version
|
||||
fi
|
||||
|
||||
# Try to query CSP registry entries
|
||||
local csp_registry
|
||||
csp_registry=$(wine64 reg query "HKLM\\SOFTWARE\\Crypto Pro" 2>/dev/null || true)
|
||||
if [[ -n "${csp_registry}" ]]; then
|
||||
log "CSP registry entries found"
|
||||
else
|
||||
log "Warning: CSP registry entries not found"
|
||||
fi
|
||||
|
||||
# Extract version if possible
|
||||
local version="unknown"
|
||||
if [[ -f "${CSP_PROGRAM_FILES}/CSP/version.txt" ]]; then
|
||||
version=$(cat "${CSP_PROGRAM_FILES}/CSP/version.txt" 2>/dev/null || echo "unknown")
|
||||
fi
|
||||
echo "${version}" > "${CSP_VERSION_FILE}"
|
||||
log "CSP version: ${version}"
|
||||
|
||||
log "Installation verification completed"
|
||||
return 0
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Cleanup on Failure
|
||||
# ------------------------------------------------------------------------------
|
||||
cleanup_failed_install() {
|
||||
log "Cleaning up failed installation"
|
||||
|
||||
# Try to uninstall via msiexec
|
||||
wine64 msiexec /x "${WINE_CSP_INSTALLER_PATH}" /qn 2>/dev/null || true
|
||||
wineserver --wait
|
||||
|
||||
# Remove any partial installation directories
|
||||
rm -rf "${CSP_PROGRAM_FILES}" 2>/dev/null || true
|
||||
|
||||
# Remove marker files
|
||||
rm -f "${CSP_MARKER}" "${CSP_VERSION_FILE}" 2>/dev/null || true
|
||||
|
||||
log "Cleanup completed"
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Main
|
||||
# ------------------------------------------------------------------------------
|
||||
main() {
|
||||
log "=========================================="
|
||||
log "CryptoPro CSP Installation Script"
|
||||
log "=========================================="
|
||||
|
||||
# Check if already installed
|
||||
if [[ -f "${CSP_MARKER}" ]]; then
|
||||
log "CryptoPro CSP is already installed"
|
||||
if [[ -f "${CSP_VERSION_FILE}" ]]; then
|
||||
log "Installed version: $(cat "${CSP_VERSION_FILE}")"
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Run prerequisite checks
|
||||
if ! check_prerequisites; then
|
||||
log_error "Prerequisites check failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Perform installation
|
||||
if ! install_csp; then
|
||||
log_error "Installation failed"
|
||||
cleanup_failed_install
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Verify installation
|
||||
if ! verify_installation; then
|
||||
log_error "Installation verification failed"
|
||||
cleanup_failed_install
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Create installation marker
|
||||
touch "${CSP_MARKER}"
|
||||
|
||||
log "=========================================="
|
||||
log "CryptoPro CSP installation successful"
|
||||
log "=========================================="
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user