Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
eu.europa.esig.dss.validation.reports.diagnostic.SignedDocumentDiagnosticDataBuilder Maven / Gradle / Ivy
/**
* 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.reports.diagnostic;
import eu.europa.esig.dss.crl.CRLBinary;
import eu.europa.esig.dss.diagnostic.jaxb.XmlBasicSignature;
import eu.europa.esig.dss.diagnostic.jaxb.XmlCommitmentTypeIndication;
import eu.europa.esig.dss.diagnostic.jaxb.XmlDiagnosticData;
import eu.europa.esig.dss.diagnostic.jaxb.XmlDigestAlgoAndValue;
import eu.europa.esig.dss.diagnostic.jaxb.XmlDigestMatcher;
import eu.europa.esig.dss.diagnostic.jaxb.XmlEncapsulationType;
import eu.europa.esig.dss.diagnostic.jaxb.XmlEvidenceRecord;
import eu.europa.esig.dss.diagnostic.jaxb.XmlFoundEvidenceRecord;
import eu.europa.esig.dss.diagnostic.jaxb.XmlFoundRevocations;
import eu.europa.esig.dss.diagnostic.jaxb.XmlFoundTimestamp;
import eu.europa.esig.dss.diagnostic.jaxb.XmlOrphanRevocation;
import eu.europa.esig.dss.diagnostic.jaxb.XmlOrphanRevocationToken;
import eu.europa.esig.dss.diagnostic.jaxb.XmlRelatedRevocation;
import eu.europa.esig.dss.diagnostic.jaxb.XmlRevocation;
import eu.europa.esig.dss.diagnostic.jaxb.XmlSignature;
import eu.europa.esig.dss.diagnostic.jaxb.XmlSignatureDigestReference;
import eu.europa.esig.dss.diagnostic.jaxb.XmlSignatureProductionPlace;
import eu.europa.esig.dss.diagnostic.jaxb.XmlSignatureScope;
import eu.europa.esig.dss.diagnostic.jaxb.XmlSignerData;
import eu.europa.esig.dss.diagnostic.jaxb.XmlSignerDocumentRepresentations;
import eu.europa.esig.dss.diagnostic.jaxb.XmlSignerInfo;
import eu.europa.esig.dss.diagnostic.jaxb.XmlSignerRole;
import eu.europa.esig.dss.diagnostic.jaxb.XmlStructuralValidation;
import eu.europa.esig.dss.diagnostic.jaxb.XmlTSAGeneralName;
import eu.europa.esig.dss.diagnostic.jaxb.XmlTimestamp;
import eu.europa.esig.dss.diagnostic.jaxb.XmlTimestampedObject;
import eu.europa.esig.dss.enumerations.DigestAlgorithm;
import eu.europa.esig.dss.enumerations.DigestMatcherType;
import eu.europa.esig.dss.enumerations.RevocationOrigin;
import eu.europa.esig.dss.enumerations.RevocationRefOrigin;
import eu.europa.esig.dss.enumerations.RevocationType;
import eu.europa.esig.dss.enumerations.TimestampedObjectType;
import eu.europa.esig.dss.enumerations.TokenExtractionStrategy;
import eu.europa.esig.dss.model.DSSDocument;
import eu.europa.esig.dss.model.DSSException;
import eu.europa.esig.dss.model.Digest;
import eu.europa.esig.dss.model.ManifestEntry;
import eu.europa.esig.dss.model.ManifestFile;
import eu.europa.esig.dss.model.ReferenceValidation;
import eu.europa.esig.dss.model.SignaturePolicyStore;
import eu.europa.esig.dss.model.identifier.EncapsulatedRevocationTokenIdentifier;
import eu.europa.esig.dss.model.identifier.Identifier;
import eu.europa.esig.dss.model.scope.SignatureScope;
import eu.europa.esig.dss.model.signature.CommitmentTypeIndication;
import eu.europa.esig.dss.model.signature.SignatureCryptographicVerification;
import eu.europa.esig.dss.model.signature.SignatureDigestReference;
import eu.europa.esig.dss.model.signature.SignaturePolicy;
import eu.europa.esig.dss.model.signature.SignatureProductionPlace;
import eu.europa.esig.dss.model.signature.SignerRole;
import eu.europa.esig.dss.model.x509.CertificateToken;
import eu.europa.esig.dss.model.x509.Token;
import eu.europa.esig.dss.model.x509.X500PrincipalHelper;
import eu.europa.esig.dss.model.x509.revocation.Revocation;
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.DSSASN1Utils;
import eu.europa.esig.dss.spi.DSSPKUtils;
import eu.europa.esig.dss.spi.DSSUtils;
import eu.europa.esig.dss.spi.signature.AdvancedSignature;
import eu.europa.esig.dss.spi.x509.CandidatesForSigningCertificate;
import eu.europa.esig.dss.spi.x509.CertificateValidity;
import eu.europa.esig.dss.spi.x509.ListCertificateSource;
import eu.europa.esig.dss.spi.x509.SignerIdentifier;
import eu.europa.esig.dss.spi.x509.evidencerecord.EvidenceRecord;
import eu.europa.esig.dss.spi.x509.revocation.ListRevocationSource;
import eu.europa.esig.dss.spi.x509.revocation.OfflineRevocationSource;
import eu.europa.esig.dss.spi.x509.revocation.RevocationRef;
import eu.europa.esig.dss.spi.x509.revocation.RevocationToken;
import eu.europa.esig.dss.spi.x509.revocation.crl.CRLRef;
import eu.europa.esig.dss.spi.x509.revocation.ocsp.OCSPCertificateSource;
import eu.europa.esig.dss.spi.x509.revocation.ocsp.OCSPRef;
import eu.europa.esig.dss.spi.x509.revocation.ocsp.OCSPResponseBinary;
import eu.europa.esig.dss.spi.x509.tsp.TimestampToken;
import eu.europa.esig.dss.spi.x509.tsp.TimestampTokenComparator;
import eu.europa.esig.dss.spi.x509.tsp.TimestampedReference;
import eu.europa.esig.dss.utils.Utils;
import javax.security.auth.x500.X500Principal;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
/**
* The common class for DiagnosticData creation from a signed/timestamped document
*
*/
public class SignedDocumentDiagnosticDataBuilder extends DiagnosticDataBuilder {
/** The signed document */
protected DSSDocument signedDocument;
/** The collection of signatures */
protected Collection signatures;
/** The collection of timestamp tokens */
protected Collection usedTimestamps;
/** The collection of evidence records */
protected Collection evidenceRecords;
/** The list of all certificate sources extracted from a validating document (signature(s), timestamp(s)) */
protected ListCertificateSource documentCertificateSource = new ListCertificateSource();
/** The list of all CRL revocation sources extracted from a validating document (signature(s), timestamp(s)) */
protected ListRevocationSource documentCRLSource = new ListRevocationSource<>();
/** The list of all OCSP revocation sources extracted from a validating document (signature(s), timestamp(s)) */
protected ListRevocationSource documentOCSPSource = new ListRevocationSource<>();
/** The cached map of signatures */
protected Map xmlSignaturesMap = new HashMap<>();
/** The cached map of timestamps */
protected Map xmlTimestampsMap = new HashMap<>();
/** The cached map of evidence records */
protected Map xmlEvidenceRecordMap = new HashMap<>();
/** The cached map of original signed data */
protected Map xmlSignedDataMap = new HashMap<>();
/**
* Default constructor instantiating object with null values and empty maps
*/
public SignedDocumentDiagnosticDataBuilder() {
// empty
}
@Override
public SignedDocumentDiagnosticDataBuilder usedCertificates(Set usedCertificates) {
return (SignedDocumentDiagnosticDataBuilder) super.usedCertificates(usedCertificates);
}
@Override
public SignedDocumentDiagnosticDataBuilder usedRevocations(Set> usedRevocations) {
return (SignedDocumentDiagnosticDataBuilder) super.usedRevocations(usedRevocations);
}
@Override
public SignedDocumentDiagnosticDataBuilder allCertificateSources(ListCertificateSource trustedCertSources) {
return (SignedDocumentDiagnosticDataBuilder) super.allCertificateSources(trustedCertSources);
}
@Override
public SignedDocumentDiagnosticDataBuilder validationDate(Date validationDate) {
return (SignedDocumentDiagnosticDataBuilder) super.validationDate(validationDate);
}
@Override
public SignedDocumentDiagnosticDataBuilder tokenExtractionStrategy(TokenExtractionStrategy tokenExtractionStrategy) {
return (SignedDocumentDiagnosticDataBuilder) super.tokenExtractionStrategy(tokenExtractionStrategy);
}
@Override
public SignedDocumentDiagnosticDataBuilder defaultDigestAlgorithm(DigestAlgorithm digestAlgorithm) {
return (SignedDocumentDiagnosticDataBuilder) super.defaultDigestAlgorithm(digestAlgorithm);
}
/**
* This method allows to set the document which is analysed
*
* @param signedDocument the document which is analysed
* @return the builder
*/
public SignedDocumentDiagnosticDataBuilder document(DSSDocument signedDocument) {
this.signedDocument = signedDocument;
return this;
}
/**
* This method allows to set the found signatures
*
* @param signatures the found signatures
* @return the builder
*/
public SignedDocumentDiagnosticDataBuilder foundSignatures(Collection signatures) {
this.signatures = signatures;
return this;
}
/**
* This method allows to set the timestamps
*
* @param usedTimestamps a set of validated {@link TimestampToken}s
* @return the builder
*/
public SignedDocumentDiagnosticDataBuilder usedTimestamps(Collection usedTimestamps) {
this.usedTimestamps = usedTimestamps;
return this;
}
/**
* This method allows to set the evidence records
*
* @param evidenceRecords a set of found {@link EvidenceRecord}s
* @return the builder
*/
public SignedDocumentDiagnosticDataBuilder foundEvidenceRecords(Collection evidenceRecords) {
this.evidenceRecords = evidenceRecords;
return this;
}
/**
* Sets a document Certificate Source containing all sources extracted from the provided signature(s)/timestamp(s)
*
* @param documentCertificateSource {@link ListCertificateSource} computed from document sources
* @return the builder
*/
public SignedDocumentDiagnosticDataBuilder documentCertificateSource(ListCertificateSource documentCertificateSource) {
this.documentCertificateSource = documentCertificateSource;
return this;
}
/**
* Sets a document CRL Source containing all sources extracted from the provided signature(s)/timestamp(s)
*
* @param documentCRLSource {@link ListRevocationSource} computed from document sources
* @return the builder
*/
public SignedDocumentDiagnosticDataBuilder documentCRLSource(ListRevocationSource documentCRLSource) {
this.documentCRLSource = documentCRLSource;
return this;
}
/**
* Sets a document OCSP Source containing all sources extracted from the provided signature(s)/timestamp(s)
*
* @param documentCRLSource {@link ListRevocationSource} computed from document sources
* @return the builder
*/
public SignedDocumentDiagnosticDataBuilder documentOCSPSource(ListRevocationSource documentCRLSource) {
this.documentOCSPSource = documentCRLSource;
return this;
}
/**
* Builds {@code XmlDiagnosticData}
*
* @return {@link XmlDiagnosticData}
*/
@Override
public XmlDiagnosticData build() {
Objects.requireNonNull(signedDocument, "signedDocument shall be provided! Use 'document()' method.");
XmlDiagnosticData diagnosticData = super.build(); // fill certificates and revocation data
diagnosticData.setDocumentName(removeSpecialCharsForXml(signedDocument.getName()));
// collect original signer documents
Collection xmlSignerData = buildXmlSignerDataList(signatures, usedTimestamps, evidenceRecords);
diagnosticData.getOriginalDocuments().addAll(xmlSignerData);
if (Utils.isCollectionNotEmpty(signatures)) {
Collection xmlSignatures = buildXmlSignatures(signatures);
diagnosticData.getSignatures().addAll(xmlSignatures);
attachCounterSignatures(signatures);
}
if (Utils.isCollectionNotEmpty(usedTimestamps)) {
List builtTimestamps = buildXmlTimestamps(usedTimestamps);
diagnosticData.getUsedTimestamps().addAll(builtTimestamps);
linkSignaturesAndTimestamps(signatures);
}
if (Utils.isCollectionNotEmpty(evidenceRecords)) {
List builtEvidenceRecords = buildXmlEvidenceRecords(evidenceRecords);
diagnosticData.getEvidenceRecords().addAll(builtEvidenceRecords);
linkSignaturesAndEvidenceRecords(signatures);
linkTimestampsAndEvidenceRecords(usedTimestamps);
linkEvidenceRecordsAndTimestamps(evidenceRecords);
}
// link the rest certificates
super.linkSigningCertificateAndChains(usedCertificates);
diagnosticData.setOrphanTokens(buildXmlOrphanTokens());
// timestamped objects must be linked after building of orphan tokens
if (Utils.isCollectionNotEmpty(usedTimestamps)) {
linkTimestampsAndTimestampsObjects(usedTimestamps);
}
if (Utils.isCollectionNotEmpty(evidenceRecords)) {
linkEvidenceRecordsAndTimestampsObjects(evidenceRecords);
}
return diagnosticData;
}
@Override
protected void linkSigningCertificateAndChains(Set certificates) {
// skip (certificate chain is build based on provided tokens)
}
/**
* Escape special characters which cause problems with jaxb or
* documentbuilderfactory and namespace aware mode
*/
private String removeSpecialCharsForXml(String text) {
if (Utils.isStringNotEmpty(text)) {
return text.replace("&", "");
}
return Utils.EMPTY_STRING;
}
private Collection buildXmlSignerDataList(Collection signatures,
Collection timestamps,
Collection evidenceRecords) {
List signerDataList = new ArrayList<>();
if (Utils.isCollectionNotEmpty(signatures)) {
for (AdvancedSignature signature : signatures) {
signerDataList.addAll(buildXmlSignerData(signature.getSignatureScopes()));
}
}
if (Utils.isCollectionNotEmpty(timestamps)) {
for (TimestampToken timestampToken : timestamps) {
signerDataList.addAll(buildXmlSignerData(timestampToken.getTimestampScopes()));
}
}
if (Utils.isCollectionNotEmpty(evidenceRecords)) {
for (EvidenceRecord evidenceRecord : evidenceRecords) {
signerDataList.addAll(buildXmlSignerData(evidenceRecord.getEvidenceRecordScopes()));
}
}
return signerDataList;
}
private List buildXmlSignerData(List signatureScopes) {
return buildXmlSignerData(signatureScopes, null);
}
private List buildXmlSignerData(List signatureScopes, XmlSignerData parentSignerData) {
List result = new ArrayList<>();
if (Utils.isCollectionNotEmpty(signatureScopes)) {
for (SignatureScope signatureScope : signatureScopes) {
if (xmlSignedDataMap.get(signatureScope.getDSSIdAsString()) == null) {
XmlSignerData xmlSignerData = buildXmlSignerData(signatureScope);
if (parentSignerData != null) {
xmlSignerData.setParent(parentSignerData);
}
result.add(xmlSignerData);
if (Utils.isCollectionNotEmpty(signatureScope.getChildren())) {
result.addAll(buildXmlSignerData(signatureScope.getChildren(), xmlSignerData));
}
}
}
}
return result;
}
private XmlSignerData buildXmlSignerData(SignatureScope signatureScope) {
String id = signatureScope.getDSSIdAsString();
XmlSignerData xmlSignerData = xmlSignedDataMap.get(id);
if (xmlSignerData == null) {
xmlSignerData = getXmlSignerData(signatureScope);
xmlSignedDataMap.put(id, xmlSignerData);
}
return xmlSignerData;
}
private XmlSignerData getXmlSignerData(SignatureScope signatureScope) {
XmlSignerData xmlSignedData = new XmlSignerData();
xmlSignedData.setId(identifierProvider.getIdAsString(signatureScope));
xmlSignedData.setDigestAlgoAndValue(getXmlDigestAlgoAndValue(signatureScope.getDigest(defaultDigestAlgorithm)));
xmlSignedData.setReferencedName(signatureScope.getName(identifierProvider));
return xmlSignedData;
}
private Collection buildXmlSignatures(Collection signatures) {
List builtSignatures = new ArrayList<>();
for (AdvancedSignature advancedSignature : signatures) {
String id = advancedSignature.getId();
XmlSignature xmlSignature = xmlSignaturesMap.get(id);
if (xmlSignature == null) {
xmlSignature = getXmlSignature(advancedSignature);
builtSignatures.add(xmlSignature);
}
}
return builtSignatures;
}
private void attachCounterSignatures(Collection signatures) {
for (AdvancedSignature advancedSignature : signatures) {
if (advancedSignature.isCounterSignature()) {
XmlSignature currentSignature = xmlSignaturesMap.get(advancedSignature.getId());
// attach master
AdvancedSignature masterSignature = advancedSignature.getMasterSignature();
XmlSignature xmlMasterSignature = xmlSignaturesMap.get(masterSignature.getId());
currentSignature.setCounterSignature(true);
currentSignature.setParent(xmlMasterSignature);
}
}
}
private XmlSignature getXmlSignature(AdvancedSignature signature) {
XmlSignature xmlSignature = buildDetachedXmlSignature(signature);
checkDuplicates(xmlSignature, signature);
setXmlSigningCertificate(xmlSignature, signature);
setXmlPolicy(xmlSignature, signature);
xmlSignature.setFoundCertificates(getXmlFoundCertificates(signature.getDSSId(), signature.getCertificateSource()));
xmlSignature.setFoundRevocations(getXmlFoundRevocations(signature.getCRLSource(), signature.getOCSPSource()));
xmlSignature.setSignatureScopes(getXmlSignatureScopes(signature.getSignatureScopes()));
xmlSignaturesMap.put(signature.getId(), xmlSignature);
return xmlSignature;
}
private void checkDuplicates(XmlSignature xmlSignature, AdvancedSignature signature) {
if (hasDuplicate(signature)) {
xmlSignature.setDuplicated(true);
}
}
private boolean hasDuplicate(AdvancedSignature currentSignature) {
for (AdvancedSignature signature : signatures) {
if (currentSignature != signature
&& (currentSignature.getId().equals(signature.getId()) ||
(currentSignature.getDAIdentifier() != null && currentSignature.getDAIdentifier().equals(signature.getDAIdentifier())
&& currentSignature.getSignatureFilename() != null && currentSignature.getSignatureFilename().equals(signature.getSignatureFilename())))) {
return true;
}
}
return false;
}
private void setXmlSigningCertificate(XmlSignature xmlSignature, AdvancedSignature signature) {
final CandidatesForSigningCertificate candidatesForSigningCertificate = signature.getCandidatesForSigningCertificate();
final CertificateValidity theCertificateValidity = candidatesForSigningCertificate.getTheCertificateValidity();
PublicKey signingCertificatePublicKey = null;
if (theCertificateValidity != null) {
xmlSignature.setSigningCertificate(getXmlSigningCertificate(signature.getDSSId(), theCertificateValidity));
xmlSignature.setCertificateChain(getXmlForCertificateChain(theCertificateValidity, signature.getCertificateSource()));
signingCertificatePublicKey = theCertificateValidity.getPublicKey();
}
xmlSignature.setBasicSignature(getXmlBasicSignature(signature, signingCertificatePublicKey));
xmlSignature.setDigestMatchers(getXmlDigestMatchers(signature));
}
private void setXmlPolicy(XmlSignature xmlSignature, AdvancedSignature signature) {
if (signature.getSignaturePolicy() != null) {
XmlPolicyBuilder policyBuilder = getPolicyBuilder(signature);
xmlSignature.setPolicy(policyBuilder.build());
xmlSignature.setSignaturePolicyStore(policyBuilder.buildSignaturePolicyStore());
}
}
/**
* Builds {@code XmlSignature}
*
* @param signature {@link AdvancedSignature}
* @return {@link XmlSignature}
*/
public XmlSignature buildDetachedXmlSignature(AdvancedSignature signature) {
XmlSignature xmlSignature = new XmlSignature();
xmlSignature.setSignatureFilename(removeSpecialCharsForXml(signature.getSignatureFilename()));
xmlSignature.setId(identifierProvider.getIdAsString(signature));
xmlSignature.setDAIdentifier(signature.getDAIdentifier());
xmlSignature.setClaimedSigningTime(signature.getSigningTime());
xmlSignature.setStructuralValidation(getXmlStructuralValidation(signature));
xmlSignature.setSignatureFormat(signature.getDataFoundUpToLevel());
xmlSignature.setSignatureProductionPlace(
getXmlSignatureProductionPlace(signature.getSignatureProductionPlace()));
xmlSignature.getCommitmentTypeIndications().addAll(
getXmlCommitmentTypeIndications(signature.getCommitmentTypeIndications()));
xmlSignature.getSignerRole().addAll(getXmlSignerRoles(signature.getSignerRoles()));
xmlSignature.setContentType(signature.getContentType());
xmlSignature.setMimeType(signature.getMimeType());
xmlSignature.setSignatureDigestReference(getXmlSignatureDigestReference(signature));
xmlSignature.setDataToBeSignedRepresentation(getXmlDataToBeSignedRepresentation(signature));
xmlSignature.setSignerDocumentRepresentations(getXmlSignerDocumentRepresentations(signature));
xmlSignature.setSignatureValue(signature.getSignatureValue());
return xmlSignature;
}
private XmlStructuralValidation getXmlStructuralValidation(AdvancedSignature signature) {
return getXmlStructuralValidation(signature.getStructureValidationResult());
}
private XmlStructuralValidation getXmlStructuralValidation(List errorMessages) {
final XmlStructuralValidation xmlStructuralValidation = new XmlStructuralValidation();
xmlStructuralValidation.setValid(Utils.isCollectionEmpty(errorMessages));
if (Utils.isCollectionNotEmpty(errorMessages)) {
xmlStructuralValidation.getMessages().addAll(errorMessages);
}
return xmlStructuralValidation;
}
private XmlSignatureProductionPlace getXmlSignatureProductionPlace(SignatureProductionPlace signatureProductionPlace) {
if (signatureProductionPlace != null) {
final XmlSignatureProductionPlace xmlSignatureProductionPlace = new XmlSignatureProductionPlace();
xmlSignatureProductionPlace.setCountryName(emptyToNull(signatureProductionPlace.getCountryName()));
xmlSignatureProductionPlace.setStateOrProvince(emptyToNull(signatureProductionPlace.getStateOrProvince()));
xmlSignatureProductionPlace.setPostOfficeBoxNumber(emptyToNull(signatureProductionPlace.getPostOfficeBoxNumber()));
xmlSignatureProductionPlace.setPostalCode(emptyToNull(signatureProductionPlace.getPostalCode()));
xmlSignatureProductionPlace.setStreetAddress(emptyToNull(signatureProductionPlace.getStreetAddress()));
xmlSignatureProductionPlace.setCity(emptyToNull(signatureProductionPlace.getCity()));
if (Utils.isCollectionNotEmpty(signatureProductionPlace.getPostalAddress())) {
xmlSignatureProductionPlace.getPostalAddress().addAll(signatureProductionPlace.getPostalAddress());
}
return xmlSignatureProductionPlace;
}
return null;
}
/**
* If text is empty returns NULL, or original text otherwise
*
* @param text {@link String}
* @return {@link String}
*/
protected String emptyToNull(String text) {
if (Utils.isStringEmpty(text)) {
return null;
}
return text;
}
private List getXmlCommitmentTypeIndications(
List commitmentTypeIndications) {
if (Utils.isCollectionNotEmpty(commitmentTypeIndications)) {
List xmlCommitmentTypeIndications = new ArrayList<>();
for (CommitmentTypeIndication commitmentTypeIndication : commitmentTypeIndications) {
xmlCommitmentTypeIndications.add(getXmlCommitmentTypeIndication(commitmentTypeIndication));
}
return xmlCommitmentTypeIndications;
}
return Collections.emptyList();
}
private XmlCommitmentTypeIndication getXmlCommitmentTypeIndication(
CommitmentTypeIndication commitmentTypeIndication) {
XmlCommitmentTypeIndication xmlCommitmentTypeIndication = new XmlCommitmentTypeIndication();
xmlCommitmentTypeIndication.setIdentifier(commitmentTypeIndication.getIdentifier());
xmlCommitmentTypeIndication.setDescription(commitmentTypeIndication.getDescription());
xmlCommitmentTypeIndication.setDocumentationReferences(commitmentTypeIndication.getDocumentReferences());
if (commitmentTypeIndication.isAllDataSignedObjects()) {
xmlCommitmentTypeIndication.setAllDataSignedObjects(commitmentTypeIndication.isAllDataSignedObjects());
} else {
xmlCommitmentTypeIndication.setObjectReferences(commitmentTypeIndication.getObjectReferences());
}
return xmlCommitmentTypeIndication;
}
private List getXmlSignerRoles(Collection signerRoles) {
List xmlSignerRoles = new ArrayList<>();
if (Utils.isCollectionNotEmpty(signerRoles)) {
for (SignerRole signerRole : signerRoles) {
XmlSignerRole xmlSignerRole = new XmlSignerRole();
xmlSignerRole.setRole(signerRole.getRole());
xmlSignerRole.setCategory(signerRole.getCategory());
xmlSignerRole.setNotBefore(signerRole.getNotBefore());
xmlSignerRole.setNotAfter(signerRole.getNotAfter());
xmlSignerRoles.add(xmlSignerRole);
}
}
return xmlSignerRoles;
}
private XmlBasicSignature getXmlBasicSignature(AdvancedSignature signature, PublicKey signingCertificatePublicKey) {
XmlBasicSignature xmlBasicSignature = new XmlBasicSignature();
xmlBasicSignature.setEncryptionAlgoUsedToSignThisToken(signature.getEncryptionAlgorithm());
xmlBasicSignature.setKeyLengthUsedToSignThisToken(DSSPKUtils.getStringPublicKeySize(signingCertificatePublicKey));
xmlBasicSignature.setDigestAlgoUsedToSignThisToken(signature.getDigestAlgorithm());
SignatureCryptographicVerification scv = signature.getSignatureCryptographicVerification();
xmlBasicSignature.setSignatureIntact(scv.isSignatureIntact());
xmlBasicSignature.setSignatureValid(scv.isSignatureValid());
return xmlBasicSignature;
}
private List getXmlDigestMatchers(AdvancedSignature signature) {
return getXmlDigestMatchers(signature.getReferenceValidations(), signature.getDetachedContents());
}
private List getXmlDigestMatchers(List referenceValidations, List detachedContents) {
List refs = new ArrayList<>();
if (Utils.isCollectionNotEmpty(referenceValidations)) {
for (ReferenceValidation referenceValidation : referenceValidations) {
refs.add(getXmlDigestMatcher(referenceValidation));
List dependentValidations = referenceValidation.getDependentValidations();
if (Utils.isCollectionNotEmpty(dependentValidations)
&& (Utils.isCollectionNotEmpty(detachedContents)
|| isAtLeastOneFound(dependentValidations))) {
for (ReferenceValidation dependentValidation : referenceValidation.getDependentValidations()) {
refs.add(getXmlDigestMatcher(dependentValidation));
}
}
}
}
return refs;
}
private List getTimestampReferenceValidationDigestMatchers(List referenceValidations) {
List refs = new ArrayList<>();
if (Utils.isCollectionNotEmpty(referenceValidations)) {
for (ReferenceValidation referenceValidation : referenceValidations) {
refs.add(getXmlDigestMatcher(referenceValidation));
}
}
return refs;
}
private XmlDigestMatcher getXmlDigestMatcher(ReferenceValidation referenceValidation) {
XmlDigestMatcher ref = new XmlDigestMatcher();
ref.setType(referenceValidation.getType());
ref.setId(referenceValidation.getId());
ref.setUri(referenceValidation.getUri());
ref.setDocumentName(referenceValidation.getDocumentName());
Digest digest = referenceValidation.getDigest();
if (digest != null) {
ref.setDigestValue(digest.getValue());
ref.setDigestMethod(digest.getAlgorithm());
}
ref.setDataFound(referenceValidation.isFound());
ref.setDataIntact(referenceValidation.isIntact());
if (referenceValidation.isDuplicated()) {
ref.setDuplicated(referenceValidation.isDuplicated());
}
return ref;
}
/**
* Checks if at least one Manifest entry was found
*
* @return TRUE if at least one ManifestEntry was found, FALSE otherwise
*/
private boolean isAtLeastOneFound(List referenceValidations) {
for (ReferenceValidation referenceValidation : referenceValidations) {
if (referenceValidation.isFound()) {
return true;
}
}
return false;
}
/**
* This method deals with the signature policy. The retrieved object is a
* builder for an {@code XmlPolicy} and {@code XmlSignaturePolicyStore}
*
* @param signature {@link AdvancedSignature}
*
*/
private XmlPolicyBuilder getPolicyBuilder(AdvancedSignature signature) {
SignaturePolicy signaturePolicy = signature.getSignaturePolicy();
SignaturePolicyStore signaturePolicyStore = signature.getSignaturePolicyStore();
XmlPolicyBuilder xmlPolicyBuilder = new XmlPolicyBuilder(signaturePolicy);
xmlPolicyBuilder.setSignaturePolicyStore(signaturePolicyStore);
return xmlPolicyBuilder;
}
private XmlSignatureDigestReference getXmlSignatureDigestReference(AdvancedSignature signature) {
SignatureDigestReference signatureDigestReference = signature
.getSignatureDigestReference(defaultDigestAlgorithm);
if (signatureDigestReference != null) {
XmlSignatureDigestReference xmlDigestReference = new XmlSignatureDigestReference();
xmlDigestReference.setCanonicalizationMethod(signatureDigestReference.getCanonicalizationMethod());
xmlDigestReference.setDigestMethod(signatureDigestReference.getDigestAlgorithm());
xmlDigestReference.setDigestValue(signatureDigestReference.getDigestValue());
return xmlDigestReference;
}
return null;
}
private XmlDigestAlgoAndValue getXmlDataToBeSignedRepresentation(AdvancedSignature signature) {
Digest dtbsr = signature.getDataToBeSignedRepresentation();
if (dtbsr != null) {
return getXmlDigestAlgoAndValue(dtbsr);
}
return null;
}
private XmlSignerDocumentRepresentations getXmlSignerDocumentRepresentations(AdvancedSignature signature) {
if (Utils.isCollectionEmpty(signature.getDetachedContents())) {
return null;
}
XmlSignerDocumentRepresentations signerDocumentRepresentation = new XmlSignerDocumentRepresentations();
signerDocumentRepresentation.setDocHashOnly(signature.isDocHashOnlyValidation());
signerDocumentRepresentation.setHashOnly(signature.isHashOnlyValidation());
return signerDocumentRepresentation;
}
private XmlFoundRevocations getXmlFoundRevocations(OfflineRevocationSource crlSource,
OfflineRevocationSource ocspSource) {
XmlFoundRevocations foundRevocations = new XmlFoundRevocations();
foundRevocations.getRelatedRevocations().addAll(getXmlRelatedRevocations(crlSource, ocspSource));
foundRevocations.getOrphanRevocations().addAll(getXmlOrphanRevocations(crlSource, ocspSource));
foundRevocations.getOrphanRevocations().addAll(getXmlOrphanRevocationRefs(crlSource, ocspSource));
return foundRevocations;
}
private List getXmlRelatedRevocations(OfflineRevocationSource crlSource,
OfflineRevocationSource ocspSource) {
List xmlRelatedRevocations = new ArrayList<>();
addRelatedRevocations(xmlRelatedRevocations, crlSource);
addRelatedRevocations(xmlRelatedRevocations, ocspSource);
return xmlRelatedRevocations;
}
private void addRelatedRevocations(List result,
OfflineRevocationSource source) {
for (Entry, Set> entry : source.getUniqueRevocationTokensWithOrigins().entrySet()) {
RevocationToken token = entry.getKey();
String id = token.getDSSIdAsString();
XmlRevocation xmlRevocation = xmlRevocationsMap.get(id);
if (xmlRevocation != null) {
XmlRelatedRevocation xmlRelatedRevocation = new XmlRelatedRevocation();
xmlRelatedRevocation.setRevocation(xmlRevocation);
xmlRelatedRevocation.setType(token.getRevocationType());
xmlRelatedRevocation.getOrigins().addAll(entry.getValue());
xmlRelatedRevocation.getRevocationRefs().addAll(getXmlRevocationRefs(xmlRevocation.getId(),
source.findRefsAndOriginsForRevocationToken(token)));
result.add(xmlRelatedRevocation);
}
}
}
private List getXmlOrphanRevocations(OfflineRevocationSource crlSource,
OfflineRevocationSource ocspSource) {
List xmlOrphanRevocations = new ArrayList<>();
addOrphanRevocations(xmlOrphanRevocations, crlSource);
addOrphanRevocations(xmlOrphanRevocations, ocspSource);
return xmlOrphanRevocations;
}
private void addOrphanRevocations(List xmlOrphanRevocations,
OfflineRevocationSource source) {
Map, Set> allBinariesWithOrigins =
source.getAllRevocationBinariesWithOrigins();
for (Entry, Set> entry : allBinariesWithOrigins.entrySet()) {
EncapsulatedRevocationTokenIdentifier token = entry.getKey();
String tokenId = token.asXmlId();
if (!xmlRevocationsMap.containsKey(tokenId)) {
XmlOrphanRevocation xmlOrphanRevocation = getXmlOrphanRevocation(token, entry.getValue());
xmlOrphanRevocation.getRevocationRefs().addAll(getXmlRevocationRefs(tokenId, source.findRefsAndOriginsForBinary(token)));
xmlOrphanRevocations.add(xmlOrphanRevocation);
}
}
}
private List getXmlOrphanRevocationRefs(OfflineRevocationSource crlSource,
OfflineRevocationSource ocspSource) {
List xmlOrphanRevocationRefs = new ArrayList<>();
addOrphanRevocationRefs(xmlOrphanRevocationRefs, crlSource, documentCRLSource);
addOrphanRevocationRefs(xmlOrphanRevocationRefs, ocspSource, documentOCSPSource);
return xmlOrphanRevocationRefs;
}
private void addOrphanRevocationRefs(List xmlOrphanRevocationRefs,
OfflineRevocationSource source, ListRevocationSource allSources) {
Map, Set> orphanRevocationReferencesWithOrigins =
source.getOrphanRevocationReferencesWithOrigins();
for (Entry, Set> entry : orphanRevocationReferencesWithOrigins.entrySet()) {
RevocationRef ref = entry.getKey();
if (allSources.isOrphan(ref) && sourceDoesNotContainOrphanBinaries(source, ref)) {
xmlOrphanRevocationRefs.add(createOrphanRevocationFromRef(ref, entry.getValue()));
}
}
}
private boolean sourceDoesNotContainOrphanBinaries(OfflineRevocationSource source,
RevocationRef ref) {
String tokenId = referenceMap.get(ref.getDSSIdAsString());
if (tokenId == null) {
return true;
}
for (Identifier revocationIdentifier : source.getAllRevocationBinaries()) {
if (tokenId.equals(revocationIdentifier.asXmlId())) {
return false;
}
}
return true;
}
private XmlOrphanRevocation getXmlOrphanRevocation(
EncapsulatedRevocationTokenIdentifier token, Set origins) {
XmlOrphanRevocation xmlOrphanRevocation = new XmlOrphanRevocation();
if (token instanceof CRLBinary) {
xmlOrphanRevocation.setType(RevocationType.CRL);
} else {
xmlOrphanRevocation.setType(RevocationType.OCSP);
}
xmlOrphanRevocation.getOrigins().addAll(origins);
xmlOrphanRevocation.setToken(createOrphanTokenFromRevocationIdentifier(token));
return xmlOrphanRevocation;
}
/**
* Creates an orphan revocation token from {@code EncapsulatedRevocationTokenIdentifier}
*
* @param revocationIdentifier {@link EncapsulatedRevocationTokenIdentifier}
* @param {@link Revocation}
* @return {@link XmlOrphanRevocationToken}
*/
protected XmlOrphanRevocationToken createOrphanTokenFromRevocationIdentifier(
EncapsulatedRevocationTokenIdentifier revocationIdentifier) {
XmlOrphanRevocationToken orphanToken = new XmlOrphanRevocationToken();
orphanToken.setEncapsulationType(XmlEncapsulationType.BINARIES);
orphanToken.setId(identifierProvider.getIdAsString(revocationIdentifier));
if (tokenExtractionStrategy.isRevocationData()) {
orphanToken.setBase64Encoded(revocationIdentifier.getBinaries());
} else {
byte[] digestValue = revocationIdentifier.getDigestValue(defaultDigestAlgorithm);
orphanToken.setDigestAlgoAndValue(getXmlDigestAlgoAndValue(defaultDigestAlgorithm, digestValue));
}
if (revocationIdentifier instanceof CRLBinary) {
orphanToken.setRevocationType(RevocationType.CRL);
} else if (revocationIdentifier instanceof OCSPResponseBinary) {
orphanToken.setRevocationType(RevocationType.OCSP);
OCSPResponseBinary ocspResponseBinary = (OCSPResponseBinary) revocationIdentifier;
OCSPCertificateSource ocspCertificateSource = new OCSPCertificateSource(ocspResponseBinary.getBasicOCSPResp());
getXmlFoundCertificates(ocspResponseBinary, ocspCertificateSource); // create from OCSP Certificate Source
}
xmlOrphanRevocationTokensMap.put(revocationIdentifier.asXmlId(), orphanToken);
return orphanToken;
}
private XmlOrphanRevocation createOrphanRevocationFromRef(RevocationRef ref,
Set origins) {
XmlOrphanRevocation xmlOrphanRevocation = new XmlOrphanRevocation();
XmlOrphanRevocationToken orphanToken = new XmlOrphanRevocationToken();
orphanToken.setEncapsulationType(XmlEncapsulationType.REFERENCE);
orphanToken.setId(identifierProvider.getIdAsString(ref));
if (ref.getDigest() != null) {
orphanToken.setDigestAlgoAndValue(getXmlDigestAlgoAndValue(ref.getDigest()));
}
xmlOrphanRevocationTokensMap.put(ref.getDSSIdAsString(), orphanToken);
xmlOrphanRevocation.setToken(orphanToken);
if (ref instanceof CRLRef) {
orphanToken.setRevocationType(RevocationType.CRL);
xmlOrphanRevocation.setType(RevocationType.CRL);
xmlOrphanRevocation.getRevocationRefs().add(getXmlCRLRevocationRef((CRLRef) ref, origins));
} else {
orphanToken.setRevocationType(RevocationType.OCSP);
xmlOrphanRevocation.setType(RevocationType.OCSP);
xmlOrphanRevocation.getRevocationRefs().add(getXmlOCSPRevocationRef((OCSPRef) ref, origins));
}
return xmlOrphanRevocation;
}
private List getXmlSignatureScopes(List scopes) {
List xmlScopes = new ArrayList<>();
if (Utils.isCollectionNotEmpty(scopes)) {
for (SignatureScope signatureScope : scopes) {
xmlScopes.add(getXmlSignatureScope(signatureScope));
if (Utils.isCollectionNotEmpty(signatureScope.getChildren())) {
xmlScopes.addAll(getXmlSignatureScopes(signatureScope.getChildren()));
}
}
}
return xmlScopes;
}
private XmlSignatureScope getXmlSignatureScope(SignatureScope scope) {
final XmlSignatureScope xmlSignatureScope = new XmlSignatureScope();
xmlSignatureScope.setName(scope.getName(identifierProvider));
xmlSignatureScope.setScope(scope.getType());
xmlSignatureScope.setDescription(scope.getDescription(identifierProvider));
xmlSignatureScope.setTransformations(scope.getTransformations());
xmlSignatureScope.setSignerData(xmlSignedDataMap.get(scope.getDSSIdAsString()));
return xmlSignatureScope;
}
private List buildXmlEvidenceRecords(Collection evidenceRecords) {
List xmlEvidenceRecords = new ArrayList<>();
if (Utils.isCollectionNotEmpty(evidenceRecords)) {
for (EvidenceRecord evidenceRecord : evidenceRecords) {
String id = evidenceRecord.getId();
XmlEvidenceRecord xmlEvidenceRecord = xmlEvidenceRecordMap.get(id);
if (xmlEvidenceRecord == null) {
xmlEvidenceRecord = buildXmlEvidenceRecord(evidenceRecord);
xmlEvidenceRecords.add(xmlEvidenceRecord);
}
}
}
return xmlEvidenceRecords;
}
private XmlEvidenceRecord buildXmlEvidenceRecord(EvidenceRecord evidenceRecord) {
XmlEvidenceRecord xmlEvidenceRecord = new XmlEvidenceRecord();
checkDuplicates(xmlEvidenceRecord, evidenceRecord);
xmlEvidenceRecord.setId(identifierProvider.getIdAsString(evidenceRecord));
xmlEvidenceRecord.setDocumentName(evidenceRecord.getFilename());
xmlEvidenceRecord.setType(evidenceRecord.getReferenceRecordType());
xmlEvidenceRecord.setStructuralValidation(getXmlStructuralValidation(evidenceRecord));
xmlEvidenceRecord.setDigestMatchers(getXmlDigestMatchers(evidenceRecord));
xmlEvidenceRecord.setEvidenceRecordScopes(getXmlSignatureScopes(evidenceRecord.getEvidenceRecordScopes()));
xmlEvidenceRecord.setFoundCertificates(getXmlFoundCertificates(evidenceRecord.getCertificateSource()));
xmlEvidenceRecord.setFoundRevocations(getXmlFoundRevocations(evidenceRecord.getCRLSource(), evidenceRecord.getOCSPSource()));
byte[] encoded = evidenceRecord.getEncoded();
if (tokenExtractionStrategy.isEvidenceRecord()) {
xmlEvidenceRecord.setBase64Encoded(encoded);
} else {
byte[] digest = DSSUtils.digest(defaultDigestAlgorithm, encoded);
xmlEvidenceRecord.setDigestAlgoAndValue(getXmlDigestAlgoAndValue(defaultDigestAlgorithm, digest));
}
xmlEvidenceRecordMap.put(evidenceRecord.getId(), xmlEvidenceRecord);
return xmlEvidenceRecord;
}
private void checkDuplicates(XmlEvidenceRecord xmlEvidenceRecord, EvidenceRecord evidenceRecord) {
if (hasDuplicate(evidenceRecord)) {
xmlEvidenceRecord.setDuplicated(true);
}
}
private boolean hasDuplicate(EvidenceRecord currentEvidenceRecord) {
for (EvidenceRecord evidenceRecord : evidenceRecords) {
if (currentEvidenceRecord != evidenceRecord && currentEvidenceRecord.getId().equals(evidenceRecord.getId())) {
return true;
}
}
return false;
}
private List getXmlDigestMatchers(EvidenceRecord evidenceRecord) {
return getXmlDigestMatchers(evidenceRecord.getReferenceValidation(), Collections.emptyList());
}
private void linkSignaturesAndEvidenceRecords(Collection signatures) {
for (AdvancedSignature signature : signatures) {
XmlSignature xmlSignature = xmlSignaturesMap.get(signature.getId());
xmlSignature.setFoundEvidenceRecords(getXmlSignatureEvidenceRecords(signature));
}
}
private List getXmlSignatureEvidenceRecords(AdvancedSignature signature) {
List foundEvidenceRecords = new ArrayList<>();
for (EvidenceRecord evidenceRecord : signature.getAllEvidenceRecords()) {
XmlFoundEvidenceRecord foundEvidenceRecord = new XmlFoundEvidenceRecord();
foundEvidenceRecord.setEvidenceRecord(xmlEvidenceRecordMap.get(evidenceRecord.getId()));
foundEvidenceRecords.add(foundEvidenceRecord);
}
return foundEvidenceRecords;
}
private void linkTimestampsAndEvidenceRecords(Collection timestampTokens) {
for (TimestampToken timestampToken : timestampTokens) {
XmlTimestamp xmlTimestamp = xmlTimestampsMap.get(timestampToken.getDSSIdAsString());
xmlTimestamp.setFoundEvidenceRecords(getXmlTimestampEvidenceRecords(timestampToken));
}
}
private List getXmlTimestampEvidenceRecords(TimestampToken timestampToken) {
List foundEvidenceRecords = new ArrayList<>();
for (EvidenceRecord evidenceRecord : timestampToken.getDetachedEvidenceRecords()) {
XmlFoundEvidenceRecord foundEvidenceRecord = new XmlFoundEvidenceRecord();
foundEvidenceRecord.setEvidenceRecord(xmlEvidenceRecordMap.get(evidenceRecord.getId()));
foundEvidenceRecords.add(foundEvidenceRecord);
}
return foundEvidenceRecords;
}
private void linkEvidenceRecordsAndTimestamps(Collection evidenceRecords) {
for (EvidenceRecord evidenceRecord : evidenceRecords) {
XmlEvidenceRecord currentEvidenceRecord = xmlEvidenceRecordMap.get(evidenceRecord.getId());
// attach timestamps
currentEvidenceRecord.setEvidenceRecordTimestamps(getXmlEvidenceRecordTimestamps(evidenceRecord));
}
}
private List getXmlEvidenceRecordTimestamps(EvidenceRecord evidenceRecord) {
List foundTimestamps = new ArrayList<>();
for (TimestampToken timestampToken : evidenceRecord.getTimestamps()) {
XmlFoundTimestamp foundTimestamp = new XmlFoundTimestamp();
foundTimestamp.setTimestamp(xmlTimestampsMap.get(timestampToken.getDSSIdAsString()));
foundTimestamps.add(foundTimestamp);
}
return foundTimestamps;
}
private XmlStructuralValidation getXmlStructuralValidation(EvidenceRecord evidenceRecord) {
return getXmlStructuralValidation(evidenceRecord.getStructureValidationResult());
}
private List buildXmlTimestamps(Collection timestamps) {
List xmlTimestampsList = new ArrayList<>();
if (Utils.isCollectionNotEmpty(timestamps)) {
List tokens = new ArrayList<>(timestamps);
tokens.sort(new TimestampTokenComparator());
for (TimestampToken timestampToken : tokens) {
String id = timestampToken.getDSSIdAsString();
XmlTimestamp xmlTimestamp = xmlTimestampsMap.get(id);
if (xmlTimestamp == null) {
xmlTimestamp = buildDetachedXmlTimestamp(timestampToken);
xmlTimestampsList.add(xmlTimestamp);
}
}
}
return xmlTimestampsList;
}
/**
* This method builds {@code XmlTimestamp} from {@code TimestampToken}
*
* @param timestampToken {@link TimestampToken}
* @return {@link XmlTimestamp}
*/
protected XmlTimestamp buildDetachedXmlTimestamp(final TimestampToken timestampToken) {
final XmlTimestamp xmlTimestampToken = new XmlTimestamp();
checkDuplicates(xmlTimestampToken, timestampToken);
xmlTimestampToken.setId(identifierProvider.getIdAsString(timestampToken));
xmlTimestampToken.setType(timestampToken.getTimeStampType());
// property is defined only for archival timestamps
xmlTimestampToken.setArchiveTimestampType(timestampToken.getArchiveTimestampType());
xmlTimestampToken.setEvidenceRecordTimestampType(timestampToken.getEvidenceRecordTimestampType());
xmlTimestampToken.setProductionTime(timestampToken.getGenerationTime());
xmlTimestampToken.setTimestampFilename(timestampToken.getFileName());
xmlTimestampToken.getDigestMatchers().addAll(getXmlDigestMatchers(timestampToken));
xmlTimestampToken.setBasicSignature(getXmlBasicSignature(timestampToken));
xmlTimestampToken.setSignerInformationStore(
getXmlSignerInformationStore(timestampToken.getSignerInformationStoreInfos()));
xmlTimestampToken.setTSAGeneralName(getXmlTSAGeneralName(timestampToken));
final CandidatesForSigningCertificate candidatesForSigningCertificate = timestampToken.getCandidatesForSigningCertificate();
final CertificateValidity theCertificateValidity = candidatesForSigningCertificate.getTheCertificateValidity();
if (theCertificateValidity != null) {
xmlTimestampToken.setSigningCertificate(getXmlSigningCertificate(timestampToken.getDSSId(), theCertificateValidity));
xmlTimestampToken.setCertificateChain(getXmlForCertificateChain(theCertificateValidity, timestampToken.getCertificateSource()));
}
xmlTimestampToken.setFoundCertificates(
getXmlFoundCertificates(timestampToken.getDSSId(), timestampToken.getCertificateSource()));
xmlTimestampToken.setFoundRevocations(
getXmlFoundRevocations(timestampToken.getCRLSource(), timestampToken.getOCSPSource()));
if (Utils.isCollectionNotEmpty(timestampToken.getTimestampScopes())) {
xmlTimestampToken.setTimestampScopes(getXmlSignatureScopes(timestampToken.getTimestampScopes()));
}
if (tokenExtractionStrategy.isTimestamp()) {
xmlTimestampToken.setBase64Encoded(timestampToken.getEncoded());
} else {
byte[] tstDigest = timestampToken.getDigest(defaultDigestAlgorithm);
xmlTimestampToken.setDigestAlgoAndValue(getXmlDigestAlgoAndValue(defaultDigestAlgorithm, tstDigest));
}
xmlTimestampsMap.put(timestampToken.getDSSIdAsString(), xmlTimestampToken);
return xmlTimestampToken;
}
private void checkDuplicates(XmlTimestamp xmlTimestamp, TimestampToken timestampToken) {
if (hasDuplicate(timestampToken)) {
xmlTimestamp.setDuplicated(true);
}
}
private boolean hasDuplicate(TimestampToken currentTimestampToken) {
for (TimestampToken timestampToken : usedTimestamps) {
if (currentTimestampToken != timestampToken &&
currentTimestampToken.getDSSIdAsString().equals(timestampToken.getDSSIdAsString())) {
return true;
}
}
return false;
}
private List getXmlDigestMatchers(TimestampToken timestampToken) {
List digestMatchers = new ArrayList<>();
digestMatchers.add(getImprintDigestMatcher(timestampToken));
digestMatchers.addAll(getManifestEntriesDigestMatchers(timestampToken.getManifestFile()));
digestMatchers.addAll(getTimestampReferenceValidationDigestMatchers(timestampToken.getReferenceValidations()));
return digestMatchers;
}
private XmlDigestMatcher getImprintDigestMatcher(TimestampToken timestampToken) {
XmlDigestMatcher digestMatcher = new XmlDigestMatcher();
digestMatcher.setType(DigestMatcherType.MESSAGE_IMPRINT);
Digest messageImprint = timestampToken.getMessageImprint();
if (messageImprint != null) {
digestMatcher.setDigestMethod(messageImprint.getAlgorithm());
digestMatcher.setDigestValue(messageImprint.getValue());
}
digestMatcher.setDataFound(timestampToken.isMessageImprintDataFound());
digestMatcher.setDataIntact(timestampToken.isMessageImprintDataIntact());
ManifestFile manifestFile = timestampToken.getManifestFile();
if (manifestFile != null) {
digestMatcher.setDocumentName(manifestFile.getFilename());
}
return digestMatcher;
}
private List getManifestEntriesDigestMatchers(ManifestFile manifestFile) {
List digestMatchers = new ArrayList<>();
if (manifestFile != null && Utils.isCollectionNotEmpty(manifestFile.getEntries())) {
for (ManifestEntry entry : manifestFile.getEntries()) {
XmlDigestMatcher digestMatcher = new XmlDigestMatcher();
digestMatcher.setType(DigestMatcherType.MANIFEST_ENTRY);
Digest digest = entry.getDigest();
if (digest != null) {
digestMatcher.setDigestMethod(digest.getAlgorithm());
digestMatcher.setDigestValue(digest.getValue());
}
digestMatcher.setDataFound(entry.isFound());
digestMatcher.setDataIntact(entry.isIntact());
digestMatcher.setUri(entry.getUri());
digestMatcher.setDocumentName(entry.getDocumentName());
digestMatchers.add(digestMatcher);
}
}
return digestMatchers;
}
/**
* Builds a list of {@code XmlSignerInfo} from {@code SignerIdentifier}s
*
* @param signerIdentifiers a set of {@link SignerIdentifier}
* @return a list of {@link XmlSignerInfo}s
*/
protected List getXmlSignerInformationStore(Set signerIdentifiers) {
if (Utils.isCollectionNotEmpty(signerIdentifiers)) {
List signerInfos = new ArrayList<>();
for (SignerIdentifier signerIdentifier : signerIdentifiers) {
signerInfos.add(getXmlSignerInfo(signerIdentifier));
}
return signerInfos;
}
return null;
}
private XmlTSAGeneralName getXmlTSAGeneralName(TimestampToken timestampToken) {
X500Principal tstInfoTsa = timestampToken.getTSTInfoTsa();
if (tstInfoTsa != null) {
XmlTSAGeneralName xmlTSAGeneralName = new XmlTSAGeneralName();
X500PrincipalHelper x500PrincipalHelper = new X500PrincipalHelper(tstInfoTsa);
xmlTSAGeneralName.setValue(x500PrincipalHelper.getRFC2253());
X500Principal issuerX500Principal = timestampToken.getIssuerX500Principal();
if (issuerX500Principal != null) {
xmlTSAGeneralName.setContentMatch(DSSASN1Utils.x500PrincipalAreEquals(tstInfoTsa, issuerX500Principal));
xmlTSAGeneralName.setOrderMatch(tstInfoTsa.equals(issuerX500Principal));
}
return xmlTSAGeneralName;
}
return null;
}
private void linkSignaturesAndTimestamps(Collection signatures) {
for (AdvancedSignature advancedSignature : signatures) {
XmlSignature currentSignature = xmlSignaturesMap.get(advancedSignature.getId());
// attach timestamps
currentSignature.setFoundTimestamps(getXmlFoundTimestamps(advancedSignature));
}
}
private List getXmlFoundTimestamps(AdvancedSignature signature) {
List foundTimestamps = new ArrayList<>();
for (TimestampToken timestampToken : signature.getAllTimestamps()) {
XmlFoundTimestamp foundTimestamp = new XmlFoundTimestamp();
foundTimestamp.setTimestamp(xmlTimestampsMap.get(timestampToken.getDSSIdAsString()));
foundTimestamps.add(foundTimestamp);
}
return foundTimestamps;
}
private void linkTimestampsAndTimestampsObjects(Collection timestamps) {
for (TimestampToken timestampToken : timestamps) {
XmlTimestamp xmlTimestampToken = xmlTimestampsMap.get(timestampToken.getDSSIdAsString());
xmlTimestampToken.setTimestampedObjects(getXmlTimestampedObjects(timestampToken.getTimestampedReferences()));
}
}
private void linkEvidenceRecordsAndTimestampsObjects(Collection evidenceRecords) {
for (EvidenceRecord evidenceRecord : evidenceRecords) {
XmlEvidenceRecord xmlEvidenceRecord = xmlEvidenceRecordMap.get(evidenceRecord.getId());
xmlEvidenceRecord.setTimestampedObjects(getXmlTimestampedObjects(evidenceRecord.getTimestampedReferences()));
}
}
private List getXmlTimestampedObjects(List timestampReferences) {
if (Utils.isCollectionNotEmpty(timestampReferences)) {
List objects = new ArrayList<>();
Set addedTokenIds = new HashSet<>();
for (final TimestampedReference timestampReference : timestampReferences) {
String id = timestampReference.getObjectId();
XmlTimestampedObject timestampedObject = createXmlTimestampedObject(timestampReference);
if (timestampedObject.getToken() == null) {
throw new DSSException(String.format("Token with Id '%s' not found", id));
}
id = timestampedObject.getToken().getId(); // can change in case of ref
if (addedTokenIds.contains(id)) {
// skip the ref if it was added before
continue;
}
addedTokenIds.add(id);
objects.add(timestampedObject);
}
return objects;
}
return null;
}
private XmlTimestampedObject createXmlTimestampedObject(final TimestampedReference timestampReference) {
XmlTimestampedObject timestampedObj = new XmlTimestampedObject();
timestampedObj.setCategory(timestampReference.getCategory());
String objectId = timestampReference.getObjectId();
switch (timestampReference.getCategory()) {
case SIGNATURE:
timestampedObj.setToken(xmlSignaturesMap.get(objectId));
return timestampedObj;
case CERTIFICATE:
if (!isUsedToken(objectId, usedCertificates)) {
String relatedCertificateId = referenceMap.get(objectId);
if (relatedCertificateId != null) {
objectId = relatedCertificateId;
if (!isUsedToken(objectId, usedCertificates)) {
break; // break to create an orphan token
}
} else {
break;
}
}
timestampedObj.setToken(xmlCertsMap.get(objectId));
return timestampedObj;
case REVOCATION:
if (!isUsedToken(objectId, usedRevocations)) {
String relatedRevocationId = referenceMap.get(objectId);
if (relatedRevocationId != null) {
objectId = relatedRevocationId;
if (!isUsedToken(objectId, usedRevocations)) {
break; // break to create an orphan token
}
} else {
break;
}
}
timestampedObj.setToken(xmlRevocationsMap.get(objectId));
return timestampedObj;
case TIMESTAMP:
timestampedObj.setToken(xmlTimestampsMap.get(objectId));
return timestampedObj;
case EVIDENCE_RECORD:
timestampedObj.setToken(xmlEvidenceRecordMap.get(objectId));
return timestampedObj;
case SIGNED_DATA:
timestampedObj.setToken(xmlSignedDataMap.get(objectId));
return timestampedObj;
default:
throw new DSSException(String.format("Unsupported category '%s'", timestampReference.getCategory()));
}
if (TimestampedObjectType.CERTIFICATE.equals(timestampedObj.getCategory())) {
timestampedObj.setToken(xmlOrphanCertificateTokensMap.get(objectId));
timestampedObj.setCategory(TimestampedObjectType.ORPHAN_CERTIFICATE);
} else if (TimestampedObjectType.REVOCATION.equals(timestampedObj.getCategory())) {
timestampedObj.setToken(xmlOrphanRevocationTokensMap.get(objectId));
timestampedObj.setCategory(TimestampedObjectType.ORPHAN_REVOCATION);
} else {
throw new DSSException(String.format("The type of object [%s] is not supported for Orphan Tokens!",
timestampedObj.getCategory()));
}
return timestampedObj;
}
private boolean isUsedToken(String tokenId, Collection usedTokens) {
for (Token token : usedTokens) {
if (token.getDSSIdAsString().equals(tokenId)) {
return true;
}
}
return false;
}
}