Skip to content

Commit 843c2e6

Browse files
committed
Added header validation for INTEGER/ENUMERATED
Added additional validations for DSA/ECDSA signature parsing.
1 parent b0c3ce9 commit 843c2e6

File tree

7 files changed

+268
-97
lines changed

7 files changed

+268
-97
lines changed

Diff for: core/src/main/java/org/bouncycastle/asn1/ASN1Enumerated.java

+11
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,17 @@ public ASN1Enumerated(
9999
public ASN1Enumerated(
100100
byte[] bytes)
101101
{
102+
if (bytes.length > 1)
103+
{
104+
if (bytes[0] == 0 && (bytes[1] & 0x80) == 0)
105+
{
106+
throw new IllegalArgumentException("malformed enumerated");
107+
}
108+
if (bytes[0] == (byte)0xff && (bytes[1] & 0x80) != 0)
109+
{
110+
throw new IllegalArgumentException("malformed enumerated");
111+
}
112+
}
102113
this.bytes = Arrays.clone(bytes);
103114
}
104115

Diff for: core/src/main/java/org/bouncycastle/asn1/ASN1Integer.java

+11
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,17 @@ public ASN1Integer(
8989

9090
ASN1Integer(byte[] bytes, boolean clone)
9191
{
92+
if (bytes.length > 1)
93+
{
94+
if (bytes[0] == 0 && (bytes[1] & 0x80) == 0)
95+
{
96+
throw new IllegalArgumentException("malformed integer");
97+
}
98+
if (bytes[0] == (byte)0xff && (bytes[1] & 0x80) != 0)
99+
{
100+
throw new IllegalArgumentException("malformed integer");
101+
}
102+
}
92103
this.bytes = (clone) ? Arrays.clone(bytes) : bytes;
93104
}
94105

Diff for: core/src/test/java/org/bouncycastle/asn1/test/MiscTest.java

+43
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import java.io.IOException;
66

77
import org.bouncycastle.asn1.ASN1Encodable;
8+
import org.bouncycastle.asn1.ASN1Enumerated;
89
import org.bouncycastle.asn1.ASN1InputStream;
10+
import org.bouncycastle.asn1.ASN1Integer;
911
import org.bouncycastle.asn1.ASN1OutputStream;
1012
import org.bouncycastle.asn1.ASN1Primitive;
1113
import org.bouncycastle.asn1.BERSequence;
@@ -67,6 +69,46 @@ public void shouldFailOnExtraData()
6769
}
6870
}
6971

72+
public void derIntegerTest()
73+
throws Exception
74+
{
75+
try
76+
{
77+
new ASN1Integer(new byte[] { 0, 0, 0, 1});
78+
}
79+
catch (IllegalArgumentException e)
80+
{
81+
isTrue("wrong exc", "malformed integer".equals(e.getMessage()));
82+
}
83+
84+
try
85+
{
86+
new ASN1Integer(new byte[] {(byte)0xff, (byte)0x80, 0, 1});
87+
}
88+
catch (IllegalArgumentException e)
89+
{
90+
isTrue("wrong exc", "malformed integer".equals(e.getMessage()));
91+
}
92+
93+
try
94+
{
95+
new ASN1Enumerated(new byte[] { 0, 0, 0, 1});
96+
}
97+
catch (IllegalArgumentException e)
98+
{
99+
isTrue("wrong exc", "malformed enumerated".equals(e.getMessage()));
100+
}
101+
102+
try
103+
{
104+
new ASN1Enumerated(new byte[] {(byte)0xff, (byte)0x80, 0, 1});
105+
}
106+
catch (IllegalArgumentException e)
107+
{
108+
isTrue("wrong exc", "malformed enumerated".equals(e.getMessage()));
109+
}
110+
}
111+
70112
public void performTest()
71113
throws Exception
72114
{
@@ -115,6 +157,7 @@ public void performTest()
115157
}
116158

117159
shouldFailOnExtraData();
160+
derIntegerTest();
118161
}
119162

120163
public String getName()

Diff for: prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/DSASigner.java

+5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.bouncycastle.crypto.digests.SHA512Digest;
3030
import org.bouncycastle.crypto.params.ParametersWithRandom;
3131
import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
32+
import org.bouncycastle.util.Arrays;
3233

3334
public class DSASigner
3435
extends SignatureSpi
@@ -180,6 +181,10 @@ private BigInteger[] derDecode(
180181
{
181182
throw new IOException("malformed signature");
182183
}
184+
if (!Arrays.areEqual(encoding, s.getEncoded(ASN1Encoding.DER)))
185+
{
186+
throw new IOException("malformed signature");
187+
}
183188

184189
return new BigInteger[]{
185190
((ASN1Integer)s.getObjectAt(0)).getValue(),

Diff for: prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/SignatureSpi.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@
2323
import org.bouncycastle.crypto.digests.SHA384Digest;
2424
import org.bouncycastle.crypto.digests.SHA3Digest;
2525
import org.bouncycastle.crypto.digests.SHA512Digest;
26-
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
2726
import org.bouncycastle.crypto.params.ParametersWithRandom;
2827
import org.bouncycastle.crypto.signers.ECDSASigner;
2928
import org.bouncycastle.crypto.signers.ECNRSigner;
3029
import org.bouncycastle.crypto.signers.HMacDSAKCalculator;
3130
import org.bouncycastle.jcajce.provider.asymmetric.util.DSABase;
3231
import org.bouncycastle.jcajce.provider.asymmetric.util.DSAEncoder;
3332
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
33+
import org.bouncycastle.util.Arrays;
3434

3535
public class SignatureSpi
3636
extends DSABase
@@ -367,6 +367,15 @@ public BigInteger[] decode(
367367
throws IOException
368368
{
369369
ASN1Sequence s = (ASN1Sequence)ASN1Primitive.fromByteArray(encoding);
370+
if (s.size() != 2)
371+
{
372+
throw new IOException("malformed signature");
373+
}
374+
if (!Arrays.areEqual(encoding, s.getEncoded(ASN1Encoding.DER)))
375+
{
376+
throw new IOException("malformed signature");
377+
}
378+
370379
BigInteger[] sig = new BigInteger[2];
371380

372381
sig[0] = ASN1Integer.getInstance(s.getObjectAt(0)).getValue();

Diff for: prov/src/test/java/org/bouncycastle/jce/provider/test/DSATest.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ public class DSATest
143143
+ "9ef41dd424a4e1c8f16967cf3365813fe8786236",
144144
"303d021c1e41b479ad576905b960fe14eadb91b0ccf34843dab916173bb8c9cd021d00ade65988d237d30f9ef4"
145145
+ "1dd424a4e1c8f16967cf3365813fe87862360000",
146-
"3040021c57b10411b54ab248af03d8f2456676ebc6d3db5f1081492ac87e9ca8021d00942b117051d7d9d107fc42cac9c5a36a1fd7f0f8916ccca86cec4ed3040100"
146+
"3040021c57b10411b54ab248af03d8f2456676ebc6d3db5f1081492ac87e9ca8021d00942b117051d7d9d107fc42cac9c5a36a1fd7f0f8916ccca86cec4ed3040100",
147+
"303e021c57b10411b54ab248af03d8f2456676ebc6d3db5f1081492ac87e9ca802811d00942b117051d7d9d107fc42cac9c5a36a1fd7f0f8916ccca86cec4ed3"
147148
};
148149

149150
private void testModified()

0 commit comments

Comments
 (0)