Identify ML-DSA by OID and gate ML-DSA tests on the capability they need - #9853
Identify ML-DSA by OID and gate ML-DSA tests on the capability they need#9853justsmth wants to merge 2 commits into
Conversation
|
@justsmth It seems the ruby/rubygems repository doesn't have the GitHub Actions CI case for Ruby with ruby/openssl built with AWS-LC right now. Perhaps, adding the AWS-LC latest stable version case to GitHub Actions to this repository may be helpful if we consider AWS-LC case. I haven't checked if this PR's modified tests pass for RubyGems with Ruby OpenSSL built with AWS-LC. As a reference, ruby/openssl repository has the AWS-LC latest stable version case on the CI. There is a trade-off about adding the AWS-LC case to the CI. Pros:
Cons:
I am not a maintainer of the ruby/rubygems. So, consider my opinion as assumption which may not happen. If you work on this before maintainers agree the direction, you may waste your time. The steps can be as follows.
The candidate GitHub Actions yml file to add this case is Until ruby/rubygems maintainers comment on this PR, I don't have anything to comment on this PR. I pend my approval for this PR for now, while I saw you requested a review from me using the PR's function. Let's wait for the maintainer's reviews. |
|
About the AWS-LC job, I am ok to add it. But I do not want to build AWS-LC on every run. If we can cache the build like your step 1, the job is worth it. @junaruga For the change itself, could you review this? |
|
@hsbt All right. Yes, I can review the change. @justsmth So, let's add AWS-LC case to this repository's CI on this PR. I feel that adding new job such as "rubygems-openssl" in .github/workflows/rubygems.yml makes sense. Right now, the ruby/openssl CI doesn't cache the compiled AWS-LC. However, it's possible to cache the compiled AWS-LC there. So, I just sent the PR ruby/openssl#1108 to the ruby/openssl now to cache the compiled AWS-LC. You can refer to the https://github.com/ruby/openssl/blob/master/.github/workflows/test.yml with the PR. |
@justsmth Note I sent the PR ruby/openssl#1109, as a follow up of ruby/openssl#1108. You can refer to the ruby/openssl#1109 about how to add the cached compiled aws-lc case to this repository. |
@justsmth Note I sent the PR ruby/openssl#1110 as a follow up of ruby/openssl#1109. We misunderstood the cache validity of the actions/cache in ruby/openssl. So, we are adding the 1 week (7 days) cache validity by the PR. You can refer to the PR. |
RubyGems currently assumes an SSL library either supports all ML-DSA operations or none of them. It also identifies ML-DSA keys using the provider-specific algorithm names registered by OpenSSL 3.5. AWS-LC loads ML-DSA keys and certificates and signs and verifies with them, but it does not provide key generation by algorithm name and registers 2.16.840.1.101.3.4.3.18 as "MLDSA65" instead of "ML-DSA-65". Match the SubjectPublicKeyInfo OIDs defined by RFC 9881 so key identification does not depend on provider-specific names. The existing support_ml_dsa_key? probe tests key generation, but several tests only load checked-in keys and certificates. Add a separate key-loading probe for fixture-based tests while keeping generation tests on the original probe.
Build and cache the latest stable AWS-LC weekly, rebuild Ruby OpenSSL against it, and run the RubyGems test suite. Include the new job in the aggregate all-pass gate.
d0217e9 to
73aa440
Compare
|
Thanks for the feedback. I rebased onto current master and added the requested cached AWS-LC CI job as its own commit. The CI workflows are currently awaiting approval to run. |
What was the end-user or developer problem that led to this PR?
RubyGems currently assumes an SSL library either supports all ML-DSA operations or none of them:
Gem::Security.ml_dsa_key?identifies ML-DSA using OpenSSL 3.5 algorithm names such asML-DSA-65. Those names are library-specific; AWS-LC registers the same standard OID asMLDSA65, so RubyGems rejects a valid ML-DSA key as unsupported and cannot verify ML-DSA signed gems.Gem::PQCUtilities.support_ml_dsa_key?probes key generation but gates tests that only load checked-in keys and certificates. AWS-LC loads, signs, and verifies with ML-DSA, but does not generate an ML-DSA key by algorithm name. This causes four incorrect test failures and skips ten positive tests that AWS-LC can run.What is your fix for the problem, implemented in this PR?
ml_dsa_key?now identifies ML-DSA using the three standard SubjectPublicKeyInfo OIDs rather than library-specific display names.The tests gain a separate
support_ml_dsa_key_load?probe. Four negative tests that assert loading failure, plus ten positive fixture-based tests, now use the load capability instead of the generation capability. Tests that callGem::Security.create_keykeep the existing generation gate.These changes are combined because they test each other: re-gating the positive tests without the OID fix exposes four failures in
digest_required?, while the OID fix alone would remain untested on libraries that can load but not generate ML-DSA keys.This continues 9a43535, which separated key generation from certificate signing but not key generation from key loading.
Testing
Using Ruby master built against AWS-LC 5.7.0:
masterThe net omission change reflects ten newly exercised positive tests and four negative tests now correctly omitted.
Gem::Security::Policy#check_dataverifies an ML-DSA signature and rejects a tampered payload with this change.Using OpenSSL 3.0.13, which has no ML-DSA support, all five affected test files produce identical results before and after. The full RubyGems test suite passes, and
bin/rubocopreports no offenses on the seven changed files.I did not have an OpenSSL 3.5 build available locally. On 3.5 both capability probes remain true, and the OIDs matched here are the same OIDs exposed by its existing ML-DSA keys.
Make sure the following tasks are checked