Fix transport encoding of nistp521 signatures (#623)

SignatureECDSA.encode() does not correctly handle signatures longer
than 128 bytes, which affects signatures using the nistp521 curve.

This commits fixes the issue by replacing the ad-hoc ASN.1 DER
parsing with a use of ASN1InputStream.
This commit is contained in:
Fabian Henneke
2020-07-28 11:56:17 +02:00
committed by GitHub
parent 64f448d438
commit 4b1619d54f

View File

@@ -15,6 +15,7 @@
*/ */
package net.schmizz.sshj.signature; package net.schmizz.sshj.signature;
import com.hierynomus.asn1.encodingrules.der.DERDecoder;
import com.hierynomus.asn1.encodingrules.der.DEREncoder; import com.hierynomus.asn1.encodingrules.der.DEREncoder;
import com.hierynomus.asn1.types.ASN1Object; import com.hierynomus.asn1.types.ASN1Object;
import com.hierynomus.asn1.types.constructed.ASN1Sequence; import com.hierynomus.asn1.types.constructed.ASN1Sequence;
@@ -23,6 +24,7 @@ import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.KeyType; import net.schmizz.sshj.common.KeyType;
import net.schmizz.sshj.common.SSHRuntimeException; import net.schmizz.sshj.common.SSHRuntimeException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
@@ -87,22 +89,16 @@ public class SignatureECDSA extends AbstractSignature {
@Override @Override
public byte[] encode(byte[] sig) { public byte[] encode(byte[] sig) {
int rIndex = 3; ByteArrayInputStream bais = new ByteArrayInputStream(sig);
int rLen = sig[rIndex++] & 0xff; com.hierynomus.asn1.ASN1InputStream asn1InputStream = new com.hierynomus.asn1.ASN1InputStream(new DERDecoder(), bais);
byte[] r = new byte[rLen];
System.arraycopy(sig, rIndex, r, 0, r.length);
int sIndex = rIndex + rLen + 1; ASN1Sequence sequence = asn1InputStream.readObject();
int sLen = sig[sIndex++] & 0xff; ASN1Integer r = (ASN1Integer) sequence.get(0);
byte[] s = new byte[sLen]; ASN1Integer s = (ASN1Integer) sequence.get(1);
System.arraycopy(sig, sIndex, s, 0, s.length);
System.arraycopy(sig, 4, r, 0, rLen);
System.arraycopy(sig, 6 + rLen, s, 0, sLen);
Buffer.PlainBuffer buf = new Buffer.PlainBuffer(); Buffer.PlainBuffer buf = new Buffer.PlainBuffer();
buf.putMPInt(new BigInteger(r)); buf.putMPInt(r.getValue());
buf.putMPInt(new BigInteger(s)); buf.putMPInt(s.getValue());
return buf.getCompactData(); return buf.getCompactData();
} }