All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.digidoc4j.impl.asic.xades.TimestampSignature Maven / Gradle / Ivy

Go to download

DigiDoc4j is a Java library for digitally signing documents and creating digital signature containers of signed documents

The newest version!
/* DigiDoc4J library
 *
 * This software is released under either the GNU Library General Public
 * License (see LICENSE.LGPL).
 *
 * Note that the only valid version of the LGPL license as far as this
 * project is concerned is the original GNU Library General Public License
 * Version 2.1, February 1999
 */

package org.digidoc4j.impl.asic.xades;

import eu.europa.esig.dss.model.DSSException;
import eu.europa.esig.dss.model.x509.CertificateToken;
import eu.europa.esig.dss.spi.x509.tsp.TimestampToken;
import eu.europa.esig.dss.xades.validation.XAdESSignature;
import eu.europa.esig.dss.xml.utils.DomUtils;
import eu.europa.esig.xades.definition.XAdESPath;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.tsp.TimeStampToken;
import org.digidoc4j.SignatureProfile;
import org.digidoc4j.X509Cert;
import org.digidoc4j.exceptions.CertificateNotFoundException;
import org.digidoc4j.exceptions.TechnicalException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.security.cert.X509Certificate;
import java.util.Date;

public class TimestampSignature extends TimemarkSignature {

  private final static Logger logger = LoggerFactory.getLogger(TimestampSignature.class);
  private transient TimeStampToken timeStampToken;
  private transient X509Cert timestampTokenCertificate;

  public TimestampSignature(XadesValidationReportGenerator xadesReportGenerator) {
    super(xadesReportGenerator);
  }

  @Override
  public SignatureProfile getProfile() {
    return SignatureProfile.LT;
  }

  @Override
  public X509Cert getTimeStampTokenCertificate() {
    if (timestampTokenCertificate != null) {
      return timestampTokenCertificate;
    }
    XAdESSignature origin = getDssSignature();
    if (origin.getSignatureTimestamps() == null || origin.getSignatureTimestamps().isEmpty()) {
      throwTimestampNotFoundException(origin.getId());
    }
    TimestampToken timestampToken = origin.getSignatureTimestamps().get(0);

    CertificateToken issuerToken = getIssuerToken(timestampToken);
    if (issuerToken == null) {
      return throwTimestampNotFoundException(origin.getId());
    }
    X509Certificate certificate = issuerToken.getCertificate();
    timestampTokenCertificate = new X509Cert(certificate);
    return timestampTokenCertificate;
  }

  @Override
  public Date getTimeStampCreationTime() {
    if (timeStampToken == null) {
      timeStampToken = findTimestampToken();
    }
    if (timeStampToken == null || timeStampToken.getTimeStampInfo() == null) {
      logger.warn("Timestamp token was not found");
      return null;
    }
    return timeStampToken.getTimeStampInfo().getGenTime();
  }

  @Override
  public Date getTrustedSigningTime() {
    return getTimeStampCreationTime();
  }

  private TimeStampToken findTimestampToken() {
    XAdESPath xAdESPaths = getxPathQueryHolder();
    logger.debug("Finding timestamp token");
    NodeList timestampNodes = DomUtils.getNodeList(getSignatureElement(), xAdESPaths.getSignatureTimestampPath());
    if (timestampNodes.getLength() == 0) {
      logger.warn("Signature timestamp element was not found");
      return null;
    }
    if (timestampNodes.getLength() > 1) {
      logger.warn("Signature contains more than one timestamp: " + timestampNodes.getLength() + ". Using only the first one");
    }
    Node timestampNode = timestampNodes.item(0);

    Element timestampTokenNode = DomUtils.getElement(timestampNode, xAdESPaths.getCurrentEncapsulatedTimestamp());
    if (timestampTokenNode == null) {
      logger.warn("The timestamp cannot be extracted from the signature");
      return null;
    }
    String base64EncodedTimestamp = timestampTokenNode.getTextContent();
    return createTimeStampToken(base64EncodedTimestamp);
  }

  private TimeStampToken createTimeStampToken(final String base64EncodedTimestamp) throws DSSException {
    logger.debug("Creating timestamp token");
    try {
      byte[] tokenBytes = Base64.decodeBase64(base64EncodedTimestamp);
      CMSSignedData signedData = new CMSSignedData(tokenBytes);
      return new TimeStampToken(signedData);
    } catch (Exception e) {
      logger.error("Error parsing timestamp token: " + e.getMessage());
      throw new TechnicalException("Error parsing timestamp token", e);
    }
  }

  private X509Cert throwTimestampNotFoundException(String sigId) {
    logger.error("TimeStamp certificate not found, Signature id: " + sigId);
    throw new CertificateNotFoundException("TimeStamp certificate not found", sigId);
  }

  private CertificateToken getIssuerToken(TimestampToken timestampToken) {
    for (CertificateToken certificateToken : timestampToken.getCertificates()) {
      if (timestampToken.isSignedBy(certificateToken)) {
        return certificateToken;
      }
    }
    return null;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy