keylimectl: A replacement for keylime_tenant in rust#1068
Draft
ansasaki wants to merge 27 commits intokeylime:masterfrom
Draft
keylimectl: A replacement for keylime_tenant in rust#1068ansasaki wants to merge 27 commits intokeylime:masterfrom
keylime_tenant in rust#1068ansasaki wants to merge 27 commits intokeylime:masterfrom
Conversation
b55ee8e to
da44cbc
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
7cd11bf to
9609be7
Compare
30 tasks
30 tasks
f15c57b to
d1ff80a
Compare
36 tasks
This initial implementation covers most of the functionality from the tenant, with some gaps. The progress is tracked in the FEATURE_PARITY.md file and the plans in ROADMAP.md file. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
The generate_random_string() function used a time-seeded linear congruential generator, making nonces predictable. Replace it with generate_secure_nonce() backed by OpenSSL RAND_bytes (CSPRNG), hex-encoding the output. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
These functions were previously only available in the crypto::testing module. Move them to the main crypto module as proper public API, with CryptoError variants for structured error handling. The testing module versions now delegate to the production implementations, preserving backward compatibility. The goal is to make them available to other crates. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Import the RSA-OAEP from the crypto module instead of importing from the testing module. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Replace the validate_tpm_quote() stub with two cfg-gated implementations controlled by the 'tpm-quote-validation' cargo feature. The default path performs structural validation only (quote format, base64 decoding, data length) and clearly documents the security limitations with SECURITY comments and a runtime warning. The feature-enabled path implements full cryptographic validation following tpm2_checkquote logic: parses the quote via decode_quote_string(), verifies the signature against the registered AIK using OpenSSL (RSA-SSA and RSA-PSS), checks the nonce from TPMS_ATTEST.extraData, and validates the PCR digest. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wrap U, V, and K key buffers in zeroize::Zeroizing so they are securely cleared from memory when they go out of scope. This prevents key material from lingering in process memory after use. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…LS 1.2 Add accept_invalid_hostnames field to TlsConfig (default: true for backward compatibility with Keylime auto-generated certificates). Enforce TLS 1.2 as the minimum protocol version. Log a warning when hostname verification is disabled so operators are aware of the security trade-off. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…mpleted Phase 1 Mark completed Phase 1 items: - 1.1: CSPRNG nonce generation (replaces insecure LCG) - 1.2: Production RSA-OAEP encryption (replaces crypto::testing) - 1.3: Optional TPM quote validation behind feature flag - 1.4: Secret key material zeroization on drop - 1.5: Configurable TLS hostname verification, TLS 1.2 minimum Update FEATURE_PARITY.md security items A and B as fixed, TPM quote validation from Partial to Yes, and summary counts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…dules Implements Phase 2 Steps 2.1-2.3 of the ROADMAP: Step 2.1 - Feature flag infrastructure: - Add api-v2 and api-v3 features to Cargo.toml (both on by default) - Add compile_error! guard requiring at least one feature enabled Step 2.2 - Shared version constants: - Create api_versions module as single source of truth for version constants (SUPPORTED_API_VERSIONS, DEFAULT_API_VERSION, is_v3) - Version arrays are feature-conditional: v2 versions behind api-v2, v3 versions behind api-v3 - Replace duplicated constants in verifier, registrar, and agent clients Step 2.3 - Gate v2-only modules: - Gate client::agent module behind #[cfg(feature = "api-v2")] - Gate commands::agent::attestation module behind api-v2 - Gate pull-model code paths in add.rs with #[cfg(feature = "api-v2")] and provide error returns when api-v2 is disabled - Gate direct agent communication in status.rs behind api-v2 - Add #[cfg_attr] annotations for dead_code that's only used in v2 - Update tests to use DEFAULT_API_VERSION and feature-conditional version array assertions All three feature combinations compile, pass tests, and pass clippy: - default (api-v2 + api-v3): 302 tests - api-v2 only: 302 tests - api-v3 only: 290 tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Gate all v3.0 private methods behind #[cfg(feature = "api-v3")]: - test_api_version_v3, get_agent_v3, delete_agent_v3, reactivate_agent_v3, list_agents_v3, get_bulk_info_v3, add_runtime_policy_v3 Gate v2.x test method behind #[cfg(feature = "api-v2")]: - test_api_version Restructure 6 public methods (get_agent, delete_agent, reactivate_agent, list_agents, get_bulk_info, add_runtime_policy) with #[cfg] blocks: - v3 branch: #[cfg(feature = "api-v3")] using is_v3() helper - v2 fallback: #[cfg(feature = "api-v2")] block - Error return when v2 fallback not available Gate detect_api_version() internals: - 410 Gone match arm behind #[cfg(feature = "api-v3")] - Version probing uses cfg-conditional blocks for v3/v2 testing Move is_v3() behind #[cfg(feature = "api-v3")] since it's only used in v3 code paths. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add CI jobs to test all keylimectl feature flag combinations: - api-v2,api-v3 (default): full functionality - api-v2 only: pull-model without v3 endpoints - api-v3 only: push-model without v2 endpoints Each combination runs build, test, and clippy. Also add a guard job verifying that building with no features triggers the compile_error! as expected. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mark completed Phase 2 items: feature flag infrastructure (2.1), version constants module (2.2), verifier method gating (2.3), command-level gating (2.4), version detection separation (2.5), CI matrix and testing (2.6). Update architecture note from "consideration" to "decision" explaining why #[cfg] was chosen over trait-based approach. Mark related items in "What needs attention" and Phase 3.1 sections. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Apply the same v3/v2 feature flag pattern to registrar's detect_api_version() as was done for verifier: add 410 Gone handler behind api-v3, split test_api_version into v2/v3 variants, and use cfg-conditional version probing. Registrar public methods (get_agent, delete_agent, list_agents) remain version-agnostic since they use self.api_version in URL construction with the same endpoint pattern. Verified: all 3 feature combinations build, pass tests (302, 301, 290), and pass clippy. Binary symbol inspection confirms gated code is absent when its feature is disabled. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add negative tests for RSA encryption with attacker-controlled keys: empty, garbage, truncated, and EC PEM keys; oversized plaintext. Add structural validation tests for malformed TPM quote parsing (base64 decode, quote format splitting edge cases). Add zeroization verification tests for key material operations (explicit .zeroize() clears data, XOR operations work through wrapper). Add negative tests for pkey_pub_from_pem and rsa_oaep_encrypt in the keylime crypto module (empty/garbage/truncated PEM, EC key, oversized plaintext). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 3 implementation: Push Model as Primary Mode. - Auto-detect push model when verifier reports API >= 3.0, removing the need for explicit --push-model flag in most cases - Add --pull-model flag to force legacy API 2.x behavior, with deprecation warning when used against v3.x verifiers - Make IP/port optional in AddAgentRequest for push model (agent doesn't need direct contact in push model) - Add --wait-for-attestation flag with configurable timeout to poll verifier until first attestation completes - Improve error messages with actionable recovery guidance for registrar not-found, verifier enrollment, and key delivery failures - Add push/pull model indicator to agent status response - Replace port==0 heuristic in update command with API version-based push model detection - Add 15 new unit tests for model auto-detection, attestation state machine, and optional field handling Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add --timeout CLI flag, no-argument behavior with config summary and dynamic clap help, interactive configuration wizard (dialoguer), config file path tracking, formalized search paths, and integration tests. Key changes: - --timeout global flag overrides client.timeout - Running without subcommand shows config summary + clap help - `configure` subcommand with interactive wizard (wizard feature flag) and --non-interactive mode for scripted configuration - Config struct tracks loaded_from path, has_config_file() helper - .keylimectl/config.toml added as highest-priority auto-discovery path - 348 tests (340 unit + 8 integration), clippy clean across all feature combinations Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add the `keylimectl info` command with subcommands for inspecting configuration, server status, agents, and TLS certificates. Info commands work even with incomplete configuration (warn on validation instead of exiting), making them useful for troubleshooting. Subcommands: - `info` (no subcommand): local diagnostics with version, features, config file search results, effective config with per-field source annotations (cli/env_var/config_file/default), KEYLIME_* env vars - `info verifier`: connect to verifier, report API version, agent count - `info registrar`: connect to registrar, report API version, agent count - `info agent <ID>`: combined verifier+registrar view with summary - `info tls`: validate cert files, check expiration, verify cert/key pair Infrastructure: - CliOverrides struct tracks which CLI args were provided for source annotation in the info command - Config::config_search_paths() exposes file search paths - RegistrarClient::api_version() public getter added - Info command gets its own match arm in main() with validation bypass Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…with new CLI subcommands Convert commands/policy.rs into a directory module (commands/policy/) with the existing CRUD operations moved to crud.rs. Add new CLI subcommands for local policy tools: - policy generate runtime/measured-boot/tpm - policy sign (DSSE signing) - policy verify-signature - policy validate - policy convert (legacy format conversion) - verify evidence (top-level command for one-shot attestation) Add new error types: PolicyGenerationError, DsseError, EvidenceError. Create policy_tools module skeleton for shared policy logic. All new subcommands return "not yet implemented" stubs. Existing CRUD commands and all 372 unit tests continue to pass unchanged. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ypes Add Rust types for policy schemas that match the Python implementation, enabling serialization compatibility between Python and Rust codebases. - RuntimePolicy: v1 schema with digests, excludes, keyrings, IMA config - MeasuredBootPolicy: UEFI Secure Boot reference state types - TpmPolicy: PCR mask and expected values with helper methods Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tion Add IMA measurement list parsing, flat-text and JSON allowlist parsing, exclude list parsing, and file digest calculation for local runtime policy generation via `keylimectl policy generate runtime`. - ima_parser: parse IMA logs (ima, ima-ng, ima-sig, ima-buf templates) - ima_parser: parse flat-text and JSON allowlists, exclude lists - digest: calculate file digests using OpenSSL (sha1/256/384/512/sm3) - generate: wire Runtime subcommand to parse inputs and build policy Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add filesystem tree scanning for rootfs digest calculation and policy merge utilities. Wire --rootfs and --skip-path CLI args to the runtime policy generate command using tokio::spawn_blocking for CPU-bound work. - filesystem: recursive directory walk with skip paths and symlink exclusion - merge: union of digests, excludes, keyrings, and ima-buf entries - runtime_policy: add deduplication to add_digest/add_keyring/add_ima_buf Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ation Add Dead Simple Signing Envelope (DSSE) support for policy signing and verification with ECDSA P-256 and X.509 certificate backends. Implements PAE (Pre-Authentication Encoding), envelope sign/verify protocol, key generation/loading, and self-signed certificate creation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…oot, and TPM policies Add structural and content validation for all three policy types with auto-detection. Validates digest formats, required fields, PCR mask consistency, and schema compatibility. Supports optional DSSE signature verification during validation via --signature-key. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add conversion from JSON and flat-text allowlists to v1 runtime policy format. Supports auto-detection of input format, exclude list merging, and verification key injection. Adds in-memory parsing helpers for JSON and flat-text allowlists to ima_parser. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add verify evidence command that posts TPM or TEE attestation evidence to the verifier's /verify/evidence endpoint. Reads quote, AK, EK files as base64, sends with nonce and policies, parses verification results including failure details. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add TPM policy generation from PCR values file with index filtering and mask calculation. Add measured boot policy generation from UEFI event logs using the shared crate's UefiLogHandler, extracting S-CRTM, platform firmware, and Secure Boot variable measurements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add 23 integration tests in tests/policy_tools.rs covering: - Help output for all new subcommands (generate, sign, validate, convert) - Runtime policy generation from IMA logs, allowlists, with excludes - TPM policy generation from PCR values files - Policy validation for runtime and TPM policy types - DSSE signing (ECDSA and X.509 backends) and verification - Legacy allowlist conversion (flat-text and JSON formats) - End-to-end pipeline: generate -> validate -> sign -> verify Fix bugs found during integration testing: - Remove duplicate stdout output (commands called output.success() AND main.rs dispatcher also called it, producing double JSON) - Remove default_value on --ima-measurement-list to make it truly optional (previously always read /sys/kernel/security/ima even when only --allowlist was specified) - Add PolicyAction::is_local_only() and match arm in main() so local-only policy commands (generate, sign, verify-signature, validate, convert) bypass strict TLS config validation Update ROADMAP.md to mark Phase 6 items as complete. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Disclaimer: this is an AI generated rewrite. We should be careful reviewing it.
Adds a modern Rust replacement for keylime_tenant with full API compatibility and improved usability.
Features
Implementation
Usage