Java tutorial
/* 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.bdoc.xades; import java.security.cert.X509Certificate; import java.util.Date; 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 eu.europa.esig.dss.DSSException; import eu.europa.esig.dss.validation.TimestampToken; import eu.europa.esig.dss.x509.CertificateToken; import eu.europa.esig.dss.xades.DSSXMLUtils; import eu.europa.esig.dss.xades.XPathQueryHolder; import eu.europa.esig.dss.xades.validation.XAdESSignature; public class TimestampSignature extends TimemarkSignature { private final static Logger logger = LoggerFactory.getLogger(TimestampSignature.class); private Element signatureElement; private XPathQueryHolder xPathQueryHolder; private TimeStampToken timeStampToken; private X509Cert timestampTokenCertificate; public TimestampSignature(XadesValidationReportGenerator xadesReportGenerator) { super(xadesReportGenerator); this.xPathQueryHolder = getxPathQueryHolder(); this.signatureElement = getSignatureElement(); } @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(); } TimestampToken timestampToken = origin.getSignatureTimestamps().get(0); CertificateToken issuerToken = timestampToken.getIssuerToken(); if (issuerToken == null) { return throwTimestampNotFoundException(); } 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() { logger.debug("Finding timestamp token"); NodeList timestampNodes = DSSXMLUtils.getNodeList(signatureElement, xPathQueryHolder.XPATH_SIGNATURE_TIMESTAMP); 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 = DSSXMLUtils.getElement(timestampNode, xPathQueryHolder.XPATH__ENCAPSULATED_TIMESTAMP); 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() { logger.error("TimeStamp certificate not found"); throw new CertificateNotFoundException("TimeStamp certificate not found"); } }