blob: a9ab7db6db54e29203f7fc84e08643bcb3abafc5 [file] [log] [blame]
package org.bouncycastle.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.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.DigestCalculator;
import org.bouncycastle.operator.DigestCalculatorProvider;
import org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
import org.bouncycastle.tsp.TSPAlgorithms;
import org.bouncycastle.tsp.TimeStampRequest;
import org.bouncycastle.tsp.TimeStampRequestGenerator;
import org.bouncycastle.tsp.TimeStampResponse;
import org.bouncycastle.tsp.TimeStampResponseGenerator;
import org.bouncycastle.tsp.TimeStampToken;
import org.bouncycastle.tsp.TimeStampTokenGenerator;
import org.bouncycastle.tsp.cms.CMSTimeStampedData;
import org.bouncycastle.tsp.cms.CMSTimeStampedDataGenerator;
import org.bouncycastle.tsp.cms.CMSTimeStampedDataParser;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Store;
import org.bouncycastle.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();
}
}