Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'pkix/src/test/java/org/spongycastle/tsp')
-rw-r--r--pkix/src/test/java/org/spongycastle/tsp/GenTimeAccuracyUnitTest.java105
-rw-r--r--pkix/src/test/java/org/spongycastle/tsp/TimeStampTokenInfoUnitTest.java144
-rw-r--r--pkix/src/test/java/org/spongycastle/tsp/test/AllTests.java32
-rw-r--r--pkix/src/test/java/org/spongycastle/tsp/test/CMSTimeStampedDataGeneratorTest.java309
-rw-r--r--pkix/src/test/java/org/spongycastle/tsp/test/CMSTimeStampedDataParserTest.java91
-rw-r--r--pkix/src/test/java/org/spongycastle/tsp/test/CMSTimeStampedDataTest.java84
-rw-r--r--pkix/src/test/java/org/spongycastle/tsp/test/NewTSPTest.java833
-rw-r--r--pkix/src/test/java/org/spongycastle/tsp/test/ParseTest.java417
-rw-r--r--pkix/src/test/java/org/spongycastle/tsp/test/SHA1DigestCalculator.java44
-rw-r--r--pkix/src/test/java/org/spongycastle/tsp/test/SHA256DigestCalculator.java44
-rw-r--r--pkix/src/test/java/org/spongycastle/tsp/test/TSPTestUtil.java229
11 files changed, 2332 insertions, 0 deletions
diff --git a/pkix/src/test/java/org/spongycastle/tsp/GenTimeAccuracyUnitTest.java b/pkix/src/test/java/org/spongycastle/tsp/GenTimeAccuracyUnitTest.java
new file mode 100644
index 00000000..ba4ca49e
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/tsp/GenTimeAccuracyUnitTest.java
@@ -0,0 +1,105 @@
+package org.spongycastle.tsp;
+
+import junit.framework.TestCase;
+import org.spongycastle.asn1.ASN1Integer;
+import org.spongycastle.asn1.tsp.Accuracy;
+
+public class GenTimeAccuracyUnitTest
+ extends TestCase
+{
+ private static final ASN1Integer ZERO_VALUE = new ASN1Integer(0);
+ private static final ASN1Integer ONE_VALUE = new ASN1Integer(1);
+ private static final ASN1Integer TWO_VALUE = new ASN1Integer(2);
+ private static final ASN1Integer THREE_VALUE = new ASN1Integer(3);
+
+ public void testOneTwoThree()
+ {
+ GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ONE_VALUE, TWO_VALUE, THREE_VALUE));
+
+ checkValues(accuracy, ONE_VALUE, TWO_VALUE, THREE_VALUE);
+
+ checkToString(accuracy, "1.002003");
+ }
+
+ public void testThreeTwoOne()
+ {
+ GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(THREE_VALUE, TWO_VALUE, ONE_VALUE));
+
+ checkValues(accuracy, THREE_VALUE, TWO_VALUE, ONE_VALUE);
+
+ checkToString(accuracy, "3.002001");
+ }
+
+ public void testTwoThreeTwo()
+ {
+ GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(TWO_VALUE, THREE_VALUE, TWO_VALUE));
+
+ checkValues(accuracy, TWO_VALUE, THREE_VALUE, TWO_VALUE);
+
+ checkToString(accuracy, "2.003002");
+ }
+
+
+ public void testZeroTwoThree()
+ {
+ GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ZERO_VALUE, TWO_VALUE, THREE_VALUE));
+
+ checkValues(accuracy, ZERO_VALUE, TWO_VALUE, THREE_VALUE);
+
+ checkToString(accuracy, "0.002003");
+ }
+
+ public void testThreeTwoNull()
+ {
+ GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(THREE_VALUE, TWO_VALUE, null));
+
+ checkValues(accuracy, THREE_VALUE, TWO_VALUE, ZERO_VALUE);
+
+ checkToString(accuracy, "3.002000");
+ }
+
+ public void testOneNullOne()
+ {
+ GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ONE_VALUE, null, ONE_VALUE));
+
+ checkValues(accuracy, ONE_VALUE, ZERO_VALUE, ONE_VALUE);
+
+ checkToString(accuracy, "1.000001");
+ }
+
+ public void testZeroNullNull()
+ {
+ GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(ZERO_VALUE, null, null));
+
+ checkValues(accuracy, ZERO_VALUE, ZERO_VALUE, ZERO_VALUE);
+
+ checkToString(accuracy, "0.000000");
+ }
+
+ public void testNullNullNull()
+ {
+ GenTimeAccuracy accuracy = new GenTimeAccuracy(new Accuracy(null, null, null));
+
+ checkValues(accuracy, ZERO_VALUE, ZERO_VALUE, ZERO_VALUE);
+
+ checkToString(accuracy, "0.000000");
+ }
+
+ private void checkValues(
+ GenTimeAccuracy accuracy,
+ ASN1Integer secs,
+ ASN1Integer millis,
+ ASN1Integer micros)
+ {
+ assertEquals(secs.getValue().intValue(), accuracy.getSeconds());
+ assertEquals(millis.getValue().intValue(), accuracy.getMillis());
+ assertEquals(micros.getValue().intValue(), accuracy.getMicros());
+ }
+
+ private void checkToString(
+ GenTimeAccuracy accuracy,
+ String expected)
+ {
+ assertEquals(expected, accuracy.toString());
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/tsp/TimeStampTokenInfoUnitTest.java b/pkix/src/test/java/org/spongycastle/tsp/TimeStampTokenInfoUnitTest.java
new file mode 100644
index 00000000..39e7285d
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/tsp/TimeStampTokenInfoUnitTest.java
@@ -0,0 +1,144 @@
+package org.spongycastle.tsp;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+import junit.framework.TestCase;
+import org.spongycastle.asn1.ASN1InputStream;
+import org.spongycastle.asn1.tsp.TSTInfo;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.util.encoders.Hex;
+
+public class TimeStampTokenInfoUnitTest
+ extends TestCase
+{
+ private static final byte[] tstInfo1 = Hex.decode(
+ "303e02010106022a033021300906052b0e03021a050004140000000000000000000000000000000000000000"
+ + "020118180f32303035313130313038313732315a");
+
+ private static final byte[] tstInfo2 = Hex.decode(
+ "304c02010106022a033021300906052b0e03021a05000414ffffffffffffffffffffffffffffffffffffffff"
+ + "020117180f32303035313130313038323934355a3009020103800101810102020164");
+
+ private static final byte[] tstInfo3 = Hex.decode(
+ "304f02010106022a033021300906052b0e03021a050004140000000000000000000000000000000000000000"
+ + "020117180f32303035313130313038343733355a30090201038001018101020101ff020164");
+
+ private static final byte[] tstInfoDudDate = Hex.decode(
+ "303e02010106022a033021300906052b0e03021a050004140000000000000000000000000000000000000000"
+ + "020118180f32303056313130313038313732315a");
+
+ public void testTstInfo1()
+ throws Exception
+ {
+ TimeStampTokenInfo tstInfo = getTimeStampTokenInfo(tstInfo1);
+
+ //
+ // verify
+ //
+ GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy();
+
+ assertNull(accuracy);
+
+ assertEquals(new BigInteger("24"), tstInfo.getSerialNumber());
+
+ assertEquals(1130833041000L, tstInfo.getGenTime().getTime());
+
+ assertEquals("1.2.3", tstInfo.getPolicy().getId());
+
+ assertEquals(false, tstInfo.isOrdered());
+
+ assertNull(tstInfo.getNonce());
+
+ assertEquals(TSPAlgorithms.SHA1, tstInfo.getMessageImprintAlgOID());
+
+ assertTrue(Arrays.areEqual(new byte[20], tstInfo.getMessageImprintDigest()));
+
+ assertTrue(Arrays.areEqual(tstInfo1, tstInfo.getEncoded()));
+ }
+
+ public void testTstInfo2()
+ throws Exception
+ {
+ TimeStampTokenInfo tstInfo = getTimeStampTokenInfo(tstInfo2);
+
+ //
+ // verify
+ //
+ GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy();
+
+ assertEquals(3, accuracy.getSeconds());
+ assertEquals(1, accuracy.getMillis());
+ assertEquals(2, accuracy.getMicros());
+
+ assertEquals(new BigInteger("23"), tstInfo.getSerialNumber());
+
+ assertEquals(1130833785000L, tstInfo.getGenTime().getTime());
+
+ assertEquals("1.2.3", tstInfo.getPolicy().getId());
+
+ assertEquals(false, tstInfo.isOrdered());
+
+ assertEquals(tstInfo.getNonce(), BigInteger.valueOf(100));
+
+ assertTrue(Arrays.areEqual(Hex.decode("ffffffffffffffffffffffffffffffffffffffff"), tstInfo.getMessageImprintDigest()));
+
+ assertTrue(Arrays.areEqual(tstInfo2, tstInfo.getEncoded()));
+ }
+
+ public void testTstInfo3()
+ throws Exception
+ {
+ TimeStampTokenInfo tstInfo = getTimeStampTokenInfo(tstInfo3);
+
+ //
+ // verify
+ //
+ GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy();
+
+ assertEquals(3, accuracy.getSeconds());
+ assertEquals(1, accuracy.getMillis());
+ assertEquals(2, accuracy.getMicros());
+
+ assertEquals(new BigInteger("23"), tstInfo.getSerialNumber());
+
+ assertEquals(1130834855000L, tstInfo.getGenTime().getTime());
+
+ assertEquals("1.2.3", tstInfo.getPolicy().getId());
+
+ assertEquals(true, tstInfo.isOrdered());
+
+ assertEquals(tstInfo.getNonce(), BigInteger.valueOf(100));
+
+ assertEquals(TSPAlgorithms.SHA1, tstInfo.getMessageImprintAlgOID());
+
+ assertTrue(Arrays.areEqual(new byte[20], tstInfo.getMessageImprintDigest()));
+
+ assertTrue(Arrays.areEqual(tstInfo3, tstInfo.getEncoded()));
+ }
+
+ public void testTstInfoDudDate()
+ throws Exception
+ {
+ try
+ {
+ getTimeStampTokenInfo(tstInfoDudDate);
+
+ fail("dud date not detected.");
+ }
+ catch (TSPException e)
+ {
+ // expected
+ }
+ }
+
+ private TimeStampTokenInfo getTimeStampTokenInfo(
+ byte[] tstInfo)
+ throws IOException, TSPException
+ {
+ ASN1InputStream aIn = new ASN1InputStream(tstInfo);
+ TSTInfo info = TSTInfo.getInstance(aIn.readObject());
+
+ return new TimeStampTokenInfo(info);
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/tsp/test/AllTests.java b/pkix/src/test/java/org/spongycastle/tsp/test/AllTests.java
new file mode 100644
index 00000000..5a990772
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/tsp/test/AllTests.java
@@ -0,0 +1,32 @@
+package org.spongycastle.tsp.test;
+
+import java.security.Security;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+
+public class AllTests
+ extends TestCase
+{
+ public static void main (String[] args)
+ {
+ junit.textui.TestRunner.run(suite());
+ }
+
+ public static Test suite()
+ {
+ Security.addProvider(new BouncyCastleProvider());
+
+ TestSuite suite = new TestSuite("TSP Tests");
+
+ suite.addTestSuite(ParseTest.class);
+ suite.addTestSuite(NewTSPTest.class);
+ suite.addTestSuite(CMSTimeStampedDataTest.class);
+ suite.addTestSuite(CMSTimeStampedDataParserTest.class);
+ suite.addTestSuite(CMSTimeStampedDataGeneratorTest.class);
+
+ return suite;
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/tsp/test/CMSTimeStampedDataGeneratorTest.java b/pkix/src/test/java/org/spongycastle/tsp/test/CMSTimeStampedDataGeneratorTest.java
new file mode 100644
index 00000000..2af0992a
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/tsp/test/CMSTimeStampedDataGeneratorTest.java
@@ -0,0 +1,309 @@
+package org.spongycastle.tsp.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import junit.framework.TestCase;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.cert.jcajce.JcaCertStore;
+import org.spongycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.bc.BcDigestCalculatorProvider;
+import org.spongycastle.tsp.TSPAlgorithms;
+import org.spongycastle.tsp.TimeStampRequest;
+import org.spongycastle.tsp.TimeStampRequestGenerator;
+import org.spongycastle.tsp.TimeStampResponse;
+import org.spongycastle.tsp.TimeStampResponseGenerator;
+import org.spongycastle.tsp.TimeStampToken;
+import org.spongycastle.tsp.TimeStampTokenGenerator;
+import org.spongycastle.tsp.cms.CMSTimeStampedData;
+import org.spongycastle.tsp.cms.CMSTimeStampedDataGenerator;
+import org.spongycastle.tsp.cms.CMSTimeStampedDataParser;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.util.Store;
+import org.spongycastle.util.io.Streams;
+
+public class CMSTimeStampedDataGeneratorTest
+ extends TestCase
+{
+
+ BouncyCastleProvider bouncyCastleProvider;
+ CMSTimeStampedDataGenerator cmsTimeStampedDataGenerator = null;
+ String fileInput = "FileDaFirmare.data";
+ byte[] baseData;
+
+ protected void setUp()
+ throws Exception
+ {
+ bouncyCastleProvider = new BouncyCastleProvider();
+ if (Security.getProvider(bouncyCastleProvider.getName()) == null)
+ {
+ Security.addProvider(bouncyCastleProvider);
+ }
+
+ cmsTimeStampedDataGenerator = new CMSTimeStampedDataGenerator();
+ ByteArrayOutputStream origStream = new ByteArrayOutputStream();
+ InputStream in = this.getClass().getResourceAsStream(fileInput);
+ int ch;
+
+ while ((ch = in.read()) >= 0)
+ {
+ origStream.write(ch);
+ }
+
+ origStream.close();
+
+ this.baseData = origStream.toByteArray();
+
+ }
+
+ protected void tearDown()
+ throws Exception
+ {
+ cmsTimeStampedDataGenerator = null;
+ Security.removeProvider(bouncyCastleProvider.getName());
+ }
+
+ public void testGenerate()
+ throws Exception
+ {
+ BcDigestCalculatorProvider calculatorProvider = new BcDigestCalculatorProvider();
+ ASN1ObjectIdentifier algOID = new ASN1ObjectIdentifier("2.16.840.1.101.3.4.2.1"); // SHA-256
+ DigestCalculator hashCalculator = calculatorProvider.get(new AlgorithmIdentifier(algOID));
+
+ cmsTimeStampedDataGenerator.initialiseMessageImprintDigestCalculator(hashCalculator);
+
+ hashCalculator.getOutputStream().write(baseData);
+ hashCalculator.getOutputStream().close();
+
+ TimeStampToken timeStampToken = createTimeStampToken(hashCalculator.getDigest(), NISTObjectIdentifiers.id_sha256);
+ CMSTimeStampedData cmsTimeStampedData = cmsTimeStampedDataGenerator.generate(timeStampToken, baseData);
+
+ for (int i = 0; i < 3; i++)
+ {
+ byte[] newRequestData = cmsTimeStampedData.calculateNextHash(hashCalculator);
+ TimeStampToken newTimeStampToken = createTimeStampToken(newRequestData, NISTObjectIdentifiers.id_sha256);
+ cmsTimeStampedData = cmsTimeStampedData.addTimeStamp(newTimeStampToken);
+ }
+ byte[] timeStampedData = cmsTimeStampedData.getEncoded();
+
+ // verify
+ DigestCalculatorProvider newCalculatorProvider = new BcDigestCalculatorProvider();
+ DigestCalculator imprintCalculator = cmsTimeStampedData.getMessageImprintDigestCalculator(newCalculatorProvider);
+ CMSTimeStampedData newCMSTimeStampedData = new CMSTimeStampedData(timeStampedData);
+ byte[] newContent = newCMSTimeStampedData.getContent();
+ assertEquals("Content expected and verified are different", true, Arrays.areEqual(newContent, baseData));
+
+ imprintCalculator.getOutputStream().write(newContent);
+
+ byte[] digest = imprintCalculator.getDigest();
+
+ TimeStampToken[] tokens = cmsTimeStampedData.getTimeStampTokens();
+ assertEquals("TimeStampToken expected and verified are different", 4, tokens.length);
+ for (int i = 0; i < tokens.length; i++)
+ {
+ cmsTimeStampedData.validate(newCalculatorProvider, digest, tokens[i]);
+ }
+ }
+
+ public void testGenerateWithMetadata()
+ throws Exception
+ {
+ cmsTimeStampedDataGenerator.setMetaData(true, fileInput, "TXT");
+
+ BcDigestCalculatorProvider calculatorProvider = new BcDigestCalculatorProvider();
+ ASN1ObjectIdentifier algOID = new ASN1ObjectIdentifier("2.16.840.1.101.3.4.2.1"); // SHA-256
+ DigestCalculator hashCalculator = calculatorProvider.get(new AlgorithmIdentifier(algOID));
+
+ cmsTimeStampedDataGenerator.initialiseMessageImprintDigestCalculator(hashCalculator);
+
+ hashCalculator.getOutputStream().write(baseData);
+ hashCalculator.getOutputStream().close();
+
+ TimeStampToken timeStampToken = createTimeStampToken(hashCalculator.getDigest(), NISTObjectIdentifiers.id_sha256);
+ CMSTimeStampedData cmsTimeStampedData = cmsTimeStampedDataGenerator.generate(timeStampToken, baseData);
+
+ for (int i = 0; i <= 3; i++)
+ {
+ byte[] newRequestData = cmsTimeStampedData.calculateNextHash(hashCalculator);
+ TimeStampToken newTimeStampToken = createTimeStampToken(newRequestData, NISTObjectIdentifiers.id_sha256);
+ cmsTimeStampedData = cmsTimeStampedData.addTimeStamp(newTimeStampToken);
+ }
+ byte[] timeStampedData = cmsTimeStampedData.getEncoded();
+
+ metadataCheck(timeStampedData);
+ metadataParserCheck(timeStampedData);
+ }
+
+ public void testGenerateWithMetadataAndDifferentAlgorithmIdentifier()
+ throws Exception
+ {
+ cmsTimeStampedDataGenerator.setMetaData(true, fileInput, "TXT");
+
+ BcDigestCalculatorProvider calculatorProvider = new BcDigestCalculatorProvider();
+
+ ASN1ObjectIdentifier algIdentifier = NISTObjectIdentifiers.id_sha224;
+
+ DigestCalculator hashCalculator = calculatorProvider.get(new AlgorithmIdentifier(algIdentifier));
+ cmsTimeStampedDataGenerator.initialiseMessageImprintDigestCalculator(hashCalculator);
+ hashCalculator.getOutputStream().write(baseData);
+ hashCalculator.getOutputStream().close();
+
+ byte[] requestData = hashCalculator.getDigest();
+ TimeStampToken timeStampToken = createTimeStampToken(requestData, algIdentifier);
+
+ CMSTimeStampedData cmsTimeStampedData = cmsTimeStampedDataGenerator.generate(timeStampToken, baseData);
+
+ for (int i = 0; i <= 3; i++) {
+ switch (i) {
+ case 0:
+ algIdentifier = NISTObjectIdentifiers.id_sha224;
+ break;
+ case 1:
+ algIdentifier = NISTObjectIdentifiers.id_sha256;
+ break;
+ case 2:
+ algIdentifier = NISTObjectIdentifiers.id_sha384;
+ break;
+ case 3:
+ algIdentifier = NISTObjectIdentifiers.id_sha512;
+ break;
+ }
+ hashCalculator = calculatorProvider.get(new AlgorithmIdentifier(algIdentifier));
+ byte[] newRequestData = cmsTimeStampedData.calculateNextHash(hashCalculator);
+ TimeStampToken newTimeStampToken = createTimeStampToken(newRequestData, algIdentifier);
+ cmsTimeStampedData = cmsTimeStampedData.addTimeStamp(newTimeStampToken);
+ }
+ byte[] timeStampedData = cmsTimeStampedData.getEncoded();
+
+ metadataCheck(timeStampedData);
+ metadataParserCheck(timeStampedData);
+
+ }
+
+
+ private void metadataCheck(byte[] timeStampedData)
+ throws Exception
+ {
+ CMSTimeStampedData cmsTspData = new CMSTimeStampedData(timeStampedData);
+ DigestCalculatorProvider newCalculatorProvider = new BcDigestCalculatorProvider();
+ DigestCalculator imprintCalculator = cmsTspData.getMessageImprintDigestCalculator(newCalculatorProvider);
+
+ byte[] newContent = cmsTspData.getContent();
+ assertEquals("Content expected and verified are different", true, Arrays.areEqual(newContent, baseData));
+
+ imprintCalculator.getOutputStream().write(newContent);
+
+ assertEquals(fileInput, cmsTspData.getFileName());
+ assertEquals("TXT", cmsTspData.getMediaType());
+
+ byte[] digest = imprintCalculator.getDigest();
+
+ TimeStampToken[] tokens = cmsTspData.getTimeStampTokens();
+ assertEquals("TimeStampToken expected and verified are different", 5, tokens.length);
+ for (int i = 0; i < tokens.length; i++)
+ {
+ cmsTspData.validate(newCalculatorProvider, digest, tokens[i]);
+ }
+ }
+
+ private void metadataParserCheck(byte[] timeStampedData)
+ throws Exception
+ {
+ CMSTimeStampedDataParser cmsTspData = new CMSTimeStampedDataParser(timeStampedData);
+ DigestCalculatorProvider newCalculatorProvider = new BcDigestCalculatorProvider();
+
+ InputStream input = cmsTspData.getContent();
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ Streams.pipeAll(input, bOut);
+
+ assertEquals("Content expected and verified are different", true, Arrays.areEqual(bOut.toByteArray(), baseData));
+
+ DigestCalculator imprintCalculator = cmsTspData.getMessageImprintDigestCalculator(newCalculatorProvider);
+
+ Streams.pipeAll(new ByteArrayInputStream(bOut.toByteArray()), imprintCalculator.getOutputStream());
+
+ assertEquals(fileInput, cmsTspData.getFileName());
+ assertEquals("TXT", cmsTspData.getMediaType());
+
+ byte[] digest = imprintCalculator.getDigest();
+
+ TimeStampToken[] tokens = cmsTspData.getTimeStampTokens();
+ assertEquals("TimeStampToken expected and verified are different", 5, tokens.length);
+ for (int i = 0; i < tokens.length; i++)
+ {
+ cmsTspData.validate(newCalculatorProvider, digest, tokens[i]);
+ }
+ }
+
+ private TimeStampToken createTimeStampToken(byte[] hash, ASN1ObjectIdentifier hashAlg)
+ throws Exception
+ {
+ String algorithmName = null;
+ if (hashAlg.equals(NISTObjectIdentifiers.id_sha224))
+ {
+ algorithmName = "SHA224withRSA";
+ }
+ else if (hashAlg.equals(NISTObjectIdentifiers.id_sha256))
+ {
+ algorithmName = "SHA256withRSA";
+ }
+ else if (hashAlg.equals(NISTObjectIdentifiers.id_sha384))
+ {
+ algorithmName = "SHA384withRSA";
+ }
+ else if (hashAlg.equals(NISTObjectIdentifiers.id_sha512))
+ {
+ algorithmName = "SHA512withRSA";
+ }
+
+ String signDN = "O=Bouncy Castle, C=AU";
+ KeyPair signKP = TSPTestUtil.makeKeyPair();
+ X509Certificate signCert = TSPTestUtil.makeCACertificate(signKP,
+ signDN, signKP, signDN);
+
+ String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU";
+ KeyPair origKP = TSPTestUtil.makeKeyPair();
+ X509Certificate cert = TSPTestUtil.makeCertificate(origKP,
+ origDN, signKP, signDN);
+
+ PrivateKey privateKey = origKP.getPrivate();
+
+ List certList = new ArrayList();
+ certList.add(cert);
+ certList.add(signCert);
+
+ Store certs = new JcaCertStore(certList);
+
+
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(
+ new JcaSimpleSignerInfoGeneratorBuilder().build(algorithmName, privateKey, cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2"));
+
+ tsTokenGen.addCertificates(certs);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+ TimeStampRequest request = reqGen.generate(hashAlg, hash);
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+
+ TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date());
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ return tsResp.getTimeStampToken();
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/tsp/test/CMSTimeStampedDataParserTest.java b/pkix/src/test/java/org/spongycastle/tsp/test/CMSTimeStampedDataParserTest.java
new file mode 100644
index 00000000..5fa14db7
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/tsp/test/CMSTimeStampedDataParserTest.java
@@ -0,0 +1,91 @@
+package org.spongycastle.tsp.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import junit.framework.TestCase;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.bc.BcDigestCalculatorProvider;
+import org.spongycastle.tsp.TimeStampToken;
+import org.spongycastle.tsp.cms.CMSTimeStampedDataParser;
+import org.spongycastle.util.io.Streams;
+
+public class CMSTimeStampedDataParserTest
+ extends TestCase
+{
+
+ CMSTimeStampedDataParser cmsTimeStampedData = null;
+ String fileInput = "FileDaFirmare.txt.tsd.der";
+ private byte[] baseData;
+
+ protected void setUp()
+ throws Exception
+ {
+ ByteArrayOutputStream origStream = new ByteArrayOutputStream();
+ InputStream in = this.getClass().getResourceAsStream(fileInput);
+ int ch;
+
+ while ((ch = in.read()) >= 0)
+ {
+ origStream.write(ch);
+ }
+
+ origStream.close();
+
+ this.baseData = origStream.toByteArray();
+
+ cmsTimeStampedData = new CMSTimeStampedDataParser(baseData);
+ }
+
+ protected void tearDown()
+ throws Exception
+ {
+ cmsTimeStampedData = null;
+ }
+
+ public void testGetTimeStampTokens()
+ throws Exception
+ {
+ TimeStampToken[] tokens = cmsTimeStampedData.getTimeStampTokens();
+ assertEquals(3, tokens.length);
+ }
+
+ public void testValidateAllTokens()
+ throws Exception
+ {
+ DigestCalculatorProvider digestCalculatorProvider = new BcDigestCalculatorProvider();
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ Streams.pipeAll(cmsTimeStampedData.getContent(), bOut);
+
+ DigestCalculator imprintCalculator = cmsTimeStampedData.getMessageImprintDigestCalculator(digestCalculatorProvider);
+
+ Streams.pipeAll(new ByteArrayInputStream(bOut.toByteArray()), imprintCalculator.getOutputStream());
+
+ byte[] digest = imprintCalculator.getDigest();
+
+ TimeStampToken[] tokens = cmsTimeStampedData.getTimeStampTokens();
+ for (int i = 0; i < tokens.length; i++)
+ {
+ cmsTimeStampedData.validate(digestCalculatorProvider, digest, tokens[i]);
+ }
+ }
+
+ public void testValidate()
+ throws Exception
+ {
+ DigestCalculatorProvider digestCalculatorProvider = new BcDigestCalculatorProvider();
+ ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ Streams.pipeAll(cmsTimeStampedData.getContent(), bOut);
+
+ DigestCalculator imprintCalculator = cmsTimeStampedData.getMessageImprintDigestCalculator(digestCalculatorProvider);
+
+ Streams.pipeAll(new ByteArrayInputStream(bOut.toByteArray()), imprintCalculator.getOutputStream());
+
+ cmsTimeStampedData.validate(digestCalculatorProvider, imprintCalculator.getDigest());
+ }
+
+}
diff --git a/pkix/src/test/java/org/spongycastle/tsp/test/CMSTimeStampedDataTest.java b/pkix/src/test/java/org/spongycastle/tsp/test/CMSTimeStampedDataTest.java
new file mode 100644
index 00000000..7f97dccb
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/tsp/test/CMSTimeStampedDataTest.java
@@ -0,0 +1,84 @@
+package org.spongycastle.tsp.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import junit.framework.TestCase;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.DigestCalculatorProvider;
+import org.spongycastle.operator.bc.BcDigestCalculatorProvider;
+import org.spongycastle.tsp.TimeStampToken;
+import org.spongycastle.tsp.cms.CMSTimeStampedData;
+
+public class CMSTimeStampedDataTest
+ extends TestCase
+{
+
+ CMSTimeStampedData cmsTimeStampedData = null;
+ String fileInput = "FileDaFirmare.txt.tsd.der";
+ String fileOutput = fileInput.substring(0, fileInput.indexOf(".tsd"));
+ private byte[] baseData;
+
+ protected void setUp()
+ throws Exception
+ {
+ ByteArrayOutputStream origStream = new ByteArrayOutputStream();
+ InputStream in = this.getClass().getResourceAsStream(fileInput);
+ int ch;
+
+ while ((ch = in.read()) >= 0)
+ {
+ origStream.write(ch);
+ }
+
+ origStream.close();
+
+ this.baseData = origStream.toByteArray();
+
+ cmsTimeStampedData = new CMSTimeStampedData(baseData);
+ }
+
+ protected void tearDown()
+ throws Exception
+ {
+ cmsTimeStampedData = null;
+ }
+
+ public void testGetTimeStampTokens()
+ throws Exception
+ {
+ TimeStampToken[] tokens = cmsTimeStampedData.getTimeStampTokens();
+ assertEquals(3, tokens.length);
+ }
+
+ public void testValidateAllTokens()
+ throws Exception
+ {
+ DigestCalculatorProvider digestCalculatorProvider = new BcDigestCalculatorProvider();
+
+ DigestCalculator imprintCalculator = cmsTimeStampedData.getMessageImprintDigestCalculator(digestCalculatorProvider);
+
+ imprintCalculator.getOutputStream().write(cmsTimeStampedData.getContent());
+
+ byte[] digest = imprintCalculator.getDigest();
+
+ TimeStampToken[] tokens = cmsTimeStampedData.getTimeStampTokens();
+ for (int i = 0; i < tokens.length; i++)
+ {
+ cmsTimeStampedData.validate(digestCalculatorProvider, digest, tokens[i]);
+ }
+ }
+
+ public void testValidate()
+ throws Exception
+ {
+ DigestCalculatorProvider digestCalculatorProvider = new BcDigestCalculatorProvider();
+
+ DigestCalculator imprintCalculator = cmsTimeStampedData.getMessageImprintDigestCalculator(digestCalculatorProvider);
+
+ imprintCalculator.getOutputStream().write(cmsTimeStampedData.getContent());
+
+ cmsTimeStampedData.validate(digestCalculatorProvider, imprintCalculator.getDigest());
+ }
+
+}
diff --git a/pkix/src/test/java/org/spongycastle/tsp/test/NewTSPTest.java b/pkix/src/test/java/org/spongycastle/tsp/test/NewTSPTest.java
new file mode 100644
index 00000000..e40ae0fc
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/tsp/test/NewTSPTest.java
@@ -0,0 +1,833 @@
+package org.spongycastle.tsp.test;
+
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.Security;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.TestCase;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cmp.PKIFailureInfo;
+import org.spongycastle.asn1.cmp.PKIStatus;
+import org.spongycastle.asn1.cms.AttributeTable;
+import org.spongycastle.asn1.ess.ESSCertID;
+import org.spongycastle.asn1.ess.ESSCertIDv2;
+import org.spongycastle.asn1.ess.SigningCertificate;
+import org.spongycastle.asn1.ess.SigningCertificateV2;
+import org.spongycastle.asn1.pkcs.PKCSObjectIdentifiers;
+import org.spongycastle.asn1.x500.X500Name;
+import org.spongycastle.asn1.x509.GeneralName;
+import org.spongycastle.asn1.x509.GeneralNames;
+import org.spongycastle.asn1.x509.IssuerSerial;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cert.jcajce.JcaCertStore;
+import org.spongycastle.cms.CMSAttributeTableGenerationException;
+import org.spongycastle.cms.CMSAttributeTableGenerator;
+import org.spongycastle.cms.DefaultSignedAttributeTableGenerator;
+import org.spongycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
+import org.spongycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder;
+import org.spongycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.operator.DigestCalculator;
+import org.spongycastle.operator.jcajce.JcaContentSignerBuilder;
+import org.spongycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
+import org.spongycastle.tsp.GenTimeAccuracy;
+import org.spongycastle.tsp.TSPAlgorithms;
+import org.spongycastle.tsp.TSPException;
+import org.spongycastle.tsp.TSPValidationException;
+import org.spongycastle.tsp.TimeStampRequest;
+import org.spongycastle.tsp.TimeStampRequestGenerator;
+import org.spongycastle.tsp.TimeStampResponse;
+import org.spongycastle.tsp.TimeStampResponseGenerator;
+import org.spongycastle.tsp.TimeStampToken;
+import org.spongycastle.tsp.TimeStampTokenGenerator;
+import org.spongycastle.tsp.TimeStampTokenInfo;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.util.Store;
+
+public class NewTSPTest
+ extends TestCase
+{
+ private static final String BC = BouncyCastleProvider.PROVIDER_NAME;
+
+ public void setUp()
+ {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ public void testGeneral()
+ throws Exception
+ {
+ String signDN = "O=Bouncy Castle, C=AU";
+ KeyPair signKP = TSPTestUtil.makeKeyPair();
+ X509Certificate signCert = TSPTestUtil.makeCACertificate(signKP,
+ signDN, signKP, signDN);
+
+ String origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU";
+ KeyPair origKP = TSPTestUtil.makeKeyPair();
+ X509Certificate origCert = TSPTestUtil.makeCertificate(origKP,
+ origDN, signKP, signDN);
+
+
+
+ List certList = new ArrayList();
+ certList.add(origCert);
+ certList.add(signCert);
+
+ Store certs = new JcaCertStore(certList);
+
+ basicTest(origKP.getPrivate(), origCert, certs);
+ basicSha256Test(origKP.getPrivate(), origCert, certs);
+ basicTestWithTSA(origKP.getPrivate(), origCert, certs);
+ overrideAttrsTest(origKP.getPrivate(), origCert, certs);
+ responseValidationTest(origKP.getPrivate(), origCert, certs);
+ incorrectHashTest(origKP.getPrivate(), origCert, certs);
+ badAlgorithmTest(origKP.getPrivate(), origCert, certs);
+ timeNotAvailableTest(origKP.getPrivate(), origCert, certs);
+ badPolicyTest(origKP.getPrivate(), origCert, certs);
+ tokenEncodingTest(origKP.getPrivate(), origCert, certs);
+ certReqTest(origKP.getPrivate(), origCert, certs);
+ testAccuracyZeroCerts(origKP.getPrivate(), origCert, certs);
+ testAccuracyWithCertsAndOrdering(origKP.getPrivate(), origCert, certs);
+ testNoNonse(origKP.getPrivate(), origCert, certs);
+ }
+
+ private void basicTest(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(
+ new JcaSimpleSignerInfoGeneratorBuilder().build("SHA1withRSA", privateKey, cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2"));
+
+ tsTokenGen.addCertificates(certs);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+ TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100));
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+
+ TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date());
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampToken tsToken = tsResp.getTimeStampToken();
+
+ tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert));
+
+ AttributeTable table = tsToken.getSignedAttributes();
+
+ assertNotNull("no signingCertificate attribute found", table.get(PKCSObjectIdentifiers.id_aa_signingCertificate));
+ }
+
+ private void basicSha256Test(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(
+ new JcaSimpleSignerInfoGeneratorBuilder().build("SHA256withRSA", privateKey, cert), new SHA256DigestCalculator(), new ASN1ObjectIdentifier("1.2"));
+
+ tsTokenGen.addCertificates(certs);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+ TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA256, new byte[32], BigInteger.valueOf(100));
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+
+ TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date());
+
+ assertEquals(PKIStatus.GRANTED, tsResp.getStatus());
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampToken tsToken = tsResp.getTimeStampToken();
+
+ tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert));
+
+ AttributeTable table = tsToken.getSignedAttributes();
+
+ assertNotNull("no signingCertificate attribute found", table.get(PKCSObjectIdentifiers.id_aa_signingCertificateV2));
+
+ DigestCalculator digCalc = new SHA256DigestCalculator();
+
+ OutputStream dOut = digCalc.getOutputStream();
+
+ dOut.write(cert.getEncoded());
+
+ dOut.close();
+
+ byte[] certHash = digCalc.getDigest();
+
+ SigningCertificateV2 sigCertV2 = SigningCertificateV2.getInstance(table.get(PKCSObjectIdentifiers.id_aa_signingCertificateV2).getAttributeValues()[0]);
+
+ assertTrue(Arrays.areEqual(certHash, sigCertV2.getCerts()[0].getCertHash()));
+ }
+
+ private void overrideAttrsTest(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ JcaSimpleSignerInfoGeneratorBuilder signerInfoGenBuilder = new JcaSimpleSignerInfoGeneratorBuilder().setProvider("SC");
+
+ IssuerSerial issuerSerial = new IssuerSerial(new GeneralNames(new GeneralName(new X509CertificateHolder(cert.getEncoded()).getIssuer())), cert.getSerialNumber());
+
+ DigestCalculator digCalc = new SHA1DigestCalculator();
+
+ OutputStream dOut = digCalc.getOutputStream();
+
+ dOut.write(cert.getEncoded());
+
+ dOut.close();
+
+ byte[] certHash = digCalc.getDigest();
+
+ digCalc = new SHA256DigestCalculator();
+
+ dOut = digCalc.getOutputStream();
+
+ dOut.write(cert.getEncoded());
+
+ dOut.close();
+
+ byte[] certHash256 = digCalc.getDigest();
+
+ final ESSCertID essCertid = new ESSCertID(certHash, issuerSerial);
+ final ESSCertIDv2 essCertidV2 = new ESSCertIDv2(certHash256, issuerSerial);
+
+ signerInfoGenBuilder.setSignedAttributeGenerator(new CMSAttributeTableGenerator()
+ {
+ public AttributeTable getAttributes(Map parameters)
+ throws CMSAttributeTableGenerationException
+ {
+ CMSAttributeTableGenerator attrGen = new DefaultSignedAttributeTableGenerator();
+
+ AttributeTable table = attrGen.getAttributes(parameters);
+ table = table.add(PKCSObjectIdentifiers.id_aa_signingCertificate, new SigningCertificate(essCertid));
+ table = table.add(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new SigningCertificateV2(new ESSCertIDv2[]{essCertidV2}));
+
+ return table;
+ }
+ });
+
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(signerInfoGenBuilder.build("SHA1withRSA", privateKey, cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2"));
+
+ tsTokenGen.addCertificates(certs);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+ TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100));
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+
+ TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date());
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampToken tsToken = tsResp.getTimeStampToken();
+
+ tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert));
+
+ AttributeTable table = tsToken.getSignedAttributes();
+
+ assertNotNull("no signingCertificate attribute found", table.get(PKCSObjectIdentifiers.id_aa_signingCertificate));
+ assertNotNull("no signingCertificateV2 attribute found", table.get(PKCSObjectIdentifiers.id_aa_signingCertificateV2));
+
+ SigningCertificate sigCert = SigningCertificate.getInstance(table.get(PKCSObjectIdentifiers.id_aa_signingCertificate).getAttributeValues()[0]);
+
+ assertEquals(new X509CertificateHolder(cert.getEncoded()).getIssuer(), sigCert.getCerts()[0].getIssuerSerial().getIssuer().getNames()[0].getName());
+ assertEquals(cert.getSerialNumber(), sigCert.getCerts()[0].getIssuerSerial().getSerial().getValue());
+ assertTrue(Arrays.areEqual(certHash, sigCert.getCerts()[0].getCertHash()));
+
+ SigningCertificateV2 sigCertV2 = SigningCertificateV2.getInstance(table.get(PKCSObjectIdentifiers.id_aa_signingCertificateV2).getAttributeValues()[0]);
+
+ assertEquals(new X509CertificateHolder(cert.getEncoded()).getIssuer(), sigCertV2.getCerts()[0].getIssuerSerial().getIssuer().getNames()[0].getName());
+ assertEquals(cert.getSerialNumber(), sigCertV2.getCerts()[0].getIssuerSerial().getSerial().getValue());
+ assertTrue(Arrays.areEqual(certHash256, sigCertV2.getCerts()[0].getCertHash()));
+ }
+
+ private void basicTestWithTSA(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(
+ new JcaSimpleSignerInfoGeneratorBuilder().build("SHA1withRSA", privateKey, cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2"));
+
+ tsTokenGen.addCertificates(certs);
+ tsTokenGen.setTSA(new GeneralName(new X500Name("CN=Test")));
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+ TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100));
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+
+ TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date());
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampToken tsToken = tsResp.getTimeStampToken();
+
+ tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert));
+
+ AttributeTable table = tsToken.getSignedAttributes();
+
+ assertNotNull("no signingCertificate attribute found", table.get(PKCSObjectIdentifiers.id_aa_signingCertificate));
+ }
+
+ private void responseValidationTest(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build());
+
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(
+ infoGeneratorBuilder.build(new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2"));
+
+ tsTokenGen.addCertificates(certs);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+ TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100));
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+
+ TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date());
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampToken tsToken = tsResp.getTimeStampToken();
+
+ tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider("SC").build(cert));
+
+ //
+ // check validation
+ //
+ tsResp.validate(request);
+
+ try
+ {
+ request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(101));
+
+ tsResp.validate(request);
+
+ fail("response validation failed on invalid nonce.");
+ }
+ catch (TSPValidationException e)
+ {
+ // ignore
+ }
+
+ try
+ {
+ request = reqGen.generate(TSPAlgorithms.SHA1, new byte[22], BigInteger.valueOf(100));
+
+ tsResp.validate(request);
+
+ fail("response validation failed on wrong digest.");
+ }
+ catch (TSPValidationException e)
+ {
+ // ignore
+ }
+
+ try
+ {
+ request = reqGen.generate(TSPAlgorithms.MD5, new byte[20], BigInteger.valueOf(100));
+
+ tsResp.validate(request);
+
+ fail("response validation failed on wrong digest.");
+ }
+ catch (TSPValidationException e)
+ {
+ // ignore
+ }
+ }
+
+ private void incorrectHashTest(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build());
+
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2"));
+
+ tsTokenGen.addCertificates(certs);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+ TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[16]);
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+
+ TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date());
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampToken tsToken = tsResp.getTimeStampToken();
+
+ if (tsToken != null)
+ {
+ fail("incorrectHash - token not null.");
+ }
+
+ PKIFailureInfo failInfo = tsResp.getFailInfo();
+
+ if (failInfo == null)
+ {
+ fail("incorrectHash - failInfo set to null.");
+ }
+
+ if (failInfo.intValue() != PKIFailureInfo.badDataFormat)
+ {
+ fail("incorrectHash - wrong failure info returned.");
+ }
+ }
+
+ private void badAlgorithmTest(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ JcaSimpleSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC);
+
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build("SHA1withRSA", privateKey, cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2"));
+
+ tsTokenGen.addCertificates(certs);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+ TimeStampRequest request = reqGen.generate(new ASN1ObjectIdentifier("1.2.3.4.5"), new byte[20]);
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+
+ TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date());
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampToken tsToken = tsResp.getTimeStampToken();
+
+ if (tsToken != null)
+ {
+ fail("badAlgorithm - token not null.");
+ }
+
+ PKIFailureInfo failInfo = tsResp.getFailInfo();
+
+ if (failInfo == null)
+ {
+ fail("badAlgorithm - failInfo set to null.");
+ }
+
+ if (failInfo.intValue() != PKIFailureInfo.badAlg)
+ {
+ fail("badAlgorithm - wrong failure info returned.");
+ }
+ }
+
+ private void timeNotAvailableTest(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build());
+
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2"));
+
+ tsTokenGen.addCertificates(certs);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+ TimeStampRequest request = reqGen.generate(new ASN1ObjectIdentifier("1.2.3.4.5"), new byte[20]);
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+
+ TimeStampResponse tsResp;
+
+ try
+ {
+ tsResp = tsRespGen.generateGrantedResponse(request, new BigInteger("23"), null);
+ }
+ catch (TSPException e)
+ {
+ tsResp = tsRespGen.generateRejectedResponse(e);
+ }
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampToken tsToken = tsResp.getTimeStampToken();
+
+ if (tsToken != null)
+ {
+ fail("timeNotAvailable - token not null.");
+ }
+
+ PKIFailureInfo failInfo = tsResp.getFailInfo();
+
+ if (failInfo == null)
+ {
+ fail("timeNotAvailable - failInfo set to null.");
+ }
+
+ if (failInfo.intValue() != PKIFailureInfo.timeNotAvailable)
+ {
+ fail("timeNotAvailable - wrong failure info returned.");
+ }
+ }
+
+ private void badPolicyTest(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build());
+
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2"));
+
+ tsTokenGen.addCertificates(certs);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+
+ reqGen.setReqPolicy(new ASN1ObjectIdentifier("1.1"));
+
+ TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20]);
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED, new HashSet());
+
+ TimeStampResponse tsResp;
+
+ try
+ {
+ tsResp = tsRespGen.generateGrantedResponse(request, new BigInteger("23"), new Date());
+ }
+ catch (TSPException e)
+ {
+ tsResp = tsRespGen.generateRejectedResponse(e);
+ }
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampToken tsToken = tsResp.getTimeStampToken();
+
+ if (tsToken != null)
+ {
+ fail("badPolicy - token not null.");
+ }
+
+ PKIFailureInfo failInfo = tsResp.getFailInfo();
+
+ if (failInfo == null)
+ {
+ fail("badPolicy - failInfo set to null.");
+ }
+
+ if (failInfo.intValue() != PKIFailureInfo.unacceptedPolicy)
+ {
+ fail("badPolicy - wrong failure info returned.");
+ }
+ }
+
+ private void certReqTest(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build());
+
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2"));
+
+ tsTokenGen.addCertificates(certs);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+
+ //
+ // request with certReq false
+ //
+ reqGen.setCertReq(false);
+
+ TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100));
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+
+ TimeStampResponse tsResp = tsRespGen.generateGrantedResponse(request, new BigInteger("23"), new Date());
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampToken tsToken = tsResp.getTimeStampToken();
+
+ assertNull(tsToken.getTimeStampInfo().getGenTimeAccuracy()); // check for abscence of accuracy
+
+ assertEquals("1.2", tsToken.getTimeStampInfo().getPolicy().getId());
+
+ try
+ {
+ tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC).build(cert));
+ }
+ catch (TSPValidationException e)
+ {
+ fail("certReq(false) verification of token failed.");
+ }
+
+ Store respCerts = tsToken.getCertificates();
+
+ Collection certsColl = respCerts.getMatches(null);
+
+ if (!certsColl.isEmpty())
+ {
+ fail("certReq(false) found certificates in response.");
+ }
+ }
+
+
+ private void tokenEncodingTest(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build());
+
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("SHA1withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2.3.4.5.6"));
+
+ tsTokenGen.addCertificates(certs);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+ TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100));
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+ TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date());
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampResponse tsResponse = new TimeStampResponse(tsResp.getEncoded());
+
+ if (!Arrays.areEqual(tsResponse.getEncoded(), tsResp.getEncoded())
+ || !Arrays.areEqual(tsResponse.getTimeStampToken().getEncoded(),
+ tsResp.getTimeStampToken().getEncoded()))
+ {
+ fail();
+ }
+ }
+
+ private void testAccuracyZeroCerts(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build());
+
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2"));
+
+ tsTokenGen.addCertificates(certs);
+
+ tsTokenGen.setAccuracySeconds(1);
+ tsTokenGen.setAccuracyMillis(2);
+ tsTokenGen.setAccuracyMicros(3);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+ TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100));
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+
+ TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("23"), new Date());
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampToken tsToken = tsResp.getTimeStampToken();
+
+ tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider("SC").build(cert));
+
+ //
+ // check validation
+ //
+ tsResp.validate(request);
+
+ //
+ // check tstInfo
+ //
+ TimeStampTokenInfo tstInfo = tsToken.getTimeStampInfo();
+
+ //
+ // check accuracy
+ //
+ GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy();
+
+ assertEquals(1, accuracy.getSeconds());
+ assertEquals(2, accuracy.getMillis());
+ assertEquals(3, accuracy.getMicros());
+
+ assertEquals(new BigInteger("23"), tstInfo.getSerialNumber());
+
+ assertEquals("1.2", tstInfo.getPolicy().getId());
+
+ //
+ // test certReq
+ //
+ Store store = tsToken.getCertificates();
+
+ Collection certificates = store.getMatches(null);
+
+ assertEquals(0, certificates.size());
+ }
+
+ private void testAccuracyWithCertsAndOrdering(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build());
+
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2.3"));
+
+ tsTokenGen.addCertificates(certs);
+
+ tsTokenGen.setAccuracySeconds(3);
+ tsTokenGen.setAccuracyMillis(1);
+ tsTokenGen.setAccuracyMicros(2);
+
+ tsTokenGen.setOrdering(true);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+
+ reqGen.setCertReq(true);
+
+ TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100));
+
+ assertTrue(request.getCertReq());
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+
+ TimeStampResponse tsResp;
+
+ try
+ {
+ tsResp = tsRespGen.generateGrantedResponse(request, new BigInteger("23"), new Date());
+ }
+ catch (TSPException e)
+ {
+ tsResp = tsRespGen.generateRejectedResponse(e);
+ }
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampToken tsToken = tsResp.getTimeStampToken();
+
+ tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider("SC").build(cert));
+
+ //
+ // check validation
+ //
+ tsResp.validate(request);
+
+ //
+ // check tstInfo
+ //
+ TimeStampTokenInfo tstInfo = tsToken.getTimeStampInfo();
+
+ //
+ // check accuracy
+ //
+ GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy();
+
+ assertEquals(3, accuracy.getSeconds());
+ assertEquals(1, accuracy.getMillis());
+ assertEquals(2, accuracy.getMicros());
+
+ assertEquals(new BigInteger("23"), tstInfo.getSerialNumber());
+
+ assertEquals("1.2.3", tstInfo.getPolicy().getId());
+
+ assertEquals(true, tstInfo.isOrdered());
+
+ assertEquals(tstInfo.getNonce(), BigInteger.valueOf(100));
+
+ //
+ // test certReq
+ //
+ Store store = tsToken.getCertificates();
+
+ Collection certificates = store.getMatches(null);
+
+ assertEquals(2, certificates.size());
+ }
+
+ private void testNoNonse(
+ PrivateKey privateKey,
+ X509Certificate cert,
+ Store certs)
+ throws Exception
+ {
+ JcaSignerInfoGeneratorBuilder infoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider(BC).build());
+
+ TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(infoGeneratorBuilder.build(new JcaContentSignerBuilder("MD5withRSA").setProvider(BC).build(privateKey), cert), new SHA1DigestCalculator(), new ASN1ObjectIdentifier("1.2.3"));
+
+ tsTokenGen.addCertificates(certs);
+
+ TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
+ TimeStampRequest request = reqGen.generate(TSPAlgorithms.SHA1, new byte[20]);
+
+ assertFalse(request.getCertReq());
+
+ TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);
+
+ TimeStampResponse tsResp = tsRespGen.generate(request, new BigInteger("24"), new Date());
+
+ tsResp = new TimeStampResponse(tsResp.getEncoded());
+
+ TimeStampToken tsToken = tsResp.getTimeStampToken();
+
+ tsToken.validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider("SC").build(cert));
+
+ //
+ // check validation
+ //
+ tsResp.validate(request);
+
+ //
+ // check tstInfo
+ //
+ TimeStampTokenInfo tstInfo = tsToken.getTimeStampInfo();
+
+ //
+ // check accuracy
+ //
+ GenTimeAccuracy accuracy = tstInfo.getGenTimeAccuracy();
+
+ assertNull(accuracy);
+
+ assertEquals(new BigInteger("24"), tstInfo.getSerialNumber());
+
+ assertEquals("1.2.3", tstInfo.getPolicy().getId());
+
+ assertEquals(false, tstInfo.isOrdered());
+
+ assertNull(tstInfo.getNonce());
+
+ //
+ // test certReq
+ //
+ Store store = tsToken.getCertificates();
+
+ Collection certificates = store.getMatches(null);
+
+ assertEquals(0, certificates.size());
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/tsp/test/ParseTest.java b/pkix/src/test/java/org/spongycastle/tsp/test/ParseTest.java
new file mode 100644
index 00000000..4bc4c985
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/tsp/test/ParseTest.java
@@ -0,0 +1,417 @@
+package org.spongycastle.tsp.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.Security;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+import junit.framework.TestCase;
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.cmp.PKIFailureInfo;
+import org.spongycastle.asn1.cmp.PKIStatus;
+import org.spongycastle.cert.X509CertificateHolder;
+import org.spongycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
+import org.spongycastle.jce.provider.BouncyCastleProvider;
+import org.spongycastle.tsp.TSPAlgorithms;
+import org.spongycastle.tsp.TimeStampRequest;
+import org.spongycastle.tsp.TimeStampResponse;
+import org.spongycastle.util.Arrays;
+import org.spongycastle.util.Store;
+import org.spongycastle.util.encoders.Base64;
+
+/**
+ * Test Cases
+ */
+public class ParseTest
+ extends TestCase
+{
+ private byte[] sha1Request = Base64.decode(
+ "MDACAQEwITAJBgUrDgMCGgUABBT5UbEBmJssO3RxcQtOePxNvfoMpgIIC+Gv"
+ + "YW2mtZQ=");
+
+
+ private byte[] sha1noNonse = Base64.decode(
+ "MCYCAQEwITAJBgUrDgMCGgUABBT5UbEBmJssO3RxcQtOePxNvfoMpg==");
+
+ private byte[] md5Request = Base64.decode(
+ "MDoCAQEwIDAMBggqhkiG9w0CBQUABBDIl9FBCvjyx0+6EbHbUR6eBgkrBgEE"
+ + "AakHBQECCDQluayIxIzn");
+
+ private byte[] ripemd160Request = Base64.decode(
+ "MD8CAQEwITAJBgUrJAMCAQUABBSq03a/mk50Yd9lMF+BSqOp/RHGQQYJKwYB"
+ + "BAGpBwUBAgkA4SZs9NfqISMBAf8=");
+
+ private byte[] sha1Response = Base64.decode(
+ "MIICbDADAgEAMIICYwYJKoZIhvcNAQcCoIICVDCCAlACAQMxCzAJBgUrDgMC"
+ + "GgUAMIHaBgsqhkiG9w0BCRABBKCBygSBxzCBxAIBAQYEKgMEATAhMAkGBSsO"
+ + "AwIaBQAEFPlRsQGYmyw7dHFxC054/E29+gymAgEEGA8yMDA0MTIwOTA3NTIw"
+ + "NVowCgIBAYACAfSBAWQBAf8CCAvhr2FtprWUoGmkZzBlMRgwFgYDVQQDEw9F"
+ + "cmljIEguIEVjaGlkbmExJDAiBgkqhkiG9w0BCQEWFWVyaWNAYm91bmN5Y2Fz"
+ + "dGxlLm9yZzEWMBQGA1UEChMNQm91bmN5IENhc3RsZTELMAkGA1UEBhMCQVUx"
+ + "ggFfMIIBWwIBATAqMCUxFjAUBgNVBAoTDUJvdW5jeSBDYXN0bGUxCzAJBgNV"
+ + "BAYTAkFVAgECMAkGBSsOAwIaBQCggYwwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3"
+ + "DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0wNDEyMDkwNzUyMDVaMCMGCSqGSIb3"
+ + "DQEJBDEWBBTGR1cbm94tWbcpDWrH+bD8UYePsTArBgsqhkiG9w0BCRACDDEc"
+ + "MBowGDAWBBS37aLzFcheqeJ5cla0gjNWHGKbRzANBgkqhkiG9w0BAQEFAASB"
+ + "gBrc9CJ3xlcTQuWQXJUqPEn6f6vfJAINKsn22z8LIfS/2p/CTFU6+W/bz8j8"
+ + "j+8uWEJe8okTsI0FflljIsspqOPTB/RrnXteajbkuk/rLmz1B2g/qWBGAzPI"
+ + "D214raBc1a7Bpd76PkvSSdjqrEaaskd+7JJiPr9l9yeSoh1AIt0N");
+
+ private byte[] sha1noNonseResponse = Base64.decode(
+ "MIICYjADAgEAMIICWQYJKoZIhvcNAQcCoIICSjCCAkYCAQMxCzAJBgUrDgMC"
+ + "GgUAMIHQBgsqhkiG9w0BCRABBKCBwASBvTCBugIBAQYEKgMEATAhMAkGBSsO"
+ + "AwIaBQAEFPlRsQGYmyw7dHFxC054/E29+gymAgECGA8yMDA0MTIwOTA3MzQx"
+ + "MlowCgIBAYACAfSBAWQBAf+gaaRnMGUxGDAWBgNVBAMTD0VyaWMgSC4gRWNo"
+ + "aWRuYTEkMCIGCSqGSIb3DQEJARYVZXJpY0Bib3VuY3ljYXN0bGUub3JnMRYw"
+ + "FAYDVQQKEw1Cb3VuY3kgQ2FzdGxlMQswCQYDVQQGEwJBVTGCAV8wggFbAgEB"
+ + "MCowJTEWMBQGA1UEChMNQm91bmN5IENhc3RsZTELMAkGA1UEBhMCQVUCAQIw"
+ + "CQYFKw4DAhoFAKCBjDAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJ"
+ + "KoZIhvcNAQkFMQ8XDTA0MTIwOTA3MzQxMlowIwYJKoZIhvcNAQkEMRYEFMNA"
+ + "xlscHYiByHL9DIEh3FewIhgSMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFLft"
+ + "ovMVyF6p4nlyVrSCM1YcYptHMA0GCSqGSIb3DQEBAQUABIGAaj46Tarrg7V7"
+ + "z13bbetrGv+xy159eE8kmIW9nPegru3DuK/GmbMx9W3l0ydx0zdXRwYi6NZc"
+ + "nNqbEZQZ2L1biJVTflgWq4Nxu4gPGjH/BGHKdH/LyW4eDcXZR39AkNBMnDAK"
+ + "EmhhJo1/Tc+S/WkV9lnHJCPIn+TAijBUO6EiTik=");
+
+ private byte[] md5Response = Base64.decode(
+ "MIICcDADAgEAMIICZwYJKoZIhvcNAQcCoIICWDCCAlQCAQMxCzAJBgUrDgMC"
+ + "GgUAMIHeBgsqhkiG9w0BCRABBKCBzgSByzCByAIBAQYJKwYBBAGpBwUBMCAw"
+ + "DAYIKoZIhvcNAgUFAAQQyJfRQQr48sdPuhGx21EengIBAxgPMjAwNDEyMDkw"
+ + "NzQ2MTZaMAoCAQGAAgH0gQFkAQH/Agg0JbmsiMSM56BppGcwZTEYMBYGA1UE"
+ + "AxMPRXJpYyBILiBFY2hpZG5hMSQwIgYJKoZIhvcNAQkBFhVlcmljQGJvdW5j"
+ + "eWNhc3RsZS5vcmcxFjAUBgNVBAoTDUJvdW5jeSBDYXN0bGUxCzAJBgNVBAYT"
+ + "AkFVMYIBXzCCAVsCAQEwKjAlMRYwFAYDVQQKEw1Cb3VuY3kgQ2FzdGxlMQsw"
+ + "CQYDVQQGEwJBVQIBAjAJBgUrDgMCGgUAoIGMMBoGCSqGSIb3DQEJAzENBgsq"
+ + "hkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcNMDQxMjA5MDc0NjE2WjAjBgkq"
+ + "hkiG9w0BCQQxFgQUFpRpaiRUUjiY7EbefbWLKDIY0XMwKwYLKoZIhvcNAQkQ"
+ + "AgwxHDAaMBgwFgQUt+2i8xXIXqnieXJWtIIzVhxim0cwDQYJKoZIhvcNAQEB"
+ + "BQAEgYBTwKsLLrQm+bvKV7Jwto/cMQh0KsVB5RoEeGn5CI9XyF2Bm+JRcvQL"
+ + "Nm7SgSOBVt4A90TqujxirNeyQnXRiSnFvXd09Wet9WIQNpwpiGlE7lCrAhuq"
+ + "/TAUe79VIpoQZDtyhbh0Vzxl24yRoechabC0zuPpOWOzrA4YC3Hv1J2tAA==");
+
+ private byte[] signingCert = Base64.decode(
+ "MIICWjCCAcOgAwIBAgIBAjANBgkqhkiG9w0BAQQFADAlMRYwFAYDVQQKEw1Cb3Vu"
+ + "Y3kgQ2FzdGxlMQswCQYDVQQGEwJBVTAeFw0wNDEyMDkwNzEzMTRaFw0wNTAzMTkw"
+ + "NzEzMTRaMGUxGDAWBgNVBAMTD0VyaWMgSC4gRWNoaWRuYTEkMCIGCSqGSIb3DQEJ"
+ + "ARYVZXJpY0Bib3VuY3ljYXN0bGUub3JnMRYwFAYDVQQKEw1Cb3VuY3kgQ2FzdGxl"
+ + "MQswCQYDVQQGEwJBVTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqGAFO3dK"
+ + "jB7Ca7u5Z3CabsbGr2Exg+3sztSPiRCIba03es4295EhtDF5bXQvrW2R1Bg72vED"
+ + "5tWaQjVDetvDfCzVC3ErHLTVk3OgpLIP1gf2T0LcOH2pTh2LP9c5Ceta+uggK8zK"
+ + "9sYUUnzGPSAZxrqHIIAlPIgqk0BMV+KApyECAwEAAaNaMFgwHQYDVR0OBBYEFO4F"
+ + "YoqogtB9MjD0NB5x5HN3TrGUMB8GA1UdIwQYMBaAFPXAecuwLqNkCxYVLE/ngFQR"
+ + "7RLIMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMA0GCSqGSIb3DQEBBAUAA4GBADGi"
+ + "D5/qmGvcBgswEM/z2dF4lOxbTNKUW31ZHiU8CXlN0IkFtNbBLBTbJOQIAUnNEabL"
+ + "T7aYgj813OZKUbJTx4MuGChhot/TEP7hKo/xz9OnXLsqYDKbqbo8iLOode+SI7II"
+ + "+yYghOtqvx32cL2Qmffi1LaMbhJP+8NbsIxowdRC");
+
+ private byte[] unacceptablePolicy = Base64.decode(
+ "MDAwLgIBAjAkDCJSZXF1ZXN0ZWQgcG9saWN5IGlzIG5vdCBzdXBwb3J0ZWQu"
+ + "AwMAAAE=");
+
+ private byte[] generalizedTime = Base64.decode(
+ "MIIKPTADAgEAMIIKNAYJKoZIhvcNAQcCoIIKJTCCCiECAQMxCzAJBgUrDgMC"
+ + "GgUAMIIBGwYLKoZIhvcNAQkQAQSgggEKBIIBBjCCAQICAQEGCisGAQQBhFkK"
+ + "AwEwITAJBgUrDgMCGgUABBQAAAAAAAAAAAAAAAAAAAAAAAAAAAICUC8YEzIw"
+ + "MDUwMzEwMTA1ODQzLjkzM1owBIACAfQBAf8CAWSggaikgaUwgaIxCzAJBgNV"
+ + "BAYTAkdCMRcwFQYDVQQIEw5DYW1icmlkZ2VzaGlyZTESMBAGA1UEBxMJQ2Ft"
+ + "YnJpZGdlMSQwIgYDVQQKExtuQ2lwaGVyIENvcnBvcmF0aW9uIExpbWl0ZWQx"
+ + "JzAlBgNVBAsTHm5DaXBoZXIgRFNFIEVTTjozMjJBLUI1REQtNzI1QjEXMBUG"
+ + "A1UEAxMOZGVtby1kc2UyMDAtMDGgggaFMIID2TCCA0KgAwIBAgICAIswDQYJ"
+ + "KoZIhvcNAQEFBQAwgYwxCzAJBgNVBAYTAkdCMRcwFQYDVQQIEw5DYW1icmlk"
+ + "Z2VzaGlyZTESMBAGA1UEBxMJQ2FtYnJpZGdlMSQwIgYDVQQKExtuQ2lwaGVy"
+ + "IENvcnBvcmF0aW9uIExpbWl0ZWQxGDAWBgNVBAsTD1Byb2R1Y3Rpb24gVEVT"
+ + "VDEQMA4GA1UEAxMHVEVTVCBDQTAeFw0wNDA2MTQxNDIzNTlaFw0wNTA2MTQx"
+ + "NDIzNTlaMIGiMQswCQYDVQQGEwJHQjEXMBUGA1UECBMOQ2FtYnJpZGdlc2hp"
+ + "cmUxEjAQBgNVBAcTCUNhbWJyaWRnZTEkMCIGA1UEChMbbkNpcGhlciBDb3Jw"
+ + "b3JhdGlvbiBMaW1pdGVkMScwJQYDVQQLEx5uQ2lwaGVyIERTRSBFU046MzIy"
+ + "QS1CNURELTcyNUIxFzAVBgNVBAMTDmRlbW8tZHNlMjAwLTAxMIGfMA0GCSqG"
+ + "SIb3DQEBAQUAA4GNADCBiQKBgQC7zUamCeLIApddx1etW5YEFrL1WXnlCd7j"
+ + "mMFI6RpSq056LBkF1z5LgucLY+e/c3u2Nw+XJuS3a2fKuBD7I1s/6IkVtIb/"
+ + "KLDjjafOnottKhprH8K41siJUeuK3PRzfZ5kF0vwB3rNvWPCBJmp7kHtUQw3"
+ + "RhIsJTYs7Wy8oVFHVwIDAQABo4IBMDCCASwwCQYDVR0TBAIwADAWBgNVHSUB"
+ + "Af8EDDAKBggrBgEFBQcDCDAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5l"
+ + "cmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFDlEe9Pd0WwQrtnEmFRI2Vmt"
+ + "b+lCMIG5BgNVHSMEgbEwga6AFNy1VPweOQLC65bs6/0RcUYB19vJoYGSpIGP"
+ + "MIGMMQswCQYDVQQGEwJHQjEXMBUGA1UECBMOQ2FtYnJpZGdlc2hpcmUxEjAQ"
+ + "BgNVBAcTCUNhbWJyaWRnZTEkMCIGA1UEChMbbkNpcGhlciBDb3Jwb3JhdGlv"
+ + "biBMaW1pdGVkMRgwFgYDVQQLEw9Qcm9kdWN0aW9uIFRFU1QxEDAOBgNVBAMT"
+ + "B1RFU1QgQ0GCAQAwDQYJKoZIhvcNAQEFBQADgYEASEMlrpRE1RYZPxP3530e"
+ + "hOYUDjgQbw0dwpPjQtLWkeJrePMzDBAbuWwpRI8dOzKP3Rnrm5rxJ7oLY2S0"
+ + "A9ZfV+iwFKagEHFytfnPm2Y9AeNR7a3ladKd7NFMw+5Tbk7Asbetbb+NJfCl"
+ + "9YzHwxLGiQbpKxgc+zYOjq74eGLKtcKhggKkMIICDQIBATCB0qGBqKSBpTCB"
+ + "ojELMAkGA1UEBhMCR0IxFzAVBgNVBAgTDkNhbWJyaWRnZXNoaXJlMRIwEAYD"
+ + "VQQHEwlDYW1icmlkZ2UxJDAiBgNVBAoTG25DaXBoZXIgQ29ycG9yYXRpb24g"
+ + "TGltaXRlZDEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOjMyMkEtQjVERC03"
+ + "MjVCMRcwFQYDVQQDEw5kZW1vLWRzZTIwMC0wMaIlCgEBMAkGBSsOAwIaBQAD"
+ + "FQDaLe88TQvM+iMKmIXMmDSyPCZ/+KBmMGSkYjBgMQswCQYDVQQGEwJVUzEk"
+ + "MCIGA1UEChMbbkNpcGhlciBDb3Jwb3JhdGlvbiBMaW1pdGVkMRgwFgYDVQQL"
+ + "Ew9Qcm9kdWN0aW9uIFRlc3QxETAPBgNVBAMTCFRlc3QgVE1DMA0GCSqGSIb3"
+ + "DQEBBQUAAgjF2jVbAAAAADAiGA8yMDA1MDMxMDAyNTQxOVoYDzIwMDUwMzEz"
+ + "MDI1NDE5WjCBjTBLBgorBgEEAYRZCgQBMT0wOzAMAgTF2jVbAgQAAAAAMA8C"
+ + "BAAAAAACBAAAaLkCAf8wDAIEAAAAAAIEAAKV/DAMAgTF3inbAgQAAAAAMD4G"
+ + "CisGAQQBhFkKBAIxMDAuMAwGCisGAQQBhFkKAwGgDjAMAgQAAAAAAgQAB6Eg"
+ + "oQ4wDAIEAAAAAAIEAAPQkDANBgkqhkiG9w0BAQUFAAOBgQB1q4d3GNWk7oAT"
+ + "WkpYmZaTFvapMhTwAmAtSGgFmNOZhs21iHWl/X990/HEBsduwxohfrd8Pz64"
+ + "hV/a76rpeJCVUfUNmbRIrsurFx6uKwe2HUHKW8grZWeCD1L8Y1pKQdrD41gu"
+ + "v0msfOXzLWW+xe5BcJguKclN8HmT7s2odtgiMTGCAmUwggJhAgEBMIGTMIGM"
+ + "MQswCQYDVQQGEwJHQjEXMBUGA1UECBMOQ2FtYnJpZGdlc2hpcmUxEjAQBgNV"
+ + "BAcTCUNhbWJyaWRnZTEkMCIGA1UEChMbbkNpcGhlciBDb3Jwb3JhdGlvbiBM"
+ + "aW1pdGVkMRgwFgYDVQQLEw9Qcm9kdWN0aW9uIFRFU1QxEDAOBgNVBAMTB1RF"
+ + "U1QgQ0ECAgCLMAkGBSsOAwIaBQCgggEnMBoGCSqGSIb3DQEJAzENBgsqhkiG"
+ + "9w0BCRABBDAjBgkqhkiG9w0BCQQxFgQUi1iYx5H3ACnvngWZTPfdxGswkSkw"
+ + "geMGCyqGSIb3DQEJEAIMMYHTMIHQMIHNMIGyBBTaLe88TQvM+iMKmIXMmDSy"
+ + "PCZ/+DCBmTCBkqSBjzCBjDELMAkGA1UEBhMCR0IxFzAVBgNVBAgTDkNhbWJy"
+ + "aWRnZXNoaXJlMRIwEAYDVQQHEwlDYW1icmlkZ2UxJDAiBgNVBAoTG25DaXBo"
+ + "ZXIgQ29ycG9yYXRpb24gTGltaXRlZDEYMBYGA1UECxMPUHJvZHVjdGlvbiBU"
+ + "RVNUMRAwDgYDVQQDEwdURVNUIENBAgIAizAWBBSpS/lH6bN/wf3E2z2X29vF"
+ + "2U7YHTANBgkqhkiG9w0BAQUFAASBgGvDVsgsG5I5WKjEDVHvdRwUx+8Cp10l"
+ + "zGF8o1h7aK5O3zQ4jLayYHea54E5+df35gG7Z3eoOy8E350J7BvHiwDLTqe8"
+ + "SoRlGs9VhL6LMmCcERfGSlSn61Aa15iXZ8eHMSc5JTeJl+kqy4I3FPP4m2ai"
+ + "8wy2fQhn7hUM8Ntg7Y2s");
+
+ private byte[] v2SigningCertResponse = Base64.decode(
+ "MIIPPTADAgEAMIIPNAYJKoZIhvcNAQcCoIIPJTCCDyECAQMxDzANBglghkgBZQMEAgEFADCB6QYL"
+ + "KoZIhvcNAQkQAQSggdkEgdYwgdMCAQEGBgQAj2cBATAxMA0GCWCGSAFlAwQCAQUABCBcU0GN08TA"
+ + "LUFi7AAwQwVkSXqGu9tAzvJ7EXW7SMXHHQIRAM7Fa7g6tMvZI3dgllwMfpcYDzIwMDcxMjExMTAy"
+ + "MTU5WjADAgEBAgYBFsi5OlmgYqRgMF4xCzAJBgNVBAYTAkRFMSQwIgYDVQQKDBtEZXV0c2NoZSBS"
+ + "ZW50ZW52ZXJzaWNoZXJ1bmcxEzARBgNVBAsMClFDIFJvb3QgQ0ExFDASBgNVBAMMC1FDIFJvb3Qg"
+ + "VFNQoIILQjCCBwkwggXxoAMCAQICAwN1pjANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJERTEk"
+ + "MCIGA1UECgwbRGV1dHNjaGUgUmVudGVudmVyc2ljaGVydW5nMRMwEQYDVQQLDApRQyBSb290IENB"
+ + "MB4XDTA3MTEyMDE2MDcyMFoXDTEyMDcyNzIwMjExMVowXjELMAkGA1UEBhMCREUxJDAiBgNVBAoM"
+ + "G0RldXRzY2hlIFJlbnRlbnZlcnNpY2hlcnVuZzETMBEGA1UECwwKUUMgUm9vdCBDQTEUMBIGA1UE"
+ + "AwwLUUMgUm9vdCBUU1AwggEkMA0GCSqGSIb3DQEBAQUAA4IBEQAwggEMAoIBAQCv1vO+EtGnJNs0"
+ + "atv76BAJXs4bmO8yzVwe3RUtgeu5z9iefh8P46i1g3EL2CD15NcTfoHksr5KudNY30olfjHG7lIu"
+ + "MO3R5sAcrGDPP7riZJnaI6VD/e6kVR569VBid5z105fJAB7mID7+Bn7pdRwDW3Fy2CzfofXGuvrO"
+ + "GPNEWq8x8kqqf75DB5nAs5QP8H41obkdkap2ttHkkPZCiMghTs8iHfpJ0STn47MKq+QrUmuATMZi"
+ + "XrdEfb7f3TBMjO0UVJF64Mh+kC9GtUEHlcm0Tq2Pk5XIUxWEyL94rZ4UWcVdSVE7IjggV2MifMNx"
+ + "geZO3SwsDZk71AhDBy30CSzBAgUAx3HB5aOCA+IwggPeMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMI"
+ + "MBMGA1UdIwQMMAqACECefuBmflfeMBgGCCsGAQUFBwEDBAwwCjAIBgYEAI5GAQEwUAYIKwYBBQUH"
+ + "AQEERDBCMEAGCCsGAQUFBzABhjRodHRwOi8vb2NzcC1yb290cWMudGMuZGV1dHNjaGUtcmVudGVu"
+ + "dmVyc2ljaGVydW5nLmRlMHcGA1UdIARwMG4wbAYNKwYBBAGBrTwBCAEBAzBbMFkGCCsGAQUFBwIB"
+ + "Fk1odHRwOi8vd3d3LmRldXRzY2hlLXJlbnRlbnZlcnNpY2hlcnVuZy1idW5kLmRlL3N0YXRpYy90"
+ + "cnVzdGNlbnRlci9wb2xpY3kuaHRtbDCCATwGA1UdHwSCATMwggEvMHygeqB4hnZsZGFwOi8vZGly"
+ + "LnRjLmRldXRzY2hlLXJlbnRlbnZlcnNpY2hlcnVuZy5kZS9vdT1RQyUyMFJvb3QlMjBDQSxjbj1Q"
+ + "dWJsaWMsbz1EUlYsYz1ERT9hdHRybmFtZT1jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0MIGuoIGr"
+ + "oIGohoGlaHR0cDovL2Rpci50Yy5kZXV0c2NoZS1yZW50ZW52ZXJzaWNoZXJ1bmcuZGU6ODA4OS9z"
+ + "ZXJ2bGV0L0Rpclh3ZWIvQ2EveC5jcmw/ZG49b3UlM0RRQyUyMFJvb3QlMjBDQSUyQ2NuJTNEUHVi"
+ + "bGljJTJDbyUzRERSViUyQ2MlM0RERSZhdHRybmFtZT1jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0"
+ + "MIIBLQYDVR0SBIIBJDCCASCGdGxkYXA6Ly9kaXIudGMuZGV1dHNjaGUtcmVudGVudmVyc2ljaGVy"
+ + "dW5nLmRlL2NuPTE0NTUxOCxvdT1RQyUyMFJvb3QlMjBDQSxjbj1QdWJsaWMsbz1EUlYsYz1ERT9h"
+ + "dHRybmFtZT1jQUNlcnRpZmljYXRlhoGnaHR0cDovL2Rpci50Yy5kZXV0c2NoZS1yZW50ZW52ZXJz"
+ + "aWNoZXJ1bmcuZGU6ODA4OS9zZXJ2bGV0L0Rpclh3ZWIvQ2EveC5jZXI/ZG49Y24lM0QxNDU1MTgl"
+ + "MkNvdSUzRFFDJTIwUm9vdCUyMENBJTJDY24lM0RQdWJsaWMlMkNvJTNERFJWJTJDYyUzRERFJmF0"
+ + "dHJuYW1lPWNBQ2VydGlmaWNhdGUwDgYDVR0PAQH/BAQDAgZAMDsGA1UdCQQ0MDIwMAYDVQQDMSkT"
+ + "J1FDIFRTUCBEZXV0c2NoZSBSZW50ZW52ZXJzaWNoZXJ1bmcgMTpQTjAMBgNVHRMBAf8EAjAAMA0G"
+ + "CSqGSIb3DQEBCwUAA4IBAQCCrWe3Pd3ioX7d8phXvVAa859Rvgf0k3pZ6R4GMj8h/k6MNjNIrdAs"
+ + "wgUVkBbXMLLBk0smsvTdFIVtTBdp1urb9l7vXjDA4MckXBOXPcz4fN8Oswk92d+fM9XU1jKVPsFG"
+ + "PV6j8lAqfq5jwaRxOnS96UBGLKG+NdcrEyiMp/ZkpqnEQZZfu2mkeq6CPahnbBTZqsE0jgY351gU"
+ + "9T6SFVvLIFH7cOxJqsoxPqv5YEcgiXPpOyyu2rpQqKYBYcnerF6/zx5hmWHxTd7MWaTHm0gJI/Im"
+ + "d8esbW+xyaJuAVUcBA+sDmSe8AAoRVxwBRY+xi9ApaJHpmwT+0n2K2GsL3wIMIIEMTCCAxmgAwIB"
+ + "AgIDAjhuMA0GCSqGSIb3DQEBCwUAMEgxCzAJBgNVBAYTAkRFMSQwIgYDVQQKDBtEZXV0c2NoZSBS"
+ + "ZW50ZW52ZXJzaWNoZXJ1bmcxEzARBgNVBAsMClFDIFJvb3QgQ0EwHhcNMDcwNzI3MjAyMTExWhcN"
+ + "MTIwNzI3MjAyMTExWjBIMQswCQYDVQQGEwJERTEkMCIGA1UECgwbRGV1dHNjaGUgUmVudGVudmVy"
+ + "c2ljaGVydW5nMRMwEQYDVQQLDApRQyBSb290IENBMIIBJDANBgkqhkiG9w0BAQEFAAOCAREAMIIB"
+ + "DAKCAQEAzuhBdo9c84DdzsggjWOgfC4jJ2jYqpsOpBo3DVyem+5R26QK4feZdyFnaGvyG+TLcdLO"
+ + "iCecGmrRGD+ey4IhjCONb7hsQQhJWTyDEtBblzYB0yjY8+9fnNeR61W+M/KlMgC6Rw/w+zwzklTM"
+ + "MWwIbxLHm8l9jTSKFjAWTwjE8bCzpUCwN8+4JbFTwjwOJ5lsVA5Xa34wpgr6lgL3WrVTV1NSprqR"
+ + "ZYDWg477tht0KkyOJt3guF3RONKBBuTO2qCbpUeI8m4v3tznoopYbV5Gp5wu5gqd6lTfgju3ldql"
+ + "bxtuCLZd0nAI5rLEOPItDKl4vPXllmmtGIrtDZlwr86cbwIFAJvMJpGjggEgMIIBHDAPBgNVHRMB"
+ + "Af8EBTADAQH/MBEGA1UdDgQKBAhAnn7gZn5X3jB3BgNVHSAEcDBuMGwGDSsGAQQBga08AQgBAQEw"
+ + "WzBZBggrBgEFBQcCARZNaHR0cDovL3d3dy5kZXV0c2NoZS1yZW50ZW52ZXJzaWNoZXJ1bmctYnVu"
+ + "ZC5kZS9zdGF0aWMvdHJ1c3RjZW50ZXIvcG9saWN5Lmh0bWwwUwYDVR0JBEwwSjBIBgNVBAMxQRM/"
+ + "UUMgV3VyemVsemVydGlmaXppZXJ1bmdzc3RlbGxlIERldXRzY2hlIFJlbnRlbnZlcnNpY2hlcnVu"
+ + "ZyAxOlBOMBgGCCsGAQUFBwEDBAwwCjAIBgYEAI5GAQEwDgYDVR0PAQH/BAQDAgIEMA0GCSqGSIb3"
+ + "DQEBCwUAA4IBAQBNGs7Dnc1yzzpZrkuC+oLv+NhbORTEYNgpaOetB1JQ1EbUBoPuNN4ih0ngy/uJ"
+ + "D2O+h4JsNkmELgaehLWyFwATqCYZY4cTAGVoEwgn93x3aW8JbMDQf+YEJDSDsXcm4oIDFPqv5M6o"
+ + "HZUWfsPka3mxKivfKtWhooTz1/+BEGReVQ2oOAvlwXlkEab9e3GOqXQUcLPYDTl8BQxiYhtQtf3d"
+ + "kORiUkuGiGX1YJ5JnZnG3ElMjPgOl8rOiYU7oj9uv1HVb5sdAwuVw0BR/eiMVDBT8DNyfoJmPeQQ"
+ + "A9pXtoAYO0Ya7wNNmCY2Y63YfBlRCF+9VQv2RZ4TdO1KGWwxR98OMYIC1zCCAtMCAQEwTzBIMQsw"
+ + "CQYDVQQGEwJERTEkMCIGA1UECgwbRGV1dHNjaGUgUmVudGVudmVyc2ljaGVydW5nMRMwEQYDVQQL"
+ + "DApRQyBSb290IENBAgMDdaYwDQYJYIZIAWUDBAIBBQCgggFZMBoGCSqGSIb3DQEJAzENBgsqhkiG"
+ + "9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgO7FFODWWwF5RUjo6wjIkgkD5u7dH+NICiCpSgRRqd/Aw"
+ + "ggEIBgsqhkiG9w0BCRACLzGB+DCB9TCB8jB3BCAMMZqK/5pZxOb3ruCbcgxStaTDwDHaf2glEo6P"
+ + "+89t8TBTMEykSjBIMQswCQYDVQQGEwJERTEkMCIGA1UECgwbRGV1dHNjaGUgUmVudGVudmVyc2lj"
+ + "aGVydW5nMRMwEQYDVQQLDApRQyBSb290IENBAgMDdaYwdwQgl7vwI+P47kpxhWLoIdEco7UfGwZ2"
+ + "X4el3jaZ67q5/9IwUzBMpEowSDELMAkGA1UEBhMCREUxJDAiBgNVBAoMG0RldXRzY2hlIFJlbnRl"
+ + "bnZlcnNpY2hlcnVuZzETMBEGA1UECwwKUUMgUm9vdCBDQQIDAjhuMA0GCSqGSIb3DQEBCwUABIIB"
+ + "AIOYgpDI0BaeG4RF/EB5QzkUqAZ9nX6w895+m2hHyRKrAKdj3913j5QI+aEVIG3DVbFaAfdKeKfn"
+ + "xsTW48aWs6aARtPAc+1OXwoGUSYElOFqqVpSeTaXe+kjY5bsLSQeETB+EPvXl8EcKTaxTRCNOqJU"
+ + "XbnyYRgWTI55A2jH6IsQQVHc5DaIcmbdI8iATaRTHY5eUeVuI+Q/3RMVBFAb5qRhM61Ddcrjq058"
+ + "C0uiH9G2IB5QRyu6RsCUgrkeMTMBqlIBlnDBy+EgLouDU4Dehxy5uzEl5DBKZEewZpQZOTO/kAgL"
+ + "WruAAg/Lj4r0f9vN12wRlHoS2UKDjrE1DnUBbrM=");
+
+ /* (non-Javadoc)
+ * @see org.spongycastle.util.test.Test#getName()
+ */
+ public String getName()
+ {
+ return "ParseTest";
+ }
+
+ private void requestParse(
+ byte[] request,
+ ASN1ObjectIdentifier algorithm)
+ throws IOException
+ {
+ TimeStampRequest req = new TimeStampRequest(request);
+
+ if (!req.getMessageImprintAlgOID().equals(algorithm))
+ {
+ fail("failed to get expected algorithm - got "
+ + req.getMessageImprintAlgOID() + " not " + algorithm);
+ }
+
+ if (request != sha1Request && request != sha1noNonse)
+ {
+ if (!req.getReqPolicy().equals(TSPTestUtil.EuroPKI_TSA_Test_Policy))
+ {
+ fail("" + algorithm + " failed policy check.");
+ }
+
+ if (request == ripemd160Request)
+ {
+ if (!req.getCertReq())
+ {
+ fail("" + algorithm + " failed certReq check.");
+ }
+ }
+ }
+
+ assertEquals("version not 1", 1, req.getVersion());
+
+ assertEquals("critical extensions found when none expected", 0, req.getCriticalExtensionOIDs().size());
+
+ assertEquals("non-critical extensions found when none expected", 0, req.getNonCriticalExtensionOIDs().size());
+
+ if (request != sha1noNonse)
+ {
+ if (req.getNonce() == null)
+ {
+ fail("" + algorithm + " nonse not found when one expected.");
+ }
+ }
+ else
+ {
+ if (req.getNonce() != null)
+ {
+ fail("" + algorithm + " nonse not found when one not expected.");
+ }
+ }
+
+ try
+ {
+ req.validate(TSPAlgorithms.ALLOWED, null, null);
+ }
+ catch (Exception e)
+ {
+ fail("validation exception.");
+ }
+
+ if (!Arrays.areEqual(req.getEncoded(), request))
+ {
+ fail("" + algorithm + " failed encode check.");
+ }
+ }
+
+ private void responseParse(
+ byte[] request,
+ byte[] response,
+ ASN1ObjectIdentifier algorithm)
+ throws Exception
+ {
+ TimeStampRequest req = new TimeStampRequest(request);
+ TimeStampResponse resp = new TimeStampResponse(response);
+
+ CertificateFactory fact = CertificateFactory.getInstance("X.509", "SC");
+
+ X509Certificate cert = (X509Certificate)fact.generateCertificate(new ByteArrayInputStream(signingCert));
+
+ resp.validate(req);
+
+ resp.getTimeStampToken().validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider("SC").build(cert));
+ }
+
+ private void unacceptableResponseParse(
+ byte[] response)
+ throws Exception
+ {
+ TimeStampResponse resp = new TimeStampResponse(response);
+
+ if (resp.getStatus() != PKIStatus.REJECTION)
+ {
+ fail("request not rejected.");
+ }
+
+ if (resp.getFailInfo().intValue() != PKIFailureInfo.unacceptedPolicy)
+ {
+ fail("request not rejected.");
+ }
+ }
+
+ private void generalizedTimeParse(
+ byte[] response)
+ throws Exception
+ {
+ TimeStampResponse resp = new TimeStampResponse(response);
+
+ if (resp.getStatus() != PKIStatus.GRANTED)
+ {
+ fail("request not rejected.");
+ }
+ }
+
+ public void setUp()
+ {
+ Security.addProvider(new BouncyCastleProvider());
+ }
+
+ public void testParsing()
+ throws Exception
+ {
+ requestParse(sha1Request, TSPAlgorithms.SHA1);
+
+ requestParse(sha1noNonse, TSPAlgorithms.SHA1);
+
+ requestParse(md5Request, TSPAlgorithms.MD5);
+
+ requestParse(ripemd160Request, TSPAlgorithms.RIPEMD160);
+
+ responseParse(sha1Request, sha1Response, TSPAlgorithms.SHA1);
+
+ responseParse(sha1noNonse, sha1noNonseResponse, TSPAlgorithms.SHA1);
+
+ responseParse(md5Request, md5Response, TSPAlgorithms.MD5);
+
+ unacceptableResponseParse(unacceptablePolicy);
+
+ generalizedTimeParse(generalizedTime);
+
+ v2SigningResponseParse(v2SigningCertResponse);
+ }
+
+ private void v2SigningResponseParse(
+ byte[] encoded)
+ throws Exception
+ {
+ TimeStampResponse response = new TimeStampResponse(encoded);
+
+ Store store = response.getTimeStampToken().getCertificates();
+ X509CertificateHolder cert = (X509CertificateHolder)store.getMatches(response.getTimeStampToken().getSID()).iterator().next();
+
+ response.getTimeStampToken().validate(new JcaSimpleSignerInfoVerifierBuilder().setProvider("SC").build(cert));
+ }
+
+ public void parse(
+ byte[] encoded,
+ boolean tokenPresent)
+ throws Exception
+ {
+ TimeStampResponse response = new TimeStampResponse(encoded);
+
+ if (tokenPresent && response.getTimeStampToken() == null)
+ {
+ fail("token not found when expected.");
+ }
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/tsp/test/SHA1DigestCalculator.java b/pkix/src/test/java/org/spongycastle/tsp/test/SHA1DigestCalculator.java
new file mode 100644
index 00000000..9d53e933
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/tsp/test/SHA1DigestCalculator.java
@@ -0,0 +1,44 @@
+package org.spongycastle.tsp.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.oiw.OIWObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.digests.SHA1Digest;
+import org.spongycastle.operator.DigestCalculator;
+
+
+class SHA1DigestCalculator
+ implements DigestCalculator
+{
+ private ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1);
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return bOut;
+ }
+
+ public byte[] getDigest()
+ {
+ byte[] bytes = bOut.toByteArray();
+
+ bOut.reset();
+
+ Digest sha1 = new SHA1Digest();
+
+ sha1.update(bytes, 0, bytes.length);
+
+ byte[] digest = new byte[sha1.getDigestSize()];
+
+ sha1.doFinal(digest, 0);
+
+ return digest;
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/tsp/test/SHA256DigestCalculator.java b/pkix/src/test/java/org/spongycastle/tsp/test/SHA256DigestCalculator.java
new file mode 100644
index 00000000..ee5fc3d9
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/tsp/test/SHA256DigestCalculator.java
@@ -0,0 +1,44 @@
+package org.spongycastle.tsp.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+
+import org.spongycastle.asn1.nist.NISTObjectIdentifiers;
+import org.spongycastle.asn1.x509.AlgorithmIdentifier;
+import org.spongycastle.crypto.Digest;
+import org.spongycastle.crypto.digests.SHA256Digest;
+import org.spongycastle.operator.DigestCalculator;
+
+
+class SHA256DigestCalculator
+ implements DigestCalculator
+{
+ private ByteArrayOutputStream bOut = new ByteArrayOutputStream();
+
+ public AlgorithmIdentifier getAlgorithmIdentifier()
+ {
+ return new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256);
+ }
+
+ public OutputStream getOutputStream()
+ {
+ return bOut;
+ }
+
+ public byte[] getDigest()
+ {
+ byte[] bytes = bOut.toByteArray();
+
+ bOut.reset();
+
+ Digest sha256 = new SHA256Digest();
+
+ sha256.update(bytes, 0, bytes.length);
+
+ byte[] digest = new byte[sha256.getDigestSize()];
+
+ sha256.doFinal(digest, 0);
+
+ return digest;
+ }
+}
diff --git a/pkix/src/test/java/org/spongycastle/tsp/test/TSPTestUtil.java b/pkix/src/test/java/org/spongycastle/tsp/test/TSPTestUtil.java
new file mode 100644
index 00000000..e4b78929
--- /dev/null
+++ b/pkix/src/test/java/org/spongycastle/tsp/test/TSPTestUtil.java
@@ -0,0 +1,229 @@
+package org.spongycastle.tsp.test;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+
+import org.spongycastle.asn1.ASN1ObjectIdentifier;
+import org.spongycastle.asn1.x509.AuthorityKeyIdentifier;
+import org.spongycastle.asn1.x509.BasicConstraints;
+import org.spongycastle.asn1.x509.ExtendedKeyUsage;
+import org.spongycastle.asn1.x509.Extension;
+import org.spongycastle.asn1.x509.KeyPurposeId;
+import org.spongycastle.asn1.x509.SubjectKeyIdentifier;
+import org.spongycastle.asn1.x509.X509Name;
+import org.spongycastle.cert.jcajce.JcaX509ExtensionUtils;
+import org.spongycastle.util.encoders.Base64;
+import org.spongycastle.x509.X509V3CertificateGenerator;
+
+public class TSPTestUtil
+{
+
+ public static SecureRandom rand = new SecureRandom();
+
+ public static KeyPairGenerator kpg;
+
+ public static KeyGenerator desede128kg;
+
+ public static KeyGenerator desede192kg;
+
+ public static KeyGenerator rc240kg;
+
+ public static KeyGenerator rc264kg;
+
+ public static KeyGenerator rc2128kg;
+
+ public static BigInteger serialNumber = BigInteger.ONE;
+
+ public static final boolean DEBUG = true;
+
+ public static ASN1ObjectIdentifier EuroPKI_TSA_Test_Policy = new ASN1ObjectIdentifier(
+ "1.3.6.1.4.1.5255.5.1");
+
+ public static JcaX509ExtensionUtils extUtils;
+
+ static
+ {
+ try
+ {
+ rand = new SecureRandom();
+
+ kpg = KeyPairGenerator.getInstance("RSA", "SC");
+ kpg.initialize(1024, rand);
+
+ desede128kg = KeyGenerator.getInstance("DESEDE", "SC");
+ desede128kg.init(112, rand);
+
+ desede192kg = KeyGenerator.getInstance("DESEDE", "SC");
+ desede192kg.init(168, rand);
+
+ rc240kg = KeyGenerator.getInstance("RC2", "SC");
+ rc240kg.init(40, rand);
+
+ rc264kg = KeyGenerator.getInstance("RC2", "SC");
+ rc264kg.init(64, rand);
+
+ rc2128kg = KeyGenerator.getInstance("RC2", "SC");
+ rc2128kg.init(128, rand);
+
+ serialNumber = new BigInteger("1");
+
+ extUtils = new JcaX509ExtensionUtils();
+
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException(ex.toString());
+ }
+ }
+
+ public static String dumpBase64(byte[] data)
+ {
+ StringBuffer buf = new StringBuffer();
+
+ data = Base64.encode(data);
+
+ for (int i = 0; i < data.length; i += 64)
+ {
+ if (i + 64 < data.length)
+ {
+ buf.append(new String(data, i, 64));
+ }
+ else
+ {
+ buf.append(new String(data, i, data.length - i));
+ }
+ buf.append('\n');
+ }
+
+ return buf.toString();
+ }
+
+ public static KeyPair makeKeyPair()
+ {
+ return kpg.generateKeyPair();
+ }
+
+ public static SecretKey makeDesede128Key()
+ {
+ return desede128kg.generateKey();
+ }
+
+ public static SecretKey makeDesede192Key()
+ {
+ return desede192kg.generateKey();
+ }
+
+ public static SecretKey makeRC240Key()
+ {
+ return rc240kg.generateKey();
+ }
+
+ public static SecretKey makeRC264Key()
+ {
+ return rc264kg.generateKey();
+ }
+
+ public static SecretKey makeRC2128Key()
+ {
+ return rc2128kg.generateKey();
+ }
+
+ public static X509Certificate makeCertificate(KeyPair _subKP,
+ String _subDN, KeyPair _issKP, String _issDN)
+ throws GeneralSecurityException, IOException
+ {
+
+ return makeCertificate(_subKP, _subDN, _issKP, _issDN, false);
+ }
+
+ public static X509Certificate makeCACertificate(KeyPair _subKP,
+ String _subDN, KeyPair _issKP, String _issDN)
+ throws GeneralSecurityException, IOException
+ {
+
+ return makeCertificate(_subKP, _subDN, _issKP, _issDN, true);
+ }
+
+ public static X509Certificate makeCertificate(KeyPair _subKP,
+ String _subDN, KeyPair _issKP, String _issDN, boolean _ca)
+ throws GeneralSecurityException, IOException
+ {
+
+ PublicKey _subPub = _subKP.getPublic();
+ PrivateKey _issPriv = _issKP.getPrivate();
+ PublicKey _issPub = _issKP.getPublic();
+
+ X509V3CertificateGenerator _v3CertGen = new X509V3CertificateGenerator();
+
+ _v3CertGen.reset();
+ _v3CertGen.setSerialNumber(allocateSerialNumber());
+ _v3CertGen.setIssuerDN(new X509Name(_issDN));
+ _v3CertGen.setNotBefore(new Date(System.currentTimeMillis()));
+ _v3CertGen.setNotAfter(new Date(System.currentTimeMillis()
+ + (1000L * 60 * 60 * 24 * 100)));
+ _v3CertGen.setSubjectDN(new X509Name(_subDN));
+ _v3CertGen.setPublicKey(_subPub);
+ _v3CertGen.setSignatureAlgorithm("MD5WithRSAEncryption");
+
+ _v3CertGen.addExtension(Extension.subjectKeyIdentifier, false,
+ createSubjectKeyId(_subPub));
+
+ _v3CertGen.addExtension(Extension.authorityKeyIdentifier, false,
+ createAuthorityKeyId(_issPub));
+
+ if (_ca)
+ {
+ _v3CertGen.addExtension(Extension.basicConstraints, false,
+ new BasicConstraints(_ca));
+ }
+ else
+ {
+ _v3CertGen.addExtension(Extension.extendedKeyUsage, true,
+ new ExtendedKeyUsage(KeyPurposeId.id_kp_timeStamping));
+ }
+
+ X509Certificate _cert = _v3CertGen.generate(_issPriv);
+
+ _cert.checkValidity(new Date());
+ _cert.verify(_issPub);
+
+ return _cert;
+ }
+
+ /*
+ *
+ * INTERNAL METHODS
+ *
+ */
+
+
+ private static AuthorityKeyIdentifier createAuthorityKeyId(PublicKey _pubKey)
+ throws IOException
+ {
+ return extUtils.createAuthorityKeyIdentifier(_pubKey);
+ }
+
+ private static SubjectKeyIdentifier createSubjectKeyId(PublicKey _pubKey)
+ throws IOException
+ {
+ return extUtils.createSubjectKeyIdentifier(_pubKey);
+ }
+
+ private static BigInteger allocateSerialNumber()
+ {
+ BigInteger _tmp = serialNumber;
+ serialNumber = serialNumber.add(BigInteger.ONE);
+ return _tmp;
+ }
+}