eu.europa.esig.dss.validation.timestamp.AbstractTimestampSource Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dss-document Show documentation
Show all versions of dss-document Show documentation
DSS Document contains the code for the creation and validation of XAdES, CAdES, PAdES and ASiC signatures.
/**
* DSS - Digital Signature Services
* Copyright (C) 2015 European Commission, provided under the CEF programme
*
* This file is part of the "DSS - Digital Signature Services" project.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package eu.europa.esig.dss.validation.timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import eu.europa.esig.dss.enumerations.ArchiveTimestampType;
import eu.europa.esig.dss.enumerations.TimestampType;
import eu.europa.esig.dss.enumerations.TimestampedObjectType;
import eu.europa.esig.dss.model.DSSDocument;
import eu.europa.esig.dss.model.DSSException;
import eu.europa.esig.dss.model.identifier.EncapsulatedRevocationTokenIdentifier;
import eu.europa.esig.dss.model.identifier.Identifier;
import eu.europa.esig.dss.model.x509.CertificateToken;
import eu.europa.esig.dss.model.x509.revocation.crl.CRL;
import eu.europa.esig.dss.model.x509.revocation.ocsp.OCSP;
import eu.europa.esig.dss.spi.x509.CertificateRef;
import eu.europa.esig.dss.spi.x509.ListCertificateSource;
import eu.europa.esig.dss.spi.x509.revocation.OfflineRevocationSource;
import eu.europa.esig.dss.spi.x509.revocation.crl.CRLRef;
import eu.europa.esig.dss.spi.x509.revocation.ocsp.OCSPRef;
import eu.europa.esig.dss.utils.Utils;
import eu.europa.esig.dss.validation.AdvancedSignature;
import eu.europa.esig.dss.validation.DefaultAdvancedSignature;
import eu.europa.esig.dss.validation.ISignatureAttribute;
import eu.europa.esig.dss.validation.ListRevocationSource;
import eu.europa.esig.dss.validation.SignatureCertificateSource;
import eu.europa.esig.dss.validation.SignatureProperties;
import eu.europa.esig.dss.validation.scope.SignatureScope;
/**
* Contains a set of {@link TimestampToken}s found in a {@link DefaultAdvancedSignature} object
*/
@SuppressWarnings("serial")
public abstract class AbstractTimestampSource implements TimestampSource {
private static final Logger LOG = LoggerFactory.getLogger(AbstractTimestampSource.class);
/**
* Sources obtained from a signature object
*/
protected final SignatureCertificateSource signatureCertificateSource;
protected final OfflineRevocationSource signatureCRLSource;
protected final OfflineRevocationSource signatureOCSPSource;
protected final String signatureId;
protected final transient List signatureScopes;
/**
* Revocation sources containing merged data from signature and timestamps
*/
protected ListRevocationSource crlSource;
protected ListRevocationSource ocspSource;
/**
* CertificateSource containing merged data from signature and timestamps
*/
protected ListCertificateSource certificateSource;
// Enclosed content timestamps.
private List contentTimestamps;
// Enclosed signature timestamps.
private List signatureTimestamps;
// Enclosed SignAndRefs timestamps.
private List sigAndRefsTimestamps;
// Enclosed RefsOnly timestamps.
private List refsOnlyTimestamps;
// This variable contains the list of enclosed archive signature timestamps.
private List archiveTimestamps;
/**
* Default constructor
*
* @param signature {@link AdvancedSignature} is being validated
*/
protected AbstractTimestampSource(final AdvancedSignature signature) {
Objects.requireNonNull(signature, "The signature cannot be null!");
this.signatureCertificateSource = signature.getCertificateSource();
this.signatureCRLSource = signature.getCRLSource();
this.signatureOCSPSource = signature.getOCSPSource();
this.signatureId = signature.getId();
this.signatureScopes = signature.getSignatureScopes();
}
@Override
public List getContentTimestamps() {
if (contentTimestamps == null) {
createAndValidate();
}
return contentTimestamps;
}
@Override
public List getSignatureTimestamps() {
if (signatureTimestamps == null) {
createAndValidate();
}
return signatureTimestamps;
}
@Override
public List getTimestampsX1() {
if (sigAndRefsTimestamps == null) {
createAndValidate();
}
return sigAndRefsTimestamps;
}
@Override
public List getTimestampsX2() {
if (refsOnlyTimestamps == null) {
createAndValidate();
}
return refsOnlyTimestamps;
}
@Override
public List getArchiveTimestamps() {
if (archiveTimestamps == null) {
createAndValidate();
}
return archiveTimestamps;
}
@Override
public List getDocumentTimestamps() {
/** Applicable only for PAdES */
return Collections.emptyList();
}
@Override
public List getAllTimestamps() {
List timestampTokens = new ArrayList<>();
timestampTokens.addAll(getContentTimestamps());
timestampTokens.addAll(getSignatureTimestamps());
timestampTokens.addAll(getTimestampsX1());
timestampTokens.addAll(getTimestampsX2());
timestampTokens.addAll(getArchiveTimestamps());
return timestampTokens;
}
@Override
public ListCertificateSource getTimestampCertificateSources() {
ListCertificateSource result = new ListCertificateSource();
for (TimestampToken timestampToken : getAllTimestamps()) {
result.add(timestampToken.getCertificateSource());
}
return result;
}
@Override
public ListCertificateSource getTimestampCertificateSourcesExceptLastArchiveTimestamp() {
ListCertificateSource result = new ListCertificateSource();
for (final TimestampToken timestampToken : getContentTimestamps()) {
result.add(timestampToken.getCertificateSource());
}
for (final TimestampToken timestampToken : getTimestampsX1()) {
result.add(timestampToken.getCertificateSource());
}
for (final TimestampToken timestampToken : getTimestampsX2()) {
result.add(timestampToken.getCertificateSource());
}
for (final TimestampToken timestampToken : getSignatureTimestamps()) {
result.add(timestampToken.getCertificateSource());
}
List archiveTsps = getArchiveTimestamps();
int archiveTimestampsSize = archiveTsps.size();
if (archiveTimestampsSize > 0) {
archiveTimestampsSize--;
}
for (int ii = 0; ii < archiveTimestampsSize; ii++) {
TimestampToken timestampToken = archiveTsps.get(ii);
result.add(timestampToken.getCertificateSource());
}
return result;
}
@Override
public ListRevocationSource getTimestampCRLSources() {
ListRevocationSource result = new ListRevocationSource();
for (TimestampToken timestampToken : getAllTimestamps()) {
result.add(timestampToken.getCRLSource());
}
return result;
}
@Override
public ListRevocationSource getTimestampOCSPSources() {
ListRevocationSource result = new ListRevocationSource();
for (TimestampToken timestampToken : getAllTimestamps()) {
result.add(timestampToken.getOCSPSource());
}
return result;
}
/**
* Creates and validates all timestamps
* Must be called only once
*/
protected void createAndValidate() {
makeTimestampTokens();
validateTimestamps();
}
@Override
public void addExternalTimestamp(TimestampToken timestamp) {
// if timestamp tokens not created yet
if (archiveTimestamps == null) {
createAndValidate();
}
processExternalTimestamp(timestamp);
if (TimestampType.ARCHIVE_TIMESTAMP == timestamp.getTimeStampType()) {
archiveTimestamps.add(timestamp);
} else {
throw new DSSException(
String.format("The signature timestamp source does not support timestamp tokens with type [%s]. " + "The TimestampToken was not added.",
timestamp.getTimeStampType().name()));
}
}
/**
* Populates all the lists by data found into the signature
*/
protected void makeTimestampTokens() {
// initialize timestamp lists
contentTimestamps = new ArrayList<>();
signatureTimestamps = new ArrayList<>();
sigAndRefsTimestamps = new ArrayList<>();
refsOnlyTimestamps = new ArrayList<>();
archiveTimestamps = new ArrayList<>();
// initialize combined revocation sources
crlSource = new ListRevocationSource(signatureCRLSource);
ocspSource = new ListRevocationSource(signatureOCSPSource);
certificateSource = new ListCertificateSource(signatureCertificateSource);
final SignatureProperties signedSignatureProperties = getSignedSignatureProperties();
final List signedAttributes = signedSignatureProperties.getAttributes();
for (SignatureAttribute signedAttribute : signedAttributes) {
TimestampToken timestampToken;
if (isContentTimestamp(signedAttribute)) {
timestampToken = makeTimestampToken(signedAttribute, TimestampType.CONTENT_TIMESTAMP, getAllSignedDataReferences());
if (timestampToken == null) {
continue;
}
} else if (isAllDataObjectsTimestamp(signedAttribute)) {
timestampToken = makeTimestampToken(signedAttribute, TimestampType.ALL_DATA_OBJECTS_TIMESTAMP, getAllSignedDataReferences());
if (timestampToken == null) {
continue;
}
} else if (isIndividualDataObjectsTimestamp(signedAttribute)) {
List references = getIndividualContentTimestampedReferences(signedAttribute);
timestampToken = makeTimestampToken(signedAttribute, TimestampType.INDIVIDUAL_DATA_OBJECTS_TIMESTAMP, references);
if (timestampToken == null) {
continue;
}
} else {
continue;
}
populateSources(timestampToken);
contentTimestamps.add(timestampToken);
}
final SignatureProperties unsignedSignatureProperties = getUnsignedSignatureProperties();
if (!unsignedSignatureProperties.isExist()) {
// timestamp tokens cannot be created if signature does not contain "unsigned-signature-properties" element
return;
}
final List timestamps = new ArrayList<>();
final List encapsulatedReferences = new ArrayList<>();
final List unsignedAttributes = unsignedSignatureProperties.getAttributes();
for (SignatureAttribute unsignedAttribute : unsignedAttributes) {
TimestampToken timestampToken;
if (isSignatureTimestamp(unsignedAttribute)) {
timestampToken = makeTimestampToken(unsignedAttribute, TimestampType.SIGNATURE_TIMESTAMP, getSignatureTimestampReferences());
if (timestampToken == null) {
continue;
}
signatureTimestamps.add(timestampToken);
} else if (isCompleteCertificateRef(unsignedAttribute)) {
addReferences(encapsulatedReferences, getTimestampedCertificateRefs(unsignedAttribute));
continue;
} else if (isAttributeCertificateRef(unsignedAttribute)) {
addReferences(encapsulatedReferences, getTimestampedCertificateRefs(unsignedAttribute));
continue;
} else if (isCompleteRevocationRef(unsignedAttribute)) {
addReferences(encapsulatedReferences, getTimestampedRevocationRefs(unsignedAttribute));
continue;
} else if (isAttributeRevocationRef(unsignedAttribute)) {
addReferences(encapsulatedReferences, getTimestampedRevocationRefs(unsignedAttribute));
continue;
} else if (isRefsOnlyTimestamp(unsignedAttribute)) {
timestampToken = makeTimestampToken(unsignedAttribute, TimestampType.VALIDATION_DATA_REFSONLY_TIMESTAMP, encapsulatedReferences);
if (timestampToken == null) {
continue;
}
refsOnlyTimestamps.add(timestampToken);
} else if (isSigAndRefsTimestamp(unsignedAttribute)) {
final List references = new ArrayList<>();
addReferencesForPreviousTimestamps(references, filterSignatureTimestamps(timestamps));
addReferences(references, encapsulatedReferences);
timestampToken = makeTimestampToken(unsignedAttribute, TimestampType.VALIDATION_DATA_TIMESTAMP, references);
if (timestampToken == null) {
continue;
}
sigAndRefsTimestamps.add(timestampToken);
} else if (isCertificateValues(unsignedAttribute)) {
addReferences(encapsulatedReferences, getTimestampedCertificateValues(unsignedAttribute));
continue;
} else if (isRevocationValues(unsignedAttribute)) {
addReferences(encapsulatedReferences, getTimestampedRevocationValues(unsignedAttribute));
continue;
} else if (isAttrAuthoritiesCertValues(unsignedAttribute)) {
addReferences(encapsulatedReferences, getTimestampedCertificateValues(unsignedAttribute));
continue;
} else if (isAttributeRevocationValues(unsignedAttribute)) {
addReferences(encapsulatedReferences, getTimestampedRevocationValues(unsignedAttribute));
continue;
} else if (isArchiveTimestamp(unsignedAttribute)) {
final List references = new ArrayList<>();
addReferencesForPreviousTimestamps(references, timestamps);
addReferences(references, encapsulatedReferences);
timestampToken = makeTimestampToken(unsignedAttribute, TimestampType.ARCHIVE_TIMESTAMP, references);
if (timestampToken == null) {
continue;
}
timestampToken.setArchiveTimestampType(getArchiveTimestampType(unsignedAttribute));
addReferences(timestampToken.getTimestampedReferences(), getArchiveTimestampOtherReferences(timestampToken));
archiveTimestamps.add(timestampToken);
} else if (isTimeStampValidationData(unsignedAttribute)) {
addReferences(encapsulatedReferences, getTimestampValidationData(unsignedAttribute));
continue;
} else {
LOG.warn("The unsigned attribute with name [{}] is not supported", unsignedAttribute);
continue;
}
populateSources(timestampToken);
timestamps.add(timestampToken);
}
}
/**
* Returns the 'signed-signature-properties' element of the signature
* @return {@link SignatureProperties}
*/
protected abstract SignatureProperties getSignedSignatureProperties();
/**
* Returns the 'unsigned-signature-properties' element of the signature
* @return {@link SignatureProperties}
*/
protected abstract SignatureProperties getUnsignedSignatureProperties();
/**
* Determines if the given {@code signedAttribute} is an instance of "content-timestamp" element
* NOTE: Applicable only for CAdES
* @param signedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is a Data Objects Timestamp, FALSE otherwise
*/
protected abstract boolean isContentTimestamp(SignatureAttribute signedAttribute);
/**
* Determines if the given {@code signedAttribute} is an instance of "data-objects-timestamp" element
* NOTE: Applicable only for XAdES
* @param signedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is a Data Objects Timestamp, FALSE otherwise
*/
protected abstract boolean isAllDataObjectsTimestamp(SignatureAttribute signedAttribute);
/**
* Determines if the given {@code signedAttribute} is an instance of "individual-data-objects-timestamp" element
* NOTE: Applicable only for XAdES
* @param signedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is a Data Objects Timestamp, FALSE otherwise
*/
protected abstract boolean isIndividualDataObjectsTimestamp(SignatureAttribute signedAttribute);
/**
* Determines if the given {@code unsignedAttribute} is an instance of "signature-timestamp" element
* @param unsignedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is a Signature Timestamp, FALSE otherwise
*/
protected abstract boolean isSignatureTimestamp(SignatureAttribute unsignedAttribute);
/**
* Determines if the given {@code unsignedAttribute} is an instance of "complete-certificate-ref" element
* @param unsignedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is a Complete Certificate Ref, FALSE otherwise
*/
protected abstract boolean isCompleteCertificateRef(SignatureAttribute unsignedAttribute);
/**
* Determines if the given {@code unsignedAttribute} is an instance of "attribute-certificate-ref" element
* @param unsignedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is an Attribute Certificate Ref, FALSE otherwise
*/
protected abstract boolean isAttributeCertificateRef(SignatureAttribute unsignedAttribute);
/**
* Determines if the given {@code unsignedAttribute} is an instance of "complete-revocation-ref" element
* @param unsignedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is a Complete Revocation Ref, FALSE otherwise
*/
protected abstract boolean isCompleteRevocationRef(SignatureAttribute unsignedAttribute);
/**
* Determines if the given {@code unsignedAttribute} is an instance of "attribute-revocation-ref" element
* @param unsignedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is an Attribute Revocation Ref, FALSE otherwise
*/
protected abstract boolean isAttributeRevocationRef(SignatureAttribute unsignedAttribute);
/**
* Determines if the given {@code unsignedAttribute} is an instance of "refs-only-timestamp" element
* @param unsignedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is a Refs Only TimeStamp, FALSE otherwise
*/
protected abstract boolean isRefsOnlyTimestamp(SignatureAttribute unsignedAttribute);
/**
* Determines if the given {@code unsignedAttribute} is an instance of "sig-and-refs-timestamp" element
* @param unsignedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is a Sig And Refs TimeStamp, FALSE otherwise
*/
protected abstract boolean isSigAndRefsTimestamp(SignatureAttribute unsignedAttribute);
/**
* Determines if the given {@code unsignedAttribute} is an instance of "certificate-values" element
* @param unsignedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is a Certificate Values, FALSE otherwise
*/
protected abstract boolean isCertificateValues(SignatureAttribute unsignedAttribute);
/**
* Determines if the given {@code unsignedAttribute} is an instance of "revocation-values" element
* @param unsignedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is a Revocation Values, FALSE otherwise
*/
protected abstract boolean isRevocationValues(SignatureAttribute unsignedAttribute);
/**
* Determines if the given {@code unsignedAttribute} is an instance of "AttrAuthoritiesCertValues" element
* @param unsignedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is an AttrAuthoritiesCertValues, FALSE otherwise
*/
protected abstract boolean isAttrAuthoritiesCertValues(SignatureAttribute unsignedAttribute);
/**
* Determines if the given {@code unsignedAttribute} is an instance of "AttributeRevocationValues" element
* @param unsignedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is an AttributeRevocationValues, FALSE otherwise
*/
protected abstract boolean isAttributeRevocationValues(SignatureAttribute unsignedAttribute);
/**
* Determines if the given {@code unsignedAttribute} is an instance of "archive-timestamp" element
* @param unsignedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is an Archive TimeStamp, FALSE otherwise
*/
protected abstract boolean isArchiveTimestamp(SignatureAttribute unsignedAttribute);
/**
* Determines if the given {@code unsignedAttribute} is an instance of "timestamp-validation-data" element
* @param unsignedAttribute {@link ISignatureAttribute} to process
* @return TRUE if the {@code unsignedAttribute} is a TimeStamp Validation Data, FALSE otherwise
*/
protected abstract boolean isTimeStampValidationData(SignatureAttribute unsignedAttribute);
/**
* Creates a timestamp token from the provided {@code signatureAttribute}
* @param signatureAttribute {@link ISignatureAttribute} to create timestamp from
* @param timestampType a target {@link TimestampType}
* @param references list of {@link TimestampedReference}s covered by the current timestamp
* @return {@link TimestampToken}
*/
protected abstract TimestampToken makeTimestampToken(SignatureAttribute signatureAttribute, TimestampType timestampType,
List references);
/**
* Returns a list of {@link TimestampedReference}s obtained from the {@code signatureScopes}
* @return list of {@link TimestampedReference}s
*/
protected List getAllSignedDataReferences() {
final List references = new ArrayList<>();
if (Utils.isCollectionNotEmpty(signatureScopes)) {
for (SignatureScope signatureScope : signatureScopes) {
addReference(references, new TimestampedReference(signatureScope.getDSSIdAsString(), TimestampedObjectType.SIGNED_DATA));
}
}
return references;
}
/**
* Returns a list of {@link TimestampedReference}s for an "individual-data-objects-timestamp"
* NOTE: Used only in XAdES
* @param signedAttribute {@link SignatureAttribute}
* @return a list of {@link TimestampedReference}s
*/
protected abstract List getIndividualContentTimestampedReferences(SignatureAttribute signedAttribute);
/**
* Returns a list of {@link TimestampedReference} for a "signature-timestamp" element
* @return list of {@link TimestampedReference}s
*/
public List getSignatureTimestampReferences() {
final List references = new ArrayList<>();
addReferencesForPreviousTimestamps(references, getContentTimestamps());
addReferences(references, getAllSignedDataReferences());
addReference(references, new TimestampedReference(signatureId, TimestampedObjectType.SIGNATURE));
addReferences(references, getSigningCertificateTimestampReferences());
return references;
}
/**
* Returns a list of {@code TimestampedReference}s created from signing certificates of the signature
* @return list of {@link TimestampedReference}s
*/
protected List getSigningCertificateTimestampReferences() {
return createReferencesForCertificates(signatureCertificateSource.getSigningCertificates());
}
/**
* Creates a list of {@code TimestampedReference}s for the provided list of {@code certificates}
* @param certificates collection of {@link CertificateToken}s
* @return list of {@link TimestampedReference}s
*/
protected List createReferencesForCertificates(Collection certificates) {
final List references = new ArrayList<>();
for (CertificateToken certificateToken : certificates) {
addReference(references, new TimestampedReference(certificateToken.getDSSIdAsString(), TimestampedObjectType.CERTIFICATE));
}
return references;
}
/**
* Returns a list of {@link TimestampedReference} certificate refs found in the
* given {@code unsignedAttribute}
*
* @param unsignedAttribute {@link SignatureAttribute} to find references from
* @return list of {@link TimestampedReference}s
*/
protected List getTimestampedCertificateRefs(SignatureAttribute unsignedAttribute) {
List timestampedReferences = new ArrayList<>();
for (CertificateRef certRef : getCertificateRefs(unsignedAttribute)) {
timestampedReferences
.add(new TimestampedReference(certRef.getDSSIdAsString(), TimestampedObjectType.CERTIFICATE));
}
return timestampedReferences;
}
/**
* Returns a list of {@link CertificateRef}s from the given
* {@code unsignedAttribute}
*
* @param unsignedAttribute {@link SignatureAttribute} to get certRefs from
* @return list of {@link CertificateRef}s
*/
protected abstract List getCertificateRefs(SignatureAttribute unsignedAttribute);
/**
* Returns a list of {@link TimestampedReference} revocation refs found in the given {@code unsignedAttribute}
* @param unsignedAttribute {@link SignatureAttribute} to find references from
* @return list of {@link TimestampedReference}s
*/
protected List getTimestampedRevocationRefs(SignatureAttribute unsignedAttribute) {
List timestampedReferences = new ArrayList<>();
for (CRLRef crlRef : getCRLRefs(unsignedAttribute)) {
EncapsulatedRevocationTokenIdentifier token = crlSource.findBinaryForReference(crlRef);
if (token != null) {
timestampedReferences.add(new TimestampedReference(token.asXmlId(), TimestampedObjectType.REVOCATION));
} else {
timestampedReferences.add(new TimestampedReference(crlRef.getDSSIdAsString(), TimestampedObjectType.REVOCATION));
}
}
for (OCSPRef ocspRef : getOCSPRefs(unsignedAttribute)) {
EncapsulatedRevocationTokenIdentifier token = ocspSource.findBinaryForReference(ocspRef);
if (token != null) {
timestampedReferences.add(new TimestampedReference(token.asXmlId(), TimestampedObjectType.REVOCATION));
} else {
timestampedReferences.add(new TimestampedReference(ocspRef.getDSSIdAsString(), TimestampedObjectType.REVOCATION));
}
}
return timestampedReferences;
}
/**
* Returns a list of CRL revocation refs from the given
* {@code unsignedAttribute}
*
* @param unsignedAttribute {@link SignatureAttribute} to get CRLRef
*
* @return list of {@link CRLRef}s
*/
protected abstract List getCRLRefs(SignatureAttribute unsignedAttribute);
/**
* Returns a list of OCSP revocation refs from the given
* {@code unsignedAttribute}
*
* @param unsignedAttribute {@link SignatureAttribute} to get OCSPRefs from
* @return list of {@link OCSPRef}s
*/
protected abstract List getOCSPRefs(SignatureAttribute unsignedAttribute);
protected List getTimestampedCertificateValues(SignatureAttribute unsignedAttribute) {
List timestampedReferences = new ArrayList<>();
for (Identifier certificateIdentifier : getEncapsulatedCertificateIdentifiers(unsignedAttribute)) {
timestampedReferences.add(new TimestampedReference(certificateIdentifier.asXmlId(), TimestampedObjectType.CERTIFICATE));
}
return timestampedReferences;
}
/**
* Returns a list of {@link Identifier}s obtained from the given {@code unsignedAttribute}
* @param unsignedAttribute {@link SignatureAttribute} to get certificate identifiers from
* @return list of {@link Identifier}s
*/
protected abstract List getEncapsulatedCertificateIdentifiers(SignatureAttribute unsignedAttribute);
protected List getTimestampedRevocationValues(SignatureAttribute unsignedAttribute) {
List timestampedReferences = new ArrayList<>();
for (Identifier revocationIdentifier : getEncapsulatedCRLIdentifiers(unsignedAttribute)) {
timestampedReferences.add(new TimestampedReference(revocationIdentifier.asXmlId(), TimestampedObjectType.REVOCATION));
}
for (Identifier revocationIdentifier : getEncapsulatedOCSPIdentifiers(unsignedAttribute)) {
timestampedReferences.add(new TimestampedReference(revocationIdentifier.asXmlId(), TimestampedObjectType.REVOCATION));
}
return timestampedReferences;
}
/**
* Returns a list of {@link Identifier}s obtained from the given {@code unsignedAttribute}
* @param unsignedAttribute {@link SignatureAttribute} to get CRL identifiers from
* @return list of {@link Identifier}s
*/
protected abstract List getEncapsulatedCRLIdentifiers(SignatureAttribute unsignedAttribute);
/**
* Returns a list of {@link Identifier}s obtained from the given {@code unsignedAttribute}
* @param unsignedAttribute {@link SignatureAttribute} to get OCSP identifiers from
* @return list of {@link Identifier}s
*/
protected abstract List getEncapsulatedOCSPIdentifiers(SignatureAttribute unsignedAttribute);
/**
* Returns a list of {@code TimestampedReference}s for the given archive {@code timestampToken}
* that cannot be extracted from signature attributes (signed or unsigned),
* depending on its format (signedData for CAdES or, keyInfo for XAdES)
*
* @param timestampToken {@link TimestampToken} to get archive timestamp references for
* @return list of {@link TimestampedReference}s
*/
protected abstract List getArchiveTimestampOtherReferences(TimestampToken timestampToken);
/**
* Returns a list of all {@code TimestampedReference}s found into CMS SignedData of the signature
* NOTE: used only in ASiC-E CAdES
*
* @return list of {@link TimestampedReference}s
*/
protected List getSignatureSignedDataReferences() {
// empty by default
return new ArrayList<>();
}
/**
* Returns a list of {@link TimestampedReference}s encapsulated to the "timestamp-validation-data" {@code unsignedAttribute}
* @param unsignedAttribute {@link SignatureAttribute} to get timestamped references from
* @return list of {@link TimestampedReference}s
*/
protected List getTimestampValidationData(SignatureAttribute unsignedAttribute) {
List timestampedReferences = new ArrayList<>();
for (Identifier certificateIdentifier : getEncapsulatedCertificateIdentifiers(unsignedAttribute)) {
timestampedReferences.add(new TimestampedReference(certificateIdentifier.asXmlId(), TimestampedObjectType.CERTIFICATE));
}
for (Identifier crlIdentifier : getEncapsulatedCRLIdentifiers(unsignedAttribute)) {
timestampedReferences.add(new TimestampedReference(crlIdentifier.asXmlId(), TimestampedObjectType.REVOCATION));
}
for (Identifier ocspIdentifier : getEncapsulatedOCSPIdentifiers(unsignedAttribute)) {
timestampedReferences.add(new TimestampedReference(ocspIdentifier.asXmlId(), TimestampedObjectType.REVOCATION));
}
return timestampedReferences;
}
/**
* Adds {@code referenceToAdd} to {@code referenceList} without duplicates
* @param referenceList - list of {@link TimestampedReference}s to be extended
* @param referenceToAdd - {@link TimestampedReference} to be added
*/
protected void addReference(List referenceList, TimestampedReference referenceToAdd) {
addReferences(referenceList, Arrays.asList(referenceToAdd));
}
/**
* Adds a reference for the given identifier and category
*
* @param referenceList - list of {@link TimestampedReference}s to be extended
* @param identifier - {@link Identifier} to be added
* @param category - {@link TimestampedObjectType} to be added
*/
protected void addReference(List referenceList, Identifier identifier,
TimestampedObjectType category) {
addReferences(referenceList, Arrays.asList(new TimestampedReference(identifier.asXmlId(), category)));
}
/**
* Adds {@code referencesToAdd} to {@code referenceList} without duplicates
* @param referenceList - list of {@link TimestampedReference}s to be extended
* @param referencesToAdd - {@link TimestampedReference}s to be added
*/
protected void addReferences(List referenceList, List referencesToAdd) {
for (TimestampedReference reference : referencesToAdd) {
if (!referenceList.contains(reference)) {
referenceList.add(reference);
}
}
}
private List filterSignatureTimestamps(List previousTimestampedTimestamp) {
List result = new ArrayList<>();
for (TimestampToken timestampToken : previousTimestampedTimestamp) {
if (TimestampType.SIGNATURE_TIMESTAMP.equals(timestampToken.getTimeStampType())) {
result.add(timestampToken);
}
}
return result;
}
protected void addReferencesForPreviousTimestamps(List references, List timestampedTimestamps) {
for (final TimestampToken timestampToken : timestampedTimestamps) {
addReference(references, new TimestampedReference(timestampToken.getDSSIdAsString(), TimestampedObjectType.TIMESTAMP));
addTimestampedReferences(references, timestampToken);
addEncapsulatedValuesFromTimestamp(references, timestampToken);
}
}
private void addTimestampedReferences(List references, TimestampToken timestampedTimestamp) {
for (TimestampedReference timestampedReference : timestampedTimestamp.getTimestampedReferences()) {
addReference(references, timestampedReference);
}
}
/**
* Adds to the {@code references} list all validation data embedded to the {@code timestampedTimestamp}
* @param references list of {@link TimestampedReference}s to extend
* @param timestampedTimestamp {@link TimestampToken} to extract embedded values from
*/
protected void addEncapsulatedValuesFromTimestamp(List references, TimestampToken timestampedTimestamp) {
for (final CertificateToken certificate : timestampedTimestamp.getCertificates()) {
addReference(references, certificate.getDSSId(), TimestampedObjectType.CERTIFICATE);
}
for (final CertificateRef certificateRef : timestampedTimestamp.getCertificateRefs()) {
addReference(references, new TimestampedReference(certificateRef.getDSSIdAsString(), TimestampedObjectType.CERTIFICATE));
}
TimestampCRLSource timestampCRLSource = timestampedTimestamp.getCRLSource();
for (EncapsulatedRevocationTokenIdentifier revocationBinary : timestampCRLSource.getAllRevocationBinaries()) {
addReference(references, revocationBinary, TimestampedObjectType.REVOCATION);
}
for (EncapsulatedRevocationTokenIdentifier revocationBinary : timestampCRLSource.getAllReferencedRevocationBinaries()) {
addReference(references, revocationBinary, TimestampedObjectType.REVOCATION);
}
TimestampOCSPSource timestampOCSPSource = timestampedTimestamp.getOCSPSource();
for (EncapsulatedRevocationTokenIdentifier revocationBinary : timestampOCSPSource.getAllRevocationBinaries()) {
addReference(references, revocationBinary, TimestampedObjectType.REVOCATION);
}
for (EncapsulatedRevocationTokenIdentifier revocationBinary : timestampOCSPSource.getAllReferencedRevocationBinaries()) {
addReference(references, revocationBinary, TimestampedObjectType.REVOCATION);
}
}
/**
* Returns {@link ArchiveTimestampType} for the given {@code unsignedAttribute}
* @param unsignedAttribute {@link SignatureAttribute} to get archive timestamp type for
*/
protected abstract ArchiveTimestampType getArchiveTimestampType(SignatureAttribute unsignedAttribute);
/**
* Validates list of all timestamps present in the source
*/
protected void validateTimestamps() {
TimestampDataBuilder timestampDataBuilder = getTimestampDataBuilder();
/*
* This validates the content-timestamp tokensToProcess present in the signature.
*/
for (final TimestampToken timestampToken : getContentTimestamps()) {
final DSSDocument timestampedData = timestampDataBuilder.getContentTimestampData(timestampToken);
timestampToken.matchData(timestampedData);
}
/*
* This validates the signature timestamp tokensToProcess present in the signature.
*/
for (final TimestampToken timestampToken : getSignatureTimestamps()) {
final DSSDocument timestampedData = timestampDataBuilder.getSignatureTimestampData(timestampToken);
timestampToken.matchData(timestampedData);
}
/*
* This validates the SigAndRefs timestamp tokensToProcess present in the signature.
*/
for (final TimestampToken timestampToken : getTimestampsX1()) {
final DSSDocument timestampedData = timestampDataBuilder.getTimestampX1Data(timestampToken);
timestampToken.matchData(timestampedData);
}
/*
* This validates the RefsOnly timestamp tokensToProcess present in the signature.
*/
for (final TimestampToken timestampToken : getTimestampsX2()) {
final DSSDocument timestampedData = timestampDataBuilder.getTimestampX2Data(timestampToken);
timestampToken.matchData(timestampedData);
}
/*
* This validates the archive timestamp tokensToProcess present in the signature.
*/
for (final TimestampToken timestampToken : getArchiveTimestamps()) {
if (!timestampToken.isProcessed()) {
final DSSDocument timestampedData = timestampDataBuilder.getArchiveTimestampData(timestampToken);
timestampToken.matchData(timestampedData);
}
}
}
/**
* Returns a related {@link TimestampDataBuilder}
* @return {@link TimestampDataBuilder}
*/
protected abstract TimestampDataBuilder getTimestampDataBuilder();
private void processExternalTimestamp(TimestampToken externalTimestamp) {
// add all validation data present in Signature CMS SignedData, because an external timestamp covers a whole signature file
addReferences(externalTimestamp.getTimestampedReferences(), getSignatureSignedDataReferences());
// add references from previously added timestamps
addReferencesForPreviousTimestamps(externalTimestamp.getTimestampedReferences(), getAllTimestamps());
// populate timestamp certificate source with values present in the timestamp
populateSources(externalTimestamp);
}
/**
* Allows to populate all merged sources with extracted from a timestamp data
*
* @param timestampToken {@link TimestampToken} to populate data from
*/
protected void populateSources(TimestampToken timestampToken) {
certificateSource.add(timestampToken.getCertificateSource());
crlSource.add(timestampToken.getCRLSource());
ocspSource.add(timestampToken.getOCSPSource());
}
}