jruby-openssl icon indicating copy to clipboard operation
jruby-openssl copied to clipboard

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

Open tamird opened this issue 10 years ago • 3 comments

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:

  • AES-128-CFB1
  • AES-192-CFB1
  • AES-256-CFB1
  • BF-CFB1
  • CAMELLIA-128-CBC
  • CAMELLIA-192-CBC
  • CAMELLIA-256-CBC
  • CAMELLIA-128-CFB
  • CAMELLIA-192-CFB
  • CAMELLIA-256-CFB
  • CAMELLIA-128-CFB1
  • CAMELLIA-192-CFB1
  • CAMELLIA-256-CFB1
  • CAMELLIA-128-CFB8
  • CAMELLIA-192-CFB8
  • CAMELLIA-256-CFB8
  • CAMELLIA-128-OFB
  • CAMELLIA-192-OFB
  • CAMELLIA-256-OFB
  • CAMELLIA128
  • CAMELLIA192
  • CAMELLIA256
  • CAST5-CFB1
  • CAST6-CBC
  • CAST6-CFB
  • CAST6-CFB1
  • CAST6-CFB8
  • CAST6-OFB
  • DES-CFB1
  • DES-EDE
  • DES-EDE-CBC
  • DES-EDE-CFB
  • DES-EDE-OFB
  • DES-EDE3-CFB1
  • DES3
  • RC2-CFB1
  • SEED
  • SEED-CBC
  • SEED-CFB
  • SEED-CFB1
  • SEED-CFB8
  • SEED-OFB

--- 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 avatar Feb 23 '15 22:02 tamird

@mkristian any progress on this?

tamird avatar Mar 10 '15 03:03 tamird

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>

kares avatar Mar 10 '15 08:03 kares

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

tamird avatar Mar 10 '15 20:03 tamird