From e7ebbc6bf1e13ac0da00b75b12814cc7827eb18d Mon Sep 17 00:00:00 2001 From: Pasi Eronen Date: Thu, 12 Jun 2014 12:27:33 +0300 Subject: [PATCH] Strip leading zero(es) from the shared secret --- .../org/apache/sshd/common/kex/AbstractDH.java | 16 ++++++++++++++++ .../main/java/org/apache/sshd/common/kex/DH.java | 2 +- .../java/org/apache/sshd/common/kex/ECDH.java | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java index 2097b5dc0..06dbdc360 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java @@ -56,4 +56,20 @@ public byte[] getK() throws Exception { } public abstract Digest getHash() throws Exception; + + // The shared secret returned by KeyAgreement.generateSecret() is + // a byte array, which can (by chance, roughly 1 out of 256 times) + // begin with zero byte (some JCE providers might strip this, though). + // In SSH, the shared secret is an integer, so we need to strip + // the leading zero(es). + protected static byte[] stripLeadingZeroes(byte[] x) { + int i = 0; + while ((i < x.length - 1) && (x[i] == 0)) { + i++; + } + if (i > 0) { System.out.println("FIXME9-removingZero"); } + byte[] ret = new byte[x.length - i]; + System.arraycopy(x, i, ret, 0, ret.length); + return ret; + } } diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/DH.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/DH.java index d576fd4e3..7b2bc8977 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/kex/DH.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/DH.java @@ -76,7 +76,7 @@ protected byte[] calculateK() throws Exception { DHPublicKeySpec keySpec = new DHPublicKeySpec(f, p, g); PublicKey yourPubKey = myKeyFac.generatePublic(keySpec); myKeyAgree.doPhase(yourPubKey, true); - return myKeyAgree.generateSecret(); + return stripLeadingZeroes(myKeyAgree.generateSecret()); } public void setP(byte[] p) { diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/ECDH.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/ECDH.java index 65fce4c73..bd6357083 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/kex/ECDH.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/ECDH.java @@ -70,7 +70,7 @@ protected byte[] calculateK() throws Exception { ECPublicKeySpec keySpec = new ECPublicKeySpec(f, params); PublicKey yourPubKey = myKeyFac.generatePublic(keySpec); myKeyAgree.doPhase(yourPubKey, true); - return myKeyAgree.generateSecret(); + return stripLeadingZeroes(myKeyAgree.generateSecret()); } public void setCurveParameters(ECParameterSpec params) {