diff options
Diffstat (limited to 'pkix/src/test/java/org/spongycastle/tsp')
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; + } +} |