Crypto Routing Audit — 07 Nov 2025

What this is: a dated point-in-time audit of where Stella Ops runtime code calls .NET cryptography directly instead of routing through the shared, sovereign-aware provider registry. It exists to drive remediation toward a single configurable crypto path (see Crypto registry decision · 2025-11-18).

Audience: crypto/platform engineers and the module owners named in the hotspot and remediation sections below.

Status: historical snapshot. File counts, paths, and tooling references reflect the repository as of November 2025 and may have moved since; treat them as a starting point, not current ground truth.

Scope. Inventory direct uses of System.Security.Cryptography (and related primitives) outside the StellaOps.Cryptography* stack, to identify callers that must be routed through sovereign-aware providers (default, PKCS#11, CryptoPro, and future PQC).

Method. rg -l "using System.Security.Cryptography" src | grep -Ev "__Tests|\.Tests/" (filtered for runtime code). Counts reflect unique files per top-level module.

Summary (runtime files by module)

Module/AreaFiles bypassing shared crypto
Concelier34
Scanner31
Authority20
Excititor18
Attestor18
EvidenceLocker10
Findings / Vuln Explorer7
Zastava6
ExportCenter6
Policy4
Scheduler3
CLI3
Bench3
AdvisoryAI3
Other (Notify, Registry, Signals, etc.)11 combined

Configuring crypto.regionalProfiles

All hosts can now express provider ordering and profile overrides via configuration:

StellaOps:
  Crypto:
    Registry:
      PreferredProviders:
        - default
        - ru.openssl.gost
        - ru.pkcs11
      ActiveProfile: ru-offline
      Profiles:
        ru-offline:
          PreferredProviders:
            - ru.cryptopro.csp
            - ru.openssl.gost
            - ru.pkcs11
    Pkcs11:
      Keys:
        - KeyId: ru-slot-token
          LibraryPath: /usr/local/lib/librutokenecp.so
          SlotId: "0x1"
          PrivateKeyLabel: signing-key
          CertificateThumbprint: "<thumbprint>"
    CryptoPro:
      Keys:
        - KeyId: ru-csp-token
          ProviderName: "Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider"
          CertificateThumbprint: "<thumbprint>"
    OpenSsl:
      Keys:
        - KeyId: ru-openssl-token
          PrivateKeyPath: /etc/stellaops/keys/ru-openssl.pem
          PrivateKeyPassphraseEnvVar: RU_OPENSSL_PASS
          SignatureFormat: Der

Windows hosts still prefer ru.cryptopro.csp, but Linux deployments automatically fall back to the new ru.openssl.gost provider (BouncyCastle/OpenSSL-backed) so sovereign GOST signing works without CryptoPro.

CLI quick check

Use the diagnostics CLI to inspect providers or produce test signatures without editing service hosts:

dotnet run --project src/Tools/StellaOps.CryptoRu.Cli -- providers --config etc/rootpack/ru/crypto.profile.yaml --profile ru-offline
dotnet run --project src/Tools/StellaOps.CryptoRu.Cli -- sign --config etc/rootpack/ru/crypto.profile.yaml --key-id ru-openssl-token --alg GOST12-256 --file samples/message.bin --format base64

The CLI accepts JSON or YAML configs, applies registry profile overrides, and prints the resolved provider name (for example, ru.cryptopro.csp on Windows and ru.openssl.gost on Linux).

Within a service host, stellaops crypto providers lists the registered providers, signing algorithms, certificate metadata, and the current preferred order. Use --json for machine-readable output, or --profile <name> to preview another profile (e.g., ru-offline) before flipping configuration.

Call builder.Services.AddStellaOpsCryptoRu(builder.Configuration) to bind this configuration and register the RU providers with the correct preferred order.

Each deployment picks a profile (ActiveProfile) that resolves to a deterministic provider order, and individual services call into ICryptoProviderRegistry rather than instantiating crypto stacks directly.

Known gaps (2025-11-09)

Even after the initial plug-ins landed, several sovereign-crypto deliverables remain outstanding. These items must be addressed before RootPack_RU can be treated as GA:

  1. Integration tests – There are zero CryptoPro/PKCS#11 tests in src/__Libraries/__Tests/StellaOps.Cryptography.Tests/. The RootPack validation script cannot validate hardware paths today.
  2. Symmetric GOST – Magma/Kuznyechik (RFC 5830 / RFC 7801) support is missing, so RU deployments cannot request sovereign symmetric encryption for exports/data-at-rest.
  3. Host adoption – Authority, Scanner, Concelier, etc. register only the default providers; none call the RU DI helpers or set ActiveProfile = ru-offline, leaving sovereign bundles inert.
  4. Docs/runbooks – RootPack docs reference the CLI/config/test harnesses, but they do not yet exist; we need explicit follow-ups (see the RootPack docs) and edits once the tooling ships.

High-priority hotspots

Concelier (ingestion + mirror connectors)

Action: Introduce ICryptoProviderRegistry consumption inside connector/lib assemblies (probably through lightweight adapter service). File follow-up tasks in src/Concelier/StellaOps.Concelier.WebService/TASKS.md and connector TASK boards to migrate hashing/signing to the new PKCS#11/CryptoPro providers (priority for RU feeds to unblock RootPack_RU).

Update (2025-11-08). OpenAPI discovery, advisory chunk IDs, SourceFetchService/SourceStateSeedProcessor, OSV/NVD + RU connectors, and the JSON exporter/mirror bundle writers now route hashing/signing through ICryptoHash + StellaOpsCryptoOptions. Remaining Concelier hotspots should now only appear inside the shared StellaOps.Cryptography* assemblies.

Scanner (web service, worker, Sbomer plug-ins)

Action: Create shared IScanCryptoService backed by ICryptoProviderRegistry so both web service and worker reuse sovereign providers. Add tasks under src/Scanner/StellaOps.Scanner.WebService/TASKS.md and src/Scanner/StellaOps.Scanner.Worker/TASKS.md.

Authority (plugins + signing host)

Action: Wire Authority signing/loading paths to ICryptoProviderRegistry so active keys can point to ru.cryptopro.csp or ru.pkcs11. Open tasks in src/Authority/StellaOps.Authority/TASKS.md covering: signing key loading, JWKS generation, secret hashing migration.

Excititor / Attestor

Action: Introduce shared hashing helper that internally calls ICryptoProviderRegistry.ResolveOrThrow(CryptoCapability.Signing, SignatureAlgorithms.GostR3410_2012_256) for digest+sign combos; log follow-ups in respective TASK boards.

Evidence Locker / Export Center

Action: Add backlog tasks for both modules to replace SHA256.Create() usage with provider-backed hashing (especially for offline bundle sealing).

Next steps

  1. Open remediation tasks per module referencing this audit (minimum: Concelier, Scanner, Authority, Excititor, Attestor, Evidence Locker, Export Center). Each task should specify which files to migrate and target provider (default vs sovereign).
  2. Provide shared helpers (e.g., ICryptoDigestService, ICasSigner) in StellaOps.Cryptography to ease adoption and avoid each module talking to the registry manually.
  3. Follow-up audit once migrations land; rerun the command and ensure only StellaOps.Cryptography* and vetted crypto libraries contain direct System.Security.Cryptography usage.
  4. RootPack validation runbook — see rootpack_ru_validation.mdfor deterministic tests, hardware validation, and the audit artifacts required before shipping RootPack_RU.

Remediation tracking snapshot (2025-11-08)

The aggregated counts above were prepared on 2025-11-07 from a stored query over runtime (non-test) files. The raw query output was a one-off scratch artifact and is not retained in the repository.