Skip to content

Commit 7817de9

Browse files
hsbtclaude
andcommitted
Report the Ruby OpenSSL floor when ML-DSA certificate signing fails
Signing a certificate for an ML-DSA key passes a nil digest, which Ruby OpenSSL rejects with a bare TypeError before 3.3. On Ruby 3.2 or 3.3 with OpenSSL >= 3.5 the key generates and only `gem cert --build` breaks, so the message has to name the missing piece. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 9a43535 commit 7817de9

3 files changed

Lines changed: 23 additions & 0 deletions

File tree

lib/rubygems/security.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,12 @@ def self.sign(certificate, signing_key, signing_cert, age = ONE_YEAR, extensions
638638
rescue OpenSSL::PKey::PKeyError, ArgumentError
639639
raise Gem::Security::Exception,
640640
"incorrect signing key for signing"
641+
# Ruby OpenSSL only accepts the nil digest ML-DSA needs from 3.3 on.
642+
rescue TypeError
643+
raise if digest_name
644+
645+
raise Gem::Security::Exception,
646+
"certificate signing failed: ML-DSA requires Ruby OpenSSL >= 3.3."
641647
end
642648
end
643649

test/rubygems/helper.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1702,6 +1702,11 @@ def omit_unless_support_ml_dsa_cert
17021702
Gem::PQCUtilities.support_ml_dsa_cert?
17031703
end
17041704

1705+
def omit_if_support_ml_dsa_cert
1706+
omit "Ruby OpenSSL can sign a certificate with an ML-DSA key" if
1707+
Gem::PQCUtilities.support_ml_dsa_cert?
1708+
end
1709+
17051710
def omit_if_support_ml_dsa_key
17061711
omit "OpenSSL supports ML-DSA" if Gem::PQCUtilities.support_ml_dsa_key?
17071712
end

test/rubygems/test_gem_security.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,18 @@ def test_class_create_cert_email
8585
assert_equal 59, key_ident.value.length
8686
end
8787

88+
def test_class_create_cert_email_ml_dsa_65_without_cert_support
89+
omit_unless_support_ml_dsa_key
90+
omit_if_support_ml_dsa_cert
91+
92+
e = assert_raise Gem::Security::Exception do
93+
Gem::Security.create_cert_email "nobody@example",
94+
ML_DSA_65_PRIVATE_KEY, 60
95+
end
96+
97+
assert_match(/^certificate signing failed: /, e.message)
98+
end
99+
88100
def test_class_create_key
89101
key = Gem::Security.create_key "rsa"
90102

0 commit comments

Comments
 (0)