A feature to check enabled/disabled PQC signature algorithms, key exchange groups considering OpenSSL config
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 276
- Forks
- 200
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 7
Description
This issue comes from https://github.com/ruby/rubygems/pull/9643#issuecomment-4811625069.
In Fedora/RHEL, the OpenSSL config is below.
$ /bin/ruby -r openssl -e 'puts OpenSSL::Config::DEFAULT_CONFIG_FILE'
/etc/pki/tls/openssl.cnf
/etc/pki/tls/openssl.cnf
...
[ crypto_policy ]
.include = /etc/crypto-policies/back-ends/opensslcnf.config
...
RHEL 9.x (>= 9.7) has security policy DEFAULT and DEFAULT:PQ, the content of the /etc/crypto-policies/back-ends/opensslcnf.config changes by the security policies.
In security policy DEFAULT, the content is below.
# update-crypto-policies --show
DEFAULT
/etc/crypto-policies/back-ends/opensslcnf.config
CipherString = @SECLEVEL=2:kEECDH:kRSA:kEDH:kPSK:kDHEPSK:kECDHEPSK:kRSAPSK:-aDSS:-3DES:!DES:!RC4:!RC2:!IDEA:-SEED:!eNULL:!aNULL:!MD5:-SHA384:-CAMELLIA:-ARIA:-AESCCM8
Ciphersuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256
TLS.MinProtocol = TLSv1.2
TLS.MaxProtocol = TLSv1.3
DTLS.MinProtocol = DTLSv1.2
DTLS.MaxProtocol = DTLSv1.2
SignatureAlgorithms = ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:ed25519:ed448:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512:rsa_pss_rsae_sha256:rsa_pss_rsae_sha384:rsa_pss_rsae_sha512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224
Groups = *X25519:secp256r1:X448:secp521r1:secp384r1:ffdhe2048:ffdhe3072:ffdhe4096:ffdhe6144:ffdhe8192
In security policy DEFAULT:PQ: the content is below.
# update-crypto-policies --show
DEFAULT:PQ
/etc/crypto-policies/back-ends/opensslcnf.config
CipherString = @SECLEVEL=2:kEECDH:kRSA:kEDH:kPSK:kDHEPSK:kECDHEPSK:kRSAPSK:-aDSS:-3DES:!DES:!RC4:!RC2:!IDEA:-SEED:!eNULL:!aNULL:!MD5:-SHA384:-CAMELLIA:-ARIA:-AESCCM8
Ciphersuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256
TLS.MinProtocol = TLSv1.2
TLS.MaxProtocol = TLSv1.3
DTLS.MinProtocol = DTLSv1.2
DTLS.MaxProtocol = DTLSv1.2
SignatureAlgorithms = ?mldsa44:?mldsa65:?mldsa87:ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:ed25519:ed448:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512:rsa_pss_rsae_sha256:rsa_pss_rsae_sha384:rsa_pss_rsae_sha512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224
Groups = *?X25519MLKEM768:?x25519_mlkem768:?SecP256r1MLKEM768:?p256_mlkem768:?SecP384r1MLKEM1024:?p384_mlkem1024/*X25519:secp256r1:X448:secp521r1:secp384r1:ffdhe2048:ffdhe3072:ffdhe4096:ffdhe6144:ffdhe8192
The difference of the opensslcnf.txt between security policy DEFAULT and DEFAULT:PQ is below.
$ diff -u opensslcnf.txt.default opensslcnf.txt.default_pq
--- opensslcnf.txt.default 2026-03-04 10:13:14.000000000 +0000
+++ opensslcnf.txt.default_pq 2026-06-26 15:50:55.000000000 +0100
@@ -4,5 +4,5 @@
TLS.MaxProtocol = TLSv1.3
DTLS.MinProtocol = DTLSv1.2
DTLS.MaxProtocol = DTLSv1.2
-SignatureAlgorithms = ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:ed25519:ed448:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512:rsa_pss_rsae_sha256:rsa_pss_rsae_sha384:rsa_pss_rsae_sha512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224
-Groups = *X25519:secp256r1:X448:secp521r1:secp384r1:ffdhe2048:ffdhe3072:ffdhe4096:ffdhe6144:ffdhe8192
+SignatureAlgorithms = ?mldsa44:?mldsa65:?mldsa87:ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:ed25519:ed448:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512:rsa_pss_rsae_sha256:rsa_pss_rsae_sha384:rsa_pss_rsae_sha512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224
+Groups = *?X25519MLKEM768:?x25519_mlkem768:?SecP256r1MLKEM768:?p256_mlkem768:?SecP384r1MLKEM1024:?p384_mlkem1024/*X25519:secp256r1:X448:secp521r1:secp384r1:ffdhe2048:ffdhe3072:ffdhe4096:ffdhe6144:ffdhe8192
In security policy DEFAULT:PQ, signature algorithms, ML-DSA-NN (mldsa44, mldsa65 and mldsa87) are added.
SignatureAlgorithms = ?mldsa44:?mldsa65:?mldsa87: ...
In security policy DEFAULT:PQ, the groups, ML-KEM groups (X25519MLKEM768, x25519_mlkem768, SecP256r1MLKEM768, p256_mlkem768, SecP384r1MLKEM1024, p384_mlkem1024) are also added.
Groups = *?X25519MLKEM768:?x25519_mlkem768:?SecP256r1MLKEM768:?p256_mlkem768:?SecP384r1MLKEM1024:?p384_mlkem1024/ ...
Is there a way to check the used PQC signature algorithms and groups easily to skip PQC tests in a portable way which is not platform-specific, if these signature algorithms and groups are disabled in the OpenSSL config? This logic can be used for ruby/* repositories that have PQC tests. Or are there OpenSSL C APIs to do this?
https://github.com/ruby/rubygems/pull/9643 is a possible implementation to do this. However, I want to find an easier way.
I want this feature if there is not such as feature in Ruby OpenSSL. If we have such a feature, maybe we can also enable specific signature algorithms and key exchange groups to be used in the PQC tests, by overriding the OpenSSL config if these are disabled in the config.
What do you think?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the proposed implementation in rubygems/pull/9643, then investigate whether OpenSSL C APIs expose portable checks for configured PQC signature algorithms and key exchange groups. Compare that with the Ruby OpenSSL API and existing PQC tests; done means defining whether a portable detection or configuration override feature is needed and what behavior it should support.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, ruby
- Domain
- cryptography, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100