From 77f5d7fdb8ff6ed95da125bc1bd1ecab6db039a2 Mon Sep 17 00:00:00 2001 From: David Kocher Date: Wed, 14 May 2014 12:33:46 +0200 Subject: [PATCH] Extract encode method for signature. Implement signing for ECDSA. --- .../sshj/signature/AbstractSignature.java | 9 +++++ .../net/schmizz/sshj/signature/Signature.java | 7 ++++ .../schmizz/sshj/signature/SignatureDSA.java | 27 ++++----------- .../sshj/signature/SignatureECDSA.java | 34 +++++++++++++------ .../schmizz/sshj/signature/SignatureRSA.java | 12 +++---- .../sshj/userauth/method/KeyedAuthMethod.java | 16 ++++----- 6 files changed, 59 insertions(+), 46 deletions(-) diff --git a/src/main/java/net/schmizz/sshj/signature/AbstractSignature.java b/src/main/java/net/schmizz/sshj/signature/AbstractSignature.java index 0c73315d..b18ef841 100644 --- a/src/main/java/net/schmizz/sshj/signature/AbstractSignature.java +++ b/src/main/java/net/schmizz/sshj/signature/AbstractSignature.java @@ -81,6 +81,15 @@ public abstract class AbstractSignature } } + @Override + public byte[] sign() { + try { + return signature.sign(); + } catch (SignatureException e) { + throw new SSHRuntimeException(e); + } + } + protected byte[] extractSig(byte[] sig) { if (sig[0] == 0 && sig[1] == 0 && sig[2] == 0) { int i = 0; diff --git a/src/main/java/net/schmizz/sshj/signature/Signature.java b/src/main/java/net/schmizz/sshj/signature/Signature.java index a58f2768..bebbad8d 100644 --- a/src/main/java/net/schmizz/sshj/signature/Signature.java +++ b/src/main/java/net/schmizz/sshj/signature/Signature.java @@ -74,6 +74,13 @@ public interface Signature { */ byte[] sign(); + /** + * Encode the signature as blog + * @param signature the signature to encode + * @return Encoded signature + */ + byte[] encode(byte[] signature); + /** * Verify against the given signature. * diff --git a/src/main/java/net/schmizz/sshj/signature/SignatureDSA.java b/src/main/java/net/schmizz/sshj/signature/SignatureDSA.java index ce1d50b8..45a1aa28 100644 --- a/src/main/java/net/schmizz/sshj/signature/SignatureDSA.java +++ b/src/main/java/net/schmizz/sshj/signature/SignatureDSA.java @@ -35,11 +35,11 @@ */ package net.schmizz.sshj.signature; +import java.security.SignatureException; + import net.schmizz.sshj.common.KeyType; import net.schmizz.sshj.common.SSHRuntimeException; -import java.security.SignatureException; - /** DSA {@link Signature} */ public class SignatureDSA extends AbstractSignature { @@ -65,14 +65,7 @@ public class SignatureDSA } @Override - public byte[] sign() { - byte[] sig; - try { - sig = signature.sign(); - } catch (SignatureException e) { - throw new SSHRuntimeException(e); - } - + public byte[] encode(byte[] sig) { // sig is in ASN.1 // SEQUENCE::={ r INTEGER, s INTEGER } @@ -90,17 +83,11 @@ public class SignatureDSA // result must be 40 bytes, but length of r and s may not be 20 bytes - System.arraycopy(r, - r.length > 20 ? 1 : 0, - result, - r.length > 20 ? 0 : 20 - r.length, - r.length > 20 ? 20 : r.length); + int r_copylen = (r.length < 20) ? r.length : 20; + int s_copylen = (s.length < 20) ? s.length : 20; - System.arraycopy(s, - s.length > 20 ? 1 : 0, - result, - s.length > 20 ? 20 : 40 - s.length, - s.length > 20 ? 20 : s.length); + System.arraycopy(r, r.length - r_copylen, result, 20 - r_copylen, r_copylen); + System.arraycopy(s, s.length - s_copylen, result, 40 - s_copylen, s_copylen); return result; } diff --git a/src/main/java/net/schmizz/sshj/signature/SignatureECDSA.java b/src/main/java/net/schmizz/sshj/signature/SignatureECDSA.java index 65596d9e..469ba14c 100644 --- a/src/main/java/net/schmizz/sshj/signature/SignatureECDSA.java +++ b/src/main/java/net/schmizz/sshj/signature/SignatureECDSA.java @@ -35,12 +35,13 @@ */ package net.schmizz.sshj.signature; +import java.math.BigInteger; +import java.security.SignatureException; + import net.schmizz.sshj.common.Buffer; import net.schmizz.sshj.common.KeyType; import net.schmizz.sshj.common.SSHRuntimeException; -import java.security.SignatureException; - /** ECDSA {@link Signature} */ public class SignatureECDSA extends AbstractSignature { @@ -66,17 +67,31 @@ public class SignatureECDSA } @Override - public byte[] sign() { - throw new UnsupportedOperationException("No implementation for sign!"); + public byte[] encode(byte[] sig) { + int rIndex = 3; + int rLen = sig[rIndex++] & 0xff; + byte[] r = new byte[rLen]; + System.arraycopy(sig, rIndex, r, 0, r.length); + + int sIndex = rIndex + rLen + 1; + int sLen = sig[sIndex++] & 0xff; + byte[] s = new byte[sLen]; + System.arraycopy(sig, sIndex, s, 0, s.length); + + System.arraycopy(sig, 4, r, 0, rLen); + System.arraycopy(sig, 6 + rLen, s, 0, sLen); + + Buffer buf = new Buffer.PlainBuffer(); + buf.putMPInt(new BigInteger(r)); + buf.putMPInt(new BigInteger(s)); + + return buf.getCompactData(); } @Override public boolean verify(byte[] sig) { - - byte[] r = null; - byte[] s = null; - - + byte[] r; + byte[] s; try { Buffer sigbuf = new Buffer.PlainBuffer(sig); final String algo = new String(sigbuf.readBytes()); @@ -139,5 +154,4 @@ public class SignatureECDSA throw new SSHRuntimeException(e); } } - } diff --git a/src/main/java/net/schmizz/sshj/signature/SignatureRSA.java b/src/main/java/net/schmizz/sshj/signature/SignatureRSA.java index a64e741b..753de0ab 100644 --- a/src/main/java/net/schmizz/sshj/signature/SignatureRSA.java +++ b/src/main/java/net/schmizz/sshj/signature/SignatureRSA.java @@ -35,11 +35,11 @@ */ package net.schmizz.sshj.signature; +import java.security.SignatureException; + import net.schmizz.sshj.common.KeyType; import net.schmizz.sshj.common.SSHRuntimeException; -import java.security.SignatureException; - /** RSA {@link Signature} */ public class SignatureRSA extends AbstractSignature { @@ -65,12 +65,8 @@ public class SignatureRSA } @Override - public byte[] sign() { - try { - return signature.sign(); - } catch (SignatureException e) { - throw new SSHRuntimeException(e); - } + public byte[] encode(byte[] signature) { + return signature; } @Override diff --git a/src/main/java/net/schmizz/sshj/userauth/method/KeyedAuthMethod.java b/src/main/java/net/schmizz/sshj/userauth/method/KeyedAuthMethod.java index 6bbcbfc4..c92f6db9 100644 --- a/src/main/java/net/schmizz/sshj/userauth/method/KeyedAuthMethod.java +++ b/src/main/java/net/schmizz/sshj/userauth/method/KeyedAuthMethod.java @@ -62,16 +62,16 @@ public abstract class KeyedAuthMethod } final String kt = KeyType.fromKey(key).toString(); - Signature sigger = Factory.Named.Util.create(params.getTransport().getConfig().getSignatureFactories(), kt); - if (sigger == null) + Signature signature = Factory.Named.Util.create(params.getTransport().getConfig().getSignatureFactories(), kt); + if (signature == null) throw new UserAuthException("Could not create signature instance for " + kt + " key"); - sigger.init(null, key); - sigger.update(new Buffer.PlainBuffer() - .putString(params.getTransport().getSessionID()) - .putBuffer(reqBuf) // & rest of the data for sig - .getCompactData()); - reqBuf.putSignature(kt, sigger.sign()); + signature.init(null, key); + signature.update(new Buffer.PlainBuffer() + .putString(params.getTransport().getSessionID()) + .putBuffer(reqBuf) // & rest of the data for sig + .getCompactData()); + reqBuf.putSignature(kt, signature.encode(signature.sign())); return reqBuf; }