package eu.europa.esig.dss.validation.process.vpfltvd.checks;
import java.util.Date;
import java.util.Set;
import eu.europa.esig.dss.jaxb.detailedreport.XmlValidationProcessLongTermData;
import eu.europa.esig.dss.utils.Utils;
import eu.europa.esig.dss.validation.policy.rules.Indication;
import eu.europa.esig.dss.validation.policy.rules.SubIndication;
import eu.europa.esig.dss.validation.process.ChainItem;
import eu.europa.esig.dss.validation.process.MessageTag;
import eu.europa.esig.dss.validation.reports.wrapper.TimestampWrapper;
import eu.europa.esig.dss.x509.TimestampType;
import eu.europa.esig.jaxb.policy.LevelConstraint;
public class TimestampCoherenceOrderCheck extends ChainItem<XmlValidationProcessLongTermData> {
private final Set<TimestampWrapper> timestamps;
public TimestampCoherenceOrderCheck(XmlValidationProcessLongTermData result, Set<TimestampWrapper> timestamps, LevelConstraint constraint) {
super(result, constraint);
this.timestamps = timestamps;
}
@Override
protected boolean process() {
if (Utils.collectionSize(timestamps) <= 1) {
return true;
}
Date latestContent = getLatestTimestampProductionDate(timestamps, TimestampType.CONTENT_TIMESTAMP, TimestampType.ALL_DATA_OBJECTS_TIMESTAMP,
TimestampType.INDIVIDUAL_DATA_OBJECTS_TIMESTAMP);
Date earliestSignature = getEarliestTimestampProductionTime(timestamps, TimestampType.SIGNATURE_TIMESTAMP);
Date latestSignature = getLatestTimestampProductionDate(timestamps, TimestampType.SIGNATURE_TIMESTAMP);
Date earliestValidationData = getEarliestTimestampProductionTime(timestamps, TimestampType.VALIDATION_DATA_TIMESTAMP,
TimestampType.VALIDATION_DATA_REFSONLY_TIMESTAMP);
Date latestValidationData = getLatestTimestampProductionDate(timestamps, TimestampType.VALIDATION_DATA_TIMESTAMP,
TimestampType.VALIDATION_DATA_REFSONLY_TIMESTAMP);
Date earliestArchive = getEarliestTimestampProductionTime(timestamps, TimestampType.ARCHIVE_TIMESTAMP);
if ((latestContent == null) && (earliestSignature == null) && (earliestValidationData == null) && (earliestArchive == null)) {
return true;
}
boolean ok = true;
if ((earliestSignature == null) && ((earliestValidationData != null) || (earliestArchive != null))) {
ok = false;
}
// Check content-timestamp against-signature timestamp
if ((latestContent != null) && (earliestSignature != null)) {
ok = ok && latestContent.before(earliestSignature);
}
// Check signature-timestamp against validation-data and validation-data-refs-only timestamp
if ((latestSignature != null) && (earliestValidationData != null)) {
ok = ok && latestSignature.before(earliestValidationData);
}
// Check archive-timestamp
if ((latestSignature != null) && (earliestArchive != null)) {
ok = ok && earliestArchive.after(latestSignature);
}
if ((latestValidationData != null) && (earliestArchive != null)) {
ok = ok && earliestArchive.after(latestValidationData);
}
return ok;
}
private Date getLatestTimestampProductionDate(Set<TimestampWrapper> timestamps, TimestampType... selectedTimestampTypes) {
Date latestProductionTime = null;
for (TimestampWrapper timestamp : timestamps) {
if (isInSelectedTypes(selectedTimestampTypes, timestamp.getType())) {
Date productionTime = timestamp.getProductionTime();
if ((latestProductionTime == null) || latestProductionTime.before(productionTime)) {
latestProductionTime = productionTime;
}
}
}
return latestProductionTime;
}
private Date getEarliestTimestampProductionTime(Set<TimestampWrapper> timestamps, TimestampType... selectedTimestampTypes) {
Date earliestProductionTime = null;
for (TimestampWrapper timestamp : timestamps) {
if (isInSelectedTypes(selectedTimestampTypes, timestamp.getType())) {
Date productionTime = timestamp.getProductionTime();
if ((earliestProductionTime == null) || earliestProductionTime.after(productionTime)) {
earliestProductionTime = productionTime;
}
}
}
return earliestProductionTime;
}
private boolean isInSelectedTypes(TimestampType[] allowedTypes, String type) {
for (TimestampType timestampType : allowedTypes) {
if (timestampType.name().equals(type)) {
return true;
}
}
return false;
}
@Override
protected MessageTag getMessageTag() {
return MessageTag.TSV_ASTPTCT;
}
@Override
protected MessageTag getErrorMessageTag() {
return MessageTag.TSV_ASTPTCT_ANS;
}
@Override
protected Indication getFailedIndicationForConclusion() {
return Indication.FAILED;
}
@Override
protected SubIndication getFailedSubIndicationForConclusion() {
return SubIndication.TIMESTAMP_ORDER_FAILURE;
}
}