Skip to content

CNF-25515: feat: add Ed25519 key and certificate support - #1817

Closed
sebrandon1 wants to merge 1 commit into
rh-ecosystem-edge:mainfrom
sebrandon1:feat/ed25519-support
Closed

sebrandon1 wants to merge 1 commit into
rh-ecosystem-edge:mainfrom
sebrandon1:feat/ed25519-support

Conversation

@sebrandon1

@sebrandon1 sebrandon1 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add Ed25519(Bytes) variants to PrivateKey and PublicKey enums, unblocking all code paths that previously rejected Ed25519 keys/certificates with bail! or todo!()
  • Key generation via openssl genpkey -algorithm Ed25519; signing branches on key type — RSA/ECDSA use openssl dgst -sha256, Ed25519 uses openssl pkeyutl -sign -rawin (EdDSA has its own internal hash)
  • Certificate re-signing detects Ed25519 via OID 1.3.101.112; SKID calculation for LibraryGoSha1/LibraryGoSha256 still bails on Ed25519 (RSA-specific Go methods; Ed25519 certs use RFC5280/RFC7093 which are algorithm-agnostic)
  • JWT and standalone key regeneration remain out of scope (OCP uses RS256 exclusively)
  • 17 new unit tests (14 positive, 3 negative) covering key generation, signing, parsing, cert round-trips, PEM serialization, and error paths

Test plan

  • cargo build compiles
  • cargo test — all existing + 17 new tests pass
  • cargo clippy / cargo fmt --check — clean
  • Manual: generate Ed25519 cert+key via openssl, run recert with a use_key rule pointing to the Ed25519 key

Closes #1739
Ref: CNF-25515

Summary by CodeRabbit

  • New Features

    • Added support for Ed25519 private and public keys.
    • Added Ed25519 certificate parsing, generation, signing, verification, serialization, and PEM conversion.
    • Improved compatibility with Ed25519 PKCS#8 keys and certificates.
  • Bug Fixes

    • Improved cryptographic error reporting, including clearer signing failures.
    • Prevented unsupported key types from causing unexpected failures during key conversion and regeneration.

@openshift-ci

openshift-ci Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Hi @sebrandon1. Thanks for your PR.

I'm waiting for a rh-ecosystem-edge member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Tip

We noticed you've done this a few times! Consider joining the org to skip this step and gain /lgtm and other bot rights. We recommend asking approvers on your previous PRs to sponsor you.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: e23deb1e-59d1-402d-81b9-493c3735508d

Walkthrough

This change adds Ed25519 private and public key support across parsing, serialization, generation, signing, certificate conversion, renewal, distributed-key persistence, and JWT handling. RSA and EC paths remain supported.

Changes

Ed25519 key and certificate support

Layer / File(s) Summary
Ed25519 key contracts and conversion
src/cluster_crypto/keys.rs
Adds PrivateKey::Ed25519 and PublicKey::Ed25519, with PEM serialization, public-key derivation, debugging, and explicit unsupported extraction errors.
Ed25519 parsing, generation, and signing
src/cluster_crypto/crypto_utils.rs
Adds OpenSSL PKCS#8 fallback parsing, Ed25519 key generation, SigningKey conversion, raw signing with pkeyutl, and interoperability tests.
Ed25519 PEM and certificate processing
src/cluster_crypto/crypto_objects.rs, src/cluster_crypto/certificate.rs, src/cluster_crypto/keys.rs
Accepts Ed25519 private keys and certificates, extracts certificate public keys, and adds round-trip, serialization, corruption, and conversion tests.
Certificate renewal and distributed-key integration
src/cluster_crypto/cert_key_pair.rs, src/cluster_crypto/distributed_private_key.rs, src/cluster_crypto/distributed_public_key.rs, src/cluster_crypto/crypto_utils/jwt.rs
Detects Ed25519 certificate keys, reuses typed regenerated keys, updates distributed-key handling, and reports Ed25519 as unsupported for JWT operations.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Certificate
  participant crypto_objects
  participant crypto_utils
  participant OpenSSL
  Certificate->>crypto_objects: process Ed25519 PEM certificate
  crypto_objects->>OpenSSL: extract certificate public key
  OpenSSL-->>crypto_objects: Ed25519 public-key PEM
  crypto_objects->>crypto_utils: parse Ed25519 PKCS#8 key
  crypto_utils->>OpenSSL: sign with pkeyutl -rawin
  OpenSSL-->>crypto_utils: Ed25519 signature
Loading

Possibly related PRs

Suggested labels: lgtm

Suggested reviewers: danmanor, tsorya

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning Most requirements are implemented, but standalone Ed25519 key regeneration is still rejected in distributed_private_key.rs. Implement standalone Ed25519 regeneration, including key generation, public-key update, and private-key storage.
Out of Scope Changes check ⚠️ Warning The PR modifies JWT verification and signing behavior even though JWT support is explicitly outside the PR scope. Remove the JWT changes or update the linked objectives to include a defined JWT-support requirement.
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the primary change: adding Ed25519 key and certificate support.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@sebrandon1
sebrandon1 force-pushed the feat/ed25519-support branch from 3804cee to 3b2f948 Compare July 20, 2026 20:01

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/cluster_crypto/keys.rs (1)

154-176: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Missing .stderr(Stdio::piped()) makes error messages from this helper always empty.

command only pipes stdin/stdout; stderr defaults to inherit() for spawn(). When openssl x509 -pubkey fails, output.stderr will be empty, so the bail! at line 172 always reports "openssl failed: " with no detail — while the sibling helper pubkey_pem_from_pkcs8_der (crypto_utils.rs) correctly pipes stderr for the same kind of call. This is now reached by both from_ec_cert_bytes and the new from_ed25519_cert_bytes.

🩹 Proposed fix
         let mut command = Command::new("openssl")
             .arg("x509")
             .arg("-pubkey")
             .arg("-noout")
             .stdin(Stdio::piped())
             .stdout(Stdio::piped())
+            .stderr(Stdio::piped())
             .spawn()
             .context("running openssl")?;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cluster_crypto/keys.rs` around lines 154 - 176, Update
pubkey_pem_from_cert_pem to configure the openssl Command with stderr piped
before spawning, matching the sibling helper’s subprocess setup. Preserve the
existing wait_with_output and bail! handling so openssl failure details remain
included in output.stderr.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@identified-work.md`:
- Around line 281-283: Reconcile the opportunity count in the summary with the
listed identifiers A1-A4, B1-B5, C1-C3, and D1-D2: either update “Total
Identified” to 14 and adjust the corresponding effort estimate, or add the
missing opportunity identifier and its details.
- Around line 53-59: Correct the A2 public-API inventory by removing
dataurl_encode from the listed public functions, or explicitly identifying it as
an internal helper because its visibility is pub(crate). Keep the documentation
scope focused on the genuinely public functions such as commit_file, globvec,
and read_file_to_string.
- Around line 88-97: Update the `LOG_RECORDS` call sites in `logging.rs`,
including the usages around lines 62 and 94, to initialize/access the
`OnceLock<Arc<Mutex<Vec<String>>>>` via `get_or_init(...).lock()` or a shared
helper instead of calling `LOG_RECORDS.lock()` directly; preserve the existing
record access behavior and complete the `lazy_static` removal.

---

Outside diff comments:
In `@src/cluster_crypto/keys.rs`:
- Around line 154-176: Update pubkey_pem_from_cert_pem to configure the openssl
Command with stderr piped before spawning, matching the sibling helper’s
subprocess setup. Preserve the existing wait_with_output and bail! handling so
openssl failure details remain included in output.stderr.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d98a0a06-cd62-4a6b-828e-0933d01363f9

📥 Commits

Reviewing files that changed from the base of the PR and between 25fa596 and 3804cee.

📒 Files selected for processing (10)
  • identified-work.md
  • src/cluster_crypto/cert_key_pair.rs
  • src/cluster_crypto/certificate.rs
  • src/cluster_crypto/crypto_objects.rs
  • src/cluster_crypto/crypto_utils.rs
  • src/cluster_crypto/crypto_utils/jwt.rs
  • src/cluster_crypto/distributed_private_key.rs
  • src/cluster_crypto/distributed_public_key.rs
  • src/cluster_crypto/keys.rs
  • src/ocp_postprocess/cluster_domain_rename/etcd_rename.rs
💤 Files with no reviewable changes (1)
  • src/ocp_postprocess/cluster_domain_rename/etcd_rename.rs

Comment thread identified-work.md Outdated
Comment thread identified-work.md Outdated
Comment thread identified-work.md Outdated
@sebrandon1
sebrandon1 force-pushed the feat/ed25519-support branch 3 times, most recently from 0cea5cb to aa28854 Compare July 20, 2026 20:14
Comment thread src/cluster_crypto/cert_key_pair.rs Outdated
Comment thread src/cluster_crypto/cert_key_pair.rs Outdated
@sebrandon1
sebrandon1 force-pushed the feat/ed25519-support branch 4 times, most recently from 327e153 to c4714ff Compare July 21, 2026 14:11
Comment thread src/cluster_crypto/crypto_objects.rs
Comment thread src/cluster_crypto/cert_key_pair.rs Outdated
Comment thread src/cluster_crypto/crypto_utils.rs Outdated
Comment thread src/cluster_crypto/keys.rs Outdated
Comment thread vendor/x509-certificate/src/signing.rs
Comment thread vendor/x509-certificate/.cargo-checksum.json
@openshift-ci

openshift-ci Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: sebrandon1
Once this PR has been reviewed and has the lgtm label, please ask for approval from omertuc. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sebrandon1
sebrandon1 force-pushed the feat/ed25519-support branch 2 times, most recently from 6f1af0c to 3021ebc Compare July 21, 2026 16:59
Comment thread src/cluster_crypto/cert_key_pair.rs Outdated
@sebrandon1

sebrandon1 commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

The baremetalds-sno-recert-cluster-rename CI failure on this PR is a known infrastructure issue — the test step polls the node at its original IP after recert changes it, causing SSH timeouts. A fix is in progress: openshift/release#82217

@sebrandon1

Copy link
Copy Markdown
Contributor Author

/retest

@sebrandon1
sebrandon1 force-pushed the feat/ed25519-support branch 2 times, most recently from 36d4a95 to fda730f Compare July 30, 2026 15:18
@sebrandon1
sebrandon1 force-pushed the feat/ed25519-support branch 2 times, most recently from bbf1c61 to 9c65b32 Compare August 6, 2026 15:47
@sebrandon1

Copy link
Copy Markdown
Contributor Author

openshift/release#82217 is now merged — issuing retests to see if it passes.

/retest

@sebrandon1
sebrandon1 force-pushed the feat/ed25519-support branch from 9c65b32 to 5d98f69 Compare August 10, 2026 12:53

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/cluster_crypto/crypto_utils.rs`:
- Around line 21-62: Update ed25519_pkcs8_to_v2 to parse and validate the PKCS#8
ASN.1 structure before extracting the private-key seed, instead of assuming it
is always at der[16..48]. Reject malformed or unexpected layouts, while allowing
valid optional attributes, then construct the v2 DER from the parsed 32-byte
seed and public key. Add fixtures covering non-default layouts and
attribute-bearing keys.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4dfe433f-3a54-4626-a821-149cd9ce619e

📥 Commits

Reviewing files that changed from the base of the PR and between e32b5cd and 5d98f69.

📒 Files selected for processing (7)
  • src/cluster_crypto/cert_key_pair.rs
  • src/cluster_crypto/crypto_objects.rs
  • src/cluster_crypto/crypto_utils.rs
  • src/cluster_crypto/crypto_utils/jwt.rs
  • src/cluster_crypto/distributed_private_key.rs
  • src/cluster_crypto/distributed_public_key.rs
  • src/cluster_crypto/keys.rs
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/cluster_crypto/crypto_utils/jwt.rs
  • src/cluster_crypto/distributed_public_key.rs
  • src/cluster_crypto/distributed_private_key.rs
  • src/cluster_crypto/cert_key_pair.rs
  • src/cluster_crypto/crypto_objects.rs
  • src/cluster_crypto/keys.rs

Comment thread src/cluster_crypto/crypto_utils.rs
@sebrandon1

Copy link
Copy Markdown
Contributor Author

/retest

1 similar comment
@sebrandon1

Copy link
Copy Markdown
Contributor Author

/retest

@sebrandon1
sebrandon1 force-pushed the feat/ed25519-support branch 2 times, most recently from 5eeed04 to 9cc9cb9 Compare August 17, 2026 17:45
@sebrandon1 sebrandon1 changed the title feat: add Ed25519 key and certificate support CNF-25515: feat: add Ed25519 key and certificate support Aug 24, 2026
@openshift-ci-robot

openshift-ci-robot commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

@sebrandon1: This pull request references CNF-25515 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.1.0" version, but no target version was set.

Details

In response to this:

Summary

  • Add Ed25519(Bytes) variants to PrivateKey and PublicKey enums, unblocking all code paths that previously rejected Ed25519 keys/certificates with bail! or todo!()
  • Key generation via openssl genpkey -algorithm Ed25519; signing branches on key type — RSA/ECDSA use openssl dgst -sha256, Ed25519 uses openssl pkeyutl -sign -rawin (EdDSA has its own internal hash)
  • Certificate re-signing detects Ed25519 via OID 1.3.101.112; SKID calculation for LibraryGoSha1/LibraryGoSha256 still bails on Ed25519 (RSA-specific Go methods; Ed25519 certs use RFC5280/RFC7093 which are algorithm-agnostic)
  • JWT and standalone key regeneration remain out of scope (OCP uses RS256 exclusively)
  • 17 new unit tests (14 positive, 3 negative) covering key generation, signing, parsing, cert round-trips, PEM serialization, and error paths

Test plan

  • cargo build compiles
  • cargo test — all existing + 17 new tests pass
  • cargo clippy / cargo fmt --check — clean
  • Manual: generate Ed25519 cert+key via openssl, run recert with a use_key rule pointing to the Ed25519 key

Closes #1739
Ref: CNF-25515

Summary by CodeRabbit

  • New Features

  • Added support for Ed25519 private and public keys.

  • Added Ed25519 certificate parsing, generation, signing, verification, serialization, and PEM conversion.

  • Improved compatibility with Ed25519 PKCS#8 keys and certificates.

  • Bug Fixes

  • Improved cryptographic error reporting, including clearer signing failures.

  • Prevented unsupported key types from causing unexpected failures during key conversion and regeneration.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@sebrandon1
sebrandon1 force-pushed the feat/ed25519-support branch 2 times, most recently from 456389f to 7be2b2d Compare August 26, 2026 16:16
@sebrandon1
sebrandon1 force-pushed the feat/ed25519-support branch 3 times, most recently from 6b00d17 to ef90f08 Compare September 2, 2026 20:04
Port remaining compile and Ed25519 crypto fixes from PR 1941 so recert
builds: bring DecodeRsaPublicKey into scope, convert OpenSSL PKCS#8 v0
keys to ring-compatible v2, and accept Ed25519 SPKI PUBLIC KEY PEMs.
Leave e2e tests on 1941 and P-384 SHA-384 signing on 1829.

Co-authored-by: Cursor <cursoragent@cursor.com>
@openshift-ci

openshift-ci Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

@sebrandon1: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/baremetalds-sno-recert-cluster-rename 3deb8a4 link true /test baremetalds-sno-recert-cluster-rename
ci/prow/e2e-aws-ovn-single-node-recert-parallel 3deb8a4 link true /test e2e-aws-ovn-single-node-recert-parallel
ci/prow/e2e-aws-ovn-single-node-recert-serial 3deb8a4 link true /test e2e-aws-ovn-single-node-recert-serial

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@omertuc

omertuc commented Sep 3, 2026

Copy link
Copy Markdown
Member

Superseded by #1941 (recert-e2e), which implements Ed25519 support differently (DER-level workaround instead of vendored code changes) and also adds Ed25519 JWT signing.

@omertuc omertuc closed this Sep 3, 2026
omertuc added a commit to omertuc/recert-1 that referenced this pull request Sep 3, 2026
Includes unit tests salvaged from rh-ecosystem-edge#1817 and rh-ecosystem-edge#1829 (now closed as
superseded by this PR).

Co-Authored-By: Claude <noreply@anthropic.com>
sebrandon1 added a commit to sebrandon1/recert that referenced this pull request Sep 18, 2026
Bring remaining Ed25519 test cleanup and SEC1 PKCS#8 helper
refactor that were not included when rh-ecosystem-edge#1941 merged the crypto
product code from rh-ecosystem-edge#1817 and rh-ecosystem-edge#1829.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Ed25519 key and certificate support

3 participants