Repository navigation
A feature to check enabled/disabled PQC signature algorithms, key exchange groups considering OpenSSL config #1075
Description
This issue comes from ruby/rubygems#9643 (comment).
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:ffdhe8192In 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?
ruby/rubygems#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?
Activity
[-]A feature to check enabled/disabled PQC signature algorithms, key exchange groups consideirng OpenSSL config[/-][+]A feature to check enabled/disabled PQC signature algorithms, key exchange groups considering OpenSSL config[/+]rhenium commentedon Jun 27, 2026
The current OpenSSL C API doesn't appear to expose the corresponding getters for
SSL_CTX_set1_sigalgs()andSSL_CTX_set1_groups(). If they were available, I think we could expose them, similar to how we do for SSL options and TLS 1.2 cipher suites.If the intent of the test is to "test PQC algorithms whenever the system supports them", then I think ruby/rubygems#9643 would be the most straightforward option at the moment. Alternatively, I think it could just special-case RHEL >= 9.7, < 10.1(?) since other distros are unlikely to do the same.
junaruga commentedon Jun 29, 2026
I investigated the case of RHEL 10.0. RHEL 10.0 is a unique feature for PQC[1] before RHEL 10.1 supports PQC by DEFAULT security policy[2].
You are right. In RHEL 10.0, PQC is also disabled by default.
Below is my command log in RHEL 10.0. OpenSSL version is 3.2.2.
However, when installing the following RPM packages, oqsprovider (PQC provider)[3] RPM is installed as a dependency of crypto-policies-pq-preview RPM package.
Then oqsprovider provider appeared. OpenSSL doesn't enable PQC yet at this moment.
But after running the following command, PQC is enabled in
/etc/crypto-policies/back-ends/opensslcnf.config.References
junaruga commentedon Jun 30, 2026
Right. This sounds good idea to me. If we have such getters, we can implement the logic to check if used PQC signature algorithms and key exchange groups are available in OpenSSL. The example is below.
And I confirmed such pattern was already used for
OpenSSL::SSL::SSLContext#options(SSL_CTX_get_options) andOpenSSL::SSL::SSLContext#ciphers(SSL_CTX_get_ciphers).Yes, my motivation of this feature is to "test PQC algorithms whenever the system supports them". The current implementation
TestGemRemoteFetcherLocalSSLServer.support_pqc_handshake?is okay when it is used in ruby/rubygems repository. But it is not convenient if the method is used in all the ruby/* repositories or generally in user's Ruby program. I am thinking that moving such logic totest-unit-ruby-coregem to be used from ruby/* repositories. ButTestGemRemoteFetcherLocalSSLServer.support_pqc_handshake?needsmldsa65_ssl_cert.pemandmldsa65_ssl_key.pemfiles.junaruga commentedon Jun 30, 2026
I opened feature request issue ticket openssl/openssl#31804 for openssl/openssl.