Skip to content

Commit 6c9121a

Browse files
committed
feat: use Nix to build OpenSSL 3.1.2
1 parent a663c46 commit 6c9121a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+3460
-942
lines changed

.github/copilot-instructions.md

Lines changed: 81 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -1,195 +1,127 @@
1-
# Cosmian KMS
1+
# Cosmian KMS — Nix-first build, test, and packaging
22

3-
Cosmian KMS is a high-performance, open-source FIPS 140-3 compliant Key Management System written in Rust. The repository contains the KMS server (`cosmian_kms_server`) and supporting libraries for cryptographic operations, database management, and various integrations.
3+
Cosmian KMS is a high-performance, open-source FIPS 140-3 compliant Key Management System written in Rust.
44

5-
Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.
5+
This repository is maintained to be reproducible, deterministic, and offline-friendly. All build, test, and packaging is orchestrated via a single entrypoint:
66

7-
## Working Effectively
7+
- Build and package: `bash .github/scripts/nix.sh package [deb|rpm|dmg]`
8+
- Run tests: `bash .github/scripts/nix.sh test [all|sqlite|mysql|psql|redis|google_cse|hsm]`
89

9-
- **Bootstrap and build the repository:**
10+
Always reference these instructions first; only fall back to ad‑hoc commands when troubleshooting discrepancies.
1011

11-
- First, initialize git submodules: `git submodule update --recursive --init`
12-
- System requires Rust stable toolchain (1.90.0) with rustfmt and clippy components
13-
- OpenSSL 3.2.0 is REQUIRED (not 3.0.13+) for proper FIPS compliance and static linking
14-
- OpenSSL must be installed to `/usr/local/openssl` using `.github/reusable_scripts/get_openssl_binaries.sh`
15-
- Build process follows CI workflow: `bash .github/scripts/cargo_build.sh`
16-
- Environment variables required: `OPENSSL_DIR=/usr/local/openssl`, `DEBUG_OR_RELEASE=debug|release`
17-
- For non-FIPS builds: `FEATURES=non-fips`
18-
- The CLI binary `cosmian` IS built in this repository and included in build artifacts
12+
## Why Nix?
1913

20-
- **UI and Packaging:**
14+
- Pinned nixpkgs for hermetic, reproducible environments
15+
- Native deterministic verification in the derivation (installCheckPhase)
16+
- Pinned Rust toolchain (1.90.0) from Nix — no rustup downloads
17+
- Pinned OpenSSL 3.1.2 with static linking (no dynamic OpenSSL at runtime)
18+
- One-command packaging for DEB/RPM/DMG with smoke tests
2119

22-
- UI is built on Ubuntu distributions using `bash .github/scripts/build_ui.sh`
23-
- UI files are located in `crate/server/ui` directory
24-
- Release builds create Debian packages via `cargo deb -p cosmian_kms_server`
25-
- RPM packages created via `cargo generate-rpm -p crate/server`
26-
- Packages support both FIPS and non-FIPS variants
20+
## Quick start
2721

28-
- **Testing and validation:**
22+
```bash
23+
# Build default packages for your platform (Linux → deb+rpm, macOS → dmg)
24+
bash .github/scripts/nix.sh package
2925

30-
- Multi-database testing: sqlite, postgresql, mysql, redis-findex
31-
- Database environment variables: `KMS_POSTGRES_URL=postgresql://kms:[email protected]:5432/kms`, `KMS_MYSQL_URL=mysql://kms:kms@localhost:3306/kms`, `KMS_SQLITE_PATH=data/shared`
32-
- MySQL tests are currently disabled (skipped in CI)
33-
- Redis-findex tests skipped in FIPS mode (not supported)
34-
- Debug builds only test sqlite; release builds test all enabled databases
35-
- macOS runners only support sqlite tests (no docker containers)
36-
- HSM testing on Ubuntu with Utimaco: `HSM_USER_PASSWORD="12345678" cargo test -p utimaco_pkcs11_loader --features utimaco`
37-
- Logging control: `RUST_LOG="cosmian_kms_cli=error,cosmian_kms_server=error,cosmian_kmip=error,test_kms_server=error"`
38-
- Test execution: `cargo test --workspace --lib $RELEASE $FEATURES -- --nocapture $SKIP_SERVICES_TESTS`
26+
# Build a specific format/variant
27+
bash .github/scripts/nix.sh --variant fips package deb
28+
bash .github/scripts/nix.sh --variant non-fips package rpm
3929

40-
- **Build artifacts and binaries:**
30+
# Build and test on SQLite only
31+
bash .github/scripts/nix.sh test sqlite
4132

42-
- Primary binaries: `cosmian`, `cosmian_kms`, `cosmian_findex_server`
43-
- Binary locations: `target/$DEBUG_OR_RELEASE/` (e.g., `target/debug/`)
44-
- Release builds include benchmarks: `cargo bench $FEATURES --no-run`
45-
- Static linking verified (no dynamic OpenSSL dependencies): `ldd cosmian_kms | grep ssl` should fail
46-
- Version verification: `cosmian_kms --info` must show OpenSSL 3.2.0
47-
- Binary tests: `cargo test --workspace --bins $RELEASE $FEATURES`
33+
# Run tests (defaults to 'all' - run 'docker compose up -d' first for DB backends)
34+
bash .github/scripts/nix.sh test
35+
```
4836

49-
- **Run the KMS server:**
37+
Artifacts are placed under `result-deb-<variant>/`, `result-rpm-<variant>/`, and `result-dmg-<variant>/`.
5038

51-
- ALWAYS build first using the build script above
52-
- Debug mode: `./target/debug/cosmian_kms --database-type sqlite --sqlite-path /tmp/kms-data`
53-
- Release mode: `./target/release/cosmian_kms --database-type sqlite --sqlite-path /tmp/kms-data`
54-
- Server listens on <http://0.0.0.0:9998> by default
55-
- Supported databases: sqlite, postgresql, mysql, redis-findex (redis-findex not available in FIPS mode)
39+
## Determinism and native hash enforcement
5640

57-
- **Docker usage:**
58-
- Development with services: `docker compose up -d` (starts postgresql, mysql, redis)
59-
- Production: `docker run -p 9998:9998 --name kms ghcr.io/cosmian/kms:latest`
60-
- Pre-built images include UI at <http://localhost:9998/ui>
61-
- Local Docker builds use the same OpenSSL setup as CI
41+
The KMS server derivation computes the SHA-256 of the output binary and compares it to `nix/expected-hashes/{fips,non-fips}.sha256` during `installCheckPhase`. Any mismatch fails the build. Packaging scripts also enforce the expected hash when reusing prebuilt results to ensure drift is caught early.
6242

63-
## Validation
43+
To update an expected hash after a legitimate change:
6444

65-
- **CRITICAL**: Always manually test server functionality after making changes by starting the server and verifying it responds to HTTP requests
66-
- Test server startup: Start server with `--database-type sqlite --sqlite-path /tmp/test-db`
67-
- Test API responses: `curl -s -X POST -H "Content-Type: application/json" -d '{}' http://localhost:9998/kmip/2_1` should return KMIP validation error (confirms server is working)
68-
- Test server version: `./target/release/cosmian_kms --version` should show version 5.11.1
69-
- OpenSSL validation: `./target/release/cosmian_kms --info` should show OpenSSL 3.2.0
70-
- Static linking check: `ldd ./target/release/cosmian_kms | grep ssl` should return empty (no dynamic OpenSSL)
71-
- Always run `cargo fmt --check` before committing (takes 3 seconds)
72-
- Clippy requires installation: `rustup component add clippy`
45+
```bash
46+
nix-build -A kms-server-fips -o result-server-fips
47+
sha256sum result-server-fips/bin/cosmian_kms | cut -d' ' -f1 > nix/expected-hashes/fips.sha256
48+
# repeat for non-fips
49+
```
7350

74-
## Common tasks
51+
## Offline packaging
7552

76-
The following are outputs from frequently run commands. Reference them instead of viewing, searching, or running bash commands to save time.
53+
The first run can prewarm the Nix store (pinned nixpkgs, tools) and the Cargo registry cache. Subsequent runs can be fully offline:
7754

78-
### Repo root structure
55+
- Nix: store prewarmed and reused; builds run with empty `substituters`
56+
- Cargo: registry and crate sources cached in `target/cargo-offline-home` and packaging runs with `CARGO_NET_OFFLINE=true`
57+
- OpenSSL: `resources/tarballs/openssl-3.1.2.tar.gz` must exist locally (script fetches it once if online)
7958

80-
```text
81-
.cargo/ # Cargo configuration
82-
.github/ # CI/CD workflows and scripts
83-
scripts/ # Build scripts (cargo_build.sh, build_ui.sh)
84-
reusable_scripts/ # OpenSSL setup scripts
85-
crate/ # Rust workspace crates
86-
server/ # KMS server binary crate
87-
ui/ # Web UI files (built by build_ui.sh)
88-
cli/ # CLI binary crate (cosmian)
89-
crypto/ # Cryptographic operations
90-
kmip/ # KMIP protocol implementation
91-
client_utils/ # Client utilities
92-
kms_client/ # KMS client library
93-
access/ # Access control
94-
interfaces/ # Database and HSM interfaces
95-
server_database/ # Database management
96-
hsm/ # HSM integrations (proteccio, utimaco, softhsm2)
97-
documentation/ # Project documentation
98-
docker-compose.yml # Development services (postgres, mysql, redis)
99-
Dockerfile # Container build
100-
README.md # Project documentation
101-
Cargo.toml # Workspace configuration
102-
rust-toolchain.toml # Rust toolchain: 1.90.0
103-
```
59+
Verification: disconnect network, then re-run `bash .github/scripts/nix.sh package deb` — it should succeed and produce the same artifact hash.
10460

105-
### Key build commands and timing
61+
## Testing
10662

10763
```bash
108-
# Full CI build process (includes UI, packaging, multi-database tests)
109-
git submodule update --recursive --init
110-
export OPENSSL_DIR=/usr/local/openssl
111-
export DEBUG_OR_RELEASE=debug # or release
112-
export FEATURES=non-fips # optional, for non-FIPS builds
113-
114-
# OpenSSL setup (required first)
115-
sudo mkdir -p /usr/local/openssl/ssl /usr/local/openssl/lib64/ossl-modules
116-
sudo chown -R $USER /usr/local/openssl
117-
bash .github/reusable_scripts/get_openssl_binaries.sh
118-
bash .github/scripts/cargo_build.sh
64+
# Typical flows
65+
bash .github/scripts/nix.sh test # all tests supported on your OS
66+
bash .github/scripts/nix.sh test sqlite # sqlite-only (macOS/Linux)
67+
bash .github/scripts/nix.sh test psql # requires local PostgreSQL
68+
bash .github/scripts/nix.sh test redis # non-FIPS only
69+
70+
# HSM tests (Linux only)
71+
bash .github/scripts/nix.sh test hsm # softhsm2 + utimaco + proteccio
72+
bash .github/scripts/nix.sh test hsm softhsm2 # single backend
73+
```
11974

75+
Environment variables for DB tests:
12076

121-
# UI build (Ubuntu only)
122-
bash .github/scripts/build_ui.sh
77+
- `KMS_POSTGRES_URL=postgresql://kms:[email protected]:5432/kms`
78+
- `KMS_MYSQL_URL=mysql://kms:kms@localhost:3306/kms`
79+
- `KMS_SQLITE_PATH=data/shared`
12380

124-
# Individual builds (after OpenSSL setup)
125-
cargo build --features non-fips
126-
cargo build --release --features non-fips
81+
Notes:
12782

128-
# Multi-database testing
129-
export KMS_TEST_DB=sqlite # or postgresql, mysql, redis-findex
130-
cargo test --workspace --lib --features non-fips
83+
- MySQL tests are currently disabled in CI
84+
- Redis-findex tests are skipped in FIPS mode
85+
- On macOS, only sqlite tests run (no DB containers)
13186

132-
# HSM testing (Ubuntu only)
133-
bash .github/reusable_scripts/test_utimaco.sh
134-
HSM_USER_PASSWORD="12345678" cargo test -p utimaco_pkcs11_loader --features utimaco
87+
## Validation and smoke tests
13588

136-
# Packaging (release builds only)
137-
cargo install cargo-deb cargo-generate-rpm
138-
cargo deb -p cosmian_kms_server
139-
cargo generate-rpm -p crate/server
89+
Packaging runs include a smoke test that extracts the artifact and runs `cosmian_kms --info` to verify OpenSSL 3.1.2 and static linkage. You can also run the server manually (after building or unpacking a package):
14090

141-
# Format check (3 seconds)
142-
cargo fmt --check
91+
```bash
92+
./cosmian_kms --database-type sqlite --sqlite-path /tmp/kms-data
14393
```
14494

145-
### Server startup and validation
95+
Basic API probe:
14696

14797
```bash
148-
# Start server (debug)
149-
./target/debug/cosmian_kms --database-type sqlite --sqlite-path /tmp/kms-data
150-
151-
# Start server (release)
152-
./target/release/cosmian_kms --database-type sqlite --sqlite-path /tmp/kms-data
153-
154-
# Test server is responding
15598
curl -s -X POST -H "Content-Type: application/json" -d '{}' http://localhost:9998/kmip/2_1
156-
# Expected response: "Invalid Request: missing field `tag` at line 1 column 2"
99+
```
157100

158-
# Check version and OpenSSL
159-
./target/release/cosmian_kms --version
160-
# Expected: "cosmian_kms_server 5.11.1"
101+
Expected response is a KMIP validation error, confirming the server is alive.
161102

162-
./target/release/cosmian_kms --info
163-
# Expected: Output containing "OpenSSL 3.2.0"
103+
## Repository layout (high level)
164104

165-
# Verify static linking (should return empty)
166-
ldd ./target/release/cosmian_kms | grep ssl
105+
```text
106+
.github/ # Orchestrator scripts (nix.sh), CI, and helpers
107+
nix/ # Nix derivations, scripts, expected hashes
108+
crate/ # Rust workspace crates (server, cli, crypto, …)
109+
pkg/ # Packaging metadata (deb/rpm service files, configs)
110+
resources/tarballs/ # OpenSSL 3.1.2 tarball (local copy for offline)
111+
result-*/ # Symlinks to build/package results
167112
```
168113

169-
### Docker quick start
114+
## Tips
115+
116+
- Format/lints: run `cargo fmt --check` and clippy inside the Nix environment if needed
117+
- If repeated packaging triggers rebuilds, set `NO_PREWARM=1` for faster reuse-only runs
118+
- If a package fails due to hash mismatch, update the relevant file in `nix/expected-hashes/` only after reviewing the change
119+
120+
## Docker
170121

171122
```bash
172-
# Pull and run pre-built image (includes UI)
173123
docker pull ghcr.io/cosmian/kms:latest
174124
docker run -p 9998:9998 --name kms ghcr.io/cosmian/kms:latest
175-
176-
# Development with services
177-
docker compose up -d
178-
179-
# Access UI
180-
curl http://localhost:9998/ui
181-
# Expected: HTML content with KMS web interface
182125
```
183126

184-
## Important notes
185-
186-
- **OpenSSL Version**: OpenSSL 3.2.0 is mandatory, not 3.0.13+. The build verifies this specific version.
187-
- **Static Linking**: All binaries must be statically linked with OpenSSL. CI verifies no dynamic OpenSSL dependencies.
188-
- **Build Artifacts**: Three primary binaries are built: `cosmian`, `cosmian_kms`, `cosmian_findex_server`
189-
- **Database Testing**: Only sqlite works in debug mode and on macOS. Full database testing requires release builds.
190-
- **FIPS vs non-FIPS**: Redis-findex database support is not available in FIPS mode
191-
- **UI Building**: UI is only built on Ubuntu distributions and requires separate build script
192-
- **Packaging**: Debian and RPM packages are created as part of release builds with proper FIPS/non-FIPS variants
193-
- **HSM Support**: Utimaco HSM testing is included but only runs on Ubuntu with specific setup
194-
- **MySQL**: MySQL database tests are currently disabled in CI
195-
- **Workspace**: Build from workspace root using cargo_build.sh script, not individual crate directories
127+
Images include the UI at `http://localhost:9998/ui`.

.github/scripts/build_packages.sh

Lines changed: 0 additions & 53 deletions
This file was deleted.

.github/scripts/build_ui.sh

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,30 @@
99
# Exit on error, print commands
1010
set -ex
1111

12-
if [ -n "$FEATURES" ]; then
13-
CARGO_FEATURES="--features $FEATURES"
12+
# Args: --variant fips|non-fips (default: fips)
13+
VARIANT="fips"
14+
while [ $# -gt 0 ]; do
15+
case "$1" in
16+
-v | --variant)
17+
VARIANT="${2:-}"
18+
shift 2 || true
19+
;;
20+
*) shift ;; # ignore
21+
esac
22+
done
23+
24+
case "$VARIANT" in
25+
fips | non-fips) : ;;
26+
*)
27+
echo "Error: --variant must be 'fips' or 'non-fips'" >&2
28+
exit 1
29+
;;
30+
esac
31+
32+
if [ "$VARIANT" = "non-fips" ]; then
33+
CARGO_FEATURES=(--features non-fips)
34+
else
35+
CARGO_FEATURES=()
1436
fi
1537

1638
# Install nodejs from nodesource if npm is not installed
@@ -37,7 +59,7 @@ cargo install wasm-pack
3759
# Build WASM component
3860
cd crate/wasm
3961
# shellcheck disable=SC2086
40-
wasm-pack build --target web --release $CARGO_FEATURES
62+
wasm-pack build --target web --release "${CARGO_FEATURES[@]}"
4163

4264
# Copy WASM artifacts to UI directory
4365
WASM_DIR="../../ui/src/wasm/"
@@ -56,7 +78,10 @@ npm audit
5678
# Deploy built UI to root
5779
cd .. # current path: ./
5880

59-
DEST_DIR="crate/server/ui${CARGO_FEATURES:+_non_fips}"
81+
DEST_DIR="crate/server/ui"
82+
if [ "$VARIANT" = "non-fips" ]; then
83+
DEST_DIR="crate/server/ui_non_fips"
84+
fi
6085
rm -rf "$DEST_DIR"
6186
mkdir -p "$DEST_DIR"
6287
cp -R ui/dist "$DEST_DIR"

.github/scripts/build_ui_all.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
# Exit on error, print commands
1010
set -ex
1111

12-
bash ./.github/scripts/build_ui.sh
12+
bash ./.github/scripts/build_ui.sh --variant fips
1313
git add crate/server/ui
1414

15-
FEATURES=non-fips bash ./.github/scripts/build_ui.sh
15+
bash ./.github/scripts/build_ui.sh --variant non-fips
1616
git add crate/server/ui_non_fips

0 commit comments

Comments
 (0)