Skip to content

Commit 4998af4

Browse files
committed
Merge branch 'issue-1859' into 'main'
fix for issue-1859: ERSEvidenceRecord was trying to read data provided by... See merge request root/bc-java!34
2 parents 48369fb + d266e4a commit 4998af4

File tree

3 files changed

+104
-2
lines changed

3 files changed

+104
-2
lines changed

pkix/src/main/java/org/bouncycastle/tsp/ers/ERSEvidenceRecord.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,10 +396,20 @@ public TimeStampRequest generateHashRenewalRequest(DigestCalculator digCalc, ERS
396396
public TimeStampRequest generateHashRenewalRequest(DigestCalculator digCalc, ERSData data, TimeStampRequestGenerator tspReqGen, BigInteger nonce)
397397
throws ERSException, TSPException, IOException
398398
{
399+
ERSData copy;
400+
if (data instanceof ERSInputStreamData)
401+
{
402+
copy = ((ERSInputStreamData) data).toByteData();
403+
404+
}
405+
else
406+
{
407+
copy = data;
408+
}
399409
// check old data present
400410
try
401411
{
402-
firstArchiveTimeStamp.validatePresent(data, new Date());
412+
firstArchiveTimeStamp.validatePresent(copy, new Date());
403413
}
404414
catch (Exception e)
405415
{
@@ -408,7 +418,7 @@ public TimeStampRequest generateHashRenewalRequest(DigestCalculator digCalc, ERS
408418

409419
ERSArchiveTimeStampGenerator atsGen = new ERSArchiveTimeStampGenerator(digCalc);
410420

411-
atsGen.addData(data);
421+
atsGen.addData(copy);
412422

413423
atsGen.addPreviousChains(evidenceRecord.getArchiveTimeStampSequence());
414424

pkix/src/main/java/org/bouncycastle/tsp/ers/ERSInputStreamData.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package org.bouncycastle.tsp.ers;
22

3+
import java.io.ByteArrayOutputStream;
34
import java.io.File;
45
import java.io.FileInputStream;
56
import java.io.FileNotFoundException;
67
import java.io.InputStream;
8+
import java.io.IOException;
79

810
import org.bouncycastle.operator.DigestCalculator;
11+
import org.bouncycastle.util.io.Streams;
912

1013
/**
1114
* Generic class for processing an InputStream of data RFC 4998 ERS.
@@ -29,6 +32,14 @@ public ERSInputStreamData(InputStream content)
2932
{
3033
this.content = content;
3134
}
35+
36+
protected ERSByteData toByteData()
37+
throws IOException
38+
{
39+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
40+
Streams.pipeAll(this.content, baos);
41+
return new ERSByteData(baos.toByteArray());
42+
}
3243

3344
protected byte[] calculateHash(DigestCalculator digestCalculator, byte[] previousChainHash)
3445
{

pkix/src/test/java/org/bouncycastle/tsp/test/ERSTest.java

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package org.bouncycastle.tsp.test;
22

3+
import java.io.ByteArrayInputStream;
34
import java.io.ByteArrayOutputStream;
45
import java.io.File;
56
import java.io.FileOutputStream;
7+
import java.io.IOException;
68
import java.io.OutputStream;
79
import java.math.BigInteger;
10+
import java.nio.charset.StandardCharsets;
811
import java.security.KeyPair;
12+
import java.security.NoSuchAlgorithmException;
913
import java.security.MessageDigest;
1014
import java.security.PrivateKey;
1115
import java.security.Security;
@@ -19,6 +23,7 @@
1923

2024
import junit.framework.Assert;
2125
import junit.framework.TestCase;
26+
import org.bouncycastle.asn1.ASN1Encoding;
2227
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
2328
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
2429
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
@@ -31,6 +36,7 @@
3136
import org.bouncycastle.operator.DigestCalculator;
3237
import org.bouncycastle.operator.DigestCalculatorProvider;
3338
import org.bouncycastle.operator.OperatorCreationException;
39+
import org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
3440
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
3541
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
3642
import org.bouncycastle.tsp.TSPAlgorithms;
@@ -1571,4 +1577,79 @@ public DigestCalculator get(AlgorithmIdentifier digestAlgorithmIdentifier)
15711577
}
15721578

15731579
}
1580+
1581+
public void testCompareStreamAndByteData () throws TSPException, ERSException, OperatorCreationException, IOException,
1582+
NoSuchAlgorithmException
1583+
{
1584+
// ER for the String "foo" using SHA-256 and a dummy cert/key.
1585+
String evidenceRecordBase64 = "MIIDCgIBATANMAsGCWCGSAFlAwQCATCCAvQwggLwMIIC7DCCAugGCSqGSI"
1586+
+ "b3DQEHAqCCAtkwggLVAgEDMQ0wCwYJYIZIAWUDBAIDMG0GCyqGSIb3DQEJEAEEoF4EXDBaAgEBBgYEA"
1587+
+ "I9nAQEwLzALBglghkgBZQMEAgEEICwmtGto/8aP+ZtFPB0wQTQTQi1wZIO/oPmKXohiZueuAgEBGA8y"
1588+
+ "MDI0MTAwMjIzMDAzNloCCFO56J9TFmGGMYICUDCCAkwCAQEwBTAAAgEAMAsGCWCGSAFlAwQCA6CCAR4"
1589+
+ "wGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNDEwMDIyMzAwMzZaMC"
1590+
+ "sGCSqGSIb3DQEJNDEeMBwwCwYJYIZIAWUDBAIDoQ0GCSqGSIb3DQEBDQUAME8GCSqGSIb3DQEJBDFCB"
1591+
+ "EDPPkk9PN5EGrAvZyjv9wJR77tQCIwoA3xWwqESBGICShZxNjt6YU3LZor99ARJ4As+yiIjW/hTg5v3"
1592+
+ "vqbTrfSIMGQGCyqGSIb3DQEJEAIvMVUwUzBRME8wCwYJYIZIAWUDBAIDBEAPvi2mNblzqqI91nWRM9s"
1593+
+ "ocS7TJfpyQsx4ZcBVeGK1XjCW6BQ5KmrPFCc+IefB5FB/ZQsPwdyYv6umJzCYK0SzMA0GCSqGSIb3DQ"
1594+
+ "EBDQUABIIBALWgWcjxzY5QEOlK92GNf9kjBflbO65dYkAKxrrgcwQ6Dz+ablUwsG01ILDUUnSL9wTQC"
1595+
+ "OkYKb1oEFNrd9lbHWBOqlu5/lMjhZcWnYzbK3rzQRuoPwXYD/GWgiO0wLmF3FQ9xaum1Oui+Y075OS4"
1596+
+ "7fXfLlSe2wMPlnoDb/IFAgHGBK/3zJ7w7n9OCa1U6qwTYCpw9MTXsOI/PbNw2h3cHTVgbY+HCTB4oJC"
1597+
+ "GpY9bbEMuJboe4DkQx2Eqpq1pVaMKRxsjhrnbH8QlkUGtuGztqnZa5AoCth79x70Ch7WhdDcxG3wiFi"
1598+
+ "29pw69obUCh3c61Q2WKl+MKW/tqq7EGYu5+jE=";
1599+
DigestCalculatorProvider digestProvider = new BcDigestCalculatorProvider();
1600+
ERSEvidenceRecord ersEvidenceRecord = new ERSEvidenceRecord(
1601+
Base64.decode(evidenceRecordBase64), digestProvider);
1602+
1603+
// Sanity check, make sure root hash of ER is what we expect.
1604+
byte[] sourceData = "foo".getBytes(StandardCharsets.UTF_8);
1605+
byte[] sourceSha256 = MessageDigest.getInstance("SHA-256").digest(sourceData);
1606+
assert Arrays.areEqual(sourceSha256, ersEvidenceRecord.getPrimaryRootHash());
1607+
1608+
1609+
// Generate hash renewal request using ERSInputStreamData.
1610+
ERSData ersStreamData = new ERSInputStreamData(new ByteArrayInputStream(sourceData));
1611+
TimeStampRequest streamDataReq = ersEvidenceRecord.generateHashRenewalRequest(
1612+
digestProvider.get(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512)),
1613+
ersStreamData,
1614+
new TimeStampRequestGenerator(),
1615+
BigInteger.ZERO);
1616+
1617+
1618+
// Generate hash renewal request using ERSByteData to compare against.
1619+
ERSData ersByteData = new ERSByteData(sourceData);
1620+
TimeStampRequest byteDataReq = ersEvidenceRecord.generateHashRenewalRequest(
1621+
digestProvider.get(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512)),
1622+
ersByteData,
1623+
new TimeStampRequestGenerator(),
1624+
BigInteger.ZERO);
1625+
1626+
1627+
// check ERSByteData and ERSInputStreamData produce same output
1628+
assert Arrays.areEqual(byteDataReq.getMessageImprintDigest(),
1629+
streamDataReq.getMessageImprintDigest());
1630+
1631+
1632+
// Generate the digest we expect to see in the requests and compare.
1633+
byte[] expectedDigest = generateExpectedRequestDigest(sourceData, ersEvidenceRecord,
1634+
MessageDigest.getInstance("SHA-512"));
1635+
assert Arrays.areEqual(byteDataReq.getMessageImprintDigest(), expectedDigest);
1636+
assert Arrays.areEqual(streamDataReq.getMessageImprintDigest(), expectedDigest);
1637+
}
1638+
1639+
/** Based on RFC 4998 section 5.2. */
1640+
private static byte[] generateExpectedRequestDigest (byte[] sourceData,
1641+
ERSEvidenceRecord evidenceRecord, MessageDigest digest) throws IOException
1642+
{
1643+
byte[] atsci = evidenceRecord.toASN1Structure().getArchiveTimeStampSequence().getEncoded(ASN1Encoding.DER);
1644+
byte[] hi = digest.digest(sourceData);
1645+
byte[] hai = digest.digest(atsci);
1646+
byte[] hihai;
1647+
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
1648+
outputStream.write(hi);
1649+
outputStream.write(hai);
1650+
hihai = outputStream.toByteArray();
1651+
}
1652+
byte[] hiprime = digest.digest(hihai);
1653+
return hiprime;
1654+
}
15741655
}

0 commit comments

Comments
 (0)