Provide a more meaningful exception when reaching past end of ASN.1 stream. Properly close ASN.1 decoder in exception paths.

A way to trigger the exception is running ScriptTest.dataDrivenValidTransactions().
This commit is contained in:
Andreas Schildbach 2014-09-08 10:25:33 +02:00
parent c8803bdefe
commit 2aa7f25a95

View File

@ -500,9 +500,12 @@ public class ECKey implements EncryptableItem, Serializable {
} }
public static ECDSASignature decodeFromDER(byte[] bytes) { public static ECDSASignature decodeFromDER(byte[] bytes) {
ASN1InputStream decoder = null;
try { try {
ASN1InputStream decoder = new ASN1InputStream(bytes); decoder = new ASN1InputStream(bytes);
DLSequence seq = (DLSequence) decoder.readObject(); DLSequence seq = (DLSequence) decoder.readObject();
if (seq == null)
throw new RuntimeException("Reached past end of ASN.1 stream.");
ASN1Integer r, s; ASN1Integer r, s;
try { try {
r = (ASN1Integer) seq.getObjectAt(0); r = (ASN1Integer) seq.getObjectAt(0);
@ -510,12 +513,14 @@ public class ECKey implements EncryptableItem, Serializable {
} catch (ClassCastException e) { } catch (ClassCastException e) {
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
} }
decoder.close();
// OpenSSL deviates from the DER spec by interpreting these values as unsigned, though they should not be // OpenSSL deviates from the DER spec by interpreting these values as unsigned, though they should not be
// Thus, we always use the positive versions. See: http://r6.ca/blog/20111119T211504Z.html // Thus, we always use the positive versions. See: http://r6.ca/blog/20111119T211504Z.html
return new ECDSASignature(r.getPositiveValue(), s.getPositiveValue()); return new ECDSASignature(r.getPositiveValue(), s.getPositiveValue());
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} finally {
if (decoder != null)
try { decoder.close(); } catch (IOException x) {}
} }
} }