/* * eID Applet Project. * Copyright (C) 2009-2011 FedICT. * Copyright (C) 2014 e-Contract.be BVBA. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version * 3.0 as published by the Free Software Foundation. * * This software 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 software; if not, see * http://www.gnu.org/licenses/. */ package be.fedict.eid.applet.service.signer.asic; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import javax.xml.crypto.URIDereferencer; import javax.xml.parsers.ParserConfigurationException; import org.apache.commons.io.IOUtils; import org.w3c.dom.Document; import org.xml.sax.SAXException; import be.fedict.eid.applet.service.signer.AbstractXmlSignatureService; import be.fedict.eid.applet.service.signer.CloseActionOutputStream; import be.fedict.eid.applet.service.signer.DigestAlgo; import be.fedict.eid.applet.service.signer.TemporaryDataStorage; import be.fedict.eid.applet.service.signer.facets.IdentitySignatureFacet; import be.fedict.eid.applet.service.signer.facets.KeyInfoSignatureFacet; import be.fedict.eid.applet.service.signer.facets.RevocationDataService; import be.fedict.eid.applet.service.signer.facets.XAdESSignatureFacet; import be.fedict.eid.applet.service.signer.facets.XAdESXLSignatureFacet; import be.fedict.eid.applet.service.signer.odf.ODFUtil; import be.fedict.eid.applet.service.signer.time.TimeStampService; import be.fedict.eid.applet.service.spi.AddressDTO; import be.fedict.eid.applet.service.spi.DigestInfo; import be.fedict.eid.applet.service.spi.IdentityDTO; import be.fedict.eid.applet.service.spi.SignatureService; /** * Abstract ASiC signature service implementation. Implements Associated * Signature Containers according to ETSI TS 102 918 v1.1.1. * * @author Frank Cornelis. * */ public class AbstractASiCSignatureService extends AbstractXmlSignatureService implements SignatureService { private final TemporaryDataStorage temporaryDataStorage; private final File tmpFile; private final OutputStream documentOutputStream; public AbstractASiCSignatureService(InputStream documentInputStream, DigestAlgo digestAlgo, RevocationDataService revocationDataService, TimeStampService timeStampService, String claimedRole, IdentityDTO identity, byte[] photo, TemporaryDataStorage temporaryDataStorage, OutputStream documentOutputStream) throws IOException { super(digestAlgo); this.temporaryDataStorage = temporaryDataStorage; this.documentOutputStream = documentOutputStream; this.tmpFile = File.createTempFile("eid-dss-", ".asice"); FileOutputStream fileOutputStream; fileOutputStream = new FileOutputStream(this.tmpFile); IOUtils.copy(documentInputStream, fileOutputStream); addSignatureFacet(new ASiCSignatureFacet(this.tmpFile, digestAlgo)); XAdESSignatureFacet xadesSignatureFacet = new XAdESSignatureFacet(getSignatureDigestAlgorithm()); xadesSignatureFacet.setRole(claimedRole); xadesSignatureFacet.setXadesNamespacePrefix("xades"); addSignatureFacet(xadesSignatureFacet); addSignatureFacet( new XAdESXLSignatureFacet(timeStampService, revocationDataService, getSignatureDigestAlgorithm())); addSignatureFacet(new KeyInfoSignatureFacet(true, false, false)); if (null != identity) { IdentitySignatureFacet identitySignatureFacet = new IdentitySignatureFacet(identity, photo, getSignatureDigestAlgorithm()); addSignatureFacet(identitySignatureFacet); } } @Override protected String getSignatureDescription() { return "Associated Signature Container"; } public String getFilesDigestAlgorithm() { return null; } @Override protected TemporaryDataStorage getTemporaryDataStorage() { return this.temporaryDataStorage; } @Override protected URIDereferencer getURIDereferencer() { return new ASiCURIDereferencer(this.tmpFile); } @Override protected OutputStream getSignedDocumentOutputStream() { return new ASiCSignatureOutputStream(this.tmpFile, new CloseActionOutputStream(this.documentOutputStream, new CloseAction())); } private class CloseAction implements Runnable { public void run() { AbstractASiCSignatureService.this.tmpFile.delete(); } } @Override public DigestInfo preSign(List<DigestInfo> digestInfos, List<X509Certificate> signingCertificateChain, IdentityDTO identity, AddressDTO address, byte[] photo) throws NoSuchAlgorithmException { return super.preSign(digestInfos, signingCertificateChain, identity, address, photo); } @Override protected Document getEnvelopingDocument() throws ParserConfigurationException, IOException, SAXException { FileInputStream fileInputStream = new FileInputStream(this.tmpFile); ZipInputStream zipInputStream = new ZipInputStream(fileInputStream); ZipEntry zipEntry; while (null != (zipEntry = zipInputStream.getNextEntry())) { if (ASiCUtil.isSignatureZipEntry(zipEntry)) { Document documentSignaturesDocument = ODFUtil.loadDocument(zipInputStream); return documentSignaturesDocument; } } Document document = ASiCUtil.createNewSignatureDocument(); return document; } }