blob: 28c7e87a7186915b0ce7c8ee198aa7601b189808 [file] [log] [blame]
package org.bouncycastle.tsp.cms;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import org.bouncycastle.asn1.BERTags;
import org.bouncycastle.asn1.DERIA5String;
import org.bouncycastle.asn1.cms.AttributeTable;
import org.bouncycastle.asn1.cms.CMSObjectIdentifiers;
import org.bouncycastle.asn1.cms.ContentInfoParser;
import org.bouncycastle.asn1.cms.TimeStampedDataParser;
import org.bouncycastle.cms.CMSContentInfoParser;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.operator.DigestCalculator;
import org.bouncycastle.operator.DigestCalculatorProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.tsp.TimeStampToken;
import org.bouncycastle.util.io.Streams;
public class CMSTimeStampedDataParser
extends CMSContentInfoParser
{
private TimeStampedDataParser timeStampedData;
private TimeStampDataUtil util;
public CMSTimeStampedDataParser(InputStream in)
throws CMSException
{
super(in);
initialize(_contentInfo);
}
public CMSTimeStampedDataParser(byte[] baseData)
throws CMSException
{
this(new ByteArrayInputStream(baseData));
}
private void initialize(ContentInfoParser contentInfo)
throws CMSException
{
try
{
if (CMSObjectIdentifiers.timestampedData.equals(contentInfo.getContentType()))
{
this.timeStampedData = TimeStampedDataParser.getInstance(contentInfo.getContent(BERTags.SEQUENCE));
}
else
{
throw new IllegalArgumentException("Malformed content - type must be " + CMSObjectIdentifiers.timestampedData.getId());
}
}
catch (IOException e)
{
throw new CMSException("parsing exception: " + e.getMessage(), e);
}
}
public byte[] calculateNextHash(DigestCalculator calculator)
throws CMSException
{
return util.calculateNextHash(calculator);
}
public InputStream getContent()
{
if (timeStampedData.getContent() != null)
{
return timeStampedData.getContent().getOctetStream();
}
return null;
}
public URI getDataUri()
throws URISyntaxException
{
DERIA5String dataURI = this.timeStampedData.getDataUri();
if (dataURI != null)
{
return new URI(dataURI.getString());
}
return null;
}
public String getFileName()
{
return util.getFileName();
}
public String getMediaType()
{
return util.getMediaType();
}
public AttributeTable getOtherMetaData()
{
return util.getOtherMetaData();
}
/**
* Initialise the passed in calculator with the MetaData for this message, if it is
* required as part of the initial message imprint calculation.
*
* @param calculator the digest calculator to be initialised.
* @throws CMSException if the MetaData is required and cannot be processed
*/
public void initialiseMessageImprintDigestCalculator(DigestCalculator calculator)
throws CMSException
{
util.initialiseMessageImprintDigestCalculator(calculator);
}
/**
* Returns an appropriately initialised digest calculator based on the message imprint algorithm
* described in the first time stamp in the TemporalData for this message. If the metadata is required
* to be included in the digest calculation, the returned calculator will be pre-initialised.
*
* @param calculatorProvider a provider of DigestCalculator objects.
* @return an initialised digest calculator.
* @throws OperatorCreationException if the provider is unable to create the calculator.
*/
public DigestCalculator getMessageImprintDigestCalculator(DigestCalculatorProvider calculatorProvider)
throws OperatorCreationException
{
try
{
parseTimeStamps();
}
catch (CMSException e)
{
throw new OperatorCreationException("unable to extract algorithm ID: " + e.getMessage(), e);
}
return util.getMessageImprintDigestCalculator(calculatorProvider);
}
public TimeStampToken[] getTimeStampTokens()
throws CMSException
{
parseTimeStamps();
return util.getTimeStampTokens();
}
/**
* Validate the digests present in the TimeStampTokens contained in the CMSTimeStampedData.
*
* @param calculatorProvider provider for digest calculators
* @param dataDigest the calculated data digest for the message
* @throws ImprintDigestInvalidException if an imprint digest fails to compare
* @throws CMSException if an exception occurs processing the message.
*/
public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest)
throws ImprintDigestInvalidException, CMSException
{
parseTimeStamps();
util.validate(calculatorProvider, dataDigest);
}
/**
* Validate the passed in timestamp token against the tokens and data present in the message.
*
* @param calculatorProvider provider for digest calculators
* @param dataDigest the calculated data digest for the message.
* @param timeStampToken the timestamp token of interest.
* @throws ImprintDigestInvalidException if the token is not present in the message, or an imprint digest fails to compare.
* @throws CMSException if an exception occurs processing the message.
*/
public void validate(DigestCalculatorProvider calculatorProvider, byte[] dataDigest, TimeStampToken timeStampToken)
throws ImprintDigestInvalidException, CMSException
{
parseTimeStamps();
util.validate(calculatorProvider, dataDigest, timeStampToken);
}
private void parseTimeStamps()
throws CMSException
{
try
{
if (util == null)
{
InputStream cont = this.getContent();
if (cont != null)
{
Streams.drain(cont);
}
util = new TimeStampDataUtil(timeStampedData);
}
}
catch (IOException e)
{
throw new CMSException("unable to parse evidence block: " + e.getMessage(), e);
}
}
}