View Javadoc

1   /**
2    * LICENCIA LGPL:
3    * 
4    * Esta librería es Software Libre; Usted puede redistribuirla y/o modificarla
5    * bajo los términos de la GNU Lesser General Public License (LGPL) tal y como 
6    * ha sido publicada por la Free Software Foundation; o bien la versión 2.1 de 
7    * la Licencia, o (a su elección) cualquier versión posterior.
8    * 
9    * Esta librería se distribuye con la esperanza de que sea útil, pero SIN 
10   * NINGUNA GARANTÍA; tampoco las implícitas garantías de MERCANTILIDAD o 
11   * ADECUACIÓN A UN PROPÓSITO PARTICULAR. Consulte la GNU Lesser General Public 
12   * License (LGPL) para más detalles
13   * 
14   * Usted debe recibir una copia de la GNU Lesser General Public License (LGPL) 
15   * junto con esta librería; si no es así, escriba a la Free Software Foundation 
16   * Inc. 51 Franklin Street, 5º Piso, Boston, MA 02110-1301, USA o consulte
17   * <http://www.gnu.org/licenses/>.
18   *
19   * Copyright 2011 Agencia de Tecnología y Certificación Electrónica
20   */
21  package es.accv.arangi.timestamp;
22  
23  import java.io.File;
24  import java.io.FileNotFoundException;
25  import java.io.InputStream;
26  import java.net.MalformedURLException;
27  import java.net.URL;
28  
29  import org.apache.log4j.Logger;
30  import org.bouncycastle.tsp.TimeStampToken;
31  
32  import es.accv.arangi.base.exception.document.HashingException;
33  import es.accv.arangi.base.exception.document.InitDocumentException;
34  import es.accv.arangi.base.exception.timestamp.MalformedTimeStampException;
35  import es.accv.arangi.base.exception.timestamp.ResponseTimeStampException;
36  import es.accv.arangi.base.exception.timestamp.TimeStampServerConnectionException;
37  
38  /**
39   * Clase para trabajar con sellos de tiempo según la 
40   * <a href="http://tools.ietf.org/rfc/rfc3161.txt" target="rfc">RFC-3161</a>.<br><br>
41   * 
42   * Si lo único que se quiere es obtener la hora actual es mejor utilizar la clase
43   * es.accv.arangi.base.util.time.Time.<br><br>
44   * 
45   * NOTA: En la clase se utilizan indistintamente los términos <i>servidor de sello de 
46   * tiempos</i> y <i>TSA - Time Stamp Authority</i><br><br>
47   * 
48   * Un ejemplo de uso sería: <br><br>
49   * 
50   * <code>
51   * 	byte[] dataToStamp = "data to stamp".getBytes();<br>
52   * 	TimeStamp timeStamp = TimeStamp.stampDocument (dataToStamp);<br><br>
53   * 
54   * 	//guardar sello<br>
55   * 	Util.saveFile(new File ("/sellos/sello.ts"), timeStamp.toDER());<br><br>
56   * 
57   * 	//cargar el sello<br>
58   *  TimeStamp timeStamp2 = new TimeStamp (new File ("/sellos/sello.ts"));
59   * </code><br><br>
60   * 
61   * @author <a href="mailto:jgutierrez@accv.es">José M Gutiérrez</a>
62   */
63  public class TimeStamp extends es.accv.arangi.base.timestamp.TimeStamp {
64  
65  	/*
66  	 * Logger de la clase
67  	 */
68  	static Logger logger = Logger.getLogger(TimeStamp.class);
69  	
70  	/**
71  	 * URL del servicio de sello de tiempos de la ACCV
72  	 */
73  	public static final String URL_ACCV_TSA_SERVER	= "http://tss.accv.es:8318/tsa";
74  	
75  	/**
76  	 * Constructor en base a un objeto sello de tiempos de Bouncy Castle
77  	 * 
78  	 * @param timeStamp Sello de tiempos de Bouncy Castle
79  	 */
80  	public TimeStamp (TimeStampToken timeStamp) {
81  		super(timeStamp);
82  	}
83  	
84  	/**
85  	 * Constructor en base a un array de bytes que contiene un sello de tiempo.
86  	 * 
87  	 * @param bytesTimeStamp Contenido de un objeto sello de tiempo
88  	 * @throws MalformedTimeStampException El objeto contenido en el stream de lectura no parece
89  	 * 	ser un sello de tiempo
90  	 */
91  	public TimeStamp(byte[] bytesTimeStamp) throws MalformedTimeStampException {
92  		super(bytesTimeStamp);
93  	}
94  
95  	/**
96  	 * Constructor en base a un fichero que contiene un sello de tiempo.
97  	 * 
98  	 * @param fileTimeStamp Fichero que contiene un objeto sello de tiempo
99  	 * @throws MalformedTimeStampException El objeto contenido en el stream de lectura no parece
100 	 * 	ser un sello de tiempo
101 	 * @throws FileNotFoundException El fichero no existe
102 	 */
103 	public TimeStamp(File fileTimeStamp) throws MalformedTimeStampException, FileNotFoundException {
104 		super(fileTimeStamp);
105 	}
106 
107 	/**
108 	 * Constructor en base a un stream de lectura que contiene el sello de tiempo.
109 	 * 
110 	 * @param isTimeStamp Stream de lectura a un objeto sello de tiempo
111 	 * @throws MalformedTimeStampException El objeto contenido en el stream de lectura no parece
112 	 * 	ser un sello de tiempo
113 	 */
114 	public TimeStamp(InputStream isTimeStamp) throws MalformedTimeStampException {
115 		super(isTimeStamp);
116 	}
117 
118 	/**
119 	 * Método que obtiene un sello de tiempos de la TSA de la ACCV para los datos
120 	 * pasados como parámetro.
121 	 * 
122 	 * @param bytesToStamp Array de bytes con el contenido del documento a sellar
123 	 * @return Sello de tiempos de la ACCV sobre los datos pasados
124 	 * @throws TimeStampServerConnectionException Errores en la conexión con el servidor de sello
125 	 * 	de tiempos
126 	 * @throws MalformedTimeStampException El objeto devuelto por el servidor no parece ser un 
127 	 * 	sello de tiempos
128 	 * @throws ResponseTimeStampException La TSA ha devuelto una respuesta con un error
129 	 * @throws HashingException Error obteniendo el hash
130 	 */
131 	public static TimeStamp stampDocument (byte[] bytesToStamp) throws MalformedTimeStampException, ResponseTimeStampException, HashingException, TimeStampServerConnectionException {
132 		logger.debug ("[TimeStamp.stamp]::Entrada::" + bytesToStamp);
133 		
134 		//-- Obtener el sello 
135 		try {
136 			return new TimeStamp (es.accv.arangi.base.timestamp.TimeStamp.stampDocument(bytesToStamp, new URL(URL_ACCV_TSA_SERVER)).toDER());
137 		} catch (MalformedURLException e) {
138 			//-- La URL está bien formada (no se va a dar)
139 			return null;
140 		} 
141 	}
142 	
143 	/**
144 	 * Método que obtiene un sello de tiempos de la TSA de la ACCV para los datos
145 	 * contenidos en el fichero pasado como parámetro.
146 	 * 
147 	 * @param fileToStamp Fichero con los datos a sellar
148 	 * @return Sello de tiempos de la ACCV sobre los datos pasados
149 	 * @throws TimeStampServerConnectionException Errores en la conexión con el servidor de sello
150 	 * 	de tiempos
151 	 * @throws MalformedTimeStampException El objeto devuelto por el servidor no parece ser un 
152 	 * 	sello de tiempos
153 	 * @throws ResponseTimeStampException La TSA ha devuelto una respuesta con un error
154 	 * @throws HashingException Error obteniendo el hash
155 	 * @throws InitDocumentException El fichero a sellar es nulo o no existe
156 	 */
157 	public static TimeStamp stampDocument (File fileToStamp) throws MalformedTimeStampException, ResponseTimeStampException, HashingException, MalformedURLException, TimeStampServerConnectionException, InitDocumentException {
158 		logger.debug ("[TimeStamp.stamp]::Entrada::" + fileToStamp);
159 		
160 		//-- Obtener el sello 
161 		try {
162 			return new TimeStamp (es.accv.arangi.base.timestamp.TimeStamp.stampDocument(fileToStamp, new URL(URL_ACCV_TSA_SERVER)).toDER());
163 		} catch (MalformedURLException e) {
164 			//-- La URL está bien formada (no se va a dar)
165 			return null;
166 		} 
167 	}
168 
169 	/**
170 	 * Método que obtiene un sello de tiempos de la TSA de la ACCV para los datos
171 	 * pasados como parámetro.
172 	 * 
173 	 * @param isToStamp Stream de lectura que apunta a los datos a sellar
174 	 * @return Sello de tiempos de la ACCV sobre los datos pasados
175 	 * @throws TimeStampServerConnectionException Errores en la conexión con el servidor de sello
176 	 * 	de tiempos
177 	 * @throws MalformedTimeStampException El objeto devuelto por el servidor no parece ser un 
178 	 * 	sello de tiempos
179 	 * @throws ResponseTimeStampException La TSA ha devuelto una respuesta con un error
180 	 * @throws HashingException Error obteniendo el hash
181 	 */
182 	public static TimeStamp stampDocument (InputStream isToStamp) throws MalformedTimeStampException, ResponseTimeStampException, HashingException, TimeStampServerConnectionException {
183 		logger.debug ("[TimeStamp.stamp]::Entrada::" + isToStamp);
184 		
185 		//-- Obtener el sello 
186 		try {
187 			return new TimeStamp (es.accv.arangi.base.timestamp.TimeStamp.stampDocument(isToStamp, new URL(URL_ACCV_TSA_SERVER)).toDER());
188 		} catch (MalformedURLException e) {
189 			//-- La URL está bien formada (no se va a dar)
190 			return null;
191 		} 
192 		
193 	}
194 
195 	/**
196 	 * Método que obtiene un sello de tiempos de la TSA de la ACCV para los datos
197 	 * pasados como parámetro.
198 	 * 
199 	 * @param urlToStamp URL del documento cuyo contenido se desea sellar
200 	 * @return Sello de tiempos de la ACCV sobre los datos pasados
201 	 * @throws TimeStampServerConnectionException Errores en la conexión con el servidor de sello
202 	 * 	de tiempos
203 	 * @throws MalformedTimeStampException El objeto devuelto por el servidor no parece ser un 
204 	 * 	sello de tiempos
205 	 * @throws ResponseTimeStampException La TSA ha devuelto una respuesta con un error
206 	 * @throws HashingException Error obteniendo el hash
207 	 * @throws InitDocumentException No se puede obtener el documento en la URL
208 	 */
209 	public static TimeStamp stampDocument (URL urlToStamp) throws MalformedTimeStampException, ResponseTimeStampException, HashingException, TimeStampServerConnectionException, InitDocumentException {
210 		logger.debug ("[TimeStamp.stamp]::Entrada::" + urlToStamp);
211 		
212 		//-- Obtener el sello 
213 		try {
214 			return new TimeStamp (es.accv.arangi.base.timestamp.TimeStamp.stampDocument(urlToStamp, new URL(URL_ACCV_TSA_SERVER)).toDER());
215 		} catch (MalformedURLException e) {
216 			//-- La URL está bien formada (no se va a dar)
217 			return null;
218 		} 
219 		
220 	}
221 
222 	/**
223 	 * Método que obtiene un sello de tiempo de un servidor de sello de tiempos.
224 	 * 
225 	 * @param hash Hash del documento cuyo contenido se desea sellar
226 	 * @throws FileNotFoundException El fichero no existe
227 	 * @throws TimeStampServerConnectionException Errores en la conexión con el servidor de sello
228 	 * 	de tiempos
229 	 * @throws MalformedTimeStampException El objeto devuelto por el servidor no parece ser un 
230 	 * 	sello de tiempos
231 	 * @throws ResponseTimeStampException La TSA ha devuelto una respuesta con un error
232 	 */
233 	public static TimeStamp stampHash (byte[] hash) throws TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException {
234 		//-- Obtener el sello 
235 		try {
236 			return new TimeStamp (es.accv.arangi.base.timestamp.TimeStamp.stampHash(hash, new URL(URL_ACCV_TSA_SERVER)).toDER());
237 		} catch (MalformedURLException e) {
238 			//-- La URL está bien formada (no se va a dar)
239 			return null;
240 		} 
241 	}
242 	
243 	/**
244 	 * Obtiene la URL de la TSA de la ACCV
245 	 * 
246 	 * @return URL de la TSA de la ACCV
247 	 */
248 	public static URL getURLACCVTSA () {
249 		try {
250 			return new URL (URL_ACCV_TSA_SERVER);
251 		} catch (MalformedURLException e) {
252 			// No se va a dar, la URL está bien formada
253 			logger.info("[TimeStamp.getURLACCVTSA]::La URL de la ACCV no está bien formada: " + URL_ACCV_TSA_SERVER, e);
254 			return null;
255 		}
256 	}
257 }