jruby / jruby-openssl

JRuby's OpenSSL gem
http://www.jruby.org
Other
47 stars 80 forks source link

many openssl ciphers are broken in the presence of jruby-openssl #31

Open tamird opened 9 years ago

tamird commented 9 years ago

Repro steps: https://gist.github.com/tamird/84a1ed716862b4e96644

There seems to be no possible configuration that permits the use of any of the following ciphers (or their lowercase equivalents) under jruby with jruby-openssl present:

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/8847443-many-openssl-ciphers-are-broken-in-the-presence-of-jruby-openssl?utm_campaign=plugin&utm_content=tracker%2F136995&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F136995&utm_medium=issues&utm_source=github).
tamird commented 9 years ago

@mkristian any progress on this?

kares commented 9 years ago

first of all the test script is semi-accurate ... it won't run the same Cipher code on MRI (there are some failures as well)

secondly, the lower-case version works due a bug - as "cfb1" ends up normalized as "CFB" while when passed in upper-case it is passed as is to the cipher engine. BC that does not like keys that are not mod length :

AES/CFB1/PKCS5Padding
16
 encryptMode = true
 cipherInited = false
 key.length = 16
 iv.length = 16
 padding = null
java.lang.ArithmeticException: / by zero
    at org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher.getUpdateOutputSize(Unknown Source)
    at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$BufferedGenericBlockCipher.getUpdateOutputSize(Unknown Source)
    at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineUpdate(Unknown Source)
    at javax.crypto.Cipher.update(Cipher.java:1714)
    at org.jruby.ext.openssl.Cipher.update(Cipher.java:1092)
    at org.jruby.ext.openssl.Cipher$INVOKER$i$1$0$update.call(Cipher$INVOKER$i$1$0$update.gen)
    at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:326)
    at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
    at jruby_crypto.chained_4_rescue_3$RUBY$SYNTHETIC__file__(jruby_crypto.rb:71)
    at jruby_crypto.block_5$RUBY$__file__(jruby_crypto.rb:70)
    at jruby_crypto$block_5$RUBY$__file__.call(jruby_crypto$block_5$RUBY$__file__)
    at org.jruby.runtime.CompiledBlock19.yield(CompiledBlock19.java:135)
    at org.jruby.runtime.Block.yield(Block.java:142)
    at org.jruby.RubyArray.eachCommon(RubyArray.java:1606)
    at org.jruby.RubyArray.each(RubyArray.java:1613)
    at org.jruby.RubyArray$INVOKER$i$0$0$each.call(RubyArray$INVOKER$i$0$0$each.gen)
    at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:316)
    at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:145)
    at org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:154)
    at jruby_crypto.block_4$RUBY$__file__(jruby_crypto.rb:55)
    at jruby_crypto$block_4$RUBY$__file__.call(jruby_crypto$block_4$RUBY$__file__)
    at org.jruby.runtime.CompiledBlock19.yield(CompiledBlock19.java:135)
    at org.jruby.runtime.Block.yield(Block.java:142)
    at org.jruby.RubyArray.eachCommon(RubyArray.java:1606)
    at org.jruby.RubyArray.each(RubyArray.java:1613)
    at org.jruby.RubyArray$INVOKER$i$0$0$each.call(RubyArray$INVOKER$i$0$0$each.gen)
    at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:316)
    at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:145)
    at org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:154)
    at jruby_crypto.block_3$RUBY$__file__(jruby_crypto.rb:37)
    at jruby_crypto$block_3$RUBY$__file__.call(jruby_crypto$block_3$RUBY$__file__)
    at org.jruby.runtime.CompiledBlock19.yield(CompiledBlock19.java:135)
    at org.jruby.runtime.Block.yield(Block.java:142)
    at org.jruby.RubyArray.eachCommon(RubyArray.java:1606)
    at org.jruby.RubyArray.each(RubyArray.java:1613)
    at org.jruby.RubyArray$INVOKER$i$0$0$each.call(RubyArray$INVOKER$i$0$0$each.gen)
    at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:316)
    at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:145)
    at org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:154)
    at jruby_crypto.__file__(jruby_crypto.rb:30)
    at jruby_crypto.load(jruby_crypto.rb)
    at org.jruby.Ruby.runScript(Ruby.java:811)
    at org.jruby.Ruby.runScript(Ruby.java:804)
    at org.jruby.Ruby.runNormally(Ruby.java:673)
    at org.jruby.Ruby.runFromMain(Ruby.java:522)
    at org.jruby.Main.doRunFromMain(Main.java:395)
    at org.jruby.Main.internalRun(Main.java:290)
    at org.jruby.Main.run(Main.java:217)
    at org.jruby.Main.main(Main.java:197)
cipher: #<OpenSSL::Cipher::Cipher:0x6774a1d3> update (50) failed: #<OpenSSL::Cipher::CipherError: / by zero>
tamird commented 9 years ago

@kares how does the test script need to be updated?