diff -rupN verifica-firma-0.2.0-src/compila_java.sh verifica-firma-0.2.0-src-GDO/compila_java.sh --- verifica-firma-0.2.0-src/compila_java.sh 1970-01-01 01:00:00.000000000 +0100 +++ verifica-firma-0.2.0-src-GDO/compila_java.sh 2011-06-18 18:18:17.986319550 +0200 @@ -0,0 +1,32 @@ +#!/bin/bash +# ---------------------------------------------------------------------- # +# Copyright: (C) 2011 Guido Brugnara +# Strada della Pozzata, 41 - Villazzano +# 38123 T R E N T O (ITALY) +# E-mail: info@leader.it +# +# Note: The authors with the rispettive contributions are available in +# SVN repository at https://svn.leader.it/wsvn/my_application +# ---------------------------------------------------------------------- # +# + +### Compilazione java: +BASE="/opt/my_application" +LIB="$BASE/lib/java" +SRC="$BASE/src/java/verifica-firma-0.2.0-src-GDO" +JAR="VerifyService.jar" + +export CLASSPATH="$LIB/bcprov-jdk16-146.jar:$LIB/bcpg-jdk16-146.jar:$LIB/bcmail-jdk16-146.jar:\ +$LIB/bcpg-jdk16-146.jar:$LIB/bctsp-jdk16-146.jar:$LIB/bctest-jdk16-146.jar:\ +$LIB/j4sign-core.jar" + +if cd $SRC/src/it/trento/comune/j4sign/verification +then + if javac X509CertRL.java CertificationAuthorities.java CertValidity.java RootsVerifier.java \ + VerifyResult.java servlet/Verifier.java servlet/VerifyService.java + then + cd $SRC/src + jar -cMf $LIB/$JAR it/trento/comune/j4sign/verification/*.class it/trento/comune/j4sign/verification/servlet/*.class + fi +fi + diff -rupN verifica-firma-0.2.0-src/LEGGIMI verifica-firma-0.2.0-src-GDO/LEGGIMI --- verifica-firma-0.2.0-src/LEGGIMI 1970-01-01 01:00:00.000000000 +0100 +++ verifica-firma-0.2.0-src-GDO/LEGGIMI 2011-07-07 15:25:14.871954553 +0200 @@ -0,0 +1,55 @@ +--------------- +verifica-firma-0.2.0-src-GDO + + +Adattamento dell'applicazione j4sign verifica-firma rel 0.2.0 + +Downoad da: + http://sourceforge.net/projects/j4sign/files/verifica-firma/ +Oppure: + cvs -z3 -d:pserver:anonymous@j4sign.cvs.sourceforge.net:/cvsroot/j4sign co -P verifica-firma + + +Classi modificate: + it/trento/comune/j4sign/verification/RootsVerifier.java + - init dei parametri come parametri passati alla chiamata del metodo getInstance + it/trento/comune/j4sign/verification/RootsVerifier.java + - aggiunti parametri cnipaDir, cnipaCa, cnipaRoots al metodo RootsVerifier ed eliminati i riferimenti alla classe ...Configuration + it/trento/comune/j4sign/verification/X509CertRL.java + - commentata riga "import org.apache.commons.configuration.ConfigurationException;" - classe non utilizzata + it/trento/comune/j4sign/verification/CertValidity.java + - aggiunto parametro Date ai metodi getExpired e getPassed per indicare la data di verifica della validità del certificato + it/trento/comune/j4sign/verification/VerifyResult.java + - aggiunto parametro Date al metodo getPassed per indicare la data di verifica della validità dei certificati + it/trento/comune/j4sign/verification/servlet/Verifier.java + - aggiunto parametro Date al metodo verify per indicare la data di verifica della validità dei certificati + + +Classi aggunte: + it/trento/comune/j4sign/verification/servlet/VerifyService.java + +Utilizzando lo script /opt/my_application/src/java/verifica-firma-0.2.0-src-GDO/compila_java.sh +verrà creato il package VerifyService.jar, copiato nella cartella /opt/my_application/lib/java + + +Classi esterne: + +Creare la cartella /opt/my_application/lib/java nella quale copiare le seguenti librerie: + +--- j4sign-core.jar +Reperibile all'indirizzo http://sourceforge.net/projects/j4sign/files/ +Applicazione freesigner rel 0.0.9 nella cartella "lib" + +Oppure compilare da file sorgenti in: +cvs -z3 -d:pserver:anonymous@j4sign.cvs.sourceforge.net:/cvsroot/j4sign co -P j4sign + +--- Bouncycastle + +Copiare i package bcmail-jdk16-146.jar bcpg-jdk16-146.jar bcprov-jdk16-146.jar bctest-jdk16-146.jar bctsp-jdk16-146.jar +reperibili all'indirizzo http://www.bouncycastle.org/latest_releases.html + + +VARIE: +Creare la cartella /opt/my_application/lib/java/InlineDir con permessi 770 e proprietario root.www-data + + I file binari verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/CertificationAuthorities.class e verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/CertificationAuthorities.class differiscono I file binari verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/CertValidity.class e verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/CertValidity.class differiscono diff -rupN verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/CertValidity.java verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/CertValidity.java --- verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/CertValidity.java 2010-07-28 14:29:50.000000000 +0200 +++ verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/CertValidity.java 2011-06-16 16:33:30.965650408 +0200 @@ -24,7 +24,7 @@ package it.trento.comune.j4sign.verifica import java.security.*; import java.security.cert.*; import java.util.logging.Logger; - +import java.util.Date; /** * This class is constructed with a certificate X509Certificate c and CertificationAuthorities C @@ -162,9 +162,13 @@ class CertValidity { * * */ - public boolean getRevoked() { + public boolean getRevoked() { + return getRevoked(new Date()); + } + + public boolean getRevoked(Date date) { - isRevoked = !CRL.isNotRevoked(cert, isDownloadCRLForced); + isRevoked = !CRL.isNotRevoked(cert, date, isDownloadCRLForced); return isRevoked; } @@ -218,15 +222,27 @@ class CertValidity { * * */ + public boolean getPassed() { + return this.getPassed(new Date()); + } - public boolean getPassed() { + /** + * Return the general result

+ * Restituisce il risultato di tutte le verifiche + * + * @param date Date for check validity + * @return true: if certificate is valid + * + * + */ + public boolean getPassed(Date date) { isPathValid = this.getPathValid(); - isExpired = this.getExpired(); - isInUse = this.getInUse(); - isRevoked = this.getRevoked(); + isExpired = this.getExpired(date); + isInUse = this.getInUse(date); + isRevoked = this.getRevoked(date); isPassed = isPathValid && !isRevoked && !isExpired && isInUse; - log.info("************************Verifica: " + + log.info("************************ Verifica: " + cert.getSubjectDN() + "\n Risultato getPassed: " + isPassed); CRLerror = CRL.getCRLerror(); @@ -241,7 +257,7 @@ class CertValidity { isRevoked = this.getRevoked(); isPassed = isPathValid && !isRevoked; - log.info("************************Verifica: " + + log.info("************************ Verifica: " + cert.getSubjectDN() + "\n Risultato getPassed: " + isPassed + "\nNB:VERIFICA SCADENZA DISABILITATA!"); CRLerror = CRL.getCRLerror(); @@ -260,8 +276,21 @@ class CertValidity { */ public boolean getExpired() { + return this.getExpired(new Date()); + } + + /**Return true if certificate is expired

+ * Restituisce true se il certificato � scaduto + * + * + * @param date Date for check validity + * @return true: if certificate is expired + * + * + */ + public boolean getExpired(Date date) { try { - cert.checkValidity(); + cert.checkValidity(date); isInUse = true; isExpired = false; } catch (CertificateNotYetValidException ex) { @@ -284,8 +313,12 @@ class CertValidity { * */ public boolean getInUse() { + return this.getInUse(new Date()); + } + + public boolean getInUse(Date date) { try { - cert.checkValidity(); + cert.checkValidity(date); isInUse = true; isExpired = false; } catch (CertificateNotYetValidException ex) { I file binari verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/RootsVerifier.class e verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/RootsVerifier.class differiscono diff -rupN verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/RootsVerifier.java verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/RootsVerifier.java --- verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/RootsVerifier.java 2010-07-28 14:29:50.000000000 +0200 +++ verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/RootsVerifier.java 2011-06-28 13:27:36.995651490 +0200 @@ -2,6 +2,10 @@ * verifica-firma - a simple web application for verifying CMS/PKCS7 signed files * Copyright (c) 2009 Roberto Resoli - Comune di Trento; * + * Partially modified for use from it/trento/comune/j4sign/verification/servlet/VerifyService.java + * Copyright (c) 2011 Guido Brugnara + * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 @@ -20,10 +24,6 @@ package it.trento.comune.j4sign.verification; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.ConfigurationException; -import org.apache.commons.configuration.PropertiesConfiguration; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -59,8 +59,6 @@ public class RootsVerifier { private CertificationAuthorities roots = null; - private Configuration conf = null; - private static RootsVerifier instance = null; private String confDir = null; @@ -73,38 +71,24 @@ public class RootsVerifier { private byte[] userApprovedFingerprint = null; - public static RootsVerifier getInstance(String confDir, byte[] fingerprint) { + public static RootsVerifier getInstance(String confDir, String cnipaDir, String cnipaCa, String cnipaRoots, byte[] fingerprint) { if (instance == null) { - try { - instance = new RootsVerifier(confDir, fingerprint); - } catch (ConfigurationException e) { - e.printStackTrace(); - } + instance = new RootsVerifier(confDir, cnipaDir, cnipaCa, cnipaRoots, fingerprint); } return instance; } - private RootsVerifier(String aConfDir, byte[] fingerprint) - throws ConfigurationException { + private RootsVerifier(String aConfDir, String cnipaDir, String cnipaCa, String cnipaRoots, byte[] fingerprint) + { this.confDir = aConfDir; - this.conf = new PropertiesConfiguration(aConfDir - + System.getProperty("file.separator") + "conf.properties"); - - init(); + this.CNIPADir = aConfDir + System.getProperty("file.separator") + cnipaDir + System.getProperty("file.separator"); + this.CAFilePath = CNIPADir + cnipaRoots; + this.CNIPACACertFilePath = CNIPADir + cnipaCa; + userApprovedFingerprint = fingerprint; } - private void init() { - - this.CNIPADir = this.confDir + System.getProperty("file.separator") - + conf.getString("cnipa.dir") - + System.getProperty("file.separator"); - - this.CAFilePath = CNIPADir + conf.getString("cnipa.roots"); - - this.CNIPACACertFilePath = CNIPADir + conf.getString("cnipa.ca"); - } /* * private byte[] getFingerprint() { I file binari verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/servlet/Verifier.class e verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/servlet/Verifier.class differiscono diff -rupN verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/servlet/Verifier.java verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/servlet/Verifier.java --- verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/servlet/Verifier.java 2010-07-28 14:29:50.000000000 +0200 +++ verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/servlet/Verifier.java 2011-06-15 14:38:02.196905782 +0200 @@ -39,6 +39,7 @@ import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; import java.util.logging.Logger; +import java.util.Date; import javax.security.auth.x500.X500Principal; @@ -208,6 +209,10 @@ public class Verifier { } void verify() { + this.verify(new Date()); + } + + void verify(Date date) { org.bouncycastle.jce.provider.BouncyCastleProvider p = new org.bouncycastle.jce.provider.BouncyCastleProvider(); if (Security.getProvider(p.getName()) == null) Security.addProvider(p); @@ -261,7 +266,7 @@ public class Verifier { VerifyResult vr = new VerifyResult(certs, cert, cms, CAroot, signer, isDownloadCRLForced); - passed = vr.getPassed(); + passed = vr.getPassed(date); CRLerror = vr.getCRLerror(); risultati.put(cert.getSubjectX500Principal(), vr); diff -rupN verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/servlet/Verifier.java~ verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/servlet/Verifier.java~ --- verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/servlet/Verifier.java~ 1970-01-01 01:00:00.000000000 +0100 +++ verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/servlet/Verifier.java~ 2011-06-15 11:25:38.000000000 +0200 @@ -0,0 +1,324 @@ + /** + * verifica-firma - a simple web application for verifying CMS/PKCS7 signed files + * Copyright (c) 2009 Roberto Resoli - Comune di Trento; + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ +package it.trento.comune.j4sign.verification.servlet; + +import it.trento.comune.j4sign.verification.CertificationAuthorities; +import it.trento.comune.j4sign.verification.RootsVerifier; +import it.trento.comune.j4sign.verification.VerifyResult; + +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Security; +import java.security.cert.CertStore; +import java.security.cert.CertStoreException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Vector; +import java.util.logging.Logger; +import java.util.Date; +import java.util.Calendar; + +import javax.security.auth.x500.X500Principal; + +import org.bouncycastle.cms.CMSException; +import org.bouncycastle.cms.CMSSignedData; +import org.bouncycastle.cms.CMSSignedDataStreamGenerator; +import org.bouncycastle.cms.SignerInformation; +import org.bouncycastle.cms.SignerInformationStore; +import org.bouncycastle.util.encoders.Base64; + +public class Verifier { + private Logger log = Logger.getLogger(this.getClass().getName()); + + private String filepath; + private int current; + + private CertificationAuthorities CAroot; + + private boolean done; + + private boolean canceled; + + private boolean passed; + + private int differentSigners; + + private ArrayList signersList; + + private Iterator currentSigner; + + private CMSSignedData cms; + + private Hashtable risultati; + + private Hashtable counterSignatures; + + private String CRLerror = ""; + + private Vector errors = new Vector(); + + private boolean isDownloadCRLForced; + + private RootsVerifier rootsVerifier = null; + + public Verifier(String f, boolean isDownloadCRLForced, RootsVerifier rv) + throws Exception { + + filepath = f; + signersList = new ArrayList(); + this.isDownloadCRLForced = isDownloadCRLForced; + this.rootsVerifier = rv; + + readFile(); + + initCARoots(); + + if (CAroot != null) { + risultati = new Hashtable(); + } + + } + + public void initCARoots() throws Exception { + try { + CAroot = this.rootsVerifier.getRoots(); + } catch (Exception ex) { + log.severe("Errore nell'inizializzazione delle CA: " + ex); + errors.add("Errore nell'inizializzazione delle CA: " + ex); + throw (new Exception(ex)); + } + if (CAroot == null) + throw (new Exception("Errore nell'inizializzazione delle CA")); + } + + public Vector getErrors() { + return errors; + } + + public static byte[] getSignedContentBytes(String filepath) + throws IOException { + + byte[] buffer = new byte[1024]; + + FileInputStream is = null; + + is = new FileInputStream(filepath); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + while (is.read(buffer) > 0) { + baos.write(buffer); + } + + byte[] risultato = baos.toByteArray(); + + // codifica file Base64 o DER? + byte[] signedBytes; + try { + // se Base64, decodifica (italian law!) + signedBytes = Base64.decode(risultato); + // Decodifica base64 completata + // setMessage("Il file firmato è in formato Base64"); + } catch (Exception e) { + // il file non e' in formato base64 + // quindi è in DER (against italian law!) + // setMessage("Il file firmato è in formato DER"); + signedBytes = risultato; + + } + + return signedBytes; + } + + public void readFile() { + + // Estrazione del certificato dal file (ora codificato DER) + try { + this.cms = new CMSSignedData(getSignedContentBytes(this.filepath)); + } catch (CMSException ex1) { + log.severe("Errore nell'estrazione del certificato dal file"); + errors.add("Errore nell'estrazione del certificato dal file"); + } catch (IllegalArgumentException ex1) { + log.severe("Errore nell'estrazione del certificato dal file"); + errors.add("Errore nell'estrazione del certificato dal file"); + } catch (IOException e) { + log.severe("Errore nella lettura del file firmato"); + errors.add("Errore nella lettura del file firmato"); + } + if (errors.isEmpty()) { + org.bouncycastle.jce.provider.BouncyCastleProvider p = new org.bouncycastle.jce.provider.BouncyCastleProvider(); + if (Security.getProvider(p.getName()) == null) + Security.addProvider(p); + + // recupero dal CMS la lista dei certificati + + try { + CertStore certs = cms + .getCertificatesAndCRLs("Collection", "BC"); + } catch (CMSException ex2) { + log.severe("Errore nel CMS"); + errors.add("Errore nel CMS"); + } catch (NoSuchProviderException ex2) { + log.severe("Non esiste il provider del servizio"); + errors.add("Non esiste il provider del servizio"); + } catch (NoSuchAlgorithmException ex2) { + log.severe("Errore nell'algoritmo"); + errors.add("Errore nell'algoritmo"); + } + + // Recupero i firmatari. + SignerInformationStore signers = cms.getSignerInfos(); + + Collection c = signers.getSigners(); + differentSigners = cms.getSignerInfos().size(); + + // non avrebbe senso che fossero uguali + // quindi fa il ciclo tra i firmatari + // PERO' PUO' CAPITARE CHE CI SIA UN FIRMATARIO CHE FIRMA DUE VOLTE + // E IN QUESTO CASO DOVREBBE FARE IL GIRO SUI CERTIFICATI!!! + currentSigner = c.iterator(); + if (!currentSigner.hasNext()) { + done = true; + } + } else { + canceled = true; + } + } + + void verify() { + Date date = Calendar.getInstance().getTime(); + this.verify(date); + } + + void verify(Date date) { + org.bouncycastle.jce.provider.BouncyCastleProvider p = new org.bouncycastle.jce.provider.BouncyCastleProvider(); + if (Security.getProvider(p.getName()) == null) + Security.addProvider(p); + + X509Certificate cert = null; + CertStore certs = null; + + passed = false; + + try { + + certs = this.cms.getCertificatesAndCRLs("Collection", "BC"); + + } catch (CMSException ex2) { + log.severe("Errore nel CMS"); + errors.add("Errore nel CMS"); + } catch (NoSuchProviderException ex2) { + log.severe("Non esiste il provider del servizio"); + errors.add("Non esiste il provider del servizio"); + } catch (NoSuchAlgorithmException ex2) { + log.severe("Errore nell'algoritmo"); + errors.add("Errore nell'algoritmo"); + } + + if (certs != null) { + SignerInformation signer = (SignerInformation) currentSigner.next(); + + Collection certCollection = null; + try { + certCollection = certs.getCertificates(signer.getSID()); + } catch (CertStoreException ex1) { + log.severe("Errore nel CertStore"); + errors.add("Errore nel CertStore"); + } + + if (certCollection.size() == 1) { + // Iterator certIt = certCollection.iterator(); + // X509Certificate cert = (X509Certificate) + // certIt.next(); + + cert = (X509Certificate) certCollection.toArray()[0]; + // CertValidity cv=new CertValidity(cert, CAroot); + // log.info(i + ") Verifiying signature from:\n" + // + cert.getSubjectDN()); + + // inserisce in una lista i DN dei firmatari + signersList.add(cert.getSubjectX500Principal()); + + log.info("Signer CN: " + getCommonName(cert)); + + VerifyResult vr = new VerifyResult(certs, cert, cms, CAroot, signer, + isDownloadCRLForced); + + passed = vr.getPassed(date); + CRLerror = vr.getCRLerror(); + + risultati.put(cert.getSubjectX500Principal(), vr); + + } else { + log + .severe("There is not exactly one certificate for this signer!"); + errors + .add("There is not exactly one certificate for this signer!"); + } + if (!currentSigner.hasNext()) { + done = true; + } + + } + + } + + public boolean isDone() { + return done; + } + + /** + * Returns the Common name of given certificate
+ *
+ * Restituisce il CN del subjct certificato in oggetto + * + * @param userCert + * certificato da cui estrarre il Common Name + * @return la stringa contenente il CN + */ + public static String getCommonName(X509Certificate userCert) { + String DN = userCert.getSubjectDN().toString(); + int offset = DN.indexOf("CN="); + int end = DN.indexOf(",", offset); + String CN; + if (end != -1) { + CN = DN.substring(offset + 3, end); + } else { + CN = DN.substring(offset + 3, DN.length()); + } + return CN; + } + + byte[] getFile() { + return (byte[]) cms.getSignedContent().getContent(); + } + + Hashtable getRisultati() { + return risultati; + } + +} I file binari verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/servlet/VerifyService.class e verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/servlet/VerifyService.class differiscono diff -rupN verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/servlet/VerifyService.java verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/servlet/VerifyService.java --- verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/servlet/VerifyService.java 1970-01-01 01:00:00.000000000 +0100 +++ verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/servlet/VerifyService.java 2011-06-20 09:12:58.775654899 +0200 @@ -0,0 +1,234 @@ +/** +* verifica-firma - a simple service application for verifying CMS/PKCS7 signed files +* derived from it.trento.comune.j4sign.verification.servlet.VerifyServlet +* * Copyright (c) 2009 Roberto Resoli - Comune di Trento; +* +* +* Copyright (c) 2011 Guido Brugnara +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ +package it.trento.comune.j4sign.verification.servlet; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Date; +import java.util.logging.Logger; +import java.security.Security; +import java.security.cert.CertStore; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.cert.CertStoreException; +import java.util.Hashtable; +import java.util.Collection; +import java.util.Iterator; + +import it.trento.comune.j4sign.verification.servlet.Verifier; +import it.trento.comune.j4sign.verification.RootsVerifier; +import it.trento.comune.j4sign.verification.VerifyResult; + +import org.bouncycastle.cms.CMSException; +import org.bouncycastle.cms.CMSSignedData; +import org.bouncycastle.operator.DigestCalculator; +import org.bouncycastle.operator.DigestCalculatorProvider; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; +import org.bouncycastle.tsp.cms.CMSTimeStampedDataParser; +import org.bouncycastle.tsp.cms.ImprintDigestInvalidException; +import org.bouncycastle.util.io.Streams; +import org.bouncycastle.tsp.TimeStampToken; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.cms.SignerInformationStore; +import org.bouncycastle.cms.SignerInformation; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.util.Store; +import org.bouncycastle.util.CollectionStore; +import java.text.SimpleDateFormat; + +import org.bouncycastle.tsp.TimeStampResponse; +import org.bouncycastle.tsp.TimeStampToken; +import org.bouncycastle.tsp.TimeStampTokenInfo; +import org.bouncycastle.tsp.TSPException; + +public class VerifyService { + private Logger log = Logger.getLogger(this.getClass().getName()); + private CMSSignedData cms = null; + public Verifier v = null; + private RootsVerifier rv = null; + + public VerifyService(String confDir, String cnipaDir, String cnipaCa, String cnipaRoots, String fingerprintDigitPA) { + // utilizzo it.trento.comune.j4sign.verification.servlet.RootsVerifier (modificato da GDO) + try { + this.rv = RootsVerifier.getInstance(confDir, cnipaDir, cnipaCa, cnipaRoots, decodeHex(fingerprintDigitPA.toCharArray()) ); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public TimeStampToken verifyTSR(String filePath){ + try { + FileInputStream fis = new FileInputStream(filePath); + TimeStampResponse resp = new TimeStampResponse (fis); + TimeStampToken tsToken = resp.getTimeStampToken(); + return tsToken; + }catch (Exception pe){ + pe.printStackTrace(); + } + return null; + } + + public Hashtable verifyP7M(String fileName){ + return this.verify(fileName, new Date()); + } + + public Hashtable verifyP7M(String fileName, String dateString){ + SimpleDateFormat fDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + try{ + return verifyP7M(fileName, fDate.parse(dateString)); + } catch (Exception pe){ + pe.printStackTrace(); + } + return null; + } + + public Hashtable verifyP7M(String fileName, Date date){ + try { + return this.verify(fileName, date); + } catch (Exception ex){ + ex.printStackTrace(); + } + return null; + } + + public Hashtable verify(String fileName, Date date){ + // utilizzo it.trento.comune.j4sign.verification.servlet.Verifier (modificato da GDO) + this.v = null; + try { + this.v = new Verifier(fileName, false, this.rv); + } catch (Exception e) { + e.printStackTrace(); + } + if (this.v != null) { + while (!this.v.isDone()) this.v.verify(date); + } + if(this.v != null) { + return this.v.getRisultati(); + }else{ + return null; + } + } + + public void saveContent(String fileName) { + try { + FileOutputStream fos = new FileOutputStream(fileName); + fos.write(this.v.getFile()); + } catch (IOException e) { + log.severe("IOException: " + e.getMessage()); + } + } + +/** ********************************************** Timestamp +*/ + + private byte[] tsdData; + CMSTimeStampedDataParser tsd = null; + + public boolean parseTSD(String filePath) { + boolean parseOk = false; + try { + FileInputStream fis = new FileInputStream(filePath); + tsd = new CMSTimeStampedDataParser(fis); + parseOk = true; + } catch (IOException e) { + log.severe("IOException: " + e.getMessage()); + } catch (CMSException e) { + log.severe("CMSException: " + e.getMessage()); + } catch (Exception e) { + log.severe("Exception: " + e.getMessage()); + } + return parseOk; + } + + public TimeStampToken[] tokensTSD () { + TimeStampToken[] res = null; + try { + res = tsd.getTimeStampTokens(); + } catch (CMSException e) { + log.severe("CMSException: " + e.getMessage()); + } catch (Exception e) { + log.severe("Exception: " + e.getMessage()); + } + return res; + } + + public boolean validateTSD(String outPath) { + boolean timestampValid = false; + DigestCalculatorProvider digestCalculatorProvider = new BcDigestCalculatorProvider(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + try { + Streams.pipeAll(tsd.getContent(), bOut); + DigestCalculator imprintCalculator = tsd.getMessageImprintDigestCalculator(digestCalculatorProvider); + Streams.pipeAll(new ByteArrayInputStream(bOut.toByteArray()), imprintCalculator.getOutputStream()); + tsd.validate(digestCalculatorProvider, imprintCalculator.getDigest()); + timestampValid = true; + FileOutputStream fos = new FileOutputStream(outPath); + fos.write(bOut.toByteArray()); + } catch (IOException e) { + log.severe("IOException: " + e.getMessage()); + } catch (OperatorCreationException e) { + log.severe("OperatorCreationException: " + e.getMessage()); + } catch (ImprintDigestInvalidException e) { + log.severe("ImprintDigestInvalidException: " + + e.getMessage()); + } catch (CMSException e) { + log.severe("CMSException: " + e.getMessage()); + } + return timestampValid; + } + + // metodo duplicato dalla classe it.trento.comune.j4sign.verification.servlet.VerifyServlet + private static byte[] decodeHex(char[] data) throws Exception { + int len = data.length; + if ((len & 0x01) != 0) { + throw new Exception("Odd number of characters."); + } + byte[] out = new byte[len >> 1]; + // two characters form the hex value. + for (int i = 0, j = 0; j < len; i++) { + int f = toDigit(data[j], j) << 4; + j++; + f = f | toDigit(data[j], j); + j++; + out[i] = (byte) (f & 0xFF); + } + return out; + } + + // metodo duplicato dalla classe it.trento.comune.j4sign.verification.servlet.VerifyServlet + private static int toDigit(char ch, int index) throws Exception { + int digit = Character.digit(ch, 16); + if (digit == -1) { + throw new Exception("Illegal hexadecimal character " + ch + + " at index " + index); + } + return digit; + } +} diff -rupN verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/servlet/VerifyService.java~ verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/servlet/VerifyService.java~ --- verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/servlet/VerifyService.java~ 1970-01-01 01:00:00.000000000 +0100 +++ verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/servlet/VerifyService.java~ 2011-06-16 11:58:21.000000000 +0200 @@ -0,0 +1,235 @@ +/** +* verifica-firma - a simple service application for verifying CMS/PKCS7 signed files +* derived from it.trento.comune.j4sign.verification.servlet.VerifyServlet +* * Copyright (c) 2009 Roberto Resoli - Comune di Trento; +* +* +* Copyright (c) 2011 Guido Brugnara +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +*/ +package it.trento.comune.j4sign.verification.servlet; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Date; +import java.util.logging.Logger; +import java.security.Security; +import java.security.cert.CertStore; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.cert.CertStoreException; +import java.util.Hashtable; +import java.util.Collection; +import java.util.Iterator; + +import it.trento.comune.j4sign.verification.servlet.Verifier; +import it.trento.comune.j4sign.verification.RootsVerifier; +import it.trento.comune.j4sign.verification.VerifyResult; + +import org.bouncycastle.cms.CMSException; +import org.bouncycastle.cms.CMSSignedData; +import org.bouncycastle.operator.DigestCalculator; +import org.bouncycastle.operator.DigestCalculatorProvider; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.bc.BcDigestCalculatorProvider; +import org.bouncycastle.tsp.cms.CMSTimeStampedDataParser; +import org.bouncycastle.tsp.cms.ImprintDigestInvalidException; +import org.bouncycastle.util.io.Streams; +import org.bouncycastle.tsp.TimeStampToken; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.cms.SignerInformationStore; +import org.bouncycastle.cms.SignerInformation; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.util.Store; +import org.bouncycastle.util.CollectionStore; +import java.text.SimpleDateFormat; + +import org.bouncycastle.tsp.TimeStampResponse; +import org.bouncycastle.tsp.TimeStampToken; +import org.bouncycastle.tsp.TimeStampTokenInfo; +import org.bouncycastle.tsp.TSPException; + +public class VerifyService { + private Logger log = Logger.getLogger(this.getClass().getName()); + private CMSSignedData cms = null; + public Verifier v = null; + private RootsVerifier rv = null; + + public VerifyService(String confDir, String cnipaDir, String cnipaCa, String cnipaRoots, String fingerprintDigitPA) { + // utilizzo it.trento.comune.j4sign.verification.servlet.RootsVerifier (modificato da GDO) + try { + this.rv = RootsVerifier.getInstance(confDir, cnipaDir, cnipaCa, cnipaRoots, decodeHex(fingerprintDigitPA.toCharArray()) ); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public Date verifyTSRdate(String filePath){ + try { + FileInputStream fis = new FileInputStream(filePath); + TimeStampResponse resp = new TimeStampResponse (fis); + TimeStampToken tsToken = resp.getTimeStampToken(); + TimeStampTokenInfo tsInfo= tsToken.getTimeStampInfo(); + return tsInfo.getGenTime(); + }catch (Exception pe){ + pe.printStackTrace(); + } + return null; + } + + public TimeStampToken verifyTSR(String filePath){ + try { + FileInputStream fis = new FileInputStream(filePath); + TimeStampResponse resp = new TimeStampResponse (fis); + TimeStampToken tsToken = resp.getTimeStampToken(); + return tsToken; + }catch (Exception pe){ + pe.printStackTrace(); + } + return null; + } + + public Hashtable verifyP7M(String fileName){ + return this.verify(fileName, new Date()); + } + + public Hashtable verifyP7M(String fileName, String dateString){ + SimpleDateFormat fDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + try{ + return verifyP7M(fileName, fDate.parse(dateString)); + } catch (Exception pe){ + pe.printStackTrace(); + } + return null; + } + + public Hashtable verifyP7M(String fileName, Date date){ + try { + return this.verify(fileName, date); + } catch (Exception ex){ + ex.printStackTrace(); + } + return null; + } + + public Hashtable verify(String fileName, Date date){ + // utilizzo it.trento.comune.j4sign.verification.servlet.Verifier (modificato da GDO) + this.v = null; + try { + this.v = new Verifier(fileName, false, this.rv); + } catch (Exception e) { + e.printStackTrace(); + } + if (this.v != null) { + while (!this.v.isDone()) this.v.verify(date); + } + if(this.v != null) { + return this.v.getRisultati(); + }else{ + return null; + } + } + + private byte[] tsdData; + CMSTimeStampedDataParser tsd = null; + + public boolean parseTSD(String filePath) { + boolean parseOk = false; + try { + FileInputStream fis = new FileInputStream(filePath); + tsd = new CMSTimeStampedDataParser(fis); + parseOk = true; + } catch (IOException e) { + log.severe("IOException: " + e.getMessage()); + } catch (CMSException e) { + log.severe("CMSException: " + e.getMessage()); + } catch (Exception e) { + log.severe("Exception: " + e.getMessage()); + } + return parseOk; + } + + public TimeStampToken[] tokensTSD () { + TimeStampToken[] res = null; + try { + res = tsd.getTimeStampTokens(); + } catch (CMSException e) { + log.severe("CMSException: " + e.getMessage()); + } catch (Exception e) { + log.severe("Exception: " + e.getMessage()); + } + return res; + } + + public boolean validateTSD(String outPath) { + boolean timestampValid = false; + DigestCalculatorProvider digestCalculatorProvider = new BcDigestCalculatorProvider(); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + try { + Streams.pipeAll(tsd.getContent(), bOut); + DigestCalculator imprintCalculator = tsd.getMessageImprintDigestCalculator(digestCalculatorProvider); + Streams.pipeAll(new ByteArrayInputStream(bOut.toByteArray()), imprintCalculator.getOutputStream()); + tsd.validate(digestCalculatorProvider, imprintCalculator.getDigest()); + timestampValid = true; + FileOutputStream fos = new FileOutputStream(outPath); + fos.write(bOut.toByteArray()); + } catch (IOException e) { + log.severe("IOException: " + e.getMessage()); + } catch (OperatorCreationException e) { + log.severe("OperatorCreationException: " + e.getMessage()); + } catch (ImprintDigestInvalidException e) { + log.severe("ImprintDigestInvalidException: " + + e.getMessage()); + } catch (CMSException e) { + log.severe("CMSException: " + e.getMessage()); + } + return timestampValid; + } + + // metodo duplicato dalla classe it.trento.comune.j4sign.verification.servlet.VerifyServlet + private static byte[] decodeHex(char[] data) throws Exception { + int len = data.length; + if ((len & 0x01) != 0) { + throw new Exception("Odd number of characters."); + } + byte[] out = new byte[len >> 1]; + // two characters form the hex value. + for (int i = 0, j = 0; j < len; i++) { + int f = toDigit(data[j], j) << 4; + j++; + f = f | toDigit(data[j], j); + j++; + out[i] = (byte) (f & 0xFF); + } + return out; + } + + // metodo duplicato dalla classe it.trento.comune.j4sign.verification.servlet.VerifyServlet + private static int toDigit(char ch, int index) throws Exception { + int digit = Character.digit(ch, 16); + if (digit == -1) { + throw new Exception("Illegal hexadecimal character " + ch + + " at index " + index); + } + return digit; + } +} diff -rupN verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/servlet/VerifyServlet.java~ verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/servlet/VerifyServlet.java~ --- verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/servlet/VerifyServlet.java~ 1970-01-01 01:00:00.000000000 +0100 +++ verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/servlet/VerifyServlet.java~ 2010-07-28 14:29:50.000000000 +0200 @@ -0,0 +1,567 @@ +/** + * verifica-firma - a simple web application for verifying CMS/PKCS7 signed files + * Copyright (c) 2009 Roberto Resoli - Comune di Trento; + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ +package it.trento.comune.j4sign.verification.servlet; + +import it.trento.comune.j4sign.verification.RootsVerifier; +import it.trento.comune.j4sign.verification.VerifyResult; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.security.MessageDigest; +import java.security.cert.X509Certificate; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Date; +import java.util.Enumeration; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Vector; +import java.util.logging.Logger; + +import javax.security.auth.x500.X500Principal; +import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.swing.JFrame; + +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileItemFactory; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItem; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.FileCleanerCleanup; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.bouncycastle.asn1.ocsp.Request; +import org.bouncycastle.cms.CMSException; +import org.bouncycastle.cms.CMSSignedData; + +/** + * Servlet implementation class for Servlet: ServletVerifica + * + */ +public class VerifyServlet extends javax.servlet.http.HttpServlet implements + javax.servlet.Servlet { + + private Logger log = Logger.getLogger(this.getClass().getName()); + + private final static long MAX_UPLOAD_SIZE = 10000L; + private final static long UPLOADED_DIR_SIZE_FACTOR = 2; + + private long maxUploadSize = MAX_UPLOAD_SIZE; + private long maxUploadDirSize = MAX_UPLOAD_SIZE * UPLOADED_DIR_SIZE_FACTOR; + + private String fingerprintString = null; + private String fingerprintGU = null; + + ServletFileUpload upload; + + @Override + public void init() throws ServletException { + + super.init(); + + try { + String mus = this.getInitParameter("maxUploadSize"); + + if (mus != null) { + maxUploadSize = Long.valueOf(mus).longValue(); + log + .fine("MaxUploadSize set from servlet \"maxUploadSize\" init parameter"); + } else + log + .info("\"maxUploadSize\" servlet init parameter not present"); + } catch (NumberFormatException nfe) { + log.severe(nfe.getMessage()); + } + + try { + String mus = this.getInitParameter("uploadedDirSizeFactor"); + + if (mus != null) { + maxUploadDirSize = Long.valueOf(mus).longValue() + * maxUploadSize; + log + .fine("uploadedDirSizeFactor set from servlet \"maxUploadSize\" init parameter"); + } else + log + .info("\"uploadedDirSizeFactor\" servlet init parameter not present"); + } catch (NumberFormatException nfe) { + log.severe(nfe.getMessage()); + } + + // Create a factory for disk-based file items + DiskFileItemFactory factory = new DiskFileItemFactory(); + + // Create a new file upload handler + upload = new ServletFileUpload(factory); + + // maximum accepted size, upload is stopped (during + // upload.parseRequest()) if exceeded + + upload.setFileSizeMax(maxUploadSize); + log.fine("MaxUploadSize set to: " + maxUploadSize + " bytes"); + + String afingerprintString = this.getServletContext().getInitParameter( + "rootsSignatureCertFingerprint"); + if (afingerprintString != null) { + try { + decodeHex(afingerprintString.toCharArray()); + log.info("\"rootsSignatureCertFingerprint\"=" + + afingerprintString + " decoded"); + fingerprintString = afingerprintString; + } catch (Exception e) { + log.severe(e.getMessage()); + log.severe("\"rootsSignatureCertFingerprint\"=" + + afingerprintString + " not decoded"); + } + + } else + log + .severe("\"rootsSignatureCertFingerprint\" context init parameter not present, cannot perform validarion!"); + + fingerprintGU = this.getServletContext().getInitParameter( + "fingerprintGU"); + if (fingerprintGU == null) + log + .warning("\"fingerprintGU\" = context init parameter not present"); + } + + /* + * (non-Java-doc) + * + * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, + * HttpServletResponse response) + */ + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + log.info("GET in corso..."); + + HttpSession session = request.getSession(false); + + String fileName = request.getPathInfo().substring(1); + String errorMsg = null; + + if (session == null) { + log.warning("session == null!"); + sendErrorMsg(response, "Sessione scaduta o cookies disabilitati."); + return; + } + + if (fileName == null) { + log.warning("fileName == null! - error getting pathInfo"); + sendErrorMsg(response, "Errore nel recupero del path info."); + return; + } + + String subDir = session.getId(); + + String realFileName = (String) session.getAttribute(fileName + ".p7m"); + + String fs = System.getProperty("file.separator"); + File f = new File(getServletContext().getRealPath("/WEB-INF/files") + + fs + subDir + fs + realFileName); + + if (f.exists()) { + // Setting correct content type + response.setContentType(getServletContext().getMimeType(fileName)); + ServletOutputStream os = response.getOutputStream(); + + try { + byte[] contentBytes = (byte[]) new CMSSignedData(Verifier + .getSignedContentBytes(f.getAbsolutePath())) + .getSignedContent().getContent(); + + sendContent(contentBytes, os); + os.flush(); + + log.info("Sent \"" + realFileName + "\" (" + fileName + + ") to client " + request.getRemoteAddr() + + " in session " + subDir); + + } catch (CMSException e) { + log.severe(e.getMessage()); + errorMsg = "Errore nell'estrazione del contenuto: " + + e.getMessage(); + } + } else{ + errorMsg = "Il file non è stato trovato"; + log.warning("file '"+f.getPath()+"' not found!"); + } + if (errorMsg != null) + sendErrorMsg(response, errorMsg); + } + + private void sendErrorMsg(HttpServletResponse response, String errorMsg) { + response.setContentType("text/html"); + try { + response.getWriter().println("

Errore

" + errorMsg + "

"); + } catch (IOException e) { + log.severe(e.getMessage()); + } + + } + + /* + * (non-Java-doc) + * + * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request, + * HttpServletResponse response) + */ + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + + StringBuffer header = new StringBuffer(""); + Vector errors = new Vector(); + Vector processedItems = new Vector(); + + response.setContentType("text/html"); + + log.info("POST in corso..."); + + HttpSession session = request.getSession(false); + + // We set maximum session duration of a session after second request + // equal to MaxInactiveInterval, so that the possibility to upload new + // files + // is at maximum 2 * MaxInactiveInterval long. + // When session is invalidated, all related uploaded file are cleaned by + // the session listener. + + long duration = -1; + if (session != null) { + + duration = session.getLastAccessedTime() + - session.getCreationTime(); + + if (duration > (session.getMaxInactiveInterval() * 1000)) { + session.invalidate(); + duration = 0; + session = request.getSession(true); + + } + } else + session = request.getSession(true); + + if (session != null) + if (fingerprintString == null) + errors + .add("Impronta SHA1 del file delle Autorità di Certificazione non configurata; impossibile eseguire la verifica"); + else { + // Check that we have a file upload request + boolean isMultipart = ServletFileUpload + .isMultipartContent(request); + + if (isMultipart) { + String sessionId = session.getId(); + + header + .append("Sessione " + + sessionId + + ((duration > 0) ? (": " + duration / 1000 + " secondi") + : "")); + + // Parse the request + try { + List items = upload.parseRequest(request); + + if (items.isEmpty()) { + errors.add("Nessun elemento da elaborare!!"); + log.warning("No element to process"); + } + // Process the uploaded items + Iterator iter = items.iterator(); + while (iter.hasNext()) { + ProcessedItem pi = null; + DiskFileItem item = iter.next(); + + if (item.isFormField()) { + pi = processFormField(item); + + } else { + + pi = processUploadedFile(item, sessionId); + if (pi != null) + session.setAttribute(pi.getFileName(), pi + .getWritedFileName()); + + log.info("Processed uploaded file \"" + + pi.getFileName() + "\" from client " + + request.getRemoteAddr() + + " in session " + sessionId); + } + + if (pi != null) + processedItems.add(pi); + + } + + } catch (FileUploadException e) { + if (e instanceof org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException) { + log.severe(e.getMessage()); + errors.add("Il file supera il limite di " + + upload.getFileSizeMax() + " bytes"); + } else { + log.severe(e.getMessage()); + errors.add(e.getMessage()); + } + } + } + + request.setAttribute("processedItems", processedItems); + } + + request.setAttribute("headerVerifica", header); + request.setAttribute("errors", errors); + this.getServletContext().getRequestDispatcher("/verifica.jsp").forward( + request, response); + + } + + private ProcessedItem processUploadedFile(DiskFileItem item, String subDir) { + String baseFileName = null; + ProcessedItem pi = null; + // Process a file upload + if (!item.isFormField()) { + + pi = new ProcessedItem(item.getFieldName(), !item.isFormField()); + String fileName = item.getName(); + + // IE insists to provide full path, get only file name (via commons + // IO). + if (fileName != null) { + baseFileName = FilenameUtils.getName(fileName); + pi.setFileName(baseFileName); + pi.setSize(item.getSize()); + pi.setInMemory(item.isInMemory()); + pi.setContentType(item.getContentType()); + } + + if (baseFileName != null) + if (!baseFileName.endsWith(".p7m")) + pi.getErrors().add( + "Il nome del file non termina con \".p7m\"!"); + else { + + File filesDir = new File(getServletContext().getRealPath( + "/WEB-INF/files")); + + File sd = new File(filesDir, subDir); + + sd.mkdirs(); + + // check maximum size for directory containing uploaded + // files + + if (FileUtils.sizeOfDirectory(filesDir) > maxUploadDirSize) { + log + .warning("MaxUploadDirSize of " + + maxUploadDirSize + + " bytes exceeded, not accepting more files at the moment"); + pi + .getErrors() + .add( + "Impossibile verificare ulteriori file, attendere qualche minuto!"); + + } else { + + String writedFileName; + try { + writedFileName = getMD5Checksum(item + .getInputStream()); + + File uploadedFile = new File(sd, writedFileName); + // File uploadedFile = item.getStoreLocation(); + + item.write(uploadedFile); + + pi.setWritedFileName(writedFileName); + // pi.setWritedFileName(uploadedFile.getName()); + + pi.setFullFileName(uploadedFile.getAbsolutePath()); + + } catch (Exception e) { + log.severe(e.getMessage()); + pi.getErrors().add(e.getMessage()); + } + + if (pi.getErrors().isEmpty()) { + String confPath = getServletContext().getRealPath( + "/WEB-INF") + + System.getProperty("file.separator") + + "conf"; + + // Inizio verifica + RootsVerifier rv; + Verifier v = null; + try { + rv = RootsVerifier.getInstance(confPath, + decodeHex(this.fingerprintString + .toCharArray())); + + v = new Verifier(pi.getFullFileName(), false, + rv); + + } catch (Exception e) { + pi.getErrors().add( + "Errore nell'inizializzazione della verifica: " + + e.getMessage()); + } + + if (v != null) { + while (!v.isDone()) + v.verify(); + + if (!v.getErrors().isEmpty()) + pi.getErrors().addAll(v.getErrors()); + + Hashtable r = v + .getRisultati(); + + if (r != null) { + Iterator principalIterator = r + .keySet().iterator(); + + boolean isVerified = false; + int i = 0; + while (principalIterator.hasNext()) { + X500Principal signer = principalIterator + .next(); + VerifyResult sv = r.get(signer); + isVerified = sv.isPassed() + && ((i == 0) || isVerified); + + } + + pi.setVerifyResults(r); + pi.setVerified(isVerified); + + } + } + } + + String o1 = pi.getFileName(); + pi.setContentFileName(o1.substring(0, o1 + .lastIndexOf("."))); + + } + } + + } + return pi; + } + + private ProcessedItem processFormField(DiskFileItem item) { + ProcessedItem pi = null; + // Process a regular form field + if (item.isFormField()) { + pi = new ProcessedItem(item.getFieldName(), !item.isFormField()); + pi.setString(item.getString()); + } + + return pi; + } + + private void sendContent(byte[] bytes, OutputStream os) throws IOException { + + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + + byte[] buffer = new byte[4096]; // A buffer to hold file contents + int bytes_read; // How many bytes in buffer + // Read a chunk of bytes into the buffer, then write them out, + // looping until we reach the end of the file (when read() returns -1). + // Note the combination of assignment and comparison in this while + // loop. This is a common I/O programming idiom. + while ((bytes_read = bais.read(buffer)) != -1) { // Read bytes until EOF + os.write(buffer, 0, bytes_read); // write bytes + } + + } + + private static byte[] createChecksum(InputStream fis) throws Exception { + + byte[] buffer = new byte[1024]; + MessageDigest complete = MessageDigest.getInstance("MD5"); + int numRead; + do { + numRead = fis.read(buffer); + if (numRead > 0) { + complete.update(buffer, 0, numRead); + } + } while (numRead != -1); + fis.close(); + return complete.digest(); + } + + public static String getMD5Checksum(InputStream fis) throws Exception { + byte[] b = createChecksum(fis); + String result = ""; + for (int i = 0; i < b.length; i++) { + result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1); + } + return result; + } + + public static byte[] decodeHex(char[] data) throws Exception { + + int len = data.length; + + if ((len & 0x01) != 0) { + throw new Exception("Odd number of characters."); + } + + byte[] out = new byte[len >> 1]; + + // two characters form the hex value. + for (int i = 0, j = 0; j < len; i++) { + int f = toDigit(data[j], j) << 4; + j++; + f = f | toDigit(data[j], j); + j++; + out[i] = (byte) (f & 0xFF); + } + + return out; + } + + protected static int toDigit(char ch, int index) throws Exception { + int digit = Character.digit(ch, 16); + if (digit == -1) { + throw new Exception("Illegal hexadecimal character " + ch + + " at index " + index); + } + return digit; + } + +} \ Manca newline alla fine del file I file binari verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/VerifyResult.class e verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/VerifyResult.class differiscono diff -rupN verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/VerifyResult.java verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/VerifyResult.java --- verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/VerifyResult.java 2010-07-28 14:29:50.000000000 +0200 +++ verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/VerifyResult.java 2011-06-16 16:33:46.535658894 +0200 @@ -28,6 +28,7 @@ import java.util.Collection; import java.util.Hashtable; import java.util.Iterator; import java.util.logging.Logger; +import java.util.Date; import javax.security.auth.x500.X500Principal; @@ -218,10 +219,19 @@ public class VerifyResult { * @return boolean */ public boolean getPassed() { - + return getPassed(new Date()); + } + /** + * Perform the global verification and return the global result
+ *
+ * Metodo complessivo che esegue e restituisce la verifica + * + * @param date for check validity + * @return boolean + */ + public boolean getPassed(Date date) { boolean isCorrect = getSignatureCorrect(); - boolean isCertValid = cv.getPassed(); - + boolean isCertValid = cv.getPassed(date); isPassed = isCorrect && isCertValid; if (risultatiCs != null) { @@ -234,7 +244,7 @@ public class VerifyResult { while (principalIterator.hasNext()) { X500Principal signer = principalIterator.next(); VerifyResult sv = risultatiCs.get(signer); - csVerified = sv.getPassed() && ((i == 0) || csVerified); + csVerified = sv.getPassed(date) && ((i == 0) || csVerified); } isPassed = isPassed && csVerified; @@ -243,7 +253,6 @@ public class VerifyResult { CRLerror = cv.getCRLerror(); certPathError = cv.getCertPathError(); - return isPassed; } I file binari verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/X509CertRL.class e verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/X509CertRL.class differiscono diff -rupN verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/X509CertRL.java verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/X509CertRL.java --- verifica-firma-0.2.0-src/src/it/trento/comune/j4sign/verification/X509CertRL.java 2010-07-28 14:29:50.000000000 +0200 +++ verifica-firma-0.2.0-src-GDO/src/it/trento/comune/j4sign/verification/X509CertRL.java 2011-06-14 17:39:29.675657623 +0200 @@ -34,7 +34,7 @@ import javax.naming.ldap.*; import javax.naming.directory.*; import javax.security.auth.x500.X500Principal; -import org.apache.commons.configuration.ConfigurationException; +//GDO import org.apache.commons.configuration.ConfigurationException; import org.bouncycastle.asn1.*; import org.bouncycastle.cms.*; import org.bouncycastle.util.encoders.*; diff -rupN verifica-firma-0.2.0-src/web/WEB-INF/conf/conf.properties verifica-firma-0.2.0-src-GDO/web/WEB-INF/conf/conf.properties --- verifica-firma-0.2.0-src/web/WEB-INF/conf/conf.properties 2010-07-28 14:29:50.000000000 +0200 +++ verifica-firma-0.2.0-src-GDO/web/WEB-INF/conf/conf.properties 2011-06-13 07:50:29.638154979 +0200 @@ -1,8 +1,8 @@ cnipa.dir=CNIPA #Name of the signed zip file of root CAs inside cnipa.dir -cnipa.roots=@cnipa.roots@ +cnipa.roots=LISTACER_20101129.zip.p7m #Name of the issuing CA of signer cert for signed zip file of root CAs -cnipa.ca=@cnipa.ca@ +cnipa.ca=DigitPA.cer proxyUsingUserPassword=false useProxy=false userName= diff -rupN verifica-firma-0.2.0-src/web/WEB-INF/conf/conf.properties~ verifica-firma-0.2.0-src-GDO/web/WEB-INF/conf/conf.properties~ --- verifica-firma-0.2.0-src/web/WEB-INF/conf/conf.properties~ 1970-01-01 01:00:00.000000000 +0100 +++ verifica-firma-0.2.0-src-GDO/web/WEB-INF/conf/conf.properties~ 2010-07-28 14:29:50.000000000 +0200 @@ -0,0 +1,12 @@ +cnipa.dir=CNIPA +#Name of the signed zip file of root CAs inside cnipa.dir +cnipa.roots=@cnipa.roots@ +#Name of the issuing CA of signer cert for signed zip file of root CAs +cnipa.ca=@cnipa.ca@ +proxyUsingUserPassword=false +useProxy=false +userName= +host=null +port=null +CRLupdate=true +