ruby / ruby/openssl

A feature to check enabled/disabled PQC signature algorithms, key exchange groups considering OpenSSL config

Open
#1,075 4 comments 0 reactions 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.