bc-java icon indicating copy to clipboard operation
bc-java copied to clipboard

Apache mina 2.7.0+ bouncycastle 2.73.3 + java8 + linux brings javax.crypto.ShortBufferException

Open IrinaSvirkina opened this issue 2 years ago • 6 comments

In short: Is it a bug of bouncycastle 2.73.3 (bcprov-lts8on:jar:2.73.3) or misconfiguration (if any exists) or java 8 bug or whatever else (see the stacktrace below)? FYI: I don't observe the exception with

  • java8+bouncycastle 1.70 (bcprov-jdk15on:jar:1.70)
  • or with java11+bouncycastle 2.73.3
  • or with java8+bouncycastle 2.73.3+windows.

But I see the exception with java8+bouncycastle 2.73.3+linux.

Details: We are developing a plugin for Jira. A new Jira version 9.13 (Jira OSGI container) provides a new bouncycastle version 2.73.3. I observe that our plugin, which uses jgit (5.13.1.202206130422-r), which uses apache mina 2.7.0, which uses bouncycastle (2.73.3) , begins to throw the exception when ED25519 ssh key is used to connect to a git repository. Is it a bouncycastle bug or misconfiguration (if any exists) or java 8 bug or whatever else? Is it possible to eliminate it by playing with dependencies versions, configurations or something like that?

Caused by: org.eclipse.jgit.errors.TransportException: [email protected]:root/TestRepo.git: output buffer too short for input.
	at org.eclipse.jgit.transport.sshd.SshdSessionFactory.getSession(SshdSessionFactory.java:248)
	at org.eclipse.jgit.transport.sshd.SshdSessionFactory.getSession(SshdSessionFactory.java:1)
	at com.bigbrassband.jira.git.services.wizard.WizardConnectionValidator.isSshConnectionValid(WizardConnectionValidator.java:316)
	... 303 more
Caused by: org.apache.sshd.common.SshException: output buffer too short for input.
	at org.apache.sshd.common.future.AbstractSshFuture.verifyResult(AbstractSshFuture.java:126)
	at org.apache.sshd.client.future.DefaultAuthFuture.verify(DefaultAuthFuture.java:39)
	at org.apache.sshd.client.future.DefaultAuthFuture.verify(DefaultAuthFuture.java:32)
	at org.apache.sshd.common.future.VerifiableFuture.verify(VerifiableFuture.java:68)
	at org.eclipse.jgit.transport.sshd.SshdSession.connect(SshdSession.java:164)
	at org.eclipse.jgit.transport.sshd.SshdSession.connect(SshdSession.java:99)
	at org.eclipse.jgit.transport.sshd.SshdSessionFactory.getSession(SshdSessionFactory.java:235)
	... 305 more
Caused by: org.apache.sshd.common.SshException: output buffer too short for input.
	at org.apache.sshd.common.session.helpers.AbstractSession.encode(AbstractSession.java:1294)
	at org.apache.sshd.common.session.helpers.AbstractSession.resolveOutputPacket(AbstractSession.java:983)
	at org.apache.sshd.common.session.helpers.AbstractSession.doWritePacket(AbstractSession.java:991)
	at org.apache.sshd.common.session.helpers.AbstractSession.sendPendingPackets(AbstractSession.java:787)
	at org.apache.sshd.common.session.helpers.AbstractSession.handleNewKeys(AbstractSession.java:749)
	at org.apache.sshd.common.session.helpers.AbstractSession.doHandleMessage(AbstractSession.java:481)
	at org.apache.sshd.common.session.helpers.AbstractSession.handleMessage(AbstractSession.java:429)
	at org.apache.sshd.common.session.helpers.AbstractSession.decode(AbstractSession.java:1466)
	at org.apache.sshd.common.session.helpers.AbstractSession.messageReceived(AbstractSession.java:389)
	at org.eclipse.jgit.internal.transport.sshd.JGitClientSession.messageReceived(JGitClientSession.java:198)
	at org.apache.sshd.common.session.helpers.AbstractSessionIoHandler.messageReceived(AbstractSessionIoHandler.java:64)
	at org.apache.sshd.common.io.nio2.Nio2Session.handleReadCycleCompletion(Nio2Session.java:359)
	at org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:336)
	at org.apache.sshd.common.io.nio2.Nio2Session$1.onCompleted(Nio2Session.java:333)
	at org.apache.sshd.common.io.nio2.Nio2CompletionHandler.lambda$completed$0(Nio2CompletionHandler.java:38)
	at java.security.AccessController.doPrivileged(Native Method)
	at org.apache.sshd.common.io.nio2.Nio2CompletionHandler.completed(Nio2CompletionHandler.java:37)
	at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
	at sun.nio.ch.Invoker$2.run(Invoker.java:218)
	at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	... 1 more
Caused by: javax.crypto.ShortBufferException: output buffer too short for input.
	at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineUpdate(BaseBlockCipher.java:1169)
	at javax.crypto.Cipher.update(Cipher.java:1944)
	at org.apache.sshd.common.cipher.BaseCipher.update(BaseCipher.java:123)
	at org.apache.sshd.common.session.helpers.AbstractSession.encryptOutgoingBuffer(AbstractSession.java:1328)
	at org.apache.sshd.common.session.helpers.AbstractSession.encode(AbstractSession.java:1274)
	... 22 more

I got the exception "javax.crypto.ShortBufferException output buffer too short for input" with linux mate and with the next java versions:

  • j08: OpenJDK 64-Bit Server VM Corretto-8.392.08.1 (build 25.392-b08, mixed mode)
  • j08: OpenJDK 64-Bit Server VM (Temurin)(build 25.392-b08, mixed mode)
  • j08: Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)
  • j11: OpenJDK 64-Bit Server VM Temurin-11.0.13+8 (build 11.0.13+8, mixed mode)

All is OK with windows and with the java versions.

  • j08: OpenJDK Runtime Environment Corretto-8.392.08.1 (build 1.8.0_392-b08)
  • j11: OpenJDK Runtime Environment Corretto-11.0.21.9.1 (build 11.0.21+9-LTS)

IrinaSvirkina avatar Jan 11 '24 14:01 IrinaSvirkina

I hate to say it, but I have no idea. If you run the 2.73.3 implementation with the native library disabled does it still happen?

dghgit avatar Jan 15 '24 07:01 dghgit

@dghgit - Sorry, could you please explain which "native library" do you mean and how can I disable it?

IrinaSvirkina avatar Jan 15 '24 09:01 IrinaSvirkina

Setting -Dorg.bouncycastle.native.cpu_variant=java will disable the native library support in the LTS release. It may make a difference, not really sure though as I can't think of anything that changes between Java 8 and Java 11 in this context.

dghgit avatar Jan 16 '24 04:01 dghgit

@dghgit David, thank you very much! A usage of "-Dorg.bouncycastle.native.cpu_variant=java" helped me. Cool. What a magical property?!

  • What does it mean?
  • Does it mean that my linux environment setup in a wrong way or my code is too hardcoded?

IrinaSvirkina avatar Jan 16 '24 12:01 IrinaSvirkina

Hi,

I am going to pick this up and investigate this further.

MW

mwcw avatar Jan 16 '24 22:01 mwcw

Hi,

Thanks for the detail in the original ticket!

TLDR; Mina's AbstractSessionHelper and BaseCipher are ignoring lengths returned from cipher update and deriving information from the input len rather than what has actually been processed during the update.

Issue:

The issue is the return values from the cipher.update and cipher.doFinal are meaningful and cannot be ignored, particularly in the case, such as with the LTS native layer, where underlying provider maybe buffering output for speed and efficiency reasons.

It is pure coincidence that the code works with the regular BC provider. It is simply because it does not buffer, except in very rare cases, that the error has not shown up.

Please raise this issue with the Apache project so they can fix it, we are more than happy to talk to them if they need any further assistance.

References:

In AbstractSessionHelper: org.apache.sshd.common.session.helpers.AbstractSession#encryptOutgoingBuffer

v2.7.0: Line 1324 HEAD: Line 1547

Link: https://github.com/apache/mina-sshd/blob/b040109746ebe2aadf7f040790b4dade6a870e41/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java#L1547

blockCount is derived from input rather than what was actually processed because outCipher.update( ... ) returns void.

In org.apache.sshd.common.cipher.BaseCipher#update v2.7.0: Line 123 HEAD: Line 121 Link: https://github.com/apache/mina-sshd/blob/b040109746ebe2aadf7f040790b4dade6a870e41/sshd-common/src/main/java/org/apache/sshd/common/cipher/BaseCipher.java#L121

Ignores the return value from update and returns void.

mwcw avatar Jan 18 '24 01:01 mwcw