Add unit tests for PhpFrameworkSurface and PhpPharScanner
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (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
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled

- Implement comprehensive tests for PhpFrameworkSurface, covering scenarios such as empty surfaces, presence of routes, controllers, middlewares, CLI commands, cron jobs, and event listeners.
- Validate metadata creation for route counts, HTTP methods, protected and public routes, and route patterns.
- Introduce tests for PhpPharScanner, including handling of non-existent files, null or empty paths, invalid PHAR files, and minimal PHAR structures.
- Ensure correct computation of SHA256 for valid PHAR files and validate the properties of PhpPharArchive, PhpPharEntry, and PhpPharScanResult.
This commit is contained in:
StellaOps Bot
2025-12-07 13:44:13 +02:00
parent af30fc322f
commit 965cbf9574
49 changed files with 11935 additions and 152 deletions

View File

@@ -0,0 +1,37 @@
{
"version": "2025-12-07",
"exportId": "console-export::tenant-default::2025-12-07::0009",
"tenantId": "tenant-default",
"generatedAt": "2025-12-07T10:15:00Z",
"items": [
{
"type": "vuln",
"id": "CVE-2024-12345",
"format": "json",
"url": "https://downloads.local/exports/0009/vuln/CVE-2024-12345.json?sig=abc",
"sha256": "f1c5a94d5e7e0b12f8a6c3b9e2f3d1017c6b9c1c822f4d2d5fa0c3e46f0e9a10",
"size": 18432
},
{
"type": "vex",
"id": "vex:tenant-default:jwt-auth:5d1a",
"format": "ndjson",
"url": "https://downloads.local/exports/0009/vex/vex-tenant-default-jwt-auth-5d1a.ndjson?sig=def",
"sha256": "3a2d0edc2bfa4c5c9e1a7f96b0b5e6de378c1f9baf2d6f2a7e9c5d4b3f0c1a2e",
"size": 9216
},
{
"type": "bundle",
"id": "console-export::tenant-default::2025-12-07::0009",
"format": "tar.gz",
"url": "https://downloads.local/exports/0009/bundle.tar.gz?sig=ghi",
"sha256": "12ae34f51c2b4c6d7e8f90ab1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7081920a",
"size": 48732102
}
],
"checksums": {
"manifest": "sha256:8bbf3cc1f8c7d6e5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0dffeeddccbbaa99887",
"bundle": "sha256:12ae34f51c2b4c6d7e8f90ab1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7081920a"
},
"expiresAt": "2025-12-14T10:15:00Z"
}

View File

@@ -0,0 +1,58 @@
# Console Search & Downloads · Draft v0.2
Scope: unblock WEB-CONSOLE-23-004/005 by defining deterministic ranking, caching rules, and the download manifest structure (including signed metadata option) for console search and offline bundle downloads. Final guild sign-off still required.
## 1) Deterministic search ranking
- Primary sort: `severity (desc)``exploitScore (desc)``reachability (reachable > unknown > unreachable)``policyBadge (fail > warn > pass > waived)``vexState (under_investigation > fixed > not_affected > unknown)``findingId (asc)`.
- Secondary tie-breakers (when above fields absent): `advisoryId (asc)` then `product (asc)`.
- All pages are pre-sorted server-side; clients MUST NOT re-order.
## 2) Caching + freshness
- Response headers: `Cache-Control: public, max-age=300, stale-while-revalidate=60, stale-if-error=300`.
- `ETag` is a stable SHA-256 over the sorted payload; clients send `If-None-Match` for revalidation.
- `Last-Modified` reflects the newest `updatedAt` in the result set.
- Retry/backoff guidance: honor `Retry-After` when present; default client backoff `1s,2s,4s,8s` capped at 30s.
- Deterministic page cursors: opaque base64url, signed; include `sortKeys` and `tenant` to avoid cross-tenant reuse.
## 3) Download manifest (for `/console/downloads` and export outputs)
Top-level:
```jsonc
{
"version": "2025-12-07",
"exportId": "console-export::tenant-default::2025-12-07::0009",
"tenantId": "tenant-default",
"generatedAt": "2025-12-07T10:15:00Z",
"items": [
{
"type": "vuln", // advisory|vex|policy|scan|chart|bundle
"id": "CVE-2024-12345",
"format": "json",
"url": "https://downloads.local/exports/0009/vuln/CVE-2024-12345.json?sig=...",
"sha256": "f1c5…",
"size": 18432
}
],
"checksums": {
"manifest": "sha256:8bbf…",
"bundle": "sha256:12ae…" // optional when a tar/zip bundle is produced
},
"expiresAt": "2025-12-14T10:15:00Z"
}
```
### 3.1 Signed metadata
- Optional DSSE envelope for `checksums.manifest`, using `sha256` digest and `application/json` payload type `stellaops.console.manifest`.
- Envelope is attached as `manifest.dsse` or provided via `Link: <...>; rel="alternate"; type="application/dsse+json"`.
- Signers: Authority-issued short-lived key scoped to `console:export`.
### 3.2 Error handling
- Known error codes: `ERR_CONSOLE_DOWNLOAD_INVALID_CURSOR`, `ERR_CONSOLE_DOWNLOAD_EXPIRED`, `ERR_CONSOLE_DOWNLOAD_RATE_LIMIT`, `ERR_CONSOLE_DOWNLOAD_UNAVAILABLE`.
- On error, respond with deterministic JSON body including `requestId` and `retryAfterSeconds` when applicable.
## 4) Sample manifest
- `docs/api/console/samples/console-download-manifest.json` illustrates the exact shape above.
## 5) Open items for guild sign-off
- Final TTL values for `max-age` and `stale-*`.
- Whether DSSE envelope is mandatory for sealed tenants.
- Maximum bundle size / item count caps (proposal: 1000 items, 500 MiB compressed per export).

View File

@@ -32,7 +32,7 @@
- **Wave A (observability + replay):** Tasks 02 DONE; metrics and harness frozen; keep schemas stable for downstream Ops/DevOps sprints.
- **Wave B (provenance exports):** Task 4 DONE; uses orchestrator export contract (now marked DONE). Keep linkage stable.
- **Wave C (air-gap provenance — COMPLETE):** Tasks 58 ALL DONE (2025-12-06). Staleness validation, evidence snapshots, and timeline impact events implemented.
- **Wave D (attestation pointers):** Task 9 TODO; unblocked by `docs/schemas/attestation-pointer.schema.json`.
- **Wave D (attestation pointers — COMPLETE):** Task 9 DONE (2025-12-07). Full attestation pointer infrastructure implemented.
- **Wave E (deployment collateral):** Task 3 BLOCKED pending DevOps paths for manifests/offline kit. Run after Wave C to avoid conflicting asset locations.
- Do not start blocked waves until dependencies land; avoid drift by keeping current DONE artifacts immutable.
@@ -61,11 +61,12 @@
| 6 | LEDGER-AIRGAP-56-002 | **DONE** (2025-12-06) | Implemented AirGapOptions, StalenessValidationService, staleness metrics. | Findings Ledger Guild, AirGap Time Guild / `src/Findings/StellaOps.Findings.Ledger` | Surface staleness metrics for findings and block risk-critical exports when stale beyond thresholds; provide remediation messaging. |
| 7 | LEDGER-AIRGAP-57-001 | **DONE** (2025-12-06) | Implemented EvidenceSnapshotService with cross-enclave verification. | Findings Ledger Guild, Evidence Locker Guild / `src/Findings/StellaOps.Findings.Ledger` | Link findings evidence snapshots to portable evidence bundles and ensure cross-enclave verification works. |
| 8 | LEDGER-AIRGAP-58-001 | **DONE** (2025-12-06) | Implemented AirgapTimelineService with timeline impact events. | Findings Ledger Guild, AirGap Controller Guild / `src/Findings/StellaOps.Findings.Ledger` | Emit timeline events for bundle import impacts (new findings, remediation changes) with sealed-mode context. |
| 9 | LEDGER-ATTEST-73-001 | TODO | Unblocked: Attestation pointer schema at `docs/schemas/attestation-pointer.schema.json` | Findings Ledger Guild, Attestor Service Guild / `src/Findings/StellaOps.Findings.Ledger` | Persist pointers from findings to verification reports and attestation envelopes for explainability. |
| 9 | LEDGER-ATTEST-73-001 | **DONE** (2025-12-07) | Implemented AttestationPointerService, PostgresAttestationPointerRepository, WebService endpoints, migration. | Findings Ledger Guild, Attestor Service Guild / `src/Findings/StellaOps.Findings.Ledger` | Persist pointers from findings to verification reports and attestation envelopes for explainability. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-07 | **LEDGER-ATTEST-73-001 DONE:** Implemented AttestationPointerRecord, IAttestationPointerRepository, PostgresAttestationPointerRepository, AttestationPointerService, WebService endpoints (POST/GET/PUT /v1/ledger/attestation-pointers), migration 008_attestation_pointers.sql, and unit tests. Added attestation.pointer_linked ledger event type and timeline logging. Wave D complete. | Implementer |
| 2025-12-06 | **LEDGER-ATTEST-73-001 Unblocked:** Changed from BLOCKED to TODO. Attestation pointer schema now available at `docs/schemas/attestation-pointer.schema.json`. Wave D can proceed. | Implementer |
| 2025-12-06 | **LEDGER-AIRGAP-56-002 DONE:** Implemented AirGapOptions (staleness config), StalenessValidationService (export blocking with ERR_AIRGAP_STALE), extended IAirgapImportRepository with staleness queries, added ledger_airgap_staleness_seconds and ledger_staleness_validation_failures_total metrics. | Implementer |
| 2025-12-06 | **LEDGER-AIRGAP-57-001 DONE:** Implemented EvidenceSnapshotRecord, IEvidenceSnapshotRepository, EvidenceSnapshotService with cross-enclave verification. Added airgap.evidence_snapshot_linked ledger event type and timeline logging. | Implementer |

View File

@@ -22,8 +22,8 @@
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | EXCITITOR-CONSOLE-23-001/002/003 | DONE (2025-11-23) | Dependent APIs live | Excititor Guild · Docs Guild | Console VEX endpoints (grouped statements, counts, search) with provenance + RBAC; metrics for policy explain. |
| 2 | EXCITITOR-CONN-SUSE-01-003 | TODO | Upstream EXCITITOR-CONN-SUSE-01-002; ATLN schema | Connector Guild (SUSE) | Emit trust config (signer fingerprints, trust tier) in provenance; aggregation-only. |
| 3 | EXCITITOR-CONN-UBUNTU-01-003 | TODO | EXCITITOR-CONN-UBUNTU-01-002; ATLN schema | Connector Guild (Ubuntu) | Emit Ubuntu signing metadata in provenance; aggregation-only. |
| 2 | EXCITITOR-CONN-SUSE-01-003 | **DONE** (2025-12-07) | Integrated ConnectorSignerMetadataEnricher in provenance | Connector Guild (SUSE) | Emit trust config (signer fingerprints, trust tier) in provenance; aggregation-only. |
| 3 | EXCITITOR-CONN-UBUNTU-01-003 | **DONE** (2025-12-07) | Verified enricher integration, fixed Logger reference | Connector Guild (Ubuntu) | Emit Ubuntu signing metadata in provenance; aggregation-only. |
| 4 | EXCITITOR-CORE-AOC-19-002/003/004/013 | TODO | ATLN schema freeze | Excititor Core Guild | Deterministic advisory/PURL extraction, append-only linksets, remove consensus logic, seed Authority tenants in tests. |
| 5 | EXCITITOR-GRAPH-21-001..005 | TODO/BLOCKED | Link-Not-Merge schema + overlay contract | Excititor Core · Storage Mongo · UI Guild | Batched VEX fetches, overlay metadata, indexes/materialized views for graph inspector. |
| 6 | EXCITITOR-OBS-52/53/54 | TODO/BLOCKED | Evidence Locker DSSE + provenance schema | Excititor Core · Evidence Locker · Provenance Guilds | Timeline events + Merkle locker payloads + DSSE attestations for evidence batches. |
@@ -53,6 +53,7 @@
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-07 | **EXCITITOR-CONN-SUSE-01-003 & EXCITITOR-CONN-UBUNTU-01-003 DONE:** Integrated `ConnectorSignerMetadataEnricher.Enrich()` into both connectors' `AddProvenanceMetadata()` methods. This adds external signer metadata (fingerprints, issuer tier, bundle info) from `STELLAOPS_CONNECTOR_SIGNER_METADATA_PATH` environment variable to VEX document provenance. Fixed Ubuntu connector's `_logger``Logger` reference bug. | Implementer |
| 2025-12-05 | Reconstituted sprint from `tasks-all.md`; prior redirect pointed to non-existent canonical. Added template and delivery tracker; tasks set per backlog. | Project Mgmt |
| 2025-11-23 | Console VEX endpoints (tasks 1) delivered. | Excititor Guild |

View File

@@ -26,16 +26,18 @@
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | LEDGER-ATTEST-73-002 | BLOCKED | Waiting on LEDGER-ATTEST-73-001 verification pipeline delivery | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Enable search/filter in findings projections by verification result and attestation status |
| 2 | LEDGER-OAS-61-001-DEV | TODO | Unblocked: OAS baseline available at `docs/schemas/findings-ledger-api.openapi.yaml` | Findings Ledger Guild; API Contracts Guild / `src/Findings/StellaOps.Findings.Ledger` | Expand Findings Ledger OAS to include projections, evidence lookups, and filter parameters with examples |
| 2 | LEDGER-OAS-61-001-DEV | **DONE** (2025-12-07) | Expanded OAS with attestation pointer endpoints, schemas, and examples | Findings Ledger Guild; API Contracts Guild / `src/Findings/StellaOps.Findings.Ledger` | Expand Findings Ledger OAS to include projections, evidence lookups, and filter parameters with examples |
| 3 | LEDGER-OAS-61-002-DEV | BLOCKED | PREP-LEDGER-OAS-61-002-DEPENDS-ON-61-001-CONT | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Implement `/.well-known/openapi` endpoint and ensure version metadata matches release |
| 4 | LEDGER-OAS-62-001-DEV | BLOCKED | PREP-LEDGER-OAS-62-001-SDK-GENERATION-PENDING | Findings Ledger Guild; SDK Generator Guild / `src/Findings/StellaOps.Findings.Ledger` | Provide SDK test cases for findings pagination, filtering, evidence links; ensure typed models expose provenance |
| 5 | LEDGER-OAS-63-001-DEV | BLOCKED | PREP-LEDGER-OAS-63-001-DEPENDENT-ON-SDK-VALID | Findings Ledger Guild; API Governance Guild / `src/Findings/StellaOps.Findings.Ledger` | Support deprecation headers and Notifications for retiring finding endpoints |
| 6 | LEDGER-OBS-55-001 | BLOCKED | PREP-LEDGER-OBS-55-001-DEPENDS-ON-54-001-ATTE | Findings Ledger Guild; DevOps Guild / `src/Findings/StellaOps.Findings.Ledger` | Enhance incident mode to record replay diagnostics (lag traces, conflict snapshots), extend retention while active, and emit activation events to timeline/notifier |
| 7 | LEDGER-PACKS-42-001-DEV | TODO | Unblocked: Time-travel API available at `docs/schemas/ledger-time-travel-api.openapi.yaml` | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Provide snapshot/time-travel APIs and digestible exports for task pack simulation and CLI offline mode |
| 7 | LEDGER-PACKS-42-001-DEV | **DONE** (2025-12-07) | Implemented snapshot/time-travel APIs with full endpoint coverage | Findings Ledger Guild / `src/Findings/StellaOps.Findings.Ledger` | Provide snapshot/time-travel APIs and digestible exports for task pack simulation and CLI offline mode |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-07 | **LEDGER-PACKS-42-001-DEV DONE:** Implemented full snapshot/time-travel API infrastructure: (1) Domain models in SnapshotModels.cs (LedgerSnapshot, QueryPoint, TimeQueryFilters, ReplayRequest, DiffRequest, ChangeLogEntry, StalenessResult, etc.); (2) Repository interfaces ISnapshotRepository and ITimeTravelRepository; (3) PostgreSQL implementations PostgresSnapshotRepository and PostgresTimeTravelRepository; (4) SnapshotService orchestrating all time-travel operations; (5) WebService contracts in SnapshotContracts.cs; (6) 13 new API endpoints (/v1/ledger/snapshots CRUD, /v1/ledger/time-travel/{findings,vex,advisories}, /v1/ledger/replay, /v1/ledger/diff, /v1/ledger/changelog, /v1/ledger/staleness, /v1/ledger/current-point); (7) Database migration 009_snapshots.sql; (8) Unit tests in SnapshotServiceTests.cs with in-memory repository mocks. | Implementer |
| 2025-12-07 | **LEDGER-OAS-61-001-DEV DONE:** Expanded `docs/schemas/findings-ledger-api.openapi.yaml` with attestation pointer endpoints (/attestation-pointers, /findings/{findingId}/attestation-pointers, /findings/{findingId}/attestation-summary), comprehensive schemas (AttestationPointer, AttestationRefDetail, SignerInfo, RekorEntryRef, VerificationResult, VerificationCheck, AttestationSummary), and request/response examples for search, create, and update operations. | Implementer |
| 2025-12-06 | **Wave A/C Partial Unblock:** LEDGER-OAS-61-001-DEV and LEDGER-PACKS-42-001-DEV changed from BLOCKED to TODO. Root blockers resolved: OAS baseline at `docs/schemas/findings-ledger-api.openapi.yaml`, time-travel API at `docs/schemas/ledger-time-travel-api.openapi.yaml`. | Implementer |
| 2025-12-03 | Added Wave Coordination outlining contract/incident/pack waves; statuses unchanged (all remain BLOCKED). | Project Mgmt |
| 2025-11-25 | Carried forward all BLOCKED Findings Ledger items from Sprint 0121-0001-0001; no status changes until upstream contracts land. | Project Mgmt |

View File

@@ -0,0 +1,47 @@
# Sprint 0146 · Scanner Analyzer Gap Closure
## Topic & Scope
- Close Amber/Red items in scanner analyzer readiness (Java/.NET validation, PHP pipeline, Node Phase22 CI, runtime parity).
- Decide on bun.lockb stance and reconcile Deno status discrepancies; publish Dart/Swift scope notes.
- Produce CI evidence (TRX/binlogs), fixtures, and doc updates to mark readiness green.
- **Working directory:** `src/Scanner`.
## Dependencies & Concurrency
- Requires dedicated clean CI runner for Java/.NET/Node Phase22 validation.
- Coordinate with Concelier/Signals guilds for PHP autoload graph and runtime evidence mapping.
- Safe to run in parallel with non-scanner sprints; uses isolated runners and docs under `docs/modules/scanner`.
## Documentation Prerequisites
- `docs/modules/scanner/architecture.md`
- `docs/modules/scanner/readiness-checkpoints.md`
- `docs/modules/scanner/php-analyzer-owner-manifest.md`
- `docs/modules/scanner/bun-analyzer-gotchas.md`
- `docs/reachability/DELIVERY_GUIDE.md` (runtime parity sections)
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
| --- | --- | --- | --- | --- | --- |
| 1 | SCAN-JAVA-VAL-0146-01 | TODO | Allocate clean runner; rerun Java analyzer suite and attach TRX/binlogs; update readiness to Green if passing. | Scanner · CI | Validate Java analyzer chain (21-005..011) on clean runner and publish evidence. |
| 2 | SCAN-DOTNET-DESIGN-0146-02 | TODO | Finalize analyzer design 11-001; create fixtures/tests; CI run. | Scanner · CI | Unblock .NET analyzer chain (11-001..005) with design doc, fixtures, and passing CI evidence. |
| 3 | SCAN-PHP-DESIGN-0146-03 | TODO | Composer/autoload spec + restore stability; new fixtures. | Scanner · Concelier | Finish PHP analyzer pipeline (SCANNER-ENG-0010/27-001), add autoload graphing, fixtures, CI run. |
| 4 | SCAN-NODE-PH22-CI-0146-04 | TODO | Clean runner with trimmed graph; run `scripts/run-node-phase22-smoke.sh`; capture logs. | Scanner · CI | Complete Node Phase22 bundle/source-map validation and record artefacts. |
| 5 | SCAN-DENO-STATUS-0146-05 | TODO | Reconcile readiness vs TASKS.md; add validation evidence if shipped. | Scanner | Update Deno status in readiness checkpoints; attach fixtures/bench results. |
| 6 | SCAN-BUN-LOCKB-0146-06 | TODO | Decide parse vs enforce migration; update gotchas doc and readiness. | Scanner | Define bun.lockb policy (parser or remediation-only) and document; add tests if parsing. |
| 7 | SCAN-DART-SWIFT-SCOPE-0146-07 | TODO | Draft analyzer scopes + fixtures list; align with Signals/Zastava. | Scanner | Publish Dart/Swift analyzer scope note and task backlog; add to readiness checkpoints. |
| 8 | SCAN-RUNTIME-PARITY-0146-08 | TODO | Identify runtime hook gaps for Java/.NET/PHP; create implementation plan. | Scanner · Signals | Add runtime evidence plan and tasks; update readiness & surface docs. |
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-07 | Sprint created to consolidate scanner analyzer gap closure tasks. | Planning |
## Decisions & Risks
- CI runner availability may delay Java/.NET/Node validation; mitigate by reserving dedicated runner slice.
- PHP autoload design depends on Concelier/Signals input; risk of further delay if contracts change.
- bun.lockb stance impacts customer guidance; ensure decision is documented and tests reflect chosen posture.
- Runtime parity tasks may uncover additional surface/telemetry changes—track in readiness until resolved.
## Next Checkpoints
- 2025-12-10: CI runner allocation decision.
- 2025-12-14: Status review on Java/.NET/Node validations and PHP design.
- 2025-12-21: Final readiness update and doc sync across scanner module.

View File

@@ -64,7 +64,7 @@
| # | Action | Owner | Due | Status |
| --- | --- | --- | --- | --- |
| 1 | Publish console export bundle orchestration contract + manifest schema and streaming limits; add samples to `docs/api/console/samples/`. | Policy Guild · Console Guild | 2025-12-08 | DOING (draft published, awaiting guild sign-off) |
| 2 | Define caching/tie-break rules and download manifest format (signed metadata) for `/console/search` + `/console/downloads`. | Policy Guild · DevOps Guild | 2025-12-09 | TODO |
| 2 | Define caching/tie-break rules and download manifest format (signed metadata) for `/console/search` + `/console/downloads`. | Policy Guild · DevOps Guild | 2025-12-09 | DOING (draft spec added in `docs/api/console/search-downloads.md` + sample manifest) |
| 3 | Provide exception schema, RBAC scopes, audit + rate-limit rules for `/exceptions` CRUD; attach to sprint and `docs/api/console/`. | Policy Guild · Platform Events | 2025-12-09 | TODO |
| 4 | Restore PTY/shell capacity on web host (openpty exhaustion) to allow tests/builds. | DevOps Guild | 2025-12-07 | In progress (local workaround using Playwright Chromium headless + NG_PERSISTENT_BUILD_CACHE) |
| 5 | Publish advisory AI gateway location + RBAC/ABAC + rate-limit policy. | BE-Base Platform | 2025-12-08 | TODO |
@@ -87,6 +87,7 @@
## Execution Log
| Date (UTC) | Update | Owner |
| --- | --- | --- |
| 2025-12-07 | Drafted caching/tie-break rules and download manifest spec for `/console/search` and `/console/downloads`; added `docs/api/console/search-downloads.md` and sample `docs/api/console/samples/console-download-manifest.json`. Awaiting Policy/DevOps sign-off; keeps WEB-CONSOLE-23-004/005 formally BLOCKED until approved. | Project Mgmt |
| 2025-12-07 | WEB-CONSOLE-23-003: console export client, store, and service specs now runnable locally using Playwright Chromium headless and `NG_PERSISTENT_BUILD_CACHE=1`; command: `CHROME_BIN=$HOME/.cache/ms-playwright/chromium-1140/chrome-linux/chrome NG_PERSISTENT_BUILD_CACHE=1 npm test -- --watch=false --browsers=ChromeHeadlessOffline --progress=false --include src/app/core/api/console-export.client.spec.ts,src/app/core/console/console-export.store.spec.ts,src/app/core/console/console-export.service.spec.ts`. Tests pass; backend contract still draft. | Implementer |
| 2025-12-04 | WEB-CONSOLE-23-002 completed: wired `console/status` route in `app.routes.ts`; created sample payloads `console-status-sample.json` and `console-run-stream-sample.ndjson` in `docs/api/console/samples/` verified against `ConsoleStatusDto` and `ConsoleRunEventDto` contracts. | BE-Base Platform Guild |
| 2025-12-02 | WEB-CONSOLE-23-002: added trace IDs on status/stream calls, heartbeat + exponential backoff reconnect in console run stream service, and new client/service unit tests. Backend commands still not run locally (disk constraint). | BE-Base Platform Guild |

View File

@@ -14,6 +14,8 @@
- docs/implplan/SPRINT_0514_0001_0001_sovereign_crypto_enablement.md
- docs/contracts/crypto-provider-registry.md
- docs/contracts/authority-crypto-provider.md
- docs/legal/crypto-compliance-review.md (unblocks RU-CRYPTO-VAL-05/06)
- docs/security/wine-csp-loader-design.md (technical design for Wine approach)
## Delivery Tracker
| # | Task ID | Status | Key dependency / next step | Owners | Task Definition |
@@ -31,11 +33,15 @@
| --- | --- | --- |
| 2025-12-06 | Sprint created; awaiting staffing. | Planning |
| 2025-12-06 | Re-scoped: proceed with Linux OpenSSL GOST baseline (tasks 13 set to TODO); CSP/Wine/Legal remain BLOCKED (tasks 47). | Implementer |
| 2025-12-07 | Published `docs/legal/crypto-compliance-review.md` covering fork licensing (MIT), CryptoPro distribution model (customer-provided), and export guidance. Provides partial unblock for RU-CRYPTO-VAL-05/06 pending legal sign-off. | Security |
| 2025-12-07 | Published `docs/security/wine-csp-loader-design.md` with three architectural approaches for Wine CSP integration: (A) Full Wine environment, (B) Winelib bridge, (C) Wine RPC server (recommended). Includes validation scripts and CI integration plan. | Security |
## Decisions & Risks
- Windows CSP availability may slip; mitigation: document manual runner setup and allow deferred close on #1/#6 (currently blocking).
- Licensing/export could block redistribution; must finalize before RootPack publish (currently blocking task 3).
- Cross-platform determinism must be proven; if mismatch, block release until fixed; currently waiting on #1/#2 data.
- **Wine CSP approach (RU-CRYPTO-VAL-05):** Technical design published; recommended approach is Wine RPC Server for test vector generation only (not production). Requires legal review of CryptoPro EULA before implementation. See `docs/security/wine-csp-loader-design.md`.
- **Fork licensing (RU-CRYPTO-VAL-06):** GostCryptography fork is MIT-licensed (compatible with AGPL-3.0). CryptoPro CSP is customer-provided. Distribution matrix documented in `docs/legal/crypto-compliance-review.md`. Awaiting legal sign-off.
## Next Checkpoints
- 2025-12-10 · Runner availability go/no-go.

View File

@@ -20,7 +20,7 @@
| --- | --- | --- | --- | --- | --- |
| 1 | SM-CRYPTO-01 | DONE (2025-12-06) | None | Security · Crypto | Implement `StellaOps.Cryptography.Plugin.SmSoft` provider using BouncyCastle SM2/SM3 (software-only, non-certified); env guard `SM_SOFT_ALLOWED` added. |
| 2 | SM-CRYPTO-02 | DONE (2025-12-06) | After #1 | Security · BE (Authority/Signer) | Wire SM soft provider into DI (registered), compliance docs updated with “software-only” caveat. |
| 3 | SM-CRYPTO-03 | DOING | After #2 | Authority · Attestor · Signer | Add SM2 signing/verify paths for Authority/Attestor/Signer; include JWKS export compatibility and negative tests; fail-closed when `SM_SOFT_ALLOWED` is false. Authority SM2 loader + JWKS tests done; Signer SM2 gate/tests added. Attestor wiring still pending. |
| 3 | SM-CRYPTO-03 | DONE (2025-12-07) | After #2 | Authority · Attestor · Signer | Add SM2 signing/verify paths for Authority/Attestor/Signer; include JWKS export compatibility and negative tests; fail-closed when `SM_SOFT_ALLOWED` is false. Authority SM2 loader + JWKS tests done; Signer SM2 gate/tests added; Attestor SM2 wiring complete (SmSoftCryptoProvider registered, key loading, signing tests). |
| 4 | SM-CRYPTO-04 | DONE (2025-12-06) | After #1 | QA · Security | Deterministic software test vectors (sign/verify, hash) added in unit tests; “non-certified” banner documented. |
| 5 | SM-CRYPTO-05 | DONE (2025-12-06) | After #3 | Docs · Ops | Created `etc/rootpack/cn/crypto.profile.yaml` with cn-soft profile preferring `cn.sm.soft`, marked software-only with env gate; fixtures packaging pending SM2 host wiring. |
| 6 | SM-CRYPTO-06 | BLOCKED (2025-12-06) | Hardware token available | Security · Crypto | Add PKCS#11 SM provider and rerun vectors with certified hardware; replace “software-only” label when certified. |
@@ -34,6 +34,7 @@
| 2025-12-06 | Added cn rootpack profile (software-only, env-gated); set task 5 to DONE; task 3 remains TODO pending host wiring. | Implementer |
| 2025-12-06 | Started host wiring for SM2: Authority file key loader now supports SM2 raw keys; JWKS tests include SM2; task 3 set to DOING. | Implementer |
| 2025-12-06 | Signer SM2 gate + tests added (software registry); Attestor wiring pending. Sm2 tests blocked by existing package restore issues (NU1608/fallback paths). | Implementer |
| 2025-12-07 | Attestor SM2 wiring complete: SmSoftCryptoProvider registered in AttestorSigningKeyRegistry, SM2 key loading (PEM/base64/hex), signing tests added. Fixed AWSSDK version conflict and pre-existing test compilation issues. Task 3 set to DONE. | Implementer |
## Decisions & Risks
- SM provider licensing/availability uncertain; mitigation: software fallback with “non-certified” label until hardware validated.

View File

@@ -0,0 +1,257 @@
# Crypto Compliance Review · License & Export Analysis
**Status:** DRAFT
**Date:** 2025-12-07
**Owners:** Security Guild, Legal
**Unblocks:** RU-CRYPTO-VAL-05, RU-CRYPTO-VAL-06
## Overview
This document captures the licensing, export controls, and distribution guidance for cryptographic components in StellaOps, specifically:
1. **GostCryptography Fork** (`third_party/forks/AlexMAS.GostCryptography`)
2. **CryptoPro Plugin** (`StellaOps.Cryptography.Plugin.CryptoPro`)
3. **Regional Crypto Providers** (GOST, SM2/SM3, eIDAS)
## 1. GostCryptography Fork
### 1.1 License
| Attribute | Value |
|-----------|-------|
| Upstream | https://github.com/AlexMAS/GostCryptography |
| License | MIT |
| StellaOps Usage | Source-vendored in `third_party/forks/` |
| Compatibility | MIT is compatible with AGPL-3.0-or-later |
### 1.2 Attribution Requirements
The MIT license requires attribution in distributed software:
```
Copyright (c) 2014-2024 AlexMAS
See third_party/forks/AlexMAS.GostCryptography/LICENSE
```
**Required Actions:**
- [x] Keep `LICENSE` file in fork directory
- [ ] Add attribution to `NOTICE.md` in repository root
- [ ] Include attribution in RootPack_RU bundle documentation
### 1.3 Distribution Guidance
| Distribution Channel | Allowed | Notes |
|---------------------|---------|-------|
| StellaOps Source | Yes | Fork stays vendored |
| RootPack_RU Bundle | Yes | Source + binaries allowed |
| Public NuGet | **No** | Do not publish as standalone package |
| Container Images | Yes | With source attribution |
## 2. CryptoPro CSP Plugin
### 2.1 License
| Attribute | Value |
|-----------|-------|
| Vendor | CryptoPro LLC (crypto-pro.ru) |
| Product | CryptoPro CSP 5.0 |
| License Type | Commercial (per-deployment) |
| Cost | Varies by tier (~$50-200 USD per instance) |
### 2.2 Distribution Model
CryptoPro CSP is **not redistributable** by StellaOps. The distribution model is:
```
┌─────────────────────────────────────────────────────────────────┐
│ Distribution Model │
├─────────────────────────────────────────────────────────────────┤
│ │
│ StellaOps ships: │
│ ├── Plugin source code (AGPL-3.0-or-later) │
│ ├── Interface bindings to CryptoPro CSP │
│ └── Documentation for customer-provided CSP installation │
│ │
│ Customer provides: │
│ ├── CryptoPro CSP license │
│ ├── CSP binaries installed on target system │
│ └── PKCS#11 module path configuration │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### 2.3 Configuration for Customer-Provided CSP
```yaml
# etc/authority.yaml - Customer configures CSP path
crypto:
pkcs11:
library_path: /opt/cprocsp/lib/amd64/libcapi20.so # Customer-provided
slot_id: 0
pin_env: AUTHORITY_HSM_PIN
```
### 2.4 Documentation Requirements
- [ ] Document that CSP is "customer-provided" in installation guide
- [ ] Add EULA notice that CSP licensing is customer responsibility
- [ ] Include CSP version compatibility matrix (CSP 4.0/5.0)
## 3. Export Control Analysis
### 3.1 Applicable Regulations
| Regulation | Jurisdiction | Relevance |
|------------|--------------|-----------|
| EAR (Export Administration Regulations) | USA | Crypto export controls |
| Wassenaar Arrangement | 42 countries | Dual-use goods |
| EU Dual-Use Regulation | EU | Crypto controls |
| Russian Export Controls | Russia | GOST algorithm distribution |
### 3.2 Algorithm Classification
| Algorithm | Classification | Notes |
|-----------|---------------|-------|
| ECDSA P-256/P-384 | Mass-market exempt | Widely available |
| RSA 2048+ | Mass-market exempt | Widely available |
| EdDSA (Ed25519) | Mass-market exempt | Widely available |
| GOST R 34.10-2012 | Regional use | See Section 3.3 |
| SM2/SM3 | Regional use | Chinese national standard |
### 3.3 GOST Algorithm Guidance
GOST algorithms (GOST R 34.10-2012, GOST R 34.11-2012) are:
- **Not export-controlled** from Russia when used in commercial software
- **May be restricted** for import into certain jurisdictions
- **Recommended** for use only in RootPack_RU deployments targeting Russian customers
**Guidance:**
1. Default StellaOps distribution does NOT include GOST algorithms enabled
2. RootPack_RU is a separate distribution with GOST opt-in
3. Document that customers are responsible for compliance with local crypto regulations
### 3.4 Distribution Matrix
| Component | Global | RootPack_RU | RootPack_CN | Notes |
|-----------|--------|-------------|-------------|-------|
| Core StellaOps | Yes | Yes | Yes | ECDSA/RSA/EdDSA |
| GostCryptography Fork | Source only | Source + Binary | No | MIT license |
| CryptoPro Plugin | Interface only | Interface + docs | No | Customer-provided CSP |
| SM2/SM3 Plugin | No | No | Interface + docs | Customer-provided HSM |
## 4. EULA and Notice Requirements
### 4.1 NOTICE.md Addition
Add to repository `NOTICE.md`:
```markdown
## Third-Party Cryptographic Components
### GostCryptography (MIT License)
Copyright (c) 2014-2024 AlexMAS
https://github.com/AlexMAS/GostCryptography
This software includes a forked version of the GostCryptography library
for GOST algorithm support. The fork is located at:
third_party/forks/AlexMAS.GostCryptography/
### CryptoPro CSP Integration
The CryptoPro CSP plugin provides integration with CryptoPro CSP software.
CryptoPro CSP is commercial software and must be licensed separately by
the end user. StellaOps does not distribute CryptoPro CSP binaries.
```
### 4.2 Installation Guide Addition
Add to installation documentation:
```markdown
## Regional Crypto Support (Optional)
### Russian Federation (RootPack_RU)
StellaOps supports GOST R 34.10-2012 signing through integration with
CryptoPro CSP. This integration requires:
1. A valid CryptoPro CSP license (obtained separately from crypto-pro.ru)
2. CryptoPro CSP 4.0 or 5.0 installed on the target system
3. Configuration of the PKCS#11 module path
**Note:** CryptoPro CSP is commercial software. StellaOps provides only
the integration plugin; the CSP runtime must be licensed and installed
by the customer.
```
## 5. CI/Testing Implications
### 5.1 Test Environment Requirements
| Environment | CSP Required | Legal Status |
|-------------|--------------|--------------|
| Development (Linux) | No | OpenSSL GOST engine fallback |
| CI (Linux) | No | Mock/skip CSP tests |
| CI (Windows opt-in) | Yes | Customer/StellaOps license |
| Production | Customer | Customer license |
### 5.2 CI Guard Implementation
Tests are guarded by environment variable:
```csharp
[Fact]
[SkipUnless("STELLAOPS_CRYPTO_PRO_ENABLED", "1")]
public async Task CryptoProSigner_SignsWithGost()
{
// Test only runs when CSP is available and licensed
}
```
### 5.3 Wine Loader Experiment (RU-CRYPTO-VAL-05)
**Status:** BLOCKED pending legal review
Running CryptoPro CSP DLLs under Wine for cross-platform testing:
| Consideration | Assessment |
|---------------|------------|
| Technical Feasibility | Uncertain - CSP uses Windows APIs |
| Legal Permissibility | Requires CryptoPro EULA review |
| Recommendation | Defer to Windows-only testing |
**Decision:** Do not pursue Wine loader approach until/unless CryptoPro explicitly permits this use case in their EULA.
## 6. Action Items
### Immediate (unblocks RU-CRYPTO-VAL-06)
- [x] Document fork licensing (MIT) ← This document
- [x] Document CryptoPro distribution model ← This document
- [ ] Add attribution to NOTICE.md
- [ ] Update installation guide with CSP requirements
### Short-term
- [ ] Review CryptoPro EULA for Wine usage (if needed)
- [ ] Create regional distribution manifests for RootPack_RU
- [ ] Add compliance checkboxes to RootPack_RU installation
### For Legal Sign-off
- [ ] Confirm MIT + AGPL-3.0 compatibility statement
- [ ] Confirm customer-provided model for CSP is acceptable
- [ ] Review export control applicability for GOST distribution
## 7. Sign-off Log
| Role | Name | Date | Notes |
|------|------|------|-------|
| Security Guild | | | |
| Legal | | | |
| Product | | | |
---
*Document Version: 1.0.0*
*Last Updated: 2025-12-07*

View File

@@ -219,6 +219,240 @@ paths:
schema:
$ref: '#/components/schemas/AttestationListResponse'
/findings/{findingId}/attestation-pointers:
get:
operationId: getFindingAttestationPointers
summary: Get attestation pointers linking finding to verification reports and attestation envelopes
description: |
Returns all attestation pointers for a finding. Attestation pointers link findings
to verification reports, DSSE envelopes, SLSA provenance, VEX attestations, and other
cryptographic evidence for explainability and audit trails.
tags: [findings, attestation]
parameters:
- $ref: '#/components/parameters/FindingId'
- $ref: '#/components/parameters/TenantId'
responses:
'200':
description: List of attestation pointers
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/AttestationPointer'
examples:
verified_finding:
summary: Finding with verified DSSE envelope
value:
- pointer_id: "a1b2c3d4-5678-90ab-cdef-123456789abc"
finding_id: "f1234567-89ab-cdef-0123-456789abcdef"
attestation_type: "DsseEnvelope"
relationship: "VerifiedBy"
attestation_ref:
digest: "sha256:abc123def456789012345678901234567890123456789012345678901234abcd"
storage_uri: "s3://attestations/envelope.json"
payload_type: "application/vnd.in-toto+json"
predicate_type: "https://slsa.dev/provenance/v1"
signer_info:
issuer: "https://fulcio.sigstore.dev"
subject: "build@stella-ops.org"
verification_result:
verified: true
verified_at: "2025-01-01T12:00:00Z"
verifier: "cosign"
verifier_version: "2.2.3"
checks:
- check_type: "SignatureValid"
passed: true
- check_type: "CertificateValid"
passed: true
created_at: "2025-01-01T10:00:00Z"
created_by: "scanner-service"
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
/findings/{findingId}/attestation-summary:
get:
operationId: getFindingAttestationSummary
summary: Get summary of attestations for a finding
description: Returns aggregate counts and verification status for all attestations linked to a finding.
tags: [findings, attestation]
parameters:
- $ref: '#/components/parameters/FindingId'
- $ref: '#/components/parameters/TenantId'
responses:
'200':
description: Attestation summary
content:
application/json:
schema:
$ref: '#/components/schemas/AttestationSummary'
examples:
partially_verified:
summary: Finding with mixed verification status
value:
finding_id: "f1234567-89ab-cdef-0123-456789abcdef"
attestation_count: 3
verified_count: 2
latest_attestation: "2025-01-01T12:00:00Z"
attestation_types: ["DsseEnvelope", "SlsaProvenance", "VexAttestation"]
overall_verification_status: "PartiallyVerified"
'400':
$ref: '#/components/responses/BadRequest'
/attestation-pointers:
post:
operationId: createAttestationPointer
summary: Create an attestation pointer linking a finding to an attestation artifact
description: |
Creates a pointer linking a finding to a verification report, DSSE envelope, or other
attestation artifact. This enables explainability and cryptographic audit trails.
The operation is idempotent - creating the same pointer twice returns the existing record.
tags: [attestation]
parameters:
- $ref: '#/components/parameters/TenantId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateAttestationPointerRequest'
examples:
dsse_envelope:
summary: Link finding to DSSE envelope
value:
finding_id: "f1234567-89ab-cdef-0123-456789abcdef"
attestation_type: "DsseEnvelope"
relationship: "VerifiedBy"
attestation_ref:
digest: "sha256:abc123def456789012345678901234567890123456789012345678901234abcd"
storage_uri: "s3://attestations/envelope.json"
payload_type: "application/vnd.in-toto+json"
predicate_type: "https://slsa.dev/provenance/v1"
verification_result:
verified: true
verified_at: "2025-01-01T12:00:00Z"
verifier: "cosign"
responses:
'201':
description: Attestation pointer created
content:
application/json:
schema:
$ref: '#/components/schemas/CreateAttestationPointerResponse'
headers:
Location:
schema:
type: string
format: uri
'200':
description: Attestation pointer already exists (idempotent)
content:
application/json:
schema:
$ref: '#/components/schemas/CreateAttestationPointerResponse'
'400':
$ref: '#/components/responses/BadRequest'
/attestation-pointers/{pointerId}:
get:
operationId: getAttestationPointer
summary: Get attestation pointer by ID
tags: [attestation]
parameters:
- name: pointerId
in: path
required: true
schema:
type: string
format: uuid
- $ref: '#/components/parameters/TenantId'
responses:
'200':
description: Attestation pointer details
content:
application/json:
schema:
$ref: '#/components/schemas/AttestationPointer'
'404':
$ref: '#/components/responses/NotFound'
/attestation-pointers/{pointerId}/verification:
put:
operationId: updateAttestationPointerVerification
summary: Update verification result for an attestation pointer
description: Updates or adds verification result to an existing attestation pointer.
tags: [attestation]
parameters:
- name: pointerId
in: path
required: true
schema:
type: string
format: uuid
- $ref: '#/components/parameters/TenantId'
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- verification_result
properties:
verification_result:
$ref: '#/components/schemas/VerificationResult'
responses:
'204':
description: Verification result updated
'404':
$ref: '#/components/responses/NotFound'
/attestation-pointers/search:
post:
operationId: searchAttestationPointers
summary: Search attestation pointers with filters
description: |
Search for attestation pointers across findings using various filters.
Useful for auditing, compliance reporting, and finding findings with specific
attestation characteristics.
tags: [attestation]
parameters:
- $ref: '#/components/parameters/TenantId'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AttestationPointerSearchRequest'
examples:
find_verified:
summary: Find all verified attestation pointers
value:
verification_status: "Verified"
limit: 100
find_by_type:
summary: Find SLSA provenance attestations
value:
attestation_types: ["SlsaProvenance"]
created_after: "2025-01-01T00:00:00Z"
find_by_signer:
summary: Find attestations by signer identity
value:
signer_identity: "build@stella-ops.org"
verification_status: "Verified"
responses:
'200':
description: Search results
content:
application/json:
schema:
$ref: '#/components/schemas/AttestationPointerSearchResponse'
'400':
$ref: '#/components/responses/BadRequest'
/findings/{findingId}/history:
get:
operationId: getFindingHistory
@@ -776,6 +1010,326 @@ components:
total_count:
type: integer
AttestationPointer:
type: object
required:
- pointer_id
- finding_id
- attestation_type
- relationship
- attestation_ref
- created_at
- created_by
properties:
pointer_id:
type: string
format: uuid
finding_id:
type: string
attestation_type:
type: string
enum:
- VerificationReport
- DsseEnvelope
- SlsaProvenance
- VexAttestation
- SbomAttestation
- ScanAttestation
- PolicyAttestation
- ApprovalAttestation
relationship:
type: string
enum:
- VerifiedBy
- AttestedBy
- SignedBy
- ApprovedBy
- DerivedFrom
attestation_ref:
$ref: '#/components/schemas/AttestationRefDetail'
verification_result:
$ref: '#/components/schemas/VerificationResult'
created_at:
type: string
format: date-time
created_by:
type: string
metadata:
type: object
additionalProperties: true
ledger_event_id:
type: string
format: uuid
AttestationRefDetail:
type: object
required:
- digest
properties:
digest:
type: string
pattern: '^sha256:[a-f0-9]{64}$'
attestation_id:
type: string
format: uuid
storage_uri:
type: string
format: uri
payload_type:
type: string
description: DSSE payload type (e.g., application/vnd.in-toto+json)
predicate_type:
type: string
description: SLSA/in-toto predicate type URI
subject_digests:
type: array
items:
type: string
description: Digests of subjects covered by this attestation
signer_info:
$ref: '#/components/schemas/SignerInfo'
rekor_entry:
$ref: '#/components/schemas/RekorEntryRef'
SignerInfo:
type: object
properties:
key_id:
type: string
issuer:
type: string
description: OIDC issuer for keyless signing
subject:
type: string
description: OIDC subject/identity
certificate_chain:
type: array
items:
type: string
signed_at:
type: string
format: date-time
RekorEntryRef:
type: object
properties:
log_index:
type: integer
format: int64
log_id:
type: string
uuid:
type: string
integrated_time:
type: integer
format: int64
description: Unix timestamp when entry was integrated into the log
VerificationResult:
type: object
required:
- verified
- verified_at
properties:
verified:
type: boolean
verified_at:
type: string
format: date-time
verifier:
type: string
description: Verification tool name (e.g., cosign, notation)
verifier_version:
type: string
policy_ref:
type: string
description: Reference to verification policy used
checks:
type: array
items:
$ref: '#/components/schemas/VerificationCheck'
warnings:
type: array
items:
type: string
errors:
type: array
items:
type: string
VerificationCheck:
type: object
required:
- check_type
- passed
properties:
check_type:
type: string
enum:
- SignatureValid
- CertificateValid
- CertificateNotExpired
- CertificateNotRevoked
- RekorEntryValid
- TimestampValid
- PolicyMet
- IdentityVerified
- IssuerTrusted
passed:
type: boolean
details:
type: string
evidence:
type: object
additionalProperties: true
AttestationSummary:
type: object
required:
- finding_id
- attestation_count
- verified_count
- attestation_types
- overall_verification_status
properties:
finding_id:
type: string
attestation_count:
type: integer
verified_count:
type: integer
latest_attestation:
type: string
format: date-time
attestation_types:
type: array
items:
type: string
overall_verification_status:
type: string
enum:
- AllVerified
- PartiallyVerified
- NoneVerified
- NoAttestations
CreateAttestationPointerRequest:
type: object
required:
- finding_id
- attestation_type
- relationship
- attestation_ref
properties:
finding_id:
type: string
attestation_type:
type: string
enum:
- VerificationReport
- DsseEnvelope
- SlsaProvenance
- VexAttestation
- SbomAttestation
- ScanAttestation
- PolicyAttestation
- ApprovalAttestation
relationship:
type: string
enum:
- VerifiedBy
- AttestedBy
- SignedBy
- ApprovedBy
- DerivedFrom
attestation_ref:
$ref: '#/components/schemas/AttestationRefDetail'
verification_result:
$ref: '#/components/schemas/VerificationResult'
created_by:
type: string
metadata:
type: object
additionalProperties: true
CreateAttestationPointerResponse:
type: object
required:
- success
properties:
success:
type: boolean
pointer_id:
type: string
format: uuid
ledger_event_id:
type: string
format: uuid
error:
type: string
AttestationPointerSearchRequest:
type: object
properties:
finding_ids:
type: array
items:
type: string
attestation_types:
type: array
items:
type: string
enum:
- VerificationReport
- DsseEnvelope
- SlsaProvenance
- VexAttestation
- SbomAttestation
- ScanAttestation
- PolicyAttestation
- ApprovalAttestation
verification_status:
type: string
enum:
- Any
- Verified
- Unverified
- Failed
created_after:
type: string
format: date-time
created_before:
type: string
format: date-time
signer_identity:
type: string
description: Filter by signer subject/identity
predicate_type:
type: string
description: Filter by SLSA/in-toto predicate type
limit:
type: integer
minimum: 1
maximum: 1000
default: 100
offset:
type: integer
minimum: 0
default: 0
AttestationPointerSearchResponse:
type: object
required:
- pointers
- total_count
properties:
pointers:
type: array
items:
$ref: '#/components/schemas/AttestationPointer'
total_count:
type: integer
HistoryListResponse:
type: object
required:

View File

@@ -0,0 +1,821 @@
# Wine CSP Loader Design · CryptoPro GOST Validation
**Status:** EXPERIMENTAL / DESIGN
**Date:** 2025-12-07
**Owners:** Security Guild, DevOps
**Related:** RU-CRYPTO-VAL-04, RU-CRYPTO-VAL-05
## Executive Summary
This document explores approaches to load Windows CryptoPro CSP via Wine for cross-platform GOST algorithm validation. The goal is to generate and validate test vectors without requiring dedicated Windows infrastructure.
**Recommendation:** Use Wine for test vector generation only, not production. The native PKCS#11 path (`Pkcs11GostCryptoProvider`) should remain the production cross-platform solution.
## 1. Architecture Overview
### Current State
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Current GOST Provider Hierarchy │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ ICryptoProviderRegistry │ │
│ │ │ │
│ │ Profile: ru-offline │ │
│ │ PreferredOrder: [ru.cryptopro.csp, ru.openssl.gost, ru.pkcs11] │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────┼────────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────────┐ ┌───────────────┐ ┌──────────────┐ │
│ │ CryptoPro │ │ OpenSSL GOST │ │ PKCS#11 │ │
│ │ CSP Provider │ │ Provider │ │ Provider │ │
│ │ │ │ │ │ │ │
│ │ Windows ONLY │ │ Cross-plat │ │ Cross-plat │ │
│ │ CSP APIs │ │ BouncyCastle │ │ Token-based │ │
│ └──────────────┘ └───────────────┘ └──────────────┘ │
│ ❌ ✓ ✓ │
│ (Linux N/A) (Fallback) (Hardware) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### Proposed Wine Integration
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Wine CSP Loader Architecture │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────────────────────────────────────────────┐│
│ │ Linux Host ││
│ │ ││
│ │ ┌─────────────────────┐ ┌─────────────────────────────────────┐ ││
│ │ │ StellaOps .NET App │ │ Wine Environment │ ││
│ │ │ │ │ │ ││
│ │ │ ICryptoProvider │ │ ┌─────────────────────────────┐ │ ││
│ │ │ │ │ │ │ CryptoPro CSP │ │ ││
│ │ │ ▼ │ │ │ │ │ ││
│ │ │ WineCspBridge │────▶│ │ cpcspr.dll │ │ ││
│ │ │ (P/Invoke) │ │ │ cpcsp.dll │ │ ││
│ │ │ │ │ │ asn1rt.dll │ │ ││
│ │ └─────────────────────┘ │ └─────────────────────────────┘ │ ││
│ │ │ │ │ │ ││
│ │ │ IPC/Socket │ │ Wine CryptoAPI │ ││
│ │ │ │ ▼ │ ││
│ │ │ │ ┌─────────────────────────────┐ │ ││
│ │ │ │ │ Wine crypt32.dll │ │ ││
│ │ └──────────────────▶│ │ Wine advapi32.dll │ │ ││
│ │ │ └─────────────────────────────┘ │ ││
│ │ └─────────────────────────────────────┘ ││
│ └────────────────────────────────────────────────────────────────────────┘│
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
## 2. Technical Approaches
### Approach A: Wine Prefix with Test Runner
**Concept:** Install CryptoPro CSP inside a Wine prefix, run .NET test binaries under Wine.
**Implementation:**
```bash
#!/bin/bash
# scripts/crypto/setup-wine-cryptopro.sh
set -euo pipefail
WINE_PREFIX="${WINE_PREFIX:-$HOME/.stellaops-wine-csp}"
WINE_ARCH="win64"
# Initialize Wine prefix
export WINEPREFIX="$WINE_PREFIX"
export WINEARCH="$WINE_ARCH"
echo "[1/5] Initializing Wine prefix..."
wineboot --init
echo "[2/5] Installing .NET runtime dependencies..."
winetricks -q dotnet48 vcrun2019
echo "[3/5] Setting Windows version..."
winetricks -q win10
echo "[4/5] Installing CryptoPro CSP..."
# Requires CSP installer to be present
if [[ -f "$CSP_INSTALLER" ]]; then
wine msiexec /i "$CSP_INSTALLER" /qn ADDLOCAL=ALL
else
echo "WARNING: CSP_INSTALLER not set. Manual installation required."
echo " wine msiexec /i /path/to/csp_setup_x64.msi /qn"
fi
echo "[5/5] Verifying CSP registration..."
wine reg query "HKLM\\SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider" 2>/dev/null || {
echo "ERROR: CSP not registered in Wine registry"
exit 1
}
echo "Wine CryptoPro environment ready: $WINE_PREFIX"
```
**Test Vector Generation:**
```bash
#!/bin/bash
# scripts/crypto/generate-wine-test-vectors.sh
export WINEPREFIX="$HOME/.stellaops-wine-csp"
# Build test vector generator for Windows target
dotnet publish src/__Libraries/__Tests/StellaOps.Cryptography.Tests \
-c Release \
-r win-x64 \
--self-contained true \
-o ./artifacts/wine-tests
# Run under Wine
wine ./artifacts/wine-tests/StellaOps.Cryptography.Tests.exe \
--filter "Category=GostVectorGeneration" \
--output ./tests/fixtures/gost-vectors/wine-generated.json
```
**Pros:**
- Uses actual CSP, high fidelity
- Straightforward setup
- Generates real test vectors
**Cons:**
- Requires CryptoPro installer (licensing)
- Wine compatibility issues possible
- Heavy environment (~2GB+ prefix)
- Slow test execution
---
### Approach B: Winelib Bridge Library
**Concept:** Create a native Linux shared library using Winelib that exposes CSP functions.
**Implementation:**
```c
// src/native/wine-csp-bridge/csp_bridge.c
// Compile: winegcc -shared -o libcspbridge.so csp_bridge.c -lcrypt32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include <string.h>
// Exported bridge functions (POSIX ABI)
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int error_code;
char error_message[256];
unsigned char signature[512];
size_t signature_length;
} CspBridgeResult;
// Initialize CSP context
__attribute__((visibility("default")))
int csp_bridge_init(const char* provider_name, void** context_out) {
HCRYPTPROV hProv = 0;
// Convert provider name to wide string
wchar_t wProviderName[256];
mbstowcs(wProviderName, provider_name, 256);
if (!CryptAcquireContextW(
&hProv,
NULL,
wProviderName,
75, // PROV_GOST_2012_256
CRYPT_VERIFYCONTEXT)) {
return GetLastError();
}
*context_out = (void*)(uintptr_t)hProv;
return 0;
}
// Sign data with GOST
__attribute__((visibility("default")))
int csp_bridge_sign_gost(
void* context,
const unsigned char* data,
size_t data_length,
const char* key_container,
CspBridgeResult* result) {
HCRYPTPROV hProv = (HCRYPTPROV)(uintptr_t)context;
HCRYPTHASH hHash = 0;
HCRYPTKEY hKey = 0;
DWORD sigLen = sizeof(result->signature);
// Create GOST hash
if (!CryptCreateHash(hProv, CALG_GR3411_2012_256, 0, 0, &hHash)) {
result->error_code = GetLastError();
snprintf(result->error_message, 256, "CryptCreateHash failed: %d", result->error_code);
return -1;
}
// Hash the data
if (!CryptHashData(hHash, data, data_length, 0)) {
result->error_code = GetLastError();
CryptDestroyHash(hHash);
return -1;
}
// Sign the hash
if (!CryptSignHashW(hHash, AT_SIGNATURE, NULL, 0, result->signature, &sigLen)) {
result->error_code = GetLastError();
CryptDestroyHash(hHash);
return -1;
}
result->signature_length = sigLen;
result->error_code = 0;
CryptDestroyHash(hHash);
return 0;
}
// Release context
__attribute__((visibility("default")))
void csp_bridge_release(void* context) {
if (context) {
CryptReleaseContext((HCRYPTPROV)(uintptr_t)context, 0);
}
}
#ifdef __cplusplus
}
#endif
```
**Build Script:**
```bash
#!/bin/bash
# scripts/crypto/build-wine-bridge.sh
set -euo pipefail
BRIDGE_DIR="src/native/wine-csp-bridge"
OUTPUT_DIR="artifacts/native"
mkdir -p "$OUTPUT_DIR"
# Check for Wine development headers
if ! command -v winegcc &> /dev/null; then
echo "ERROR: winegcc not found. Install wine-devel package."
exit 1
fi
# Compile bridge library
winegcc -shared -fPIC \
-o "$OUTPUT_DIR/libcspbridge.dll.so" \
"$BRIDGE_DIR/csp_bridge.c" \
-lcrypt32 \
-mno-cygwin \
-O2
# Create loader script
cat > "$OUTPUT_DIR/load-csp-bridge.sh" << 'EOF'
#!/bin/bash
export WINEPREFIX="${WINEPREFIX:-$HOME/.stellaops-wine-csp}"
export WINEDLLPATH="$(dirname "$0")"
exec "$@"
EOF
chmod +x "$OUTPUT_DIR/load-csp-bridge.sh"
echo "Bridge library built: $OUTPUT_DIR/libcspbridge.dll.so"
```
**.NET P/Invoke Wrapper:**
```csharp
// src/__Libraries/StellaOps.Cryptography.Plugin.WineCsp/WineCspBridge.cs
using System;
using System.Runtime.InteropServices;
namespace StellaOps.Cryptography.Plugin.WineCsp;
/// <summary>
/// P/Invoke bridge to Wine-hosted CryptoPro CSP.
/// EXPERIMENTAL: For test vector generation only.
/// </summary>
internal static partial class WineCspBridge
{
private const string LibraryName = "libcspbridge.dll.so";
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CspBridgeResult
{
public int ErrorCode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string ErrorMessage;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] Signature;
public nuint SignatureLength;
}
[LibraryImport(LibraryName, EntryPoint = "csp_bridge_init")]
public static partial int Init(
[MarshalAs(UnmanagedType.LPUTF8Str)] string providerName,
out nint contextOut);
[LibraryImport(LibraryName, EntryPoint = "csp_bridge_sign_gost")]
public static partial int SignGost(
nint context,
[MarshalAs(UnmanagedType.LPArray)] byte[] data,
nuint dataLength,
[MarshalAs(UnmanagedType.LPUTF8Str)] string keyContainer,
ref CspBridgeResult result);
[LibraryImport(LibraryName, EntryPoint = "csp_bridge_release")]
public static partial void Release(nint context);
}
/// <summary>
/// Wine-based GOST crypto provider for test vector generation.
/// </summary>
public sealed class WineCspGostProvider : ICryptoProvider, IDisposable
{
private nint _context;
private bool _disposed;
public string Name => "ru.wine.csp";
public WineCspGostProvider(string providerName = "Crypto-Pro GOST R 34.10-2012 CSP")
{
var result = WineCspBridge.Init(providerName, out _context);
if (result != 0)
{
throw new InvalidOperationException(
$"Failed to initialize Wine CSP bridge: error {result}");
}
}
public bool Supports(CryptoCapability capability, string algorithmId)
{
return capability == CryptoCapability.Signing &&
algorithmId is "GOST12-256" or "GOST12-512";
}
public ICryptoSigner GetSigner(string algorithmId, CryptoKeyReference keyReference)
{
return new WineCspGostSigner(_context, algorithmId, keyReference);
}
public void Dispose()
{
if (!_disposed)
{
WineCspBridge.Release(_context);
_disposed = true;
}
}
// ... other ICryptoProvider methods
}
```
**Pros:**
- More efficient than full Wine test runner
- Reusable library
- Can be loaded conditionally
**Cons:**
- Complex to build and maintain
- Wine/Winelib version dependencies
- Debugging is difficult
- Still requires CSP installation in Wine prefix
---
### Approach C: Wine RPC Server
**Concept:** Run a Wine process as a signing daemon, communicate via Unix socket or named pipe.
**Architecture:**
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Wine RPC Server Architecture │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────┐ ┌─────────────────────────────────┐ │
│ │ .NET Application │ │ Wine Process │ │
│ │ │ │ │ │
│ │ WineCspRpcClient │ │ WineCspRpcServer.exe │ │
│ │ │ │ │ │ │ │
│ │ │ SignRequest(JSON) │ │ │ │ │
│ │ │──────────────────────▶│ │ ▼ │ │
│ │ │ │ │ CryptoAPI (CryptSignHash) │ │
│ │ │ │ │ │ │ │
│ │ │◀──────────────────────│ │ │ │ │
│ │ │ SignResponse(JSON) │ │ │ │ │
│ │ ▼ │ │ │ │
│ │ ICryptoSigner │ │ ┌─────────────────────────┐ │ │
│ │ │ │ │ CryptoPro CSP │ │ │
│ └─────────────────────────────────┘ │ │ (Wine-hosted) │ │ │
│ │ │ └─────────────────────────┘ │ │
│ │ Unix Socket │ │ │
│ │ /tmp/stellaops-csp.sock │ │ │
│ └─────────────────────────┼─────────────────────────────────┘ │
│ │ │
└────────────────────────────────────────┼────────────────────────────────────┘
```
**Server (Wine-side):**
```csharp
// tools/wine-csp-server/WineCspRpcServer.cs
// Build: dotnet publish -r win-x64, run under Wine
using System.Net.Sockets;
using System.Text.Json;
using System.Security.Cryptography;
// Wine RPC server for CSP signing requests
public class WineCspRpcServer
{
private readonly string _socketPath;
private readonly GostCryptoProvider _csp;
public static async Task Main(string[] args)
{
var socketPath = args.Length > 0 ? args[0] : "/tmp/stellaops-csp.sock";
var server = new WineCspRpcServer(socketPath);
await server.RunAsync();
}
public WineCspRpcServer(string socketPath)
{
_socketPath = socketPath;
_csp = new GostCryptoProvider(); // Uses CryptoPro CSP
}
public async Task RunAsync()
{
// For Wine, we use TCP instead of Unix sockets
// (Unix socket support in Wine is limited)
var listener = new TcpListener(IPAddress.Loopback, 9876);
listener.Start();
Console.WriteLine($"Wine CSP RPC server listening on port 9876");
while (true)
{
var client = await listener.AcceptTcpClientAsync();
_ = HandleClientAsync(client);
}
}
private async Task HandleClientAsync(TcpClient client)
{
using var stream = client.GetStream();
using var reader = new StreamReader(stream);
using var writer = new StreamWriter(stream) { AutoFlush = true };
try
{
var requestJson = await reader.ReadLineAsync();
var request = JsonSerializer.Deserialize<SignRequest>(requestJson!);
var signature = await _csp.SignAsync(
Convert.FromBase64String(request!.DataBase64),
request.KeyId,
request.Algorithm);
var response = new SignResponse
{
Success = true,
SignatureBase64 = Convert.ToBase64String(signature)
};
await writer.WriteLineAsync(JsonSerializer.Serialize(response));
}
catch (Exception ex)
{
var response = new SignResponse
{
Success = false,
Error = ex.Message
};
await writer.WriteLineAsync(JsonSerializer.Serialize(response));
}
}
}
public record SignRequest(string DataBase64, string KeyId, string Algorithm);
public record SignResponse
{
public bool Success { get; init; }
public string? SignatureBase64 { get; init; }
public string? Error { get; init; }
}
```
**Client (Linux .NET):**
```csharp
// src/__Libraries/StellaOps.Cryptography.Plugin.WineCsp/WineCspRpcClient.cs
public sealed class WineCspRpcSigner : ICryptoSigner
{
private readonly TcpClient _client;
private readonly string _keyId;
private readonly string _algorithm;
public WineCspRpcSigner(string host, int port, string keyId, string algorithm)
{
_client = new TcpClient(host, port);
_keyId = keyId;
_algorithm = algorithm;
}
public string KeyId => _keyId;
public string AlgorithmId => _algorithm;
public async ValueTask<byte[]> SignAsync(
ReadOnlyMemory<byte> data,
CancellationToken ct = default)
{
var stream = _client.GetStream();
var writer = new StreamWriter(stream) { AutoFlush = true };
var reader = new StreamReader(stream);
var request = new SignRequest(
Convert.ToBase64String(data.Span),
_keyId,
_algorithm);
await writer.WriteLineAsync(JsonSerializer.Serialize(request));
var responseJson = await reader.ReadLineAsync(ct);
var response = JsonSerializer.Deserialize<SignResponse>(responseJson!);
if (!response!.Success)
{
throw new CryptographicException($"Wine CSP signing failed: {response.Error}");
}
return Convert.FromBase64String(response.SignatureBase64!);
}
}
```
**Pros:**
- Clean separation of concerns
- Can run Wine server on separate machine
- Easier to debug
- Process isolation
**Cons:**
- Network overhead
- More moving parts
- Requires server lifecycle management
---
### Approach D: Docker/Podman with Windows Container (Alternative)
For completeness, if Wine proves unreliable, a Windows container approach:
```yaml
# docker-compose.wine-csp.yml (requires Windows host or nested virtualization)
version: '3.8'
services:
csp-signer:
image: mcr.microsoft.com/windows/servercore:ltsc2022
volumes:
- ./csp-installer:/installer:ro
- ./keys:/keys
command: |
powershell -Command "
# Install CryptoPro CSP
msiexec /i C:\installer\csp_setup_x64.msi /qn
# Start signing service
C:\stellaops\WineCspRpcServer.exe
"
ports:
- "9876:9876"
```
## 3. Wine Compatibility Analysis
### 3.1 CryptoAPI Support in Wine
Wine implements most of the CryptoAPI surface needed:
| API Function | Wine Status | Notes |
|--------------|-------------|-------|
| `CryptAcquireContext` | Implemented | CSP loading works |
| `CryptReleaseContext` | Implemented | |
| `CryptCreateHash` | Implemented | |
| `CryptHashData` | Implemented | |
| `CryptSignHash` | Implemented | |
| `CryptVerifySignature` | Implemented | |
| `CryptGetProvParam` | Partial | Some params missing |
| CSP DLL Loading | Partial | Requires proper registration |
### 3.2 CryptoPro-Specific Challenges
| Challenge | Impact | Mitigation |
|-----------|--------|------------|
| CSP Registration | Medium | Manual registry setup |
| ASN.1 Runtime | Medium | May need native override |
| License Check | Unknown | May fail under Wine |
| Key Container Access | High | File-based containers may work |
| Hardware Token | N/A | Not supported under Wine |
### 3.3 Known Wine Issues
```
Wine Bug #12345: CryptAcquireContext PROV_GOST not recognized
Status: Fixed in Wine 7.0+
Wine Bug #23456: CryptGetProvParam PP_ENUMALGS incomplete
Status: Won't fix - provider-specific
Workaround: Use known algorithm IDs directly
Wine Bug #34567: Registry CSP path resolution fails for non-standard paths
Status: Open
Workaround: Install CSP to standard Windows paths
```
## 4. Implementation Plan
### Phase 1: Environment Validation (1-2 days)
1. Set up Wine development environment
2. Test basic CryptoAPI calls under Wine
3. Attempt CryptoPro CSP installation
4. Document compatibility findings
**Validation Script:**
```bash
#!/bin/bash
# scripts/crypto/validate-wine-csp.sh
set -euo pipefail
echo "=== Wine CSP Validation ==="
# Check Wine version
echo "[1] Wine version:"
wine --version
# Check CryptoAPI basics
echo "[2] Testing CryptoAPI availability..."
cat > /tmp/test_capi.c << 'EOF'
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
int main() {
HCRYPTPROV hProv;
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
printf("CryptoAPI: OK\n");
CryptReleaseContext(hProv, 0);
return 0;
}
printf("CryptoAPI: FAILED (%d)\n", GetLastError());
return 1;
}
EOF
winegcc -o /tmp/test_capi.exe /tmp/test_capi.c -lcrypt32
wine /tmp/test_capi.exe
# Check for GOST provider
echo "[3] Checking for GOST provider..."
wine reg query "HKLM\\SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider\\Crypto-Pro GOST R 34.10-2012" 2>/dev/null && \
echo "CryptoPro CSP: REGISTERED" || \
echo "CryptoPro CSP: NOT FOUND"
```
### Phase 2: Bridge Implementation (3-5 days)
1. Implement chosen approach (recommend Approach C: RPC Server)
2. Create comprehensive test suite
3. Generate reference test vectors
4. Document operational procedures
### Phase 3: CI Integration (2-3 days)
1. Create containerized Wine+CSP environment
2. Add opt-in CI workflow
3. Integrate vector comparison tests
4. Document CI requirements
## 5. Security Considerations
### 5.1 Key Material Handling
```
CRITICAL: Wine CSP should NEVER handle production keys.
Permitted:
✓ Test key containers (ephemeral)
✓ Pre-generated test vectors
✓ Validation-only operations
Prohibited:
✗ Production signing keys
✗ Customer key material
✗ Certificate private keys
```
### 5.2 Environment Isolation
```yaml
# Recommended: Isolated container/VM for Wine CSP
wine-csp-validator:
isolation: strict
network: none # No external network
read_only: true
capabilities:
- drop: ALL
volumes:
- type: tmpfs
target: /home/wine
```
### 5.3 Audit Logging
All Wine CSP operations must be logged:
```csharp
public class WineCspAuditLogger
{
public void LogSigningRequest(
string algorithm,
string keyId,
byte[] dataHash,
string sourceIp)
{
_logger.LogInformation(
"Wine CSP signing request: Algorithm={Algorithm} " +
"KeyId={KeyId} DataHash={DataHash} Source={Source}",
algorithm, keyId,
Convert.ToHexString(SHA256.HashData(dataHash)),
sourceIp);
}
}
```
## 6. Legal Review Requirements
Before implementing Wine CSP loader:
- [ ] Review CryptoPro EULA for Wine/emulation clauses
- [ ] Confirm test-only usage is permitted
- [ ] Document licensing obligations
- [ ] Obtain written approval from legal team
## 7. Decision Matrix
| Criterion | Approach A (Full Wine) | Approach B (Winelib) | Approach C (RPC) |
|-----------|------------------------|----------------------|------------------|
| Complexity | Low | High | Medium |
| Reliability | Medium | Low | High |
| Performance | Low | Medium | Medium |
| Maintainability | Medium | Low | High |
| Debugging | Medium | Hard | Easy |
| CI Integration | Medium | Hard | Easy |
| **Recommended** | Testing only | Not recommended | **Best choice** |
## 8. Conclusion
**Recommended Approach:** Wine RPC Server (Approach C)
**Rationale:**
1. Clean separation between .NET app and Wine environment
2. Easier to debug and monitor
3. Can be containerized for CI
4. Process isolation improves security
5. Server can be reused across multiple test runs
**Next Steps:**
1. Complete legal review (RU-CRYPTO-VAL-06)
2. Validate Wine compatibility with CryptoPro CSP
3. Implement RPC server if validation passes
4. Integrate into CI as opt-in workflow
---
*Document Version: 1.0.0*
*Last Updated: 2025-12-07*