Skip to content

Commit e12ae01

Browse files
karesclaude
andcommitted
[fix] Cipher#reset when key not set (jruby/jruby#5776)
CRuby's reset calls EVP_CipherInit_ex with NULL key/IV which is a no-op if no key was set. JRuby was calling doInitCipher unconditionally which requires a key. Skip doInitCipher when key is null. Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent 1a12af3 commit e12ae01

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

src/main/java/org/jruby/ext/openssl/Cipher.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,9 @@ public IRubyObject reset(final ThreadContext context) {
942942
checkCipherNotNull(runtime);
943943
if ( ! isStreamCipher() ) {
944944
this.realIV = orgIV;
945-
doInitCipher(runtime);
945+
// CRuby's reset calls EVP_CipherInit_ex with NULL key/IV which
946+
// is a no-op if key hasn't been set yet. Match that behavior.
947+
if ( key != null ) doInitCipher(runtime);
946948
}
947949
return this;
948950
}

src/test/ruby/test_cipher.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,27 @@ def test_aes_ecb_iv_len
137137
end
138138

139139

140+
# jruby/jruby#5776: reset without key should not raise
141+
def test_reset_without_key
142+
c = OpenSSL::Cipher.new("AES-128-CBC")
143+
c.reset # should not raise
144+
end
145+
146+
def test_reset_produces_same_ciphertext
147+
key = "0123456789abcdef"
148+
iv = "fedcba9876543210"
149+
data = "hello world!!!!!"
150+
151+
c = OpenSSL::Cipher.new("AES-128-CBC")
152+
c.encrypt; c.key = key; c.iv = iv
153+
ct1 = c.update(data) + c.final
154+
155+
c.reset; c.iv = iv
156+
ct2 = c.update(data) + c.final
157+
158+
assert_equal ct1, ct2
159+
end
160+
140161
@@test_encrypt_decrypt_des_variations = nil
141162

142163
def test_encrypt_decrypt_des_variations

0 commit comments

Comments
 (0)