Skip to content

fix(rdc): let the CA set the extensions on issued certificates - #13703

Open
adam360x wants to merge 1 commit into
developfrom
users/adam360x/rdc-ca-extensions
Open

adam360x wants to merge 1 commit into
developfrom
users/adam360x/rdc-ca-extensions

Conversation

@adam360x

Copy link
Copy Markdown
Contributor

Motivation

The certificate authority setup in projects/rdc/authentication (01gen_root_cert.sh,
02gen_ssl_artifacts.sh, openssl.cnf) copied every extension of a certificate request into the
issued certificate (copy_extensions = copyall), and the CA set none of its own. A request that
asks for basicConstraints = CA:TRUE got a certificate that can sign other certificates. Its
holder could then create client certificates that rdcd accepts and server certificates that
rdci trusts, without the CA operator. RDC has no revocation, so the only remedy for an affected
deployment is a new root certificate.

The operator could not notice it: openssl ca reads name_opt and cert_opt, so the
nameopt and certopt lines were ignored, and the signing prompt showed only the subject and the
validity dates.

The OpenSSL documentation warns about exactly this setup and gives this fix:
https://docs.openssl.org/3.0/man1/openssl-ca/#warnings

This only affects certificates signed from requests that someone else created. The readme flow,
where the operator creates every key with 02gen_ssl_artifacts.sh, issues normal certificates.

Technical Details

  • copy_extensions = copy and x509_extensions = usr_cert. The new [ usr_cert ] section sets
    basicConstraints = critical, CA:FALSE, keyUsage, extendedKeyUsage = serverAuth, clientAuth
    and the key identifiers. copy only adds request extensions the CA has not set, so a request can
    still supply its subject alternative names (the shipped request asks for localhost and
    *.amd.com).
  • name_opt = ca_default and cert_opt = ca_default, so the signing prompt shows the certificate
    with its extensions, including the subject alternative names the operator is about to approve.
  • New tests/ci/test_authentication.py runs the shipped openssl commands in a temporary CA
    and answers the prompts like the readme says. It checks that:
    • a request asking for CA:TRUE gets CA:FALSE;
    • the shipped request keeps its alternative names;
    • issued certificates allow TLS server and client use;
    • the prompt shows the extensions.
      It needs only the openssl command, which the RDC CI image has (OpenSSL 3.0.2), and skips
      without it.
  • CHANGELOG entry under Resolved Issues, with what to check if you signed requests that other
    people created.

Certificates that are already installed keep working; only future signing changes.

Issue Tracking

No ticket. Found during a security review of RDC.

Test Plan

  • Run the new tests with this openssl.cnf (OpenSSL 3.0.2 and 3.6.3) and with develop's.
  • Generate certificates with develop's and this openssl.cnf (shipped commands plus one request
    asking for CA:TRUE). Then run an ASan Debug rdcd in its default mTLS mode and run
    rdci discovery against it with:
    • the legitimate certificates;
    • a client certificate signed with the certificate issued to that request;
    • a server certificate signed with that certificate.
  • Run RDC pre-commit on the changed files.

Test Result

  • New tests with this openssl.cnf: 4 passed on OpenSSL 3.0.2 and 3.6.3.

  • New tests with develop's openssl.cnf: 3 failed (CA, TLS usage, prompt); the alternative-name
    test passes on both.

  • mTLS runs:

    develop openssl.cnf this PR
    Certificate issued to the CA:TRUE request CA:TRUE CA:FALSE
    Legitimate certificates accepted accepted
    Client certificate signed with that certificate accepted rejected (handshake failed)
    Server certificate signed with that certificate trusted by rdci rejected (handshake failed)

    No ASan reports.

  • Pre-commit: all hooks pass.

Submission Checklist

- Pin basicConstraints, keyUsage and extendedKeyUsage in a CA-controlled
  section so an issued certificate cannot be a signing certificate.
- Request extensions were previously copied verbatim and could replace
  anything the CA set, so a signing request could choose its own
  constraints; requests can still supply a subject alternative name.
- Show the certificate with its extensions before asking whether to sign
  it. OpenSSL reads name_opt and cert_opt, so the nameopt and certopt
  lines were ignored and the prompt showed no extensions.
- Add CI tests that run the shipped openssl commands, and a changelog
  entry.

Signed-off-by: Adam360x <Adam.pryor@amd.com>
Copilot AI balanced review requested due to automatic review settings October 18, 2026 15:56
@adam360x
adam360x requested review from a team as code owners October 18, 2026 15:56
@therock-pr-bot

Copy link
Copy Markdown

❌ PR Check — Action Required

Check Status Details
📝 PR Description ❌ Fail Error: PR description must reference a JIRA ID, ISSUE ID, or a GitHub closing keyword.
Expected: include a JIRA ID / ISSUE ID line (separator : or -, or omitted; value may be a JIRA key, a number with/without #, or a link), OR a closing keyword + issue reference. Accepted examples:
• JIRA ID : TESTAUTO-6039
• JIRA ID - #330
• JIRA ID #330
• JIRA ID (on separate line)
ROCM-25757
• ISSUE ID : TESTUTO-3334
• ISSUE ID #3334
• ISSUE ID - TESTAUTO-3433
• ISSUE ID (on separate line)
AIRUNTIME-2352
• ISSUE ID : https://github.com/<org_name>/<repo_name>/issues/1234
• Closes #10
• Fixes octo-org/octo-repo#100
• Resolves: #123
• #123
• https://github.com/<org_name>/<repo_name>/issues/123
Current: no valid JIRA/ISSUE/closing-keyword reference found
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ✅ Pass PR does not contain code files — Unit Test auto-passed
🔎 pre-commit ⏳ Pending ⏳ Still running…
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —

⚠️ 1 policy check(s) failed. Please address the issues above before this PR can be Reviewed.

🚫 Please fix the failed policies

  • ❌ PR Description

The Not ready to Review label was added to this PR. Once all policies pass, the label is removed automatically.

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

🙋 Wish to Override Policy?

@therock-pr-bot

Copy link
Copy Markdown

🚫 Please fix the failed policies before requesting reviews.

The following policy checks failed:

  • ❌ PR Description

The Not ready to Review label has been added to this PR.
Once all policies pass, the label will be removed automatically.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The focused configuration fix prevents requester-controlled signing authority, with regression coverage and no identified blocking issues.

No open issues 🎉

What changed in this PR

Hardens RDC certificate issuance so requests cannot grant themselves certificate-signing authority.

Changes:

  • Enforces CA-controlled certificate extensions while preserving requested alternative names.
  • Makes signing prompts display extensions and adds regression tests.
  • Documents recovery guidance for affected deployments.
File Description
projects/​rdc/​tests/​ci/​test_authentication.py Tests certificate restrictions, alternative names, TLS usage, and prompts.
projects/​rdc/​CHANGELOG.md Documents the security fix and recovery steps.
projects/​rdc/​authentication/​openssl.cnf Enforces leaf-certificate restrictions and enables extension display.

Review effort: Balanced

This branch has not been deployed

No deployments
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.

2 participants