/**
* 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.wrapper;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import eu.europa.esig.dss.DigestAlgorithm;
import eu.europa.esig.dss.EncryptionAlgorithm;
import eu.europa.esig.dss.jaxb.diagnostic.XmlCertificate;
import eu.europa.esig.dss.jaxb.diagnostic.XmlContainerInfo;
import eu.europa.esig.dss.jaxb.diagnostic.XmlSignature;
import eu.europa.esig.dss.jaxb.diagnostic.XmlTimestamp;
import eu.europa.esig.dss.jaxb.diagnostic.XmlTrustedList;
import eu.europa.esig.dss.utils.Utils;
import eu.europa.esig.dss.x509.TimestampType;
/**
* This class represents all static data extracted by the process analysing the signature. They are independent from the
* validation policy to be applied.
*/
public class DiagnosticData {
private final eu.europa.esig.dss.jaxb.diagnostic.DiagnosticData diagnosticData;
private List<SignatureWrapper> foundSignatures;
private List<CertificateWrapper> usedCertificates;
public DiagnosticData(final eu.europa.esig.dss.jaxb.diagnostic.DiagnosticData diagnosticData) {
this.diagnosticData = diagnosticData;
}
public String getDocumentName() {
return diagnosticData.getDocumentName();
}
/**
* This method returns the list of the signature id. The result is stored in the local variable.
*
* @return list of signature ids, is never null, can be empty
*/
public List<String> getSignatureIdList() {
List<String> signatureIds = new ArrayList<String>();
List<XmlSignature> signatures = diagnosticData.getSignatures();
if (Utils.isCollectionNotEmpty(signatures)) {
for (XmlSignature xmlSignature : signatures) {
signatureIds.add(xmlSignature.getId());
}
}
return signatureIds;
}
/**
* This method returns the first signature id.
*
* @return
*/
public String getFirstSignatureId() {
SignatureWrapper firstSignature = getFirstSignatureNullSafe();
return firstSignature.getId();
}
public Date getSignatureDate() {
SignatureWrapper firstSignature = getFirstSignatureNullSafe();
return firstSignature.getDateTime();
}
/**
* This method returns the claimed signing time.
*
* @param signatureId
* The identifier of the signature, for which the date is sought.
* @return
*/
public Date getSignatureDate(final String signatureId) {
SignatureWrapper signature = getSignatureByIdNullSafe(signatureId);
return signature.getDateTime();
}
/**
* This method returns the signature format for the first signature.
*
* @return The signature format
*/
public String getSignatureFormat() {
SignatureWrapper signature = getFirstSignatureNullSafe();
return signature.getSignatureFormat();
}
/**
* This method returns the signature format for the given signature.
*
* @param signatureId
* The identifier of the signature, for which the format is sought.
* @return The signature format
*/
public String getSignatureFormat(final String signatureId) {
SignatureWrapper signature = getSignatureByIdNullSafe(signatureId);
return signature.getSignatureFormat();
}
/**
* This method returns the {@code DigestAlgorithm} of the first signature.
*
* @return The {@code DigestAlgorithm} of the first signature
*/
public DigestAlgorithm getSignatureDigestAlgorithm() {
SignatureWrapper signature = getFirstSignatureNullSafe();
return signature.getDigestAlgorithm();
}
/**
* This method returns the {@code DigestAlgorithm} for the given signature.
*
* @param signatureId
* The identifier of the signature, for which the algorithm is sought.
* @return The {@code DigestAlgorithm} for the given signature
*/
public DigestAlgorithm getSignatureDigestAlgorithm(final String signatureId) {
SignatureWrapper signature = getSignatureByIdNullSafe(signatureId);
return signature.getDigestAlgorithm();
}
/**
* This method returns the {@code EncryptionAlgorithm} of the first signature.
*
* @return The {@code EncryptionAlgorithm} of the first signature
*/
public EncryptionAlgorithm getSignatureEncryptionAlgorithm() {
SignatureWrapper signature = getFirstSignatureNullSafe();
return signature.getEncryptionAlgorithm();
}
/**
* This method returns the {@code DigestAlgorithm} for the given signature.
*
* @param signatureId
* The identifier of the signature, for which the algorithm is sought.
* @return The {@code DigestAlgorithm} for the given signature
*/
public EncryptionAlgorithm getSignatureEncryptionAlgorithm(final String signatureId) {
SignatureWrapper signature = getSignatureByIdNullSafe(signatureId);
return signature.getEncryptionAlgorithm();
}
/**
* This method returns signing certificate dss id for the first signature.
*
* @return signing certificate dss id.
*/
public String getSigningCertificateId() {
SignatureWrapper signature = getFirstSignatureNullSafe();
return signature.getSigningCertificateId();
}
/**
* This method returns signing certificate dss id for the given signature.
*
* @param signatureId
* The identifier of the signature, for which the signing certificate is sought.
* @return signing certificate dss id for the given signature.
*/
public String getSigningCertificateId(final String signatureId) {
SignatureWrapper signature = getSignatureByIdNullSafe(signatureId);
return signature.getSigningCertificateId();
}
/**
* This method indicates if the digest value and the issuer and serial match for the signing certificate .
*
* @param signatureId
* The identifier of the signature.
* @return true if the digest value and the issuer and serial match.
*/
public boolean isSigningCertificateIdentified(final String signatureId) {
SignatureWrapper signature = getSignatureByIdNullSafe(signatureId);
return signature.isSigningCertificateIdentified();
}
/**
* This method returns the list of certificates in the chain of the main signature.
*
* @param signatureId
* The identifier of the signature.
* @return list of certificate's dss id for the given signature.
*/
public List<String> getSignatureCertificateChain(final String signatureId) {
SignatureWrapper signature = getSignatureByIdNullSafe(signatureId);
return signature.getCertificateChainIds();
}
public String getPolicyId() {
SignatureWrapper signature = getFirstSignatureNullSafe();
return signature.getPolicyId();
}
/**
* The identifier of the policy.
*
* @param signatureId
* The identifier of the signature.
* @return the policy identifier
*/
public String getPolicyId(final String signatureId) {
SignatureWrapper signature = getSignatureByIdNullSafe(signatureId);
return signature.getPolicyId();
}
/**
* This method returns the list of identifier of the timestamps related to the given signature.
*
* @param signatureId
* The identifier of the signature.
* @return The list of identifier of the timestamps
*/
public List<String> getTimestampIdList(final String signatureId) {
SignatureWrapper signature = getSignatureByIdNullSafe(signatureId);
return signature.getTimestampIdsList();
}
public List<TimestampWrapper> getTimestampList(final String signatureId) {
SignatureWrapper signature = getSignatureByIdNullSafe(signatureId);
return signature.getTimestampList();
}
/**
* Indicates if the -B level is technically valid. It means that the signature value is valid.
*
* @param signatureId
* The identifier of the signature.
* @return true if the signature value is valid
*/
public boolean isBLevelTechnicallyValid(final String signatureId) {
SignatureWrapper signature = getSignatureByIdNullSafe(signatureId);
return signature.isBLevelTechnicallyValid();
}
/**
* Indicates if there is a signature timestamp.
*
* @param signatureId
* The identifier of the signature.
* @return true if the signature timestamp is present
*/
public boolean isThereTLevel(final String signatureId) {
SignatureWrapper signatureWrapper = getSignatureByIdNullSafe(signatureId);
return signatureWrapper.isThereTLevel();
}
/**
* Indicates if the -T level is technically valid. It means that the signature and the digest are valid.
*
* @param signatureId
* The identifier of the signature.
* @return true if the signature and digest are valid
*/
public boolean isTLevelTechnicallyValid(final String signatureId) {
SignatureWrapper signatureWrapper = getSignatureByIdNullSafe(signatureId);
return signatureWrapper.isTLevelTechnicallyValid();
}
/**
* Indicates if there is an -X1 or -X2 timestamp.
*
* @param signatureId
* The identifier of the signature.
* @return true if the -X1 or -X2 is present
*/
public boolean isThereXLevel(final String signatureId) {
SignatureWrapper signatureWrapper = getSignatureByIdNullSafe(signatureId);
return signatureWrapper.isThereXLevel();
}
/**
* Indicates if the -X level is technically valid. It means that the signature and the digest are valid.
*
* @param signatureId
* The identifier of the signature.
* @return true if the signature and digest are valid
*/
public boolean isXLevelTechnicallyValid(final String signatureId) {
SignatureWrapper signatureWrapper = getSignatureByIdNullSafe(signatureId);
return signatureWrapper.isXLevelTechnicallyValid();
}
/**
* Indicates if there is an archive timestamp.
*
* @param signatureId
* The identifier of the signature.
* @return true if the archive timestamp is present
*/
public boolean isThereALevel(final String signatureId) {
SignatureWrapper signatureWrapper = getSignatureByIdNullSafe(signatureId);
return signatureWrapper.isThereALevel();
}
/**
* Indicates if the -A (-LTA) level is technically valid. It means that the signature of the archive timestamps are
* valid and their imprint is valid too.
*
* @param signatureId
* The identifier of the signature.
* @return true if the signature and digest are valid
*/
public boolean isALevelTechnicallyValid(final String signatureId) {
SignatureWrapper signatureWrapper = getSignatureByIdNullSafe(signatureId);
return signatureWrapper.isALevelTechnicallyValid();
}
/**
* Returns the identifier of the timestamp signing certificate.
*
* @param timestampId
* timestamp id
* @return signing certificate id
*/
public String getTimestampSigningCertificateId(final String timestampId) {
TimestampWrapper timestamp = getTimestampByIdNullSafe(timestampId);
return timestamp.getSigningCertificateId();
}
public String getTimestampType(String timestampId) {
TimestampWrapper timestamp = getTimestampByIdNullSafe(timestampId);
return timestamp.getType();
}
/**
* This method indicates if the certificate signature is valid and the revocation status is valid.
*
* @param dssCertificateId
* DSS certificate identifier to be checked
* @return certificate validity
*/
public boolean isValidCertificate(final String dssCertificateId) {
CertificateWrapper certificate = getUsedCertificateByIdNullSafe(dssCertificateId);
return certificate.isValidCertificate();
}
/**
* This method returns the subject distinguished name for the given dss certificate identifier.
*
* @param dssCertificateId
* DSS certificate identifier to be checked
* @return subject distinguished name
*/
public String getCertificateDN(final String dssCertificateId) {
CertificateWrapper certificate = getUsedCertificateByIdNullSafe(dssCertificateId);
return certificate.getCertificateDN();
}
/**
* This method returns the issuer distinguished name for the given dss certificate identifier.
*
* @param dssCertificateId
* DSS certificate identifier to be checked
* @return issuer distinguished name
*/
public String getCertificateIssuerDN(final String dssCertificateId) {
CertificateWrapper certificate = getUsedCertificateByIdNullSafe(dssCertificateId);
return certificate.getCertificateIssuerDN();
}
/**
* This method returns the serial number of the given dss certificate identifier.
*
* @param dssCertificateId
* DSS certificate identifier to be checked
* @return serial number
*/
public String getCertificateSerialNumber(final String dssCertificateId) {
CertificateWrapper certificate = getUsedCertificateByIdNullSafe(dssCertificateId);
return certificate.getSerialNumber();
}
/**
* This method returns the revocation source for the given certificate.
*
* @param dssCertificateId
* DSS certificate identifier to be checked
* @return revocation source
*/
public String getCertificateRevocationSource(final String dssCertificateId) {
CertificateWrapper certificate = getUsedCertificateByIdNullSafe(dssCertificateId);
if (certificate.isRevocationDataAvailable()) {
return certificate.getLatestRevocationData().getSource();
}
return Utils.EMPTY_STRING;
}
/**
* This method returns the revocation status for the given certificate.
*
* @param dssCertificateId
* DSS certificate identifier to be checked
* @return revocation status
*/
public boolean getCertificateRevocationStatus(final String dssCertificateId) {
CertificateWrapper certificate = getUsedCertificateByIdNullSafe(dssCertificateId);
if (certificate.isRevocationDataAvailable()) {
return certificate.getLatestRevocationData().isStatus();
}
return false;
}
/**
* This method returns the revocation reason for the given certificate.
*
* @param dssCertificateId
* DSS certificate identifier to be checked
* @return revocation reason
*/
public String getCertificateRevocationReason(String dssCertificateId) {
CertificateWrapper certificate = getUsedCertificateByIdNullSafe(dssCertificateId);
if (certificate.isRevocationDataAvailable()) {
return certificate.getLatestRevocationData().getReason();
}
return Utils.EMPTY_STRING;
}
public String getErrorMessage(final String signatureId) {
SignatureWrapper signature = getSignatureByIdNullSafe(signatureId);
return signature.getErrorMessage();
}
private SignatureWrapper getFirstSignatureNullSafe() {
List<SignatureWrapper> signatures = getSignatures();
if (Utils.isCollectionNotEmpty(signatures)) {
return signatures.get(0);
}
return new SignatureWrapper(new XmlSignature()); // TODO improve ?
}
public SignatureWrapper getSignatureById(String id) {
List<SignatureWrapper> signatures = getSignatures();
if (Utils.isCollectionNotEmpty(signatures)) {
for (SignatureWrapper xmlSignature : signatures) {
if (Utils.areStringsEqual(id, xmlSignature.getId())) {
return xmlSignature;
}
}
}
return null;
}
private SignatureWrapper getSignatureByIdNullSafe(String id) {
List<SignatureWrapper> signatures = getSignatures();
if (Utils.isCollectionNotEmpty(signatures)) {
for (SignatureWrapper xmlSignature : signatures) {
if (Utils.areStringsEqual(id, xmlSignature.getId())) {
return xmlSignature;
}
}
}
return new SignatureWrapper(new XmlSignature()); // TODO improve ?
}
private TimestampWrapper getTimestampByIdNullSafe(String id) {
List<SignatureWrapper> signatures = getSignatures();
for (SignatureWrapper signatureWrapper : signatures) {
List<TimestampWrapper> timestampList = signatureWrapper.getTimestampList();
for (TimestampWrapper timestampWrapper : timestampList) {
if (Utils.areStringsEqual(id, timestampWrapper.getId())) {
return timestampWrapper;
}
}
}
return new TimestampWrapper(new XmlTimestamp());
}
public CertificateWrapper getUsedCertificateByIdNullSafe(String id) {
List<CertificateWrapper> certificates = getUsedCertificates();
if (Utils.isCollectionNotEmpty(certificates)) {
for (CertificateWrapper certificate : certificates) {
if (Utils.areStringsEqual(id, certificate.getId())) {
return certificate;
}
}
}
return new CertificateWrapper(new XmlCertificate()); // TODO improve ?
}
public CertificateWrapper getUsedCertificateById(String id) {
List<CertificateWrapper> certificates = getUsedCertificates();
if (Utils.isCollectionNotEmpty(certificates)) {
for (CertificateWrapper certificate : certificates) {
if (Utils.areStringsEqual(id, certificate.getId())) {
return certificate;
}
}
}
return null;
}
public List<SignatureWrapper> getSignatures() {
if (foundSignatures == null) {
foundSignatures = new ArrayList<SignatureWrapper>();
List<XmlSignature> xmlSignatures = diagnosticData.getSignatures();
if (Utils.isCollectionNotEmpty(xmlSignatures)) {
for (XmlSignature xmlSignature : xmlSignatures) {
foundSignatures.add(new SignatureWrapper(xmlSignature));
}
}
}
return foundSignatures;
}
public List<CertificateWrapper> getUsedCertificates() {
if (usedCertificates == null) {
usedCertificates = new ArrayList<CertificateWrapper>();
List<XmlCertificate> xmlCertificates = diagnosticData.getUsedCertificates();
if (Utils.isCollectionNotEmpty(xmlCertificates)) {
for (XmlCertificate certificate : xmlCertificates) {
usedCertificates.add(new CertificateWrapper(certificate));
}
}
}
return usedCertificates;
}
/**
* This method returns signatures (not countersignatures)
*
* @return
*/
public Set<SignatureWrapper> getAllSignatures() {
Set<SignatureWrapper> signatures = new HashSet<SignatureWrapper>();
List<SignatureWrapper> mixedSignatures = getSignatures();
for (SignatureWrapper signatureWrapper : mixedSignatures) {
if (Utils.isStringEmpty(signatureWrapper.getParentId())) {
signatures.add(signatureWrapper);
}
}
return signatures;
}
/**
* This method returns counter-signatures (not signatures)
*
* @return
*/
public Set<SignatureWrapper> getAllCounterSignatures() {
Set<SignatureWrapper> signatures = new HashSet<SignatureWrapper>();
List<SignatureWrapper> mixedSignatures = getSignatures();
for (SignatureWrapper signatureWrapper : mixedSignatures) {
if (Utils.isStringNotEmpty(signatureWrapper.getParentId())) {
signatures.add(signatureWrapper);
}
}
return signatures;
}
public Set<RevocationWrapper> getAllRevocationData() {
Set<RevocationWrapper> revocationData = new HashSet<RevocationWrapper>();
List<CertificateWrapper> certificates = getUsedCertificates();
if (Utils.isCollectionNotEmpty(certificates)) {
for (CertificateWrapper certificate : certificates) {
Set<RevocationWrapper> revocations = certificate.getRevocationData();
if (revocations != null) {
revocationData.addAll(revocations);
}
}
}
return revocationData;
}
public Set<TimestampWrapper> getAllTimestampsNotArchival() {
Set<TimestampWrapper> notArchivalTimestamps = new HashSet<TimestampWrapper>();
List<SignatureWrapper> signatures = getSignatures();
if (Utils.isCollectionNotEmpty(signatures)) {
for (SignatureWrapper signatureWrapper : signatures) {
notArchivalTimestamps.addAll(signatureWrapper.getAllTimestampsNotArchival());
}
}
return notArchivalTimestamps;
}
public Set<TimestampWrapper> getAllTimestampsNotArchival(String signatureId) {
SignatureWrapper signature = getSignatureById(signatureId);
if (signature != null) {
return signature.getAllTimestampsNotArchival();
}
return new HashSet<TimestampWrapper>();
}
public Set<TimestampWrapper> getAllArchiveTimestamps() {
Set<TimestampWrapper> archivalTimestamps = new HashSet<TimestampWrapper>();
List<SignatureWrapper> signatures = getSignatures();
if (Utils.isCollectionNotEmpty(signatures)) {
for (SignatureWrapper signatureWrapper : signatures) {
archivalTimestamps.addAll(signatureWrapper.getTimestampListByType(TimestampType.ARCHIVE_TIMESTAMP));
}
}
return archivalTimestamps;
}
public Set<TimestampWrapper> getAllTimestamps() {
Set<TimestampWrapper> allTimestamps = new HashSet<TimestampWrapper>();
List<SignatureWrapper> signatures = getSignatures();
if (Utils.isCollectionNotEmpty(signatures)) {
for (SignatureWrapper signatureWrapper : signatures) {
allTimestamps.addAll(signatureWrapper.getTimestampList());
}
}
return allTimestamps;
}
public eu.europa.esig.dss.jaxb.diagnostic.DiagnosticData getJaxbModel() {
return diagnosticData;
}
public boolean isContainerInfoPresent() {
return diagnosticData.getContainerInfo() != null;
}
public String getContainerType() {
XmlContainerInfo containerInfo = diagnosticData.getContainerInfo();
if (containerInfo != null) {
return containerInfo.getContainerType();
}
return null;
}
public String getZipComment() {
XmlContainerInfo containerInfo = diagnosticData.getContainerInfo();
if (containerInfo != null) {
return containerInfo.getZipComment();
}
return null;
}
public boolean isMimetypeFilePresent() {
XmlContainerInfo containerInfo = diagnosticData.getContainerInfo();
if (containerInfo != null) {
return containerInfo.isMimeTypeFilePresent();
}
return false;
}
public String getMimetypeFileContent() {
XmlContainerInfo containerInfo = diagnosticData.getContainerInfo();
if (containerInfo != null) {
return containerInfo.getMimeTypeContent();
}
return null;
}
public XmlContainerInfo getContainerInfo() {
return diagnosticData.getContainerInfo();
}
public List<XmlTrustedList> getTrustedLists() {
return diagnosticData.getTrustedLists();
}
public XmlTrustedList getListOfTrustedLists() {
return diagnosticData.getListOfTrustedLists();
}
public String getLOTLCountryCode() {
XmlTrustedList listOfTrustedLists = diagnosticData.getListOfTrustedLists();
if (listOfTrustedLists != null) {
return listOfTrustedLists.getCountryCode();
}
return null;
}
}