package fr.gouv.finances.dgfip.xemelios.batch.chaineimport.xasverifier;
-import fr.gouv.finances.dgfip.xemelios.batch.chaineimport.xasverifier.FileUtils.ByExtensionFileFilter;
-import fr.gouv.finances.dgfip.xemelios.batch.chaineimport.xasverifier.FileUtils.LastModifiedFileComparator;
-import fr.gouv.finances.dgfip.utils.xml.FactoryProvider;
-import fr.gouv.finances.dgfip.utils.xml.NamespaceContextImpl;
-import fr.gouv.finances.dgfip.xemelios.batch.Batch;
-import fr.gouv.finances.dgfip.xemelios.batch.suivi.Message;
-import fr.gouv.finances.dgfip.xemelios.batch.suivi.Traitement;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
+
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
+
import org.apache.log4j.Logger;
import org.apache.xml.security.utils.resolver.ResourceResolver;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
+
import xades4j.XAdES4jException;
import xades4j.providers.CertificateValidationProvider;
import xades4j.providers.impl.PKIXCertificateValidationProvider;
import xades4j.verification.XAdESVerificationResult;
import xades4j.verification.XadesVerificationProfile;
import xades4j.verification.XadesVerifier;
+import fr.gouv.finances.dgfip.utils.xml.FactoryProvider;
+import fr.gouv.finances.dgfip.utils.xml.NamespaceContextImpl;
+import fr.gouv.finances.dgfip.xemelios.batch.Batch;
+import fr.gouv.finances.dgfip.xemelios.batch.chaineimport.xasverifier.FileUtils.ByExtensionFileFilter;
+import fr.gouv.finances.dgfip.xemelios.batch.chaineimport.xasverifier.FileUtils.LastModifiedFileComparator;
+import fr.gouv.finances.dgfip.xemelios.batch.suivi.Message;
+import fr.gouv.finances.dgfip.xemelios.batch.suivi.Traitement;
/**
* @author CBO
*/
public class XasVerifier extends Batch {
- private static final Logger logger = Logger.getLogger(XasVerifier.class);
- public static final String SIGNATURE_SPEC_NS = "http://www.w3.org/2000/09/xmldsig#";
-
- // pour s'assurer qu'on en fait pas plusieurs à la fois
- private static int instanceCount = 0;
- private static Object instance = null;
- private static final Object locker = new Object();
-
- public static final String BATCH_NAME = "xas.verifier";
- static {
- ResourceResolver.init();
- ResourceResolver.register(StdResourceResolver.class.getName());
- }
- private static int BUFFER_SIZE = 2048;
- public static final String INPUT_DIR_PROPNAME = "cft.dir";
- public static final String FILE_OK_PROPNAME = "xar.out";
- public static final String FILE_KO_PROPNAME = "xas.error";
- public static final String FILE_ARCH_PROPNAME = "arch.dir";
- public static final String ARCH_PROPNAME = "archive.xas";
-
- private boolean shouldArchivateXas = false;
- private File archiveDir = null;
- private File inputDir = null;
- private File okDir = null;
- private File koDir = null;
-
- private Traitement traitement;
-
- public XasVerifier(String args[]) {
- super(args);
- // on vérifie que le machin ne tourne pas, et sinon on quitte
- traitement = new Traitement(XasVerifier.class, BATCH_NAME);
- }
-
- @Override
- protected void initialize() throws Exception {
- String inputDirFileName = getProps().getProperty(INPUT_DIR_PROPNAME);
- String fileOkDirName = getProps().getProperty(FILE_OK_PROPNAME);
- String fileKODirName = getProps().getProperty(FILE_KO_PROPNAME);
- String fileOkArchDirName = getProps().getProperty(FILE_ARCH_PROPNAME);
- String archivateXas = getProps().getProperty(ARCH_PROPNAME, "false");
- shouldArchivateXas = Boolean.parseBoolean(archivateXas);
- if(shouldArchivateXas ) {
- archiveDir = new File(fileOkArchDirName);
- }
- inputDir = new File(inputDirFileName);
- okDir = new File(fileOkDirName);
- koDir = new File(fileKODirName);
- checkWriteDirectory(inputDir);
- checkWriteDirectory(okDir);
- checkWriteDirectory(koDir);
- if(shouldArchivateXas)
- checkWriteDirectory(archiveDir);
- }
-
- protected void process(File fileInputDir, File fileOKDir, File fileKODir, File fileOKArchDir) throws Exception {
-// logger.info(" Répertoire d'entrée : " + fileInputDir.getAbsolutePath());
-// logger.info(" Répertoire de sortie OK : " + fileOKDir.getAbsolutePath());
-// logger.info(" Répertoire de sortie KO : " + fileKODir.getAbsolutePath());
-// if(fileOKArchDir!=null)
-// logger.info(" Répertoire d'archivage XAS OK : " + fileOKArchDir.getAbsolutePath());
-// else
-// logger.info(" Pas d'archivqge des XAS");
- URL tcUrl = XasVerifier.class.getResource("/fr/gouv/finances/dgfip/xemelios/batch/chaineimport/xasverifier/resources/trustChains.zip");
- CertificateContainer trustChains = CertificateContainer.fromZipURL(tcUrl);
- URL tsUrl = XasVerifier.class.getResource("/fr/gouv/finances/dgfip/xemelios/batch/chaineimport/xasverifier/resources/trustSigners.zip");
- CertificateContainer trustSigners = CertificateContainer.fromZipURL(tsUrl);
- CertificateValidationProvider certValidator = new PKIXCertificateValidationProvider(
- CertificateContainer.fromCollection(trustChains.extractRootCertificates()).buildJKSKeyStore(),
- false,
- CertificateContainer.fromCollection(trustChains.extractNotRootCertificates()).buildCertStore());
- XadesVerificationProfile p = new XadesVerificationProfile(certValidator);
- XadesVerifier v = p.newVerifier();
- for (File xasFile : getXasFiles(fileInputDir)) {
- String _msg = "Vérification du fichier " + xasFile.getAbsolutePath();
- logger.info(_msg);
- Message msg = traitement.addMessage(Traitement.SEVERITY_INFO, _msg);
- UnZippedXasFile unZippedXasFile = null;
- try {
- unZippedXasFile = unzipXasFile(xasFile);
- XAdESVerificationResult result = verifyXas(unZippedXasFile, v, trustSigners); // TODO : log result
- FileUtils.moveFileWithOverwrite(unZippedXasFile.getXarFile(), new File(fileOKDir, unZippedXasFile.getXarFile().getName()));
- unZippedXasFile.delete();
- if(shouldArchivateXas)
- FileUtils.moveFileWithOverwrite(xasFile, new File(fileOKArchDir, xasFile.getName()));
- else
- xasFile.delete();
-// _msg = "Le fichier " + xasFile.getAbsolutePath() + " a été vérifié avec succès.";
- logger.info(_msg);
- msg.setInfoCompl(_msg);
- } catch (InvalidXasFileException e) {
- if (unZippedXasFile != null) {
- unZippedXasFile.delete();
- }
- FileUtils.moveFileWithOverwrite(xasFile, new File(fileKODir, xasFile.getName()));
- _msg = "Le fichier " + xasFile.getAbsolutePath() + " est invalide: ";
-// logger.info(_msg, e);
- msg.setSeverity(Traitement.SEVERITY_WARN);
- msg.setInfoCompl(_msg+e.getMessage());
- } catch (Exception e) {
- if (unZippedXasFile != null) {
- unZippedXasFile.delete();
- }
- FileUtils.moveFileWithOverwrite(xasFile, new File(fileKODir, xasFile.getName()));
- _msg = "Le fichier " + xasFile.getAbsolutePath() + " a provoquée une erreur inattendue. ";
- msg.setSeverity(Traitement.SEVERITY_WARN);
- msg.setInfoCompl(_msg+e.getMessage());
- logger.error(_msg, e);
- }
- }
- logger.info("Fin du processus de vérification xas");
- traitement.setEnd(System.currentTimeMillis());
- }
-
- protected static XAdESVerificationResult verifyXas(UnZippedXasFile unizipedXasFile, XadesVerifier verifier, CertificateContainer trustSigners) throws InvalidXasFileException, FileNotFoundException, ParserConfigurationException, SAXException, IOException, TransformerException, CertificateEncodingException, XPathExpressionException {
- if (!unizipedXasFile.getXadFile().exists()) {
- throw new InvalidXasFileException("Fichier de signature non trouvé : " + unizipedXasFile.getXadFile().getName());
- }
- if (!unizipedXasFile.getXarFile().exists()) {
- throw new InvalidXasFileException("Fichier xar non trouvé : " + unizipedXasFile.getXarFile().getName());
- }
-
- javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
- dbf.setNamespaceAware(true);
- dbf.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE);
- FileInputStream xadInputStream = new FileInputStream(unizipedXasFile.getXadFile());
- try {
- Document document = dbf.newDocumentBuilder().parse(new InputSource(xadInputStream));
- XPathFactory xpf = FactoryProvider.getXPathFactory();
- XPath xp = xpf.newXPath();
- NamespaceContextImpl nsCtx = new NamespaceContextImpl();
- nsCtx.addMapping("ds", SIGNATURE_SPEC_NS);
- xp.setNamespaceContext(nsCtx);
- NodeList sigs = (NodeList)xp.evaluate("//ds:Signature", document, XPathConstants.NODESET);
- if (sigs.getLength() != 1) {
- throw new InvalidXasFileException("Plusieurs signatures ont été détectées dans le fichier xad, interruption de la vérification");
- }
- Element sigElement = (Element) sigs.item(0);
- StdResourceResolver.startSigningProcess(unizipedXasFile.getDirectory());
- try {
- XAdESVerificationResult xaesvr = verifier.verify(sigElement);
- if (trustSigners.contains(xaesvr.getValidationCertificate())) {
- return xaesvr;
- } else {
- throw new InvalidXasFileException("Le certificat du signataire n'a pas été reconnu (" + xaesvr.getValidationCertificate().getSerialNumber() + ")");
- }
- } catch (XAdES4jException xaese) {
- throw new InvalidXasFileException(xaese);
- } finally {
- StdResourceResolver.endSigningProcess();
- }
- } finally {
- xadInputStream.close();
- }
- }
-
- private static File createCleanTempDir(File xasFile) throws IOException {
- File xasDirectory = new File(xasFile + ".tmpDir");
- if (xasDirectory.exists()) {
- if (!xasDirectory.delete()) {
- throw new IOException("Impossible de supprimer le répertoire " + xasDirectory);
- }
- }
- if (!xasDirectory.mkdir()) {
- throw new IOException("Impossible de créer le répertoire " + xasDirectory);
- }
- return xasDirectory;
- }
-
- private static UnZippedXasFile unzipXasFile(File xasFile) throws IOException, InvalidXasFileException {
- File xasDirectory = createCleanTempDir(xasFile);
- ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(xasFile)));
- try {
- try {
- ZipEntry entry = null;
- String xarFilename = null;
- String xadFilename = null;
- while ((entry = zis.getNextEntry()) != null) {
- String outputFilename = xasDirectory + File.separator + entry.getName();
- if (entry.getName().toLowerCase().endsWith(".xar")) {
- if (xarFilename == null) {
- xarFilename = entry.getName();
- } else {
- throw new InvalidXasFileException("L'archive est invalide : elle contient plusieurs fichiers xar");
- }
- }
- if (entry.getName().toLowerCase().endsWith(".xad")) {
- if (xadFilename == null) {
- xadFilename = entry.getName();
- } else {
- throw new InvalidXasFileException("L'archive est invalide : elle contient plusieurs fichiers xad");
- }
- }
- BufferedOutputStream dest = new BufferedOutputStream(new FileOutputStream(outputFilename), BUFFER_SIZE);
- try {
- byte data[] = new byte[BUFFER_SIZE];
- int count;
- while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
- dest.write(data, 0, count);
- }
- } finally {
- dest.flush();
- dest.close();
- }
- }
- if (xarFilename == null) {
- throw new InvalidXasFileException("L'archive est invalide : aucun fichier xar trouvé");
- }
- if (xadFilename == null) {
- throw new InvalidXasFileException("L'archive est invalide : aucun fichier xad trouvé");
- }
- return new UnZippedXasFile(xasDirectory, xasFile, new File(xasDirectory, xadFilename), new File(xasDirectory, xarFilename));
- } finally {
- zis.close();
- }
- } catch (IOException ioe) {
- FileUtils.deleteDirectory(xasDirectory);
- throw ioe;
- } catch (InvalidXasFileException ixfe) {
- FileUtils.deleteDirectory(xasDirectory);
- throw ixfe;
- }
- }
-
- private static List<File> getXasFiles(File fileInputDir) {
- return FileUtils.listFiles(fileInputDir, new ByExtensionFileFilter("xas"), new LastModifiedFileComparator());
- }
-
- @Override
- protected void doProcess() throws Exception {
- if(checkNotRunning()) {
- try {
- process(inputDir, okDir, koDir, archiveDir);
- } catch(Exception ex) {
- logger.error("unexpected exception:",ex);
- throw ex;
- } finally {
- clearLock();
- }
- } else {
- traitement.setResume("Dejà en cours d'execution");
- traitement.setEnd(System.currentTimeMillis());
- }
- }
-
- @Override
- public String getResumeTraitement() {
- return "xas.verifier";
- }
-
- @Override
- public String typeTraitementRefCode() {
- return "xas.verifier";
- }
-
- @Override
- public String getInformations() {
- return "Running";
- }
-
- @Override
- protected String getBatchVersion() {
- return "1.0.0";
- }
-
- private boolean checkNotRunning() {
- synchronized(locker) {
- if(instanceCount==0) {
- instanceCount++;
- instance = this;
- return true;
- }
- return false;
- }
- }
- private void clearLock() {
- synchronized(locker) {
- // on ne peut pas supprimer un lock qu'on a pas posé
- if(instance==this) {
- instanceCount--;
- instance=null;
- }
- }
- }
-
- public static class VerifiedUnizipedXasFile {
-
- private UnZippedXasFile unizipedXasFile;
- private XAdESVerificationResult xaesvr;
-
- public VerifiedUnizipedXasFile(UnZippedXasFile unizipedXasFile, XAdESVerificationResult xaesvr) {
- this.unizipedXasFile = unizipedXasFile;
- this.xaesvr = xaesvr;
- }
-
- public UnZippedXasFile getUnizipedXasFile() {
- return unizipedXasFile;
- }
-
- public XAdESVerificationResult getXaesvr() {
- return xaesvr;
- }
- }
-
- public static class UnZippedXasFile {
-
- private File directory;
- private File xasFile;
- private File xadFile;
- private File xarFile;
-
- public UnZippedXasFile(File directory, File xasFile, File xadFile, File xarFile) {
- this.directory = directory;
- this.xasFile = xasFile;
- this.xadFile = xadFile;
- this.xarFile = xarFile;
- }
-
- public File getDirectory() {
- return directory;
- }
-
- public File getXadFile() {
- return xadFile;
- }
-
- public File getXarFile() {
- return xarFile;
- }
-
- public File getXasFile() {
- return xasFile;
- }
-
- public void delete() throws IOException {
- FileUtils.deleteDirectory(directory);
- }
- }
-
- private void checkWriteDirectory(File file) throws ConfigurationException {
- if (!file.exists() || !file.isDirectory() || !file.canWrite()) {
- String message = "Le répertoire " + file.getAbsolutePath() + " doit exister et l'application doit avoir les droits d'écriure";
- traitement.addMessage(Traitement.SEVERITY_ERROR, message);
- throw new ConfigurationException(message);
- }
- }
-
- public static class InvalidXasFileException extends Exception {
-
- public InvalidXasFileException(String message) {
- super(message);
- }
-
- public InvalidXasFileException(XAdES4jException xaese) {
- super(xaese);
- }
- }
-
- public static class ConfigurationException extends Exception {
-
- public ConfigurationException(String message) {
- super(message);
- }
- }
+ private static final Logger logger = Logger.getLogger(XasVerifier.class);
+ public static final String SIGNATURE_SPEC_NS = "http://www.w3.org/2000/09/xmldsig#";
+
+ // pour s'assurer qu'on en fait pas plusieurs à la fois
+ private static int instanceCount = 0;
+ private static Object instance = null;
+ private static final Object locker = new Object();
+
+ public static final String BATCH_NAME = "xas.verifier";
+ static {
+ ResourceResolver.init();
+ ResourceResolver.register(StdResourceResolver.class.getName());
+ }
+ private static int BUFFER_SIZE = 2048;
+ public static final String INPUT_DIR_PROPNAME = "cft.dir";
+ public static final String FILE_OK_PROPNAME = "xar.out";
+ public static final String FILE_KO_PROPNAME = "xas.error";
+ public static final String FILE_ARCH_PROPNAME = "arch.dir";
+ public static final String ARCH_PROPNAME = "archive.xas";
+
+ private boolean shouldArchivateXas = false;
+ private File archiveDir = null;
+ private File inputDir = null;
+ private File okDir = null;
+ private File koDir = null;
+
+ private final Traitement traitement;
+
+ public XasVerifier(final String args[]) {
+ super(args);
+ // on vérifie que le machin ne tourne pas, et sinon on quitte
+ this.traitement = new Traitement(XasVerifier.class, BATCH_NAME);
+ }
+
+ @Override
+ protected void initialize() throws Exception {
+ final String inputDirFileName = this.getProps().getProperty(INPUT_DIR_PROPNAME);
+ final String fileOkDirName = this.getProps().getProperty(FILE_OK_PROPNAME);
+ final String fileKODirName = this.getProps().getProperty(FILE_KO_PROPNAME);
+ final String fileOkArchDirName = this.getProps().getProperty(FILE_ARCH_PROPNAME);
+ final String archivateXas = this.getProps().getProperty(ARCH_PROPNAME, "false");
+ this.shouldArchivateXas = Boolean.parseBoolean(archivateXas);
+ if (this.shouldArchivateXas) {
+ this.archiveDir = new File(fileOkArchDirName);
+ }
+ this.inputDir = new File(inputDirFileName);
+ this.okDir = new File(fileOkDirName);
+ this.koDir = new File(fileKODirName);
+ this.checkWriteDirectory(this.inputDir);
+ this.checkWriteDirectory(this.okDir);
+ this.checkWriteDirectory(this.koDir);
+ if (this.shouldArchivateXas) {
+ this.checkWriteDirectory(this.archiveDir);
+ }
+ }
+
+ protected void process(final File fileInputDir, final File fileOKDir, final File fileKODir, final File fileOKArchDir) throws Exception {
+ // logger.info(" Répertoire d'entrée : " + fileInputDir.getAbsolutePath());
+ // logger.info(" Répertoire de sortie OK : " + fileOKDir.getAbsolutePath());
+ // logger.info(" Répertoire de sortie KO : " + fileKODir.getAbsolutePath());
+ // if(fileOKArchDir!=null)
+ // logger.info(" Répertoire d'archivage XAS OK : " + fileOKArchDir.getAbsolutePath());
+ // else
+ // logger.info(" Pas d'archivqge des XAS");
+ final URL tcUrl = XasVerifier.class.getResource("/fr/gouv/finances/dgfip/xemelios/batch/chaineimport/xasverifier/resources/trustChains.zip");
+ final CertificateContainer trustChains = CertificateContainer.fromZipURL(tcUrl);
+ final URL tsUrl = XasVerifier.class.getResource("/fr/gouv/finances/dgfip/xemelios/batch/chaineimport/xasverifier/resources/trustSigners.zip");
+ final CertificateContainer trustSigners = CertificateContainer.fromZipURL(tsUrl);
+ final CertificateValidationProvider certValidator = new PKIXCertificateValidationProvider(CertificateContainer.fromCollection(trustChains.extractRootCertificates()).buildJKSKeyStore(), false, CertificateContainer.fromCollection(trustChains.extractNotRootCertificates()).buildCertStore());
+ final XadesVerificationProfile p = new XadesVerificationProfile(certValidator);
+ final XadesVerifier v = p.newVerifier();
+ for (final File xasFile : getXasFiles(fileInputDir)) {
+ String _msg = "Vérification du fichier " + xasFile.getAbsolutePath();
+ logger.info(_msg);
+ final Message msg = this.traitement.addMessage(Traitement.SEVERITY_INFO, _msg);
+ UnZippedXasFile unZippedXasFile = null;
+ try {
+ unZippedXasFile = unzipXasFile(xasFile);
+ final XAdESVerificationResult result = verifyXas(unZippedXasFile, v, trustSigners); // TODO : log result
+ FileUtils.moveFileWithOverwrite(unZippedXasFile.getXarFile(), new File(fileOKDir, unZippedXasFile.getXarFile().getName()));
+ unZippedXasFile.delete();
+ if (this.shouldArchivateXas) {
+ FileUtils.moveFileWithOverwrite(xasFile, new File(fileOKArchDir, xasFile.getName()));
+ } else {
+ xasFile.delete();
+ }
+ // _msg = "Le fichier " + xasFile.getAbsolutePath() + " a été vérifié avec succès.";
+ logger.info(_msg);
+ msg.setInfoCompl(_msg);
+ } catch (final InvalidXasFileException e) {
+ if (unZippedXasFile != null) {
+ unZippedXasFile.delete();
+ }
+ FileUtils.moveFileWithOverwrite(xasFile, new File(fileKODir, xasFile.getName()));
+ _msg = "Le fichier " + xasFile.getAbsolutePath() + " est invalide: ";
+ // logger.info(_msg, e);
+ msg.setSeverity(Traitement.SEVERITY_WARN);
+ msg.setInfoCompl(_msg + e.getMessage());
+ } catch (final Exception e) {
+ if (unZippedXasFile != null) {
+ unZippedXasFile.delete();
+ }
+ FileUtils.moveFileWithOverwrite(xasFile, new File(fileKODir, xasFile.getName()));
+ _msg = "Le fichier " + xasFile.getAbsolutePath() + " a provoquée une erreur inattendue. ";
+ msg.setSeverity(Traitement.SEVERITY_WARN);
+ msg.setInfoCompl(_msg + e.getMessage());
+ logger.error(_msg, e);
+ }
+ }
+ logger.info("Fin du processus de vérification xas");
+ this.traitement.setEnd(System.currentTimeMillis());
+ }
+
+ protected static XAdESVerificationResult verifyXas(final UnZippedXasFile unizipedXasFile, final XadesVerifier verifier, final CertificateContainer trustSigners) throws InvalidXasFileException, FileNotFoundException, ParserConfigurationException, SAXException, IOException, TransformerException,
+ CertificateEncodingException, XPathExpressionException {
+ if (!unizipedXasFile.getXadFile().exists()) {
+ throw new InvalidXasFileException("Fichier de signature non trouvé : " + unizipedXasFile.getXadFile().getName());
+ }
+ if (!unizipedXasFile.getXarFile().exists()) {
+ throw new InvalidXasFileException("Fichier xar non trouvé : " + unizipedXasFile.getXarFile().getName());
+ }
+
+ final javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ dbf.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE);
+ final FileInputStream xadInputStream = new FileInputStream(unizipedXasFile.getXadFile());
+ try {
+ final Document document = dbf.newDocumentBuilder().parse(new InputSource(xadInputStream));
+ final XPathFactory xpf = FactoryProvider.getXPathFactory();
+ final XPath xp = xpf.newXPath();
+ final NamespaceContextImpl nsCtx = new NamespaceContextImpl();
+ nsCtx.addMapping("ds", SIGNATURE_SPEC_NS);
+ xp.setNamespaceContext(nsCtx);
+ final NodeList sigs = (NodeList) xp.evaluate("//ds:Signature", document, XPathConstants.NODESET);
+ if (sigs.getLength() != 1) {
+ throw new InvalidXasFileException("Plusieurs signatures ont été détectées dans le fichier xad, interruption de la vérification");
+ }
+ final Element sigElement = (Element) sigs.item(0);
+ StdResourceResolver.startSigningProcess(unizipedXasFile.getDirectory());
+ try {
+ final XAdESVerificationResult xaesvr = verifier.verify(sigElement);
+ if (trustSigners.contains(xaesvr.getValidationCertificate())) {
+ return xaesvr;
+ } else {
+ throw new InvalidXasFileException("Le certificat du signataire n'a pas été reconnu (" + xaesvr.getValidationCertificate().getSerialNumber() + ")");
+ }
+ } catch (final XAdES4jException xaese) {
+ throw new InvalidXasFileException(xaese);
+ } finally {
+ StdResourceResolver.endSigningProcess();
+ }
+ } finally {
+ xadInputStream.close();
+ }
+ }
+
+ private static File createCleanTempDir(final File xasFile) throws IOException {
+ final File xasDirectory = new File(xasFile + ".tmpDir");
+ if (xasDirectory.exists()) {
+ if (!xasDirectory.delete()) {
+ throw new IOException("Impossible de supprimer le répertoire " + xasDirectory);
+ }
+ }
+ if (!xasDirectory.mkdir()) {
+ throw new IOException("Impossible de créer le répertoire " + xasDirectory);
+ }
+ return xasDirectory;
+ }
+
+ private static UnZippedXasFile unzipXasFile(final File xasFile) throws IOException, InvalidXasFileException {
+ final File xasDirectory = createCleanTempDir(xasFile);
+ final ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(xasFile)));
+ try {
+ try {
+ ZipEntry entry = null;
+ String xarFilename = null;
+ String xadFilename = null;
+ while ((entry = zis.getNextEntry()) != null) {
+ final String outputFilename = xasDirectory + File.separator + entry.getName();
+ if (entry.getName().toLowerCase().endsWith(".xar")) {
+ if (xarFilename == null) {
+ xarFilename = entry.getName();
+ } else {
+ throw new InvalidXasFileException("L'archive est invalide : elle contient plusieurs fichiers xar");
+ }
+ }
+ if (entry.getName().toLowerCase().endsWith(".xad")) {
+ if (xadFilename == null) {
+ xadFilename = entry.getName();
+ } else {
+ throw new InvalidXasFileException("L'archive est invalide : elle contient plusieurs fichiers xad");
+ }
+ }
+ final BufferedOutputStream dest = new BufferedOutputStream(new FileOutputStream(outputFilename), BUFFER_SIZE);
+ try {
+ final byte data[] = new byte[BUFFER_SIZE];
+ int count;
+ while ((count = zis.read(data, 0, BUFFER_SIZE)) != -1) {
+ dest.write(data, 0, count);
+ }
+ } finally {
+ dest.flush();
+ dest.close();
+ }
+ }
+ if (xarFilename == null) {
+ throw new InvalidXasFileException("L'archive est invalide : aucun fichier xar trouvé");
+ }
+ if (xadFilename == null) {
+ throw new InvalidXasFileException("L'archive est invalide : aucun fichier xad trouvé");
+ }
+ return new UnZippedXasFile(xasDirectory, xasFile, new File(xasDirectory, xadFilename), new File(xasDirectory, xarFilename));
+ } finally {
+ zis.close();
+ }
+ } catch (final IOException ioe) {
+ FileUtils.deleteDirectory(xasDirectory);
+ throw ioe;
+ } catch (final InvalidXasFileException ixfe) {
+ FileUtils.deleteDirectory(xasDirectory);
+ throw ixfe;
+ }
+ }
+
+ private static List<File> getXasFiles(final File fileInputDir) {
+ return FileUtils.listFiles(fileInputDir, new ByExtensionFileFilter("xas"), new LastModifiedFileComparator());
+ }
+
+ @Override
+ protected void doProcess() throws Exception {
+ if (this.checkNotRunning()) {
+ try {
+ this.process(this.inputDir, this.okDir, this.koDir, this.archiveDir);
+ } catch (final Exception ex) {
+ logger.error("unexpected exception:", ex);
+ throw ex;
+ } finally {
+ this.clearLock();
+ }
+ } else {
+ this.traitement.setResume("Dejà en cours d'execution");
+ this.traitement.setEnd(System.currentTimeMillis());
+ }
+ }
+
+ @Override
+ public String getResumeTraitement() {
+ return "xas.verifier";
+ }
+
+ @Override
+ public String typeTraitementRefCode() {
+ return "xas.verifier";
+ }
+
+ @Override
+ public String getInformations() {
+ return "Running";
+ }
+
+ @Override
+ protected String getBatchVersion() {
+ return "1.0.0";
+ }
+
+ private boolean checkNotRunning() {
+ synchronized (locker) {
+ if (instanceCount == 0) {
+ instanceCount++;
+ instance = this;
+ return true;
+ }
+ return false;
+ }
+ }
+
+ private void clearLock() {
+ synchronized (locker) {
+ // on ne peut pas supprimer un lock qu'on a pas posé
+ if (instance == this) {
+ instanceCount--;
+ instance = null;
+ }
+ }
+ }
+
+ public static class VerifiedUnizipedXasFile {
+
+ private final UnZippedXasFile unizipedXasFile;
+ private final XAdESVerificationResult xaesvr;
+
+ public VerifiedUnizipedXasFile(final UnZippedXasFile unizipedXasFile, final XAdESVerificationResult xaesvr) {
+ this.unizipedXasFile = unizipedXasFile;
+ this.xaesvr = xaesvr;
+ }
+
+ public UnZippedXasFile getUnizipedXasFile() {
+ return this.unizipedXasFile;
+ }
+
+ public XAdESVerificationResult getXaesvr() {
+ return this.xaesvr;
+ }
+ }
+
+ public static class UnZippedXasFile {
+
+ private final File directory;
+ private final File xasFile;
+ private final File xadFile;
+ private final File xarFile;
+
+ public UnZippedXasFile(final File directory, final File xasFile, final File xadFile, final File xarFile) {
+ this.directory = directory;
+ this.xasFile = xasFile;
+ this.xadFile = xadFile;
+ this.xarFile = xarFile;
+ }
+
+ public File getDirectory() {
+ return this.directory;
+ }
+
+ public File getXadFile() {
+ return this.xadFile;
+ }
+
+ public File getXarFile() {
+ return this.xarFile;
+ }
+
+ public File getXasFile() {
+ return this.xasFile;
+ }
+
+ public void delete() throws IOException {
+ FileUtils.deleteDirectory(this.directory);
+ }
+ }
+
+ private void checkWriteDirectory(final File file) throws ConfigurationException {
+ if (!file.exists() || !file.isDirectory() || !file.canWrite()) {
+ final String message = "Le répertoire " + file.getAbsolutePath() + " doit exister et l'application doit avoir les droits d'écriure";
+ this.traitement.addMessage(Traitement.SEVERITY_ERROR, message);
+ throw new ConfigurationException(message);
+ }
+ }
+
+ public static class InvalidXasFileException extends Exception {
+
+ public InvalidXasFileException(final String message) {
+ super(message);
+ }
+
+ public InvalidXasFileException(final XAdES4jException xaese) {
+ super(xaese);
+ }
+ }
+
+ public static class ConfigurationException extends Exception {
+
+ public ConfigurationException(final String message) {
+ super(message);
+ }
+ }
}