Extract encode method for signature. Implement signing for ECDSA.

This commit is contained in:
David Kocher
2014-05-14 12:33:46 +02:00
parent 08d0e59b6b
commit 77f5d7fdb8
6 changed files with 59 additions and 46 deletions

View File

@@ -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;

View File

@@ -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.
*

View File

@@ -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;
}

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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;
}