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 }