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.base.signature;
22  
23  import java.io.ByteArrayInputStream;
24  import java.io.File;
25  import java.io.FileNotFoundException;
26  import java.io.IOException;
27  import java.io.InputStream;
28  import java.net.URL;
29  import java.security.MessageDigest;
30  import java.security.cert.CertificateEncodingException;
31  import java.security.cert.CertificateException;
32  import java.security.cert.X509Certificate;
33  import java.util.ArrayList;
34  import java.util.Arrays;
35  import java.util.Date;
36  
37  import javax.xml.crypto.dsig.CanonicalizationMethod;
38  import javax.xml.xpath.XPath;
39  import javax.xml.xpath.XPathConstants;
40  import javax.xml.xpath.XPathExpression;
41  import javax.xml.xpath.XPathFactory;
42  
43  import org.apache.log4j.Logger;
44  import org.apache.xml.security.exceptions.XMLSecurityException;
45  import org.apache.xml.security.signature.XMLSignature;
46  import org.apache.xml.security.signature.XMLSignatureException;
47  import org.apache.xml.security.transforms.Transforms;
48  import org.w3c.dom.Attr;
49  import org.w3c.dom.Document;
50  import org.w3c.dom.Element;
51  import org.w3c.dom.NamedNodeMap;
52  import org.w3c.dom.Node;
53  import org.w3c.dom.NodeList;
54  
55  import es.accv.arangi.base.certificate.Certificate;
56  import es.accv.arangi.base.certificate.validation.CAList;
57  import es.accv.arangi.base.device.DeviceManager;
58  import es.accv.arangi.base.document.FileDocument;
59  import es.accv.arangi.base.document.IDocument;
60  import es.accv.arangi.base.document.URLDocument;
61  import es.accv.arangi.base.exception.TimeStampException;
62  import es.accv.arangi.base.exception.certificate.NormalizeCertificateException;
63  import es.accv.arangi.base.exception.device.LoadingObjectException;
64  import es.accv.arangi.base.exception.device.SearchingException;
65  import es.accv.arangi.base.exception.document.HashingException;
66  import es.accv.arangi.base.exception.document.InitDocumentException;
67  import es.accv.arangi.base.exception.signature.CounterSignatureException;
68  import es.accv.arangi.base.exception.signature.NoCoincidentDocumentException;
69  import es.accv.arangi.base.exception.signature.NoDocumentToSignException;
70  import es.accv.arangi.base.exception.signature.RetrieveOCSPException;
71  import es.accv.arangi.base.exception.signature.SignatureException;
72  import es.accv.arangi.base.exception.signature.SignatureNotFoundException;
73  import es.accv.arangi.base.exception.signature.XMLDocumentException;
74  import es.accv.arangi.base.exception.timestamp.MalformedTimeStampException;
75  import es.accv.arangi.base.exception.timestamp.ResponseTimeStampException;
76  import es.accv.arangi.base.exception.timestamp.TimeStampServerConnectionException;
77  import es.accv.arangi.base.mityc.CAListCertStatusRecover;
78  import es.accv.arangi.base.mityc.ContraFirmaXML;
79  import es.accv.arangi.base.signature.util.TSAData;
80  import es.accv.arangi.base.signature.util.XAdESAttachedNodeToSignObject;
81  import es.accv.arangi.base.signature.util.XAdESAttachedSignatureOptions;
82  import es.accv.arangi.base.signature.util.XAdESDataObjectFormat;
83  import es.accv.arangi.base.signature.util.XAdESDetachedSignatureOptions;
84  import es.accv.arangi.base.timestamp.TimeStamp;
85  import es.accv.arangi.base.util.Util;
86  import es.accv.arangi.base.util.validation.ValidationResult;
87  import es.mityc.firmaJava.libreria.ConstantesXADES;
88  import es.mityc.firmaJava.libreria.excepciones.AddXadesException;
89  import es.mityc.firmaJava.libreria.utilidades.Base64Coder;
90  import es.mityc.firmaJava.libreria.utilidades.I18n;
91  import es.mityc.firmaJava.libreria.utilidades.NombreNodo;
92  import es.mityc.firmaJava.libreria.utilidades.UtilidadFechas;
93  import es.mityc.firmaJava.libreria.utilidades.UtilidadFicheros;
94  import es.mityc.firmaJava.libreria.utilidades.UtilidadFirmaElectronica;
95  import es.mityc.firmaJava.libreria.utilidades.UtilidadTratarNodo;
96  import es.mityc.firmaJava.libreria.xades.CanonicalizationEnum;
97  import es.mityc.firmaJava.libreria.xades.DataToSign;
98  import es.mityc.firmaJava.libreria.xades.EnumFormatoFirma;
99  import es.mityc.firmaJava.libreria.xades.RespYCerts;
100 import es.mityc.firmaJava.libreria.xades.ResultadoEnum;
101 import es.mityc.firmaJava.libreria.xades.ResultadoValidacion;
102 import es.mityc.firmaJava.libreria.xades.UtilidadXadesA;
103 import es.mityc.firmaJava.libreria.xades.XAdESSchemas;
104 import es.mityc.firmaJava.libreria.xades.elementos.xades.CRLRef;
105 import es.mityc.firmaJava.libreria.xades.elementos.xades.EncapsulatedX509Certificate;
106 import es.mityc.firmaJava.libreria.xades.errores.BadFormedSignatureException;
107 import es.mityc.firmaJava.libreria.xades.errores.FirmaXMLError;
108 import es.mityc.firmaJava.ts.ConstantesTSA;
109 import es.mityc.firmaJava.ts.TSCliente;
110 import es.mityc.firmaJava.ts.TSClienteError;
111 import es.mityc.javasign.certificate.CertStatusException;
112 import es.mityc.javasign.certificate.ICertStatus;
113 import es.mityc.javasign.certificate.IOCSPCertStatus;
114 import es.mityc.javasign.certificate.IX509CRLCertStatus;
115 
116 /**
117  * Clase que maneja firmas en formato XAdES-X-L de acuerdo al estándar 
118  * <a href="http://uri.etsi.org/01903/v1.3.2/ts_101903v010302p.pdf" target="etsi">
119  * ETSI TS 101 903</a><br><br>
120  * 
121  * El formato XAdES-A también es tratado por esta clase. Gracias al método 
122  * {@link #getTimeStampCertificateExpiration() getTimeStampCertificateExpiration} es
123  * posible determinar la fecha de caducidad del certificado de TSA. Antes de que se
124  * llegue a esta fecha es conveniente resellar la firma con un sello de archivo
125  * mediante el método {@link #addArchiveTimeStamp(URL) addArchiveTimeStamp}.<br><br>
126  *  
127  * Ejemplo de uso: <br><br>
128  * 
129  * <code> 
130  * KeyStoreManager manager = new KeyStoreManager (..., ...);<br>
131  * String alias = ...;<br>
132  * InputStreamDocument documentTexto = new InputStreamDocument (new FileInputStream (...));<br>
133  * InputStreamDocument documentXML = new InputStreamDocument (new FileInputStream (...));<br>
134  * File file = new File (...);<br>
135  * URL url = new URL (...);<br>
136  * URL urlTSA = new URL (...);<br>
137  * CAList caList = new CAList (...);<br><br>
138  * 
139  * //-- Genera una firma attached. El documento se guardará en la firma en base64<br>
140  * XAdESXLSignature signature1 = XAdESXLSignature.signAttached(manager, alias, documentTexto, urlTSA, caList);<br><br>
141  * 
142  * //-- Genera una firma detached que referencia al fichero en disco<br>
143  * XAdESXLSignature signature2 = XAdESXLSignature.signDetached(manager, alias, file, urlTSA, caList);<br><br>
144  * 
145  * //-- Genera una firma detached que referencia a "2011/04/29/certificados/CER-2584665.pdf"<br>
146  * XAdESXLSignature signature3 = XAdESXLSignature.signDetached(manager, alias, file, "2011/04/29/certificados/CER-2584665.pdf", urlTSA, caList);<br><br>
147  * 
148  * //-- Genera una firma detached que referencia al fichero ubicado en la URL<br>
149  * XAdESXLSignature signature4 = XAdESXLSignature.signDetached(manager, alias, url, urlTSA, caList);<br><br>
150  * 
151  * //-- Genera una firma attached dentro del propio documento<br>
152  * XAdESXLSignature signature5 = XAdESXLSignature.signAttached(manager, alias, documentoXML, "titulo", "documento", urlTSA, caList);<br><br>
153  * </code>
154  * 
155  * @author <a href="mailto:jgutierrez@accv.es">José M Gutiérrez</a>
156  */
157 public class XAdESXLSignature extends XAdESSignature {
158 	
159 	/*
160 	 * Logger de la clase
161 	 */
162 	static Logger logger = Logger.getLogger(XAdESXLSignature.class);
163 	
164 	/**
165 	 * Tipo de la firma
166 	 */
167 	public static final String SIGNATURE_TYPE	= "XAdES-X-L";
168 	
169 	/*
170 	 * Referencia por defecto al node SignatureTimeStamp
171 	 */
172 	protected static final String DEFAULT_SIGNATURE_TIMESTAMP_ID 	= "SignTimeStamp";
173 	
174 	/*
175 	 * URI para espacios de nombres XADES
176 	 */
177 	protected static final String NAMESPACE_XADES_URI = "http://uri.etsi.org/01903/v1.3.2#";
178 
179 	/*
180 	 * Constante que indica el algoritmo de canonicalización por defecto
181 	 */
182 	protected static final String DEFAULT_CANONICALIZATION_ALGORITHM	= CanonicalizationMethod.INCLUSIVE;
183 	
184 
185 	//-- Constructores
186 	
187 	/**
188 	 * Construye el objeto en base a un XML que tiene el formato
189 	 * XAdES-X-L
190 	 * 
191 	 * @param xmlDocument Documento XML
192 	 */
193 	public XAdESXLSignature(Document xmlDocument) {
194 		initialize (xmlDocument);
195 	}
196 	
197 	/**
198 	 * Construye el objeto en base a un fichero XAdES-X-L
199 	 * 
200 	 * @param xmlFile Fichero XAdES-X-L
201 	 * @throws FileNotFoundException El fichero no existe
202 	 * @throws XMLDocumentException El fichero no parece un XML válido
203 	 */
204 	public XAdESXLSignature(File xmlFile) throws FileNotFoundException, XMLDocumentException {
205 		initialize (xmlFile);
206 	}
207 
208 	/**
209 	 * Construye el objeto en base a un array de bytes.
210 	 * 
211 	 * @param signature Firma XAdES-X-L
212 	 * @throws XMLDocumentException El fichero no parece un XML válido
213 	 */
214 	public XAdESXLSignature(byte[] signature) throws XMLDocumentException {
215 		initialize (signature);
216 	}
217 
218 	/**
219 	 * Construye el objeto en base a un stream de lectura.
220 	 * 
221 	 * @param isSignature Stream de lectura a una firma XAdES-X-L
222 	 * @throws XMLDocumentException El fichero no parece un XML válido
223 	 */
224 	public XAdESXLSignature(InputStream isSignature) throws XMLDocumentException {
225 		initialize(isSignature);
226 	}
227 
228 	/**
229 	 * Construye el objeto en base a otro XAdES-X-L
230 	 * 
231 	 * @param xlSignature Firma XAdES-X-L
232 	 */
233 	protected XAdESXLSignature(XAdESXLSignature xlSignature) {
234 		xadesDocument = xlSignature.xadesDocument;
235 	}
236 	
237 	//-- Métodos públicos
238 	
239 	/**
240 	 * Obtiene la fecha del sello de tiempos de la firma (Punto 7.3 del estándar).
241 	 * 
242 	 * @return Fecha del sello de tiempos
243 	 * @throws MalformedTimeStampException El sello de tiempos guardado en el fichero XAdES-X-L no 
244 	 * está bien formado
245 	 */
246 	public Date getTimeStampTime () throws MalformedTimeStampException {
247 		return getXAdESTimeStampTime();
248 
249 	}
250 	
251 	/**
252 	 * Realiza una firma XAdES-X-L detached (el fichero no se incluirá en la firma). No completa los campos 
253 	 * no obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier', 
254 	 * 'signatureProductionPlace' y 'signerRole'.
255 	 * 
256 	 * La referencia a la que apuntará la firma será el path del fichero.
257 	 * 
258 	 * @param manager Dispositivo criptográfico que realizará la firma
259 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
260 	 * @param document Fichero a firmar
261 	 * @param urlTSA URL del servidor de sello de tiempos
262 	 * @param caList Lista de CAs para obtener información de validación
263 	 * @return Firma XADES-XL
264 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
265 	 *  para realizar la firma
266 	 * @throws SignatureException No se puede realizar la firma
267 	 * @throws NoDocumentToSignException El fichero a firmar no existe o es nulo
268 	 * @deprecated Usar {@link #signDetached(DeviceManager,String,IDocument,String,TSAData,CAList,XAdESDetachedSignatureOptions) signDetached}
269 	 */
270 	public static XAdESXLSignature signDetached (DeviceManager manager, String alias, File document, URL urlTSA, CAList caList) throws LoadingObjectException, SignatureException, NoDocumentToSignException {
271 		return signDetached(manager, alias, document, null, urlTSA, caList, null, null);
272 	}
273 	
274 	/**
275 	 * Realiza una firma XAdES-X-L detached (el fichero no se incluirá en la firma). No completa los campos 
276 	 * no obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier' y
277 	 * 'signatureProductionPlace'.
278 	 * 
279 	 * La referencia a la que apuntará la firma será el path del fichero.
280 	 * 
281 	 * @param manager Dispositivo criptográfico que realizará la firma
282 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
283 	 * @param document Fichero a firmar
284 	 * @param digitalSignatureAlgorithm Algoritmo de firma (si nulo algoritmo por defecto)
285 	 * @param urlTSA URL del servidor de sello de tiempos
286 	 * @param caList Lista de CAs para obtener información de validación
287 	 * @param dof Información para construir el tag DataObjectFormat (puede ser null)
288 	 * @param claimedRoles Roles de la firma (puede ser null)
289 	 * @return Firma XADES-XL
290 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
291 	 *  para realizar la firma
292 	 * @throws SignatureException No se puede realizar la firma
293 	 * @throws NoDocumentToSignException El fichero a firmar no existe o es nulo
294 	 * @deprecated Usar {@link #signDetached(DeviceManager,String,IDocument,String,TSAData,CAList,XAdESDetachedSignatureOptions) signDetached}
295 	 */
296 	public static XAdESXLSignature signDetached (DeviceManager manager, String alias, File document, 
297 			String digitalSignatureAlgorithm, URL urlTSA, CAList caList, XAdESDataObjectFormat dof, 
298 			String[] claimedRoles) throws LoadingObjectException, SignatureException, NoDocumentToSignException {
299 		
300 		logger.debug("[XAdESXLSignature.signDetached]::Entrada::" + Arrays.asList(new Object[] { manager, alias, document, digitalSignatureAlgorithm, urlTSA, caList, dof, claimedRoles }));
301 		
302 		//-- Obtener el document de Arangi y llamar a la firma attached
303 		FileDocument fileDocument;
304 		try {
305 			fileDocument = new FileDocument(document);
306 		} catch (InitDocumentException e) {
307 			logger.info("[XAdESXLSignature.signDetached]::El fichero a firmar no existe o es nulo:: " + document);
308 			throw new NoDocumentToSignException("El fichero a firmar no existe o es nulo: " + document);
309 		}
310 		
311 		//-- Obtener la referencia al fichero
312 		String reference = UtilidadFicheros.relativizeRute("#", document);
313 		
314 		return signDetached(manager, alias, fileDocument, digitalSignatureAlgorithm, reference, urlTSA, caList, dof, claimedRoles);
315 		
316 	}
317 	
318 	/**
319 	 * Realiza una firma XAdES-XL detached (el fichero no se incluirá en la firma). No completa los campos 
320 	 * no obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier', 
321 	 * 'signatureProductionPlace' y 'signerRole'.
322 	 * 
323 	 * La referencia a la que apuntará la firma será la URL del documento.
324 	 * 
325 	 * @param manager Dispositivo criptográfico que realizará la firma
326 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
327 	 * @param urlDocument Documento a firmar. Se encuentra en una URL accesible.
328 	 * @param urlTSA URL del servidor de sello de tiempos
329 	 * @param caList Lista de CAs para obtener información de validación
330 	 * @return Firma XADES-XL
331 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
332 	 *  para realizar la firma
333 	 * @throws SignatureException No se puede realizar la firma
334 	 * @throws NoDocumentToSignException La URL a firmar no existe o es nula
335 	 * @deprecated Usar {@link #signDetached(DeviceManager,String,IDocument,String,TSAData,CAList,XAdESDetachedSignatureOptions) signDetached}
336 	 */
337 	public static XAdESXLSignature signDetached (DeviceManager manager, String alias, URL urlDocument, URL urlTSA, CAList caList) throws LoadingObjectException, SignatureException, NoDocumentToSignException {
338 		return signDetached(manager, alias, urlDocument, null, urlTSA, caList, null, null);
339 	}
340 	
341 	/**
342 	 * Realiza una firma XAdES-XL detached (el fichero no se incluirá en la firma). No completa los campos 
343 	 * no obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier' y 
344 	 * 'signatureProductionPlace'.
345 	 * 
346 	 * La referencia a la que apuntará la firma será la URL del documento.
347 	 * 
348 	 * @param manager Dispositivo criptográfico que realizará la firma
349 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
350 	 * @param urlDocument Documento a firmar. Se encuentra en una URL accesible.
351 	 * @param digitalSignatureAlgorithm Algoritmo de firma (si nulo algoritmo por defecto)
352 	 * @param urlTSA URL del servidor de sello de tiempos
353 	 * @param caList Lista de CAs para obtener información de validación
354 	 * @param dof Información para construir el tag DataObjectFormat (puede ser null)
355 	 * @param claimedRoles Roles de la firma (puede ser null)
356 	 * @return Firma XADES-XL
357 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
358 	 *  para realizar la firma
359 	 * @throws SignatureException No se puede realizar la firma
360 	 * @throws NoDocumentToSignException La URL a firmar no existe o es nula
361 	 * @deprecated Usar {@link #signDetached(DeviceManager,String,IDocument,String,TSAData,CAList,XAdESDetachedSignatureOptions) signDetached}
362 	 */
363 	public static XAdESXLSignature signDetached (DeviceManager manager, String alias, URL urlDocument, 
364 			String digitalSignatureAlgorithm, URL urlTSA, CAList caList, XAdESDataObjectFormat dof, 
365 			String[] claimedRoles) throws LoadingObjectException, SignatureException, NoDocumentToSignException {
366 		
367 		logger.debug("[XAdESXLSignature.signDetached]::Entrada::" + Arrays.asList(new Object[] { manager, alias, urlDocument, digitalSignatureAlgorithm, urlTSA, caList, dof, claimedRoles }));
368 		
369 		//-- Obtener el document de Arangi y llamar a la firma attached
370 		URLDocument document;
371 		try {
372 			document = new URLDocument(urlDocument);
373 		} catch (InitDocumentException e) {
374 			logger.info("[XAdESXLSignature.signDetached]::La URL a firmar no existe o es nula:: " + urlDocument);
375 			throw new NoDocumentToSignException("La URL a firmar no existe o es nula: " + urlDocument);
376 		}
377 		
378 		//-- Obtener la referencia al fichero
379 		String reference = urlDocument.toString();
380 		
381 		return signDetached(manager, alias, document, digitalSignatureAlgorithm, reference, urlTSA, caList, dof, claimedRoles);
382 	}
383 	
384 	/**
385 	 * Realiza una firma XAdES-XL detached (el fichero no se incluirá en la firma). No completa los campos 
386 	 * no obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier', 
387 	 * 'signatureProductionPlace' y 'signerRole'.
388 	 * 
389 	 * @param manager Dispositivo criptográfico que realizará la firma
390 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
391 	 * @param document Documento a firmar. 
392 	 * @param reference Referencia a la que apuntará la firma
393 	 * @param urlTSA URL del servidor de sello de tiempos
394 	 * @param caList Lista de CAs para obtener información de validación
395 	 * @return Firma XADES-XL
396 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
397 	 *  para realizar la firma
398 	 * @throws SignatureException No se puede realizar la firma
399 	 * @deprecated Usar {@link #signDetached(DeviceManager,String,IDocument,String,TSAData,CAList,XAdESDetachedSignatureOptions) signDetached}
400 	 */
401 	public static XAdESXLSignature signDetached (DeviceManager manager, String alias, IDocument document, String reference, URL urlTSA, CAList caList) throws LoadingObjectException, SignatureException {
402 		return signDetached(manager, alias, document, reference, null, urlTSA, caList, null, null);
403 	}
404 	
405 	/**
406 	 * Realiza una firma XAdES-XL detached (el fichero no se incluirá en la firma). No completa los campos 
407 	 * no obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier' y
408 	 * 'signatureProductionPlace'.
409 	 * 
410 	 * @param manager Dispositivo criptográfico que realizará la firma
411 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
412 	 * @param document Documento a firmar. 
413 	 * @param digitalSignatureAlgorithm Algoritmo de firma (si nulo algoritmo por defecto)
414 	 * @param reference Referencia a la que apuntará la firma
415 	 * @param urlTSA URL del servidor de sello de tiempos
416 	 * @param caList Lista de CAs para obtener información de validación
417 	 * @param dof Información para construir el tag DataObjectFormat (puede ser null)
418 	 * @param claimedRoles Roles de la firma (puede ser null)
419 	 * @return Firma XADES-XL
420 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
421 	 *  para realizar la firma
422 	 * @throws SignatureException No se puede realizar la firma
423 	 * @deprecated Usar {@link #signDetached(DeviceManager,String,IDocument,String,TSAData,CAList,XAdESDetachedSignatureOptions) signDetached}
424 	 */
425 	public static XAdESXLSignature signDetached (DeviceManager manager, String alias, IDocument document, 
426 			String digitalSignatureAlgorithm, String reference, URL urlTSA, CAList caList, XAdESDataObjectFormat dof, String[] claimedRoles) throws LoadingObjectException, SignatureException {
427 		
428 		logger.debug("[XAdESXLSignature.signDetached]::Entrada::" + Arrays.asList(new Object[] { manager, alias, document, digitalSignatureAlgorithm, reference, urlTSA, caList, dof, claimedRoles }));
429 		
430 		TSAData tsaData = new TSAData(urlTSA);
431 		XAdESDetachedSignatureOptions options = new XAdESDetachedSignatureOptions(digitalSignatureAlgorithm, null, dof, claimedRoles, null, null);
432 		return signDetached(manager, alias, document, reference, tsaData, caList, options);
433 	}
434 	
435 	/**
436 	 * Realiza una firma XAdES-XL detached (el fichero no se incluirá en la firma). Si no
437 	 * se puede obtener la información de validación mediante OCSP se producirá una
438 	 * excepción.
439 	 * 
440 	 * @param manager Dispositivo criptográfico que realizará la firma
441 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
442 	 * @param document Documento a firmar. 
443 	 * @param reference Referencia a la que apuntará la firma
444 	 * @param tsaData Información de conexión a la TSA
445 	 * @param caList Lista de CAs para obtener información de validación
446 	 * @param options Opciones de la firma
447 	 * @return Firma XADES-XL
448 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
449 	 *  para realizar la firma
450 	 * @throws SignatureException No se puede realizar la firma
451 	 */
452 	public static XAdESXLSignature signDetached (DeviceManager manager, String alias, IDocument document, 
453 			String reference, TSAData tsaData, CAList caList, XAdESDetachedSignatureOptions options) throws LoadingObjectException, SignatureException {
454 		
455 		return signDetached(manager, alias, document, reference, tsaData, caList, options, false);
456 	}
457 	
458 	/**
459 	 * Realiza una firma XAdES-XL detached (el fichero no se incluirá en la firma). <br><br>
460 	 * 
461 	 * Utilizar este método si se desea permitir que se obtenga la información de validación mediante 
462 	 * CRL (en caso de que no se pueda mediante OCSP). Cuidado con esta opción ya que las CRLs pueden 
463 	 * tener un tamaño considerable, por lo que la obtención de la firma será más lenta y la misma firma
464 	 * puede acabar con un tamaño muy grande.
465 	 * 
466 	 * @param manager Dispositivo criptográfico que realizará la firma
467 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
468 	 * @param document Documento a firmar. 
469 	 * @param reference Referencia a la que apuntará la firma
470 	 * @param tsaData Información de conexión a la TSA
471 	 * @param caList Lista de CAs para obtener información de validación
472 	 * @param options Opciones de la firma
473 	 * @param allowCRLValidation Permitir generar la firma con CRLs si no se puede
474 	 *  realizar la validación mediante OCSP
475 	 * @return Firma XADES-XL
476 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
477 	 *  para realizar la firma
478 	 * @throws SignatureException No se puede realizar la firma
479 	 */
480 	public static XAdESXLSignature signDetached (DeviceManager manager, String alias, IDocument document, 
481 			String reference, TSAData tsaData, CAList caList, XAdESDetachedSignatureOptions options,
482 			boolean allowCRLValidation) throws LoadingObjectException, SignatureException {
483 		
484 		logger.debug("[XAdESXLSignature.signDetached]::Entrada::" + Arrays.asList(new Object[] { manager, alias, document, reference, tsaData, caList, options, allowCRLValidation }));
485 		
486 		return (XAdESXLSignature) signDetached(manager, alias, document, reference, tsaData, new CAListCertStatusRecover(caList, allowCRLValidation), options, EnumFormatoFirma.XAdES_XL, XAdESXLSignature.class);
487 	}
488 	
489 	/**
490 	 * Realiza una firma XAdES-XL atached (el documento se incluye en la firma). No completa los campos no 
491 	 * obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier', 'signatureProductionPlace' 
492 	 * y 'signerRole'.
493 	 * 
494 	 * Si el documento es un XML y los parámetros <code>idToSign</code> y <code>signatureParent</code>
495 	 * no son nulos la firma y los campos propios de XAdES se añadirán al XML. En caso contrario el fichero 
496 	 * XAdES resultante seguirá la plantilla de Arangí, por ejemplo:<br>
497 	 * <code>
498 	 * 	&lt;arangi-xades&gt;<br>
499 	 *  &nbsp;&nbsp;&lt;document&gt;...&lt;/document&gt;
500 	 *  &nbsp;&nbsp;&lt;ds:Signature&gt;...&lt;/ds:Signature&gt;
501 	 * 	&lt;/arangi-xades&gt;<br>
502 	 * </code>
503 	 * 
504 	 * @param manager Dispositivo criptográfico que realizará la firma
505 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
506 	 * @param document Documento a firmar
507 	 * @param idToSign Valor del atributo 'ID' que indica lo que se firmará dentro del documento. Si tiene 
508 	 *  valor nulo el XML de la firma tendrá el formato por defecto de las firmas XAdES de Arangí.
509 	 * @param signatureParent Nombre del tag que será el padre de los nodos de firma. Si tiene valor nulo
510 	 * 	la firma colgará del nodo raíz.
511 	 * @param urlTSA URL del servidor de sello de tiempos
512 	 * @param caList Lista de CAs para obtener información de validación
513 	 * @return Firma XADES-XL
514 	 * @throws XMLDocumentException Error montando el fichero XML
515 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
516 	 *  para realizar la firma
517 	 * @throws SignatureException No se puede realizar la firma
518 	 * @deprecated Usar {@link #signAttached(DeviceManager,String,IDocument,TSAData,CAList,XAdESAttachedSignatureOptions) signAttached}
519 	 */
520 	public static XAdESXLSignature signAttached (DeviceManager manager, String alias, IDocument document, String idToSign,
521 			String signatureParent, URL urlTSA, CAList caList) throws XMLDocumentException, LoadingObjectException, SignatureException  {
522 		return signAttached(manager, alias, document, null, idToSign, signatureParent, urlTSA, caList, null, null);
523 	}
524 	
525 	/**
526 	 * Realiza una firma XAdES-XL atached (el documento se incluye en la firma). No completa los campos no 
527 	 * obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier' y 'signatureProductionPlace'. 
528 	 * 
529 	 * Si el documento es un XML y los parámetros <code>idToSign</code> y <code>signatureParent</code>
530 	 * no son nulos la firma y los campos propios de XAdES se añadirán al XML. En caso contrario el fichero 
531 	 * XAdES resultante seguirá la plantilla de Arangí, por ejemplo:<br>
532 	 * <code>
533 	 * 	&lt;arangi-xades&gt;<br>
534 	 *  &nbsp;&nbsp;&lt;document&gt;...&lt;/document&gt;
535 	 *  &nbsp;&nbsp;&lt;ds:Signature&gt;...&lt;/ds:Signature&gt;
536 	 * 	&lt;/arangi-xades&gt;<br>
537 	 * </code>
538 	 * 
539 	 * @param manager Dispositivo criptográfico que realizará la firma
540 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
541 	 * @param document Documento a firmar
542 	 * @param digitalSignatureAlgorithm Algoritmo de firma (si nulo algoritmo por defecto)
543 	 * @param idToSign Valor del atributo 'ID' que indica lo que se firmará dentro del documento. Si tiene 
544 	 *  valor nulo el XML de la firma tendrá el formato por defecto de las firmas XAdES de Arangí.
545 	 * @param signatureParent Nombre del tag que será el padre de los nodos de firma. Si tiene valor nulo
546 	 * 	la firma colgará del nodo raíz.
547 	 * @param urlTSA URL del servidor de sello de tiempos
548 	 * @param caList Lista de CAs para obtener información de validación
549 	 * @param dof Información para construir el tag DataObjectFormat (puede ser null)
550 	 * @param claimedRoles Roles de la firma (puede ser null)
551 	 * @return Firma XADES-XL
552 	 * @throws XMLDocumentException Error montando el fichero XML
553 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
554 	 *  para realizar la firma
555 	 * @throws SignatureException No se puede realizar la firma
556 	 * @deprecated Usar {@link #signAttached(DeviceManager,String,IDocument,TSAData,CAList,XAdESAttachedSignatureOptions) signAttached}
557 	 */
558 	public static XAdESXLSignature signAttached (DeviceManager manager, String alias, IDocument document, 
559 			String digitalSignatureAlgorithm, String idToSign, String signatureParent, URL urlTSA, 
560 			CAList caList, XAdESDataObjectFormat dof, String[] claimedRoles) 
561 					throws XMLDocumentException, LoadingObjectException, SignatureException  {
562 		
563 		TSAData tsaData = new TSAData(urlTSA);
564 		XAdESAttachedNodeToSignObject nodeToSign = null;
565 		if (idToSign != null) {
566 			nodeToSign = new XAdESAttachedNodeToSignObject(idToSign);
567 		}
568 		XAdESAttachedSignatureOptions options = new XAdESAttachedSignatureOptions(digitalSignatureAlgorithm, null, dof, claimedRoles, null, null, nodeToSign, signatureParent);
569 		return signAttached(manager, alias, document, tsaData, caList, options);
570 	}
571 	
572 	/**
573 	 * Realiza una firma XAdES-XL atached (el documento se incluye en la firma). No completa los campos no 
574 	 * obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier', 'signatureProductionPlace' 
575 	 * y 'signerRole'.<br><br>
576 	 * 
577 	 * El fichero XAdES seguirá la plantilla de Arangí. Ejemplo:<br>
578 	 * <code>
579 	 * 	&lt;arangi-xades&gt;<br>
580 	 *  &nbsp;&nbsp;&lt;document&gt;...&lt;/document&gt;
581 	 *  &nbsp;&nbsp;&lt;ds:Signature&gt;...&lt;/ds:Signature&gt;
582 	 * 	&lt;/arangi-xades&gt;<br>
583 	 * </code>
584 	 * 
585 	 * @param manager Dispositivo criptográfico que realizará la firma
586 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
587 	 * @param document Documento a firmar
588 	 * @param urlTSA URL del servidor de sello de tiempos
589 	 * @param caList Lista de CAs para obtener información de validación
590 	 * @return Firma XADES-XL
591 	 * @throws XMLDocumentException Error montando el fichero XML
592 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
593 	 *  para realizar la firma
594 	 * @throws SignatureException No se puede realizar la firma
595 	 * @deprecated Usar {@link #signAttached(DeviceManager,String,IDocument,TSAData,CAList,XAdESAttachedSignatureOptions) signAttached}
596 	 */
597 	public static XAdESXLSignature signAttached (DeviceManager manager, String alias, IDocument document, 
598 			URL urlTSA, CAList caList) throws XMLDocumentException, LoadingObjectException, SignatureException  {
599 		return signAttached(manager, alias, document, null, urlTSA, caList, null, null);
600 	}
601 	
602 	/**
603 	 * Realiza una firma XAdES-XL atached (el documento se incluye en la firma). No completa los campos no 
604 	 * obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier' y 'signatureProductionPlace' 
605 	 * .<br><br>
606 	 * 
607 	 * El fichero XAdES seguirá la plantilla de Arangí. Ejemplo:<br>
608 	 * <code>
609 	 * 	&lt;arangi-xades&gt;<br>
610 	 *  &nbsp;&nbsp;&lt;document&gt;...&lt;/document&gt;
611 	 *  &nbsp;&nbsp;&lt;ds:Signature&gt;...&lt;/ds:Signature&gt;
612 	 * 	&lt;/arangi-xades&gt;<br>
613 	 * </code>
614 	 * 
615 	 * @param manager Dispositivo criptográfico que realizará la firma
616 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
617 	 * @param document Documento a firmar
618 	 * @param digitalSignatureAlgorithm Algoritmo de firma (si nulo algoritmo por defecto)
619 	 * @param urlTSA URL del servidor de sello de tiempos
620 	 * @param caList Lista de CAs para obtener información de validación
621 	 * @param dof Información para construir el tag DataObjectFormat (puede ser null)
622 	 * @param claimedRoles Roles de la firma (puede ser null)
623 	 * @return Firma XADES-XL
624 	 * @throws XMLDocumentException Error montando el fichero XML
625 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
626 	 *  para realizar la firma
627 	 * @throws SignatureException No se puede realizar la firma
628 	 * @deprecated Usar {@link #signAttached(DeviceManager,String,IDocument,TSAData,CAList,XAdESAttachedSignatureOptions) signAttached}
629 	 */
630 	public static XAdESXLSignature signAttached (DeviceManager manager, String alias, IDocument document, 
631 			String digitalSignatureAlgorithm, URL urlTSA, CAList caList, XAdESDataObjectFormat dof, 
632 			String[] claimedRoles) throws XMLDocumentException, LoadingObjectException, SignatureException  {
633 		
634 		logger.debug("[XAdESXLSignature.signAttached]::Entrada::" + Arrays.asList(new Object[] { manager, alias, document, digitalSignatureAlgorithm, urlTSA, caList, dof, claimedRoles }));
635 	
636 		TSAData tsaData = new TSAData(urlTSA);
637 		XAdESAttachedSignatureOptions options = new XAdESAttachedSignatureOptions(digitalSignatureAlgorithm, null, dof, claimedRoles, null, null, null, null);
638 		return signAttached(manager, alias, document, tsaData, caList, options);
639 	}
640 	
641 	/**
642 	 * Realiza una firma XAdES-XL atached (el documento se incluye en la firma). No completa los campos no 
643 	 * obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier', 'signatureProductionPlace' 
644 	 * y 'signerRole'.<br><br>
645 	 * 
646 	 * El fichero XAdES seguirá la plantilla de Arangí. Ejemplo:<br>
647 	 * <code>
648 	 * 	&lt;arangi-xades&gt;<br>
649 	 *  &nbsp;&nbsp;&lt;document&gt;...&lt;/document&gt;
650 	 *  &nbsp;&nbsp;&lt;ds:Signature&gt;...&lt;/ds:Signature&gt;
651 	 * 	&lt;/arangi-xades&gt;<br>
652 	 * </code>
653 	 * 
654 	 * @param manager Dispositivo criptográfico que realizará la firma
655 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
656 	 * @param document Fichero a firmar
657 	 * @param urlTSA URL del servidor de sello de tiempos
658 	 * @param caList Lista de CAs para obtener información de validación
659 	 * @return Firma XADES-XL
660 	 * @throws XMLDocumentException Error montando el fichero XML
661 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
662 	 *  para realizar la firma
663 	 * @throws SignatureException No se puede realizar la firma
664 	 * @deprecated Usar {@link #signAttached(DeviceManager,String,IDocument,TSAData,CAList,XAdESAttachedSignatureOptions) signAttached}
665 	 */
666 	public static XAdESXLSignature signAttached (DeviceManager manager, String alias, File document, URL urlTSA, CAList caList) throws LoadingObjectException, SignatureException, NoDocumentToSignException, XMLDocumentException {
667 		return signAttached(manager, alias, document, null, urlTSA, caList, null, null);
668 	}
669 	
670 	/**
671 	 * Realiza una firma XAdES-XL atached (el documento se incluye en la firma). No completa los campos no 
672 	 * obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier' y 'signatureProductionPlace' 
673 	 * .<br><br>
674 	 * 
675 	 * El fichero XAdES seguirá la plantilla de Arangí. Ejemplo:<br>
676 	 * <code>
677 	 * 	&lt;arangi-xades&gt;<br>
678 	 *  &nbsp;&nbsp;&lt;document&gt;...&lt;/document&gt;
679 	 *  &nbsp;&nbsp;&lt;ds:Signature&gt;...&lt;/ds:Signature&gt;
680 	 * 	&lt;/arangi-xades&gt;<br>
681 	 * </code>
682 	 * 
683 	 * @param manager Dispositivo criptográfico que realizará la firma
684 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
685 	 * @param document Fichero a firmar
686 	 * @param digitalSignatureAlgorithm Algoritmo de firma (si nulo algoritmo por defecto)
687 	 * @param urlTSA URL del servidor de sello de tiempos
688 	 * @param caList Lista de CAs para obtener información de validación
689 	 * @param dof Información para construir el tag DataObjectFormat (puede ser null)
690 	 * @param claimedRoles Roles de la firma (puede ser null)
691 	 * @return Firma XADES-XL
692 	 * @throws XMLDocumentException Error montando el fichero XML
693 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
694 	 *  para realizar la firma
695 	 * @throws SignatureException No se puede realizar la firma
696 	 * @deprecated Usar {@link #signAttached(DeviceManager,String,IDocument,TSAData,CAList,XAdESAttachedSignatureOptions) signAttached}
697 	 */
698 	public static XAdESXLSignature signAttached (DeviceManager manager, String alias, File document, 
699 			String digitalSignatureAlgorithm, URL urlTSA, CAList caList, XAdESDataObjectFormat dof, 
700 			String[] claimedRoles) throws LoadingObjectException, SignatureException, NoDocumentToSignException, XMLDocumentException {
701 		
702 		logger.debug("[XAdESXLSignature.signAttached]::Entrada::" + Arrays.asList(new Object[] { manager, alias, document, digitalSignatureAlgorithm,  urlTSA, caList, dof, claimedRoles }));
703 		
704 		//-- Obtener el document de Arangi y llamar a la firma attached
705 		FileDocument fileDocument;
706 		try {
707 			fileDocument = new FileDocument(document);
708 		} catch (InitDocumentException e) {
709 			logger.info("[XAdESXLSignature.signAttached]::El fichero a firmar no existe o es nulo:: " + document);
710 			throw new NoDocumentToSignException("El fichero a firmar no existe o es nulo: " + document);
711 		}
712 		
713 		return signAttached(manager, alias, fileDocument, digitalSignatureAlgorithm, urlTSA, caList, dof, claimedRoles);
714 		
715 	}
716 	
717 	/**
718 	 * Realiza una firma XAdES-XL atached (el documento se incluye en la firma). No completa los campos no 
719 	 * obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier', 'signatureProductionPlace' 
720 	 * y 'signerRole'.<br><br>
721 	 * 
722 	 * El fichero XAdES seguirá la plantilla de Arangí. Ejemplo:<br>
723 	 * <code>
724 	 * 	&lt;arangi-xades&gt;<br>
725 	 *  &nbsp;&nbsp;&lt;document&gt;...&lt;/document&gt;
726 	 *  &nbsp;&nbsp;&lt;ds:Signature&gt;...&lt;/ds:Signature&gt;
727 	 * 	&lt;/arangi-xades&gt;<br>
728 	 * </code>
729 	 * 
730 	 * @param manager Dispositivo criptográfico que realizará la firma
731 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
732 	 * @param document Fichero a firmar (se encuentra en una URL accesible)
733 	 * @param urlTSA URL del servidor de sello de tiempos
734 	 * @param caList Lista de CAs para obtener información de validación
735 	 * @return Firma XADES-XL
736 	 * @throws XMLDocumentException Error montando el fichero XML
737 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
738 	 *  para realizar la firma
739 	 * @throws SignatureException No se puede realizar la firma
740 	 * @deprecated Usar {@link #signAttached(DeviceManager,String,IDocument,TSAData,CAList,XAdESAttachedSignatureOptions) signAttached}
741 	 */
742 	public static XAdESXLSignature signAttached (DeviceManager manager, String alias, URL document, URL urlTSA, CAList caList) throws LoadingObjectException, SignatureException, NoDocumentToSignException, XMLDocumentException {
743 		return signAttached(manager, alias, document, null, urlTSA, caList, null, null);
744 	}
745 	
746 	/**
747 	 * Realiza una firma XAdES-XL atached (el documento se incluye en la firma). No completa los campos no 
748 	 * obligatorios del tag 'SignedSignatureProperties':'signaturePolicyIdentifier' y 'signatureProductionPlace' 
749 	 * .<br><br>
750 	 * 
751 	 * El fichero XAdES seguirá la plantilla de Arangí. Ejemplo:<br>
752 	 * <code>
753 	 * 	&lt;arangi-xades&gt;<br>
754 	 *  &nbsp;&nbsp;&lt;document&gt;...&lt;/document&gt;
755 	 *  &nbsp;&nbsp;&lt;ds:Signature&gt;...&lt;/ds:Signature&gt;
756 	 * 	&lt;/arangi-xades&gt;<br>
757 	 * </code>
758 	 * 
759 	 * @param manager Dispositivo criptográfico que realizará la firma
760 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
761 	 * @param document Fichero a firmar (se encuentra en una URL accesible)
762 	 * @param digitalSignatureAlgorithm Algoritmo de firma (si nulo algoritmo por defecto)
763 	 * @param urlTSA URL del servidor de sello de tiempos
764 	 * @param caList Lista de CAs para obtener información de validación
765 	 * @param dof Información para construir el tag DataObjectFormat (puede ser null)
766 	 * @param claimedRoles Roles de la firma (puede ser null)
767 	 * @return Firma XADES-XL
768 	 * @throws XMLDocumentException Error montando el fichero XML
769 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
770 	 *  para realizar la firma
771 	 * @throws SignatureException No se puede realizar la firma
772 	 * @deprecated Usar {@link #signAttached(DeviceManager,String,IDocument,TSAData,CAList,XAdESAttachedSignatureOptions) signAttached}
773 	 */
774 	public static XAdESXLSignature signAttached (DeviceManager manager, String alias, URL document, 
775 			String digitalSignatureAlgorithm, URL urlTSA, CAList caList, XAdESDataObjectFormat dof, 
776 			String[] claimedRoles) throws LoadingObjectException, SignatureException, NoDocumentToSignException, XMLDocumentException {
777 		
778 		logger.debug("[XAdESTSignature.signAttached]::Entrada::" + Arrays.asList(new Object[] { manager, alias, document, digitalSignatureAlgorithm, urlTSA, caList, dof, claimedRoles }));
779 		
780 		//-- Obtener el document de Arangi y llamar a la firma attached
781 		URLDocument urlDocument;
782 		try {
783 			urlDocument = new URLDocument(document);
784 		} catch (InitDocumentException e) {
785 			logger.info("[XAdESTSignature.signAttached]::La URL a firmar no existe o es nula:: " + document);
786 			throw new NoDocumentToSignException("La URL a firmar no existe o es nula: " + document);
787 		}
788 		
789 		return signAttached(manager, alias, urlDocument, digitalSignatureAlgorithm, urlTSA, caList, dof, claimedRoles);
790 		
791 	}
792 	
793 	/**
794 	 * Realiza una firma XAdES-XL atached (el documento se incluye en la firma). Si no
795 	 * se puede obtener la información de validación mediante OCSP se producirá una
796 	 * excepción.
797 	 * 
798 	 * @param manager Dispositivo criptográfico que realizará la firma
799 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
800 	 * @param document Documento a firmar
801 	 * @param tsaData Información de conexión a la TSA
802 	 * @param caList Lista de CAs para obtener información de validación
803 	 * @param options Opciones de la firma
804 	 * @return Firma XADES-XL
805 	 * @throws XMLDocumentException Error montando el fichero XML
806 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
807 	 *  para realizar la firma
808 	 * @throws SignatureException No se puede realizar la firma
809 	 */
810 	public static XAdESXLSignature signAttached (DeviceManager manager, String alias, IDocument document, 
811 			TSAData tsaData, CAList caList, XAdESAttachedSignatureOptions options) throws XMLDocumentException, LoadingObjectException, SignatureException  {
812 		
813 		return signAttached(manager, alias, document, tsaData, caList, options, false);
814 	}
815 	
816 	/**
817 	 * Realiza una firma XAdES-XL atached (el documento se incluye en la firma).  <br><br>
818 	 * 
819 	 * Utilizar este método si se desea permitir que se obtenga la información de validación mediante 
820 	 * CRL (en caso de que no se pueda mediante OCSP). Cuidado con esta opción ya que las CRLs pueden 
821 	 * tener un tamaño considerable, por lo que la obtención de la firma será más lenta y la misma firma
822 	 * puede acabar con un tamaño muy grande.
823 	 * 
824 	 * @param manager Dispositivo criptográfico que realizará la firma
825 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
826 	 * @param document Documento a firmar
827 	 * @param tsaData Información de conexión a la TSA
828 	 * @param caList Lista de CAs para obtener información de validación
829 	 * @param options Opciones de la firma
830 	 * @param allowCRLValidation Permitir generar la firma con CRLs si no se puede
831 	 *  realizar la validación mediante OCSP
832 	 * @return Firma XADES-XL
833 	 * @throws XMLDocumentException Error montando el fichero XML
834 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
835 	 *  para realizar la firma
836 	 * @throws SignatureException No se puede realizar la firma
837 	 */
838 	public static XAdESXLSignature signAttached (DeviceManager manager, String alias, IDocument document, 
839 			TSAData tsaData, CAList caList, XAdESAttachedSignatureOptions options, boolean allowCRLValidation) 
840 					throws XMLDocumentException, LoadingObjectException, SignatureException  {
841 		
842 		logger.debug("[XAdESXLSignature.signAttached]::Entrada::" + Arrays.asList(new Object[] { manager, alias, document, tsaData, caList, options, allowCRLValidation }));
843 	
844 		return (XAdESXLSignature) signAttached(manager, alias, document, tsaData, new CAListCertStatusRecover(caList, allowCRLValidation), options, EnumFormatoFirma.XAdES_XL, XAdESXLSignature.class);
845 	}
846 	
847 	/**
848 	 * La definición de las contrafirmas en XAdES puede observarse en el punto 7.2.4
849 	 * del estándar de la ETSI.<br><br>
850 	 * 
851 	 * Este método realiza una contrafirma para la última firma del XAdES. Es útil 
852 	 * cuando se sabe que el XAdES contiene sólo una firma.<br><br>
853 	 * 
854 	 * Como resultado el XAdES a la que hace referencia este objeto se modificará 
855 	 * para añadir la contrafirma.
856 	 * 
857 	 * @param manager Dispositivo criptográfico que realizará la contrafirma
858 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
859 	 * @param urlTSA URL del servidor de sello de tiempos para incluir en la contrafirma
860 	 * @param caList Lista de CAs para obtener información de validación
861 	 * @throws LoadingObjectException No es posible obtener la clave privada o el
862 	 * 	certificado del alias
863 	 * @throws CounterSignatureException Errores durante el proceso de contrafirma
864 	 */
865 	public void counterSign (DeviceManager manager, String alias, URL urlTSA, CAList caList) throws LoadingObjectException, CounterSignatureException {
866 		counterSign(manager, alias, null, null, urlTSA, caList);
867 	}
868 	
869 	/**
870 	 * La definición de las contrafirmas en XAdES puede observarse en el punto 7.2.4
871 	 * del estándar de la ETSI.<br><br>
872 	 * 
873 	 * Este método realiza una contrafirma para la firma cuyo certificado se pasa
874 	 * en el parámetro 'signatureToCounterSignCertificate'. Es útil cuando se quiere
875 	 * contrafirmar un XAdES que contiene varias firmas. Para saber qué firma se
876 	 * desea contrafirmar se puede llamar primero a 
877 	 * {@link #getCertificates() getCertificates} para ver los certificados de cada
878 	 * una de las firmas que contiene el XAdES.<br><br>
879 	 * 
880 	 * Como resultado el XAdES a la que hace referencia este objeto se modificará 
881 	 * para añadir la contrafirma.
882 	 * 
883 	 * @param manager Dispositivo criptográfico que realizará la contrafirma
884 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
885 	 * @param signatureToCounterSignCertificate Certificado de la firma que se 
886 	 * 	contrafirmará
887 	 * @param digitalSignatureAlgorithm Algoritmo de firma (si nulo algoritmo por defecto)
888 	 * @param urlTSA URL del servidor de sello de tiempos para incluir en la contrafirma
889 	 * @param caList Lista de CAs para obtener información de validación
890 	 * @throws LoadingObjectException No es posible obtener la clave privada o el
891 	 * 	certificado del alias
892 	 * @throws CounterSignatureException Errores durante el proceso de contrafirma
893 	 */
894 	public void counterSign (DeviceManager manager, String alias, Certificate signatureToCounterSignCertificate,
895 			String digitalSignatureAlgorithm, URL urlTSA, CAList caList) throws LoadingObjectException, CounterSignatureException {
896 		counterSign(manager, alias, signatureToCounterSignCertificate, digitalSignatureAlgorithm, urlTSA, caList, false);
897 	}
898 	
899 	/**
900 	 * La definición de las contrafirmas en XAdES puede observarse en el punto 7.2.4
901 	 * del estándar de la ETSI.<br><br>
902 	 * 
903 	 * Este método realiza una contrafirma para la firma cuyo certificado se pasa
904 	 * en el parámetro 'signatureToCounterSignCertificate'. Es útil cuando se quiere
905 	 * contrafirmar un XAdES que contiene varias firmas. Para saber qué firma se
906 	 * desea contrafirmar se puede llamar primero a 
907 	 * {@link #getCertificates() getCertificates} para ver los certificados de cada
908 	 * una de las firmas que contiene el XAdES.<br><br>
909 	 * 
910 	 * Como resultado el XAdES a la que hace referencia este objeto se modificará 
911 	 * para añadir la contrafirma.
912 	 * 
913 	 * @param manager Dispositivo criptográfico que realizará la contrafirma
914 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
915 	 * @param signatureToCounterSignCertificate Certificado de la firma que se 
916 	 * 	contrafirmará
917 	 * @param digitalSignatureAlgorithm Algoritmo de firma (si nulo algoritmo por defecto)
918 	 * @param urlTSA URL del servidor de sello de tiempos para incluir en la contrafirma
919 	 * @param caList Lista de CAs para obtener información de validación
920 	 * @param allowCRLValidation Permitir generar la firma con CRLs si no se puede
921 	 *  realizar la validación mediante OCSP
922 	 * @throws LoadingObjectException No es posible obtener la clave privada o el
923 	 * 	certificado del alias
924 	 * @throws CounterSignatureException Errores durante el proceso de contrafirma
925 	 */
926 	public void counterSign (DeviceManager manager, String alias, Certificate signatureToCounterSignCertificate,
927 			String digitalSignatureAlgorithm, URL urlTSA, CAList caList, boolean allowCRLValidation) throws LoadingObjectException, CounterSignatureException {
928 		
929 		logger.debug("[XAdESXLSignature.counterSign]::Entrada::" + Arrays.asList(new Object[] { manager, alias, signatureToCounterSignCertificate, digitalSignatureAlgorithm, urlTSA, caList, allowCRLValidation }));
930 		
931 		//-- El documento a firmar es la firma en la que nos encontramos
932         DataToSign dataToSign = new DataToSign();
933         dataToSign.setXadesFormat(getXAdESSignatureFormat());
934         dataToSign.setEsquema(DEFAULT_XADES_SCHEMA);
935         dataToSign.setXMLEncoding(DEFAULT_XML_ENCODING);
936         dataToSign.setEnveloped(true);
937         dataToSign.setDocument(this.xadesDocument);
938        	dataToSign.setCertStatusManager (new CAListCertStatusRecover(caList, allowCRLValidation));
939         
940 		Document doc;
941 		try {
942 			doc = ContraFirmaXML.counterSign(manager.getCertificate(alias), dataToSign, 
943 					signatureToCounterSignCertificate!=null?signatureToCounterSignCertificate.toX509Certificate():null, 
944 					manager.getPrivateKey(alias), digitalSignatureAlgorithm, urlTSA, DEFAULT_XADES_SCHEMA_URI);
945 		} catch (LoadingObjectException e) {
946 			logger.info("[XAdESXLSignature.counterSign]::No es posible obtener la clave privada del alias '" + alias + "'", e);
947 			throw e;
948 		} catch (SearchingException e) {
949 			logger.info("[XAdESXLSignature.counterSign]::No es posible obtener el certificado del alias '" + alias + "'", e);
950 			throw new LoadingObjectException ("No es posible obtener el certificado del alias '" + alias + "'", e);
951 		} catch (CounterSignatureException e) {
952 			logger.info("[XAdESXLSignature.counterSign]::No es posible realizar la contrafirma", e);
953 			throw e;
954 		}
955 		
956 		logger.debug("[XAdESXLSignature.counterSign]::Se ha obtenido la contrafirma");
957 		this.xadesDocument = doc;
958 	}
959 	
960 	/**
961 	 * Añade una Cofirma a la firma XAdES-XL. Realizará una firma de las mismas características que 
962 	 * la primera que encuentre (attached o dettached).<br><br>
963 	 * 
964 	 * Si la firma es dettached i la referencia al documento que hay en la firma no
965 	 * es una URL será necesario usar el método {@link #coSign(DeviceManager, String, IDocument, URL, CAList)}
966 	 * al que le proporcionaremos este documento.  
967 	 * 
968 	 * @param manager Dispositivo criptográfico que realizará la cofirma
969 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
970 	 * @param urlTSA URL del servidor de sello de tiempos para incluir en la contrafirma
971 	 * @param caList Lista de CAs para obtener información de validación
972 	 * @throws SignatureNotFoundException No existe ninguna firma que cofirmar
973 	 * @throws NoDocumentToSignException El fichero a firmar no existe o es nulo
974 	 * @throws HashingException Error realizando el hash del documento
975 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
976 	 *  para realizar la firma
977 	 * @throws SignatureException No ha sido posible parsear la firma XAdES o no se puede realizar la cofirma
978 	 * @throws NoCoincidentDocumentException El documento que se quiere firmar no se corresponde con el de
979 	 * 	la firma XAdES  
980 	 */
981 	public void coSign (DeviceManager manager, String alias, URL urlTSA, CAList caList) throws SignatureNotFoundException, 
982 		NoDocumentToSignException, HashingException, LoadingObjectException, SignatureException, NoCoincidentDocumentException {
983 		
984 		logger.debug("[XAdESXLSignature.coSign]::Entrada::" + Arrays.asList(new Object[] { manager, alias }));
985 		coSign (manager, alias, null, null, urlTSA, caList);
986 	}
987 	
988 	
989 	/**
990 	 * Añade una Cofirma a la firma XAdES-XL. Realizará una firma de las mismas características que 
991 	 * la primera que encuentre (attached o dettached).<br><br>
992 	 * 
993 	 * Este método es útil si la firma es dettached i la referencia al documento que hay en la firma no
994 	 * es una URL.  
995 	 * 
996 	 * @param manager Dispositivo criptográfico que realizará la cofirma
997 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
998 	 * @param signedDoc contenido a firmar. El mismo utilizado en la generación de las otras firmas
999 	 * @param digitalSignatureAlgorithm Algoritmo de firma (si nulo algoritmo por defecto)
1000 	 * @param urlTSA URL del servidor de sello de tiempos para incluir en la contrafirma
1001 	 * @param caList Lista de CAs para obtener información de validación
1002 	 * @throws SignatureNotFoundException No existe ninguna firma que cofirmar
1003 	 * @throws NoDocumentToSignException El fichero a firmar no existe o es nulo
1004 	 * @throws HashingException Error realizando el hash del documento
1005 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
1006 	 *  para realizar la firma
1007 	 * @throws SignatureException No ha sido posible parsear la firma XAdES o no se puede realizar la cofirma
1008 	 * @throws NoCoincidentDocumentException El documento que se quiere firmar no se corresponde con el de
1009 	 * 	la firma XAdES  
1010 	 */
1011 	public void coSign (DeviceManager manager, String alias, IDocument signedDoc, 
1012 			String digitalSignatureAlgorithm, URL urlTSA, CAList caList) 
1013 					throws SignatureNotFoundException, NoDocumentToSignException, HashingException, 
1014 					LoadingObjectException, SignatureException, NoCoincidentDocumentException {
1015 		coSign(manager, alias, signedDoc, digitalSignatureAlgorithm, urlTSA, caList, false);
1016 	}
1017 	
1018 	/**
1019 	 * Añade una Cofirma a la firma XAdES-XL. Realizará una firma de las mismas características que 
1020 	 * la primera que encuentre (attached o dettached).<br><br>
1021 	 * 
1022 	 * Este método es útil si la firma es dettached i la referencia al documento que hay en la firma no
1023 	 * es una URL.  
1024 	 * 
1025 	 * @param manager Dispositivo criptográfico que realizará la cofirma
1026 	 * @param alias Alias donde se encuentra la clave privada dentro del dispositivo
1027 	 * @param signedDoc contenido a firmar. El mismo utilizado en la generación de las otras firmas
1028 	 * @param digitalSignatureAlgorithm Algoritmo de firma (si nulo algoritmo por defecto)
1029 	 * @param urlTSA URL del servidor de sello de tiempos para incluir en la contrafirma
1030 	 * @param caList Lista de CAs para obtener información de validación
1031 	 * @param allowCRLValidation Permitir generar la firma con CRLs si no se puede
1032 	 *  realizar la validación mediante OCSP
1033 	 * @throws SignatureNotFoundException No existe ninguna firma que cofirmar
1034 	 * @throws NoDocumentToSignException El fichero a firmar no existe o es nulo
1035 	 * @throws HashingException Error realizando el hash del documento
1036 	 * @throws LoadingObjectException No ha sido posible cargar la clave privada o el certificado usados
1037 	 *  para realizar la firma
1038 	 * @throws SignatureException No ha sido posible parsear la firma XAdES o no se puede realizar la cofirma
1039 	 * @throws NoCoincidentDocumentException El documento que se quiere firmar no se corresponde con el de
1040 	 * 	la firma XAdES  
1041 	 */
1042 	public void coSign (DeviceManager manager, String alias, IDocument signedDoc, 
1043 			String digitalSignatureAlgorithm, URL urlTSA, CAList caList, boolean allowCRLValidation) 
1044 					throws SignatureNotFoundException, NoDocumentToSignException, HashingException, 
1045 					LoadingObjectException, SignatureException, NoCoincidentDocumentException {
1046 		
1047 		coSign(manager, alias, signedDoc, digitalSignatureAlgorithm, urlTSA, new CAListCertStatusRecover(caList, allowCRLValidation), EnumFormatoFirma.XAdES_XL, XAdESXLSignature.class);
1048 		
1049 	}
1050 	
1051 	/**
1052 	 * Devuelve una cadena de texto con el tipo de la firma
1053 	 * 
1054 	 * @return Cadena de texto con el tipo de la firma
1055 	 */
1056 	public String getSignatureType () {
1057 		return SIGNATURE_TYPE;
1058 	}
1059 	
1060 	/**
1061 	 * Añade lo que falta para completar el XAdES a XAdES-X-L. La firma tiene que ser attached. 
1062 	 * Si no es así es necesario
1063 	 * usar {@link #completeToXAdESXL (XAdESSignature, IDocument, CAList, URL)}.
1064 	 * 
1065 	 * @param xades Firma XAdES
1066 	 * @param caList lista de certificados de CA
1067 	 * @param urlTSA URL del servidor de sello de tiempos
1068 	 * @return Firma XAdES-X-L
1069 	 * @throws NormalizeCertificateException Alguno de los certificados no puede ser 
1070 	 * 	normalizado al formato reconocido por el proveedor criptográfico de Arangí o su 
1071 	 * 	firma no es correcta o no puede ser analizada
1072 	 * @throws SignatureException Error tratando el objeto firma o la firma XAdES-T no es
1073 	 * 	válida
1074 	 * @throws RetrieveOCSPException Error obteniendo las respuestas OCSP
1075 	 * @throws XMLDocumentException Error completando el XML del XAdES-T a XAdES-X-L
1076 	 */
1077 	public static XAdESXLSignature completeToXAdESXL (XAdESSignature xades, CAList caList, URL urlTSA) throws SignatureException, NormalizeCertificateException, RetrieveOCSPException, XMLDocumentException {
1078 		return completeToXAdESXL (xades, null, caList, urlTSA);
1079 	}
1080 	
1081 	/**
1082 	 * Añade lo que falta para completar el XAdES a XAdES-X-L. Si no
1083 	 * se puede obtener la información de validación mediante OCSP se producirá una
1084 	 * excepción.
1085 	 * 
1086 	 * @param xades Firma XAdES
1087 	 * @param document documento firmado en el XAdES. Útil en el caso que el XAdES sea detached.
1088 	 * @param caList lista de certificados de CA
1089 	 * @param urlTSA URL del servidor de sello de tiempos
1090 	 * @return Firma XAdES-X-L
1091 	 * @throws NormalizeCertificateException Alguno de los certificados no puede ser 
1092 	 * 	normalizado al formato reconocido por el proveedor criptográfico de Arangí o su 
1093 	 * 	firma no es correcta o no puede ser analizada
1094 	 * @throws SignatureException Error tratando el objeto firma o la firma XAdES-T no es
1095 	 * 	válida
1096 	 * @throws RetrieveOCSPException Error obteniendo las respuestas OCSP
1097 	 * @throws XMLDocumentException Error completando el XML del XAdES-T a XAdES-X-L
1098 	 */
1099 	public static XAdESXLSignature completeToXAdESXL (XAdESSignature xades, IDocument document, CAList caList, URL urlTSA) throws SignatureException, NormalizeCertificateException, RetrieveOCSPException, XMLDocumentException {
1100 		return completeToXAdESXL(xades, document, caList, urlTSA, false);
1101 	}
1102 	
1103 	/**
1104 	 * Añade lo que falta para completar el XAdES a XAdES-X-L.  <br><br>
1105 	 * 
1106 	 * Utilizar este método si se desea permitir que se obtenga la información de validación mediante 
1107 	 * CRL (en caso de que no se pueda mediante OCSP). Cuidado con esta opción ya que las CRLs pueden 
1108 	 * tener un tamaño considerable, por lo que la obtención de la firma será más lenta y la misma firma
1109 	 * puede acabar con un tamaño muy grande.
1110 	 * 
1111 	 * @param xades Firma XAdES
1112 	 * @param document documento firmado en el XAdES. Útil en el caso que el XAdES sea detached.
1113 	 * @param caList lista de certificados de CA
1114 	 * @param urlTSA URL del servidor de sello de tiempos
1115 	 * @param allowCRLValidation Permitir generar la firma con CRLs si no se puede
1116 	 *  realizar la validación mediante OCSP
1117 	 * @return Firma XAdES-X-L
1118 	 * @throws NormalizeCertificateException Alguno de los certificados no puede ser 
1119 	 * 	normalizado al formato reconocido por el proveedor criptográfico de Arangí o su 
1120 	 * 	firma no es correcta o no puede ser analizada
1121 	 * @throws SignatureException Error tratando el objeto firma o la firma XAdES-T no es
1122 	 * 	válida
1123 	 * @throws RetrieveOCSPException Error obteniendo las respuestas OCSP
1124 	 * @throws XMLDocumentException Error completando el XML del XAdES-T a XAdES-X-L
1125 	 */
1126 	public static XAdESXLSignature completeToXAdESXL (XAdESSignature xades, IDocument document, CAList caList, 
1127 			URL urlTSA, boolean allowCRLValidation) throws SignatureException, NormalizeCertificateException, RetrieveOCSPException, XMLDocumentException {
1128 		logger.debug("[XAdESXLSignature.completeToXAdESXL]::Entrada::" + Arrays.asList(new Object[] { xades, urlTSA, allowCRLValidation }));
1129 		
1130 		Document doc = xades.getDOM();
1131 		
1132 		//-- Comprobar que el XAdES-T es correcto
1133 		logger.debug("[XAdESXLSignature.completeToXAdESXL]::Verificando que el XAdES-T es correcto");
1134 		ValidationResult[] resultadoValidacion = null;
1135 		if (document == null) {
1136 			resultadoValidacion = xades.isValid(caList);			
1137 		} else {
1138 			resultadoValidacion = xades.isValid(document, caList);
1139 		}
1140 		
1141 		String[] tiposFirmas = new String[resultadoValidacion.length]; 
1142 		for (int i = 0; i < resultadoValidacion.length; i++) {
1143 			if (!resultadoValidacion[i].isValid()) {
1144 				logger.info("[XAdESXLSignature.completeToXAdESXL]::El XAdES-T no es válido: " + resultadoValidacion[i].getResultText());
1145 				throw new SignatureException("El XAdES-T no es válido: " + resultadoValidacion[i].getResultText());
1146 			}
1147 			
1148 			//-- Obtener el tipo de firma
1149 			if (resultadoValidacion[i].getOcspResponses() != null && resultadoValidacion[i].getOcspResponses().length > 0) {
1150 				tiposFirmas[i] = XAdESXLSignature.SIGNATURE_TYPE;
1151 			} else {
1152 				if (resultadoValidacion[i].getTimeStamp() != null) {
1153 					tiposFirmas[i] = XAdESTSignature.SIGNATURE_TYPE;
1154 				} else {
1155 					tiposFirmas[i] = XAdESBESSignature.SIGNATURE_TYPE;
1156 				}
1157 			}
1158 
1159 		}
1160 		
1161 		NodeList listaFirmas = doc.getElementsByTagNameNS(ConstantesXADES.SCHEMA_DSIG, ConstantesXADES.LIBRERIAXADES_SIGNATURE);
1162 		for(int i=0;i<listaFirmas.getLength();i++) {
1163 			Element nodeFirma = (Element) listaFirmas.item(i);
1164 			
1165 			//-- Comprobar el tipo de firma
1166 			if (tiposFirmas[i].equals(XAdESXLSignature.SIGNATURE_TYPE)) {
1167 				logger.debug("[XAdESXLSignature.completeToXAdESXL]::La firma ya es XL, no es necesario completar");
1168 				continue;
1169 			}
1170 			if (tiposFirmas[i].equals(XAdESBESSignature.SIGNATURE_TYPE)) {
1171 				logger.debug("[XAdESXLSignature.completeToXAdESXL]::La firma es BES, primero completar a T");
1172 				Node idAttribute = nodeFirma.getAttributes().getNamedItem(ConstantesXADES.ID);
1173 
1174 				//-- Obtener el sello de tiempos
1175 				TimeStamp timeStamp;
1176 				try {
1177 					byte[] byteSignature = UtilidadTratarNodo.obtenerByteNodo(nodeFirma, ConstantesXADES.SCHEMA_DSIG, ConstantesXADES.SIGNATURE_VALUE, CanonicalizationEnum.C14N_OMIT_COMMENTS, 5);
1178 					timeStamp = TimeStamp.stampDocument(byteSignature, urlTSA);
1179 				} catch (FirmaXMLError e) {
1180 					logger.info ("[XAdESXLSignature.completeToXAdESXL]::Error obteniendo el elemento a sellar", e);
1181 					throw new SignatureException("Error obteniendo el elemento a sellar", e);
1182 				} catch (TimeStampServerConnectionException e) {
1183 					logger.info("[XAdESXLSignature.completeToXAdESXL]::No ha sido posible conectarse al servidor de sello de tiempos", e);
1184 					throw new SignatureException ("No ha sido posible conectarse al servidor de sello de tiempos", e);
1185 				} catch (HashingException e) {
1186 					logger.info("[XAdESXLSignature.completeToXAdESXL]::No ha sido posible obtener el hash para obtener el sello de tiempos", e);
1187 					throw new SignatureException ("No ha sido posible obtener el hash para obtener el sello de tiempos", e);
1188 				} catch (MalformedTimeStampException e) {
1189 					logger.info("[XAdESXLSignature.completeToXAdESXL]::El sello de tiempos está mal formado", e);
1190 					throw new SignatureException ("El sello de tiempos está mal formado", e);
1191 				} catch (ResponseTimeStampException e) {
1192 					logger.info("[XAdESXLSignature.completeToXAdESXL]::Error en la respuesta del servidor de sello de tiempos", e);
1193 					throw new SignatureException ("Error en la respuesta del servidor de sello de tiempos", e);
1194 				} 
1195 				
1196 				try {
1197 					doc = addXadesT(nodeFirma, idAttribute.getNodeValue(), timeStamp.toDER(), searchXAdESNamespace (doc.getDocumentElement()));
1198 					logger.debug("[XAdESXLSignature.completeToXAdESXL]::Completado a XAdES-T");
1199 				} catch (Exception e) {
1200 					throw new XMLDocumentException(e);
1201 				}
1202 
1203 			}
1204 			
1205 			// Se obtiene el certificado firmante
1206 	    	Element certificateNode = (Element) nodeFirma.getElementsByTagNameNS(ConstantesXADES.SCHEMA_DSIG, "X509Certificate").item(0);
1207 	    	byte[] certificateContent = Util.decodeBase64(certificateNode.getFirstChild().getNodeValue());
1208 	    	X509Certificate signatureCertificate = (X509Certificate) Util.getCertificate(certificateContent);
1209 
1210 			// Se obtiene el certificado firmante del sello de tiempos
1211 	    	X509Certificate timeStampCertificate;
1212 	    	try {
1213 	    		timeStampCertificate = getXAdESTimeStampCertificate(doc).toX509Certificate();
1214 			} catch (MalformedTimeStampException e1) {
1215 				logger.info("[XAdESXLSignature.completeToXAdESXL]::No se puede obtener el sello de tiempos del xades", e1);
1216 				throw new SignatureException ("No se puede obtener el sello de tiempos del xades", e1);
1217 			}
1218 	    	
1219 	    	//-- Lista de certificados y respuestas OCSP: cadena de los certificados de firma y cadena de los certificados de tsa 
1220 			ArrayList<RespYCerts> respuestasFirma = new ArrayList<RespYCerts>();
1221 			try {
1222 				logger.debug("[XAdESXLSignature.completeToXAdESXL]::Obteniendo respuestas OCSP para el certificado de firma");
1223 				respuestasFirma = convertICertStatus2RespYCerts(new CAListCertStatusRecover(caList,allowCRLValidation).getCertChainStatus(signatureCertificate));
1224 			} catch (CertStatusException e) {
1225 				logger.info("[XAdESXLSignature.completeToXAdESXL]::Error obteniendo respuestas OCSP para el certificado de firma", e);
1226 				throw new RetrieveOCSPException("Error obteniendo respuestas OCSP para el certificado de firma", e);
1227 			}
1228 			ArrayList<RespYCerts> respuestasSello = new ArrayList<RespYCerts>();
1229 			try {
1230 				logger.debug("[XAdESXLSignature.completeToXAdESXL]::Obteniendo respuestas OCSP para el certificado de sello");
1231 				respuestasSello = convertICertStatus2RespYCerts(new CAListCertStatusRecover(caList,allowCRLValidation).getCertChainStatus(timeStampCertificate));
1232 			} catch (CertStatusException e) {
1233 				logger.info("[XAdESXLSignature.completeToXAdESXL]::Error obteniendo respuestas OCSP para el certificado de sello", e);
1234 				throw new RetrieveOCSPException("Error obteniendo respuestas OCSP para el certificado de sello", e);
1235 			}
1236 			
1237 			//-- Completar a XAdES-C
1238 			try {
1239 				doc = addXadesC((Element) nodeFirma, respuestasFirma, respuestasSello, DEFAULT_XADES_SCHEMA, 
1240 						UtilidadFirmaElectronica.DIGEST_ALG_SHA1, searchXAdESNamespace (doc.getDocumentElement()));
1241 				logger.debug("[XAdESXLSignature.completeToXAdESXL]::Completado a XAdES-C");
1242 			} catch (Exception e) {
1243 				throw new XMLDocumentException(e);
1244 			}
1245 			
1246 			//-- Completar a XAdES-X
1247 			// A partir del nodo raíz de la firma se obtiene el nodo UnsignedSignatureProperties
1248 			Element unsignedSignaturePropertiesElement = null;
1249 			NodeList unsignedSignaturePropertiesNodes = 
1250 					nodeFirma.getElementsByTagNameNS(DEFAULT_XADES_SCHEMA_URI, ConstantesXADES.UNSIGNED_SIGNATURE_PROPERTIES);
1251 			
1252 			if (unsignedSignaturePropertiesNodes.getLength() != 1) {
1253 				// El nodo UnsignedSignatureProperties no existe o no es único 
1254 				logger.info("[XAdESXLSignature.completeToXAdESXL]::El nodo UnsignedSignatureProperties no existe o no es único");
1255 				// El sistema no soporta nodos UnsignedSignatureProperties múltiples
1256 				throw new XMLDocumentException("El nodo UnsignedSignatureProperties no existe o no es único");
1257 			} else {
1258 				unsignedSignaturePropertiesElement = (Element) unsignedSignaturePropertiesNodes.item(0);
1259 			}
1260 			
1261 			// Se añaden los elementos propios de la firma XADES-X
1262 			try {
1263 				doc = addXadesX(unsignedSignaturePropertiesElement, urlTSA, ConstantesTSA.SHA1, searchXAdESNamespace (doc.getDocumentElement()));
1264 				logger.debug("[XAdESXLSignature.completeToXAdESXL]::Completado a XAdES-X");
1265 			} catch (Exception e) {
1266 				throw new XMLDocumentException(e);
1267 			}
1268 
1269 			//-- Completar a XAdES-X-L
1270 			try {
1271 				doc = addXadesXL(nodeFirma, respuestasFirma, respuestasSello, XAdESSchemas.getXAdESSchema(DEFAULT_XADES_SCHEMA_URI),
1272 						searchXAdESNamespace (doc.getDocumentElement()));
1273 				logger.debug("[XAdESXLSignature.completeToXAdESXL]::Completado a XAdES-X-L");
1274 			} catch (Exception e) {
1275 				throw new XMLDocumentException(e);
1276 			}
1277 		}
1278 		
1279 		return new XAdESXLSignature(doc);
1280 	}
1281 	
1282 	/**
1283 	 * Añade un sello de tiempos de archivado a todas las firmas incluidas en este
1284 	 * fichero XAdES-X-L (convirtiéndolo, si no lo era ya, en un XAdES-A).
1285 	 * 
1286 	 * @param urlTSA URL del servidor de sello de tiempos
1287 	 * @throws SignatureException Error tratando con las firmas contenidas en el XAdES-X-L
1288 	 * @throws TimeStampException Error obteniendo el sello de tiempos
1289 	 * @throws XMLDocumentException Error modificando el XML para añadirle los nuevos sellos
1290 	 * 	de tiempos
1291 	 */
1292 	public void addArchiveTimeStamp (URL urlTSA) throws SignatureException, TimeStampException, XMLDocumentException {
1293 		logger.debug("[XAdESXLSignature.addArchiveTimeStamp]::Entrada");
1294 		
1295 		//-- Por si acaso inicializar el xmlsec
1296 		org.apache.xml.security.Init.init();
1297 		
1298 		try {
1299 			TSCliente tsCliente = new TSCliente(urlTSA.toString(), ConstantesTSA.SHA1);
1300 			
1301 			//-- Obtener los nodos de firma
1302 			String uriXmlNS = "http://www.w3.org/2000/09/xmldsig#";
1303 			NodeList signatureList = xadesDocument.getElementsByTagNameNS(uriXmlNS, "Signature");
1304 			
1305 			//-- Recorrer los nodos de firma
1306 			for(int i=0;i<signatureList.getLength();i++) {
1307 				XMLSignature firma = new XMLSignature((Element)signatureList.item(i), "./");
1308 				logger.debug("[XAdESXLSignature.addArchiveTimeStamp]::Resellando la firma: " + firma.getId());
1309 				
1310 				// Para los esquemas 1.1.1 y 1.2.2 se añaden includes con los nodos tomados
1311 				ArrayList<String> inc = null;
1312 				if (ConstantesXADES.SCHEMA_XADES_111.equals(DEFAULT_XADES_SCHEMA_URI) || ConstantesXADES.SCHEMA_XADES_122.equals(DEFAULT_XADES_SCHEMA_URI)) {
1313 					inc = UtilidadXadesA.obtenerListadoIdsElementosXadesA(DEFAULT_XADES_SCHEMA_URI, firma, null);
1314 				}
1315 				
1316 				// Se obtiene la cadena de bytes de entrada del sello XAdES-A
1317 				byte[] input = UtilidadXadesA.obtenerListadoXadesA(DEFAULT_XADES_SCHEMA_URI, firma, null);
1318 				addXadesA(firma.getElement(), tsCliente.generarSelloTiempo(input), inc) ;
1319 				logger.debug("[XAdESXLSignature.addArchiveTimeStamp]::Resellada la firma: " + firma.getId());
1320 			}
1321 		} catch (XMLSignatureException e) {
1322 			logger.info("[XAdESXLSignature.addArchiveTimeStamp]::Uno de los elementos 'Signature' está mal formado", e);
1323 			throw new SignatureException("Uno de los elementos 'Signature' está mal formado", e);
1324 		} catch (XMLSecurityException e) {
1325 			logger.info("[XAdESXLSignature.addArchiveTimeStamp]::Error de seguridad accediendo a uno de los elementos 'Signature'", e);
1326 			throw new SignatureException("Error de seguridad accediendo a uno de los elementos 'Signature'", e);
1327 		} catch (BadFormedSignatureException e) {
1328 			logger.info("[XAdESXLSignature.addArchiveTimeStamp]::Uno de los elementos 'Signature' está mal formado", e);
1329 			throw new SignatureException("Uno de los elementos 'Signature' está mal formado", e);
1330 		} catch (FirmaXMLError e) {
1331 			logger.info("[XAdESXLSignature.addArchiveTimeStamp]::Uno de los elementos 'Signature' está mal formado", e);
1332 			throw new SignatureException("Uno de los elementos 'Signature' está mal formado", e);
1333 		} catch (IOException e) {
1334 			logger.info("[XAdESXLSignature.addArchiveTimeStamp]::No se puede obtener o leer el documento que originó la firma, o no es posible escribir en memoria", e);
1335 			throw new SignatureException("No se puede obtener o leer el documento que originó la firma, o no es posible escribir en memoria", e);
1336 		} catch (TSClienteError e) {
1337 			logger.info("[XAdESXLSignature.addArchiveTimeStamp]::No se puede obtener el sello de tiempos", e);
1338 			throw new TimeStampException("No se puede obtener el sello de tiempos", e);
1339 		} catch (Exception e) {
1340 			logger.info("[XAdESXLSignature.addArchiveTimeStamp]::No se puede añadir el sello de tiempos de archivo a una de las firmas", e);
1341 			throw new XMLDocumentException("No se puede añadir el sello de tiempos de archivo a una de las firmas", e);
1342 		} 
1343 		
1344 	}
1345 	
1346 	/**
1347 	 * Devuelve la fecha en la que caducará el certificado de la TSA incluido en el
1348 	 * sello de tiempos. En caso de que los sellos de tiempos estén firmados por 
1349 	 * varias TSA se devolverá la fecha de caducidad del certificado de TSA más cercana 
1350 	 * a caducar.<br><br>
1351 	 * 
1352 	 * En el caso de que ya se haya resellado (las firmas sean XAdES-A) se devolverá
1353 	 * la fecha de caducidad del certificado de TSA del último resellado.
1354 	 * 
1355 	 * @return Fecha de caducidad del certificado de TSA 
1356 	 * @throws MalformedTimeStampException Alguno de los sellos de tiempos no está bien formado
1357 	 */
1358 	public Date getTimeStampCertificateExpiration () throws MalformedTimeStampException {
1359 		logger.debug("[XAdESXLSignature.getTimeStampCertificateExpiration]::Entrada");
1360 		
1361 		//-- Buscar los nodos ArchiveTimeStamp (si existen)
1362 		XPathFactory factory = XPathFactory.newInstance();
1363 		XPath xpath = factory.newXPath();
1364 		NodeList nodeList = null;
1365 		try {
1366 			XPathExpression expr = xpath.compile("//*[local-name()='" + ConstantesXADES.ARCHIVE_TIME_STAMP + "']/*[local-name()='EncapsulatedTimeStamp']");
1367 			nodeList = (NodeList) expr.evaluate (xadesDocument, XPathConstants.NODESET);
1368 		} catch (Exception e) {
1369 			logger.info ("[XAdESXLSignature.getTimeStampCertificateExpiration]::Error inesperado", e);
1370 			return null;
1371 		}
1372 		
1373 		Date fecha = null;
1374 		for (int i = 0; i < nodeList.getLength(); i++) {
1375 			//-- Obtener el sello de tiempos
1376 			TimeStamp timeStamp = new TimeStamp(new ByteArrayInputStream (Util.decodeBase64(nodeList.item(i).getTextContent())));
1377 			
1378 			//-- Obtener fecha 
1379 			Date timeStampDate = timeStamp.getSignatureCertificate().getValidityPeriodEnd();
1380 			if (fecha == null) {
1381 				fecha = timeStampDate;
1382 			}
1383 			if (fecha.before(timeStampDate)) {
1384 				fecha = timeStampDate;
1385 			}
1386 		}
1387 		
1388 		if (fecha != null) {
1389 			logger.debug("[XAdESXLSignature.getTimeStampCertificateExpiration]::Fecha obtenida del ultimo resellado: " + fecha);
1390 			return fecha;
1391 		}
1392 
1393 		//-- Obtener todos los nodos sello de tiempo
1394 		try {
1395 			XPathExpression expr = xpath.compile("//*[local-name()='EncapsulatedTimeStamp']");
1396 			nodeList = (NodeList) expr.evaluate (xadesDocument, XPathConstants.NODESET);
1397 		} catch (Exception e) {
1398 			logger.info ("[XAdESXLSignature.getTimeStampCertificateExpiration]::Error inesperado", e);
1399 			return null;
1400 		}
1401 		
1402 		fecha = null;
1403 		for (int i = 0; i < nodeList.getLength(); i++) {
1404 			//-- Obtener el sello de tiempos
1405 			TimeStamp timeStamp = new TimeStamp(new ByteArrayInputStream (Util.decodeBase64(nodeList.item(i).getTextContent())));
1406 			
1407 			//-- Obtener fecha 
1408 			Date timeStampDate = timeStamp.getSignatureCertificate().getValidityPeriodEnd();
1409 			if (fecha == null) {
1410 				fecha = timeStampDate;
1411 			}
1412 			if (fecha.after(timeStampDate)) {
1413 				fecha = timeStampDate;
1414 			}
1415 		}
1416 		
1417 		logger.debug("[XAdESXLSignature.getTimeStampCertificateExpiration]::Fecha obtenida del certificado TSA más próximo a caducar: " + fecha);
1418 		return fecha;
1419 		
1420 
1421 	}
1422 	
1423 	/**
1424 	 * Método empleado para añadir los certificados de sello de tiempo y
1425 	 * su cadena al XAdES. ¡Emplear sólo en los casos en que sea necesario:
1426 	 * firmas completadas con versiones anteriores a la 1.4.5 de Arangí!
1427 	 * 
1428 	 * @param caList Lista de CAs admitidas
1429 	 * @param urlTSA URL de la TSA
1430 	 * @throws Exception Errores durante la modificación del XML
1431 	 */
1432 	public void fix (CAList caList, URL urlTSA) throws Exception {
1433 
1434 		// Se obtiene el certificado firmante del sello de tiempos
1435     	X509Certificate timeStampCertificate;
1436     	try {
1437     		timeStampCertificate = getXAdESTimeStampCertificate(xadesDocument).toX509Certificate();
1438 		} catch (MalformedTimeStampException e1) {
1439 			logger.info("[XAdESXLSignature.completeToXAdESXL]::No se puede obtener el sello de tiempos del xades", e1);
1440 			throw new SignatureException ("No se puede obtener el sello de tiempos del xades", e1);
1441 		}
1442     	
1443     	//-- Lista de certificados y respuestas OCSP: cadena del certificado de tsa 
1444 		ArrayList<RespYCerts> respuestasSello = new ArrayList<RespYCerts>();
1445 		try {
1446 			logger.debug("[XAdESXLSignature.completeToXAdESXL]::Obteniendo respuestas OCSP para el certificado de sello");
1447 			respuestasSello = convertICertStatus2RespYCerts(new CAListCertStatusRecover(caList, false).getCertChainStatus(timeStampCertificate));
1448 		} catch (CertStatusException e) {
1449 			logger.info("[XAdESXLSignature.completeToXAdESXL]::Error obteniendo respuestas OCSP para el certificado de sello", e);
1450 			throw new RetrieveOCSPException("Error obteniendo respuestas OCSP para el certificado de sello", e);
1451 		}
1452 		
1453 		//-- Completar a XAdES-C
1454 		NodeList listaCertRefs = xadesDocument.getElementsByTagNameNS(DEFAULT_XADES_SCHEMA_URI, ConstantesXADES.CERT_REFS);
1455 		NodeList listaOcspRefs = xadesDocument.getElementsByTagNameNS(DEFAULT_XADES_SCHEMA_URI, ConstantesXADES.OCSP_REFS);
1456 		NodeList listaCrlRefs = xadesDocument.getElementsByTagNameNS(DEFAULT_XADES_SCHEMA_URI, ConstantesXADES.CRL_REFS);
1457 		NodeList listaCertificateValues = xadesDocument.getElementsByTagNameNS(DEFAULT_XADES_SCHEMA_URI, ConstantesXADES.CERTIFICATE_VALUES);
1458 		NodeList listaOcspValues = xadesDocument.getElementsByTagNameNS(DEFAULT_XADES_SCHEMA_URI, ConstantesXADES.OCSP_VALUES);
1459 		NodeList listaCrlValues = xadesDocument.getElementsByTagNameNS(DEFAULT_XADES_SCHEMA_URI, ConstantesXADES.CRL_VALUES);
1460 		NodeList listaSigAndRefsTimestamp = xadesDocument.getElementsByTagNameNS(DEFAULT_XADES_SCHEMA_URI, ConstantesXADES.SIG_AND_REFS_TIME_STAMP);
1461 		
1462 		String namespace = searchXAdESNamespace (xadesDocument.getDocumentElement());
1463 		String algDigestXML = UtilidadFirmaElectronica.DIGEST_ALG_SHA1;
1464 
1465         if(respuestasSello != null && !respuestasSello.isEmpty()) {
1466         	
1467         	int i = -1;
1468         	for (RespYCerts respYCerts : respuestasSello) {
1469         		i++;
1470         		
1471         		X509Certificate certificado = respYCerts.getCertstatus().getCertificate();
1472         		
1473         		//-- COMPLETE CERTIFICATE REFS
1474             	// Se agrega una id al certificado
1475             	String idCertificado = UtilidadTratarNodo.newID(xadesDocument, ConstantesXADES.LIBRERIAXADES_CERT_PATH);
1476             	respuestasSello.get(i).setIdCertificado(idCertificado);
1477             	
1478          		Element elementCertRef = xadesDocument.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.CERT);
1479         		
1480         		// Creamos los atributos de UnSignedProperties
1481             	Attr uris = xadesDocument.createAttributeNS(null, "URI");
1482             	uris.setValue( ConstantesXADES.ALMOHADILLA + idCertificado );
1483             	NamedNodeMap atributosURI = elementCertRef.getAttributes();
1484             	atributosURI.setNamedItem(uris);
1485 
1486     	        Element resumenElementoCert = xadesDocument.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.CERT_DIGEST);
1487 
1488     	        // Creamos el xades:DigestMethod
1489     	        Element metodoResumenElemento = xadesDocument.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.DIGEST_METHOD);
1490 
1491     	        // Creamos los atributos de DigestMethod
1492     	        Attr propiedadesFirmaAlgoritmo = xadesDocument.createAttributeNS(null, ConstantesXADES.ALGORITHM);
1493     	        propiedadesFirmaAlgoritmo.setValue(algDigestXML);
1494     	        NamedNodeMap cualidadesMetodoResumenElemento =
1495     	                metodoResumenElemento.getAttributes();
1496     	        cualidadesMetodoResumenElemento.setNamedItem(propiedadesFirmaAlgoritmo);
1497 
1498     	        // Creamos el xades:DigestValue
1499     	        String resumenCertificado = ConstantesXADES.CADENA_VACIA;
1500     	        try
1501     	        {
1502         			MessageDigest resumenCertificadoTemp = UtilidadFirmaElectronica.getMessageDigest(algDigestXML);
1503         			if (resumenCertificadoTemp == null)
1504         	        	throw new Exception("No se ha podido realizar el digest");
1505     	            byte[] resumenMensajeByte =resumenCertificadoTemp.digest(certificado.getEncoded());
1506     	            resumenCertificado = new String(Base64Coder.encode(resumenMensajeByte));
1507     	        } catch (CertificateEncodingException e) {
1508     	        	logger.error(e);
1509     	        	throw new Exception("Error obteniendo la huella del certificado");				
1510     	        }
1511 
1512     	        Element elementDigestValue =
1513     	        		xadesDocument.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.DIGEST_VALUE);
1514     	        elementDigestValue.appendChild(
1515     	        		xadesDocument.createTextNode(resumenCertificado));
1516 
1517     	        // Creamos el xades:IssuerSerial
1518     	        Element elementoEmisorSerial =
1519     	        		xadesDocument.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.ISSUER_SERIAL);
1520     	        // Creamos el xades:X509IssuerName
1521     	        Element elementoX509EmisorNombre =
1522     	        		xadesDocument.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.X_509_ISSUER_NAME);
1523     	        elementoX509EmisorNombre.appendChild(
1524     	        		xadesDocument.createTextNode(certificado.getIssuerX500Principal().getName()));
1525 
1526     	        // Creamos el xades:X509SerialNumber
1527     	        Element elementoX509NumeroSerial =
1528     	        		xadesDocument.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.X_509_SERIAL_NUMBER);
1529     	        elementoX509NumeroSerial.appendChild(
1530     	        		xadesDocument.createTextNode(certificado.getSerialNumber().toString()));
1531 
1532     	        //Add references
1533     	        elementoEmisorSerial.appendChild(elementoX509EmisorNombre);
1534     	        elementoEmisorSerial.appendChild(elementoX509NumeroSerial);
1535 
1536     	        resumenElementoCert.appendChild(metodoResumenElemento);
1537     	        resumenElementoCert.appendChild(elementDigestValue);
1538 
1539     	        elementCertRef.appendChild(resumenElementoCert);
1540     	        elementCertRef.appendChild(elementoEmisorSerial);
1541 
1542     	        appendChild (listaCertRefs, elementCertRef);
1543     	        
1544         		//-- COMPLETE REVOCATION REFS
1545     	    	Element elementOCSPRef = null;
1546     	    	String tiempoRespuesta = null;
1547     	    	byte[] mensajeRespuesta = null;
1548             	int nOCSPRefs = 0;
1549             	int nCRLRefs = 0;
1550         		ICertStatus certStatus = respYCerts.getCertstatus();
1551         		if (certStatus instanceof IOCSPCertStatus) {
1552         			nOCSPRefs++;
1553         			IOCSPCertStatus respOcsp = (IOCSPCertStatus) certStatus;
1554 
1555 	        		tiempoRespuesta = UtilidadFechas.formatFechaXML(respOcsp.getResponseDate());
1556 	        		IOCSPCertStatus.TYPE_RESPONDER tipoResponder = respOcsp.getResponderType();
1557 	        		String valorResponder = respOcsp.getResponderID();
1558 	        		mensajeRespuesta = respOcsp.getEncoded();
1559 	
1560 	        		elementOCSPRef = xadesDocument.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.OCSP_REF);
1561 	        		
1562 	        		// Creamos los atributos de UnSignedProperties
1563 	        		String idOcsp = UtilidadTratarNodo.newID(xadesDocument, ConstantesXADES.OCSP);
1564 	
1565 	            	Element identificadorElementoOCSP = xadesDocument.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.OCSP_IDENTIFIER);
1566 	            	uris = xadesDocument.createAttributeNS(null, "URI");
1567 	            	uris.setValue( ConstantesXADES.ALMOHADILLA + idOcsp );
1568 	            	atributosURI = identificadorElementoOCSP.getAttributes();
1569 	            	atributosURI.setNamedItem(uris);
1570 	
1571 	        		// Creamos el xades:DigestMethod
1572 	        		Element elementoRespondedorId = xadesDocument.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.RESPONDER_ID);
1573 	
1574 	        		
1575 	        		Element responderFinal = elementoRespondedorId;
1576 	        		if (!(ConstantesXADES.SCHEMA_XADES_111.equals(DEFAULT_XADES_SCHEMA_URI)) && !(ConstantesXADES.SCHEMA_XADES_122.equals(DEFAULT_XADES_SCHEMA_URI))) {
1577 	        			Element hijo = null;
1578 	        			if (tipoResponder.equals(IOCSPCertStatus.TYPE_RESPONDER.BY_NAME)) {
1579 	        				hijo = xadesDocument.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.BY_NAME);
1580 	        			}
1581 	        			else {
1582 	        				hijo = xadesDocument.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.BY_KEY);
1583 	        			}
1584 	        			// TODO: tener en cuenta que podria no ser ninguno de estos valores en un futuro
1585 	            		elementoRespondedorId.appendChild(hijo);
1586 	            		responderFinal = hijo;
1587 	        		}
1588 	        		responderFinal.appendChild(xadesDocument.createTextNode(valorResponder));
1589 	    			
1590 	
1591 	        		Element elementoProdujoEn = xadesDocument.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.PRODUCE_AT);
1592 	
1593 	
1594 	        		elementoProdujoEn.appendChild(xadesDocument.createTextNode(tiempoRespuesta));
1595 	
1596 	        		identificadorElementoOCSP.appendChild(elementoRespondedorId);
1597 	        		identificadorElementoOCSP.appendChild(elementoProdujoEn);
1598 	        		Element valorYResumenElemento = xadesDocument.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.DIGEST_ALG_AND_VALUE);
1599 	
1600 	        		// Creamos el xades:DigestMethod
1601 	        		metodoResumenElemento = xadesDocument.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.DIGEST_METHOD);
1602 	
1603 	        		// Creamos los atributos de DigestMethod
1604 	        		Attr propiedadesAlgoritmoFirmado = xadesDocument.createAttributeNS(null, ConstantesXADES.ALGORITHM);
1605 	        		propiedadesAlgoritmoFirmado.setValue(algDigestXML);
1606 	        		NamedNodeMap atributosMetodoResumenElemento = metodoResumenElemento.getAttributes();
1607 	        		atributosMetodoResumenElemento.setNamedItem(propiedadesAlgoritmoFirmado);
1608 	
1609 	        		// Creamos el xades:DigestValue
1610 	        		// El mensaje de la respuesta es el OCSPResponse
1611 	        		String digestCertificado =ConstantesXADES.CADENA_VACIA;
1612         			MessageDigest resumenCertificadoTemp = UtilidadFirmaElectronica.getMessageDigest(algDigestXML);
1613         			if (resumenCertificadoTemp == null)
1614         				throw new Exception("No se ha podido generar el digest");
1615         			byte[] resumenMensajeByte = resumenCertificadoTemp.digest(mensajeRespuesta);
1616         			digestCertificado = new String(Base64Coder.encode(resumenMensajeByte));
1617 	
1618 	        		Element valorResumenElemento = xadesDocument.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.DIGEST_VALUE);
1619 	
1620 	        		valorResumenElemento.appendChild(xadesDocument.createTextNode(digestCertificado));
1621 	
1622 	        		valorYResumenElemento.appendChild(metodoResumenElemento);
1623 	        		valorYResumenElemento.appendChild(valorResumenElemento);
1624 	
1625 	        		elementOCSPRef.appendChild(identificadorElementoOCSP);
1626 	        		elementOCSPRef.appendChild(valorYResumenElemento);
1627 	
1628 	        		appendChild(listaOcspRefs, elementOCSPRef);
1629 	        		
1630 	        		// REVOCATION VALUES
1631 	        		Element valorElementoEncapsuladoOCSP = xadesDocument.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.ENCAPSULATED_OCSP_VALUE);
1632     	            valorElementoEncapsuladoOCSP.appendChild(
1633     	            		xadesDocument.createTextNode(new String(Base64Coder.encode(respOcsp.getEncoded()))));
1634     	            valorElementoEncapsuladoOCSP.setAttributeNS(null, ConstantesXADES.ID, idOcsp);
1635     	            appendChild(listaOcspValues, valorElementoEncapsuladoOCSP);
1636 
1637         		}
1638         		else if (certStatus instanceof IX509CRLCertStatus) {
1639         			nCRLRefs++;
1640         			IX509CRLCertStatus respCRL = (IX509CRLCertStatus) certStatus;
1641         			CRLRef crlRef = new CRLRef(DEFAULT_XADES_SCHEMA, algDigestXML, respCRL.getX509CRL());
1642 
1643 					String idCrl = UtilidadTratarNodo.newID(xadesDocument, ConstantesXADES.CRL);
1644 					crlRef.getCrlIdentifier().setUri(ConstantesXADES.ALMOHADILLA + idCrl);
1645 	
1646 					appendChild(listaCrlRefs, crlRef.createElement(xadesDocument, xmldsigNS, namespace));
1647 					
1648 	        		// REVOCATION VALUES
1649 	        		Element valorElementoEncapsuladoCRL = xadesDocument.createElementNS(DEFAULT_XADES_SCHEMA_URI, namespace + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.ENCAPSULATED_CRL_VALUE);
1650 	        		valorElementoEncapsuladoCRL.appendChild(
1651     	            		xadesDocument.createTextNode(new String(Base64Coder.encode(respCRL.getX509CRL().getEncoded()))));
1652 	        		valorElementoEncapsuladoCRL.setAttributeNS(null, ConstantesXADES.ID, idCrl);
1653     	            appendChild(listaCrlValues, valorElementoEncapsuladoCRL);
1654         		}
1655 
1656         		//-- CERTIFICATE VALUES
1657         		EncapsulatedX509Certificate encapsulatedX509certificate = new EncapsulatedX509Certificate(DEFAULT_XADES_SCHEMA, idCertificado);
1658 	        	try {
1659 					encapsulatedX509certificate.setX509Certificate(certificado);
1660 				} catch (CertificateException e) {
1661 					logger.info(e.getMessage(), e);
1662 					throw new Exception("No ha sido posible crear el elemento 'encapsulatedX509certificate' ");
1663 				}
1664 	        	appendChild(listaCertificateValues, encapsulatedX509certificate.createElement(xadesDocument, namespace));
1665 
1666         	}
1667         	
1668         	//-- SIGANDREFSTIMESTAMP
1669         	if (listaSigAndRefsTimestamp != null && listaSigAndRefsTimestamp.getLength() == 1) {
1670 	        	// Se crea el nodo SigAndRefsTimeStamp
1671 	            Element sigAndRefsTimeStampElement = (Element) listaSigAndRefsTimestamp.item(0);
1672 	            sigAndRefsTimeStampElement.removeChild(sigAndRefsTimeStampElement.getFirstChild());
1673 	            sigAndRefsTimeStampElement.removeChild(sigAndRefsTimeStampElement.getFirstChild());
1674 	            Element unsignedSignatureProperties = (Element) sigAndRefsTimeStampElement.getParentNode();
1675 	            
1676 	            addXadesX(unsignedSignatureProperties, sigAndRefsTimeStampElement, urlTSA, ConstantesTSA.SHA1, namespace);
1677         	}       	
1678         }
1679 		
1680 	}
1681 
1682 	//-- Implementación de XAdESSignature
1683 	
1684 	@Override
1685 	protected int tratarResultadoValidacion(ResultadoValidacion resultadoValidacion) {
1686 		if (resultadoValidacion.isValidate() && resultadoValidacion.getEnumNivel() == EnumFormatoFirma.XAdES_XL) {
1687 			//válido
1688 			logger.debug("[XAdESXLSignature.isValidSignatureOnly]::La firma ha pasado la validación");
1689 			return ValidationResult.RESULT_VALID;
1690 		} else if (resultadoValidacion.getNivelValido() == null || resultadoValidacion.getNivelValido().equals("")) {
1691 			if (resultadoValidacion.getLog().toLowerCase().indexOf("firma inválida") > -1) {
1692 				//certificado válido, el problema será con la firma
1693 				logger.debug("[XAdESXLSignature.isValidSignatureOnly]::La firma no es válida");
1694 				return ValidationResult.RESULT_SIGNATURE_NOT_MATCH_DATA;
1695 			} else {
1696 				//certificado caducado
1697 				logger.debug("[XAdESXLSignature.isValidSignatureOnly]::El certificado está caducado");
1698 				return ValidationResult.RESULT_CERTIFICATE_NOT_ACTIVE;
1699 			}
1700 		} else if (resultadoValidacion.getEnumNivel() == EnumFormatoFirma.XAdES_BES ||
1701 				resultadoValidacion.getEnumNivel() == EnumFormatoFirma.XAdES_C) {
1702 			//El BES es válido, o sea que es un problema con el sello de tiempos
1703 			logger.debug("[XAdESXLSignature.isValidSignatureOnly]::El sello de tiempos no es válido");
1704 			return ValidationResult.RESULT_INVALID_TIMESTAMP;
1705 		} else if (resultadoValidacion.getResultado() == ResultadoEnum.INVALID) {
1706 			//revocado
1707 			logger.debug("[XAdESXLSignature.isValidSignatureOnly]::El certificado de la firma está revocado");
1708 			return ValidationResult.RESULT_CERTIFICATE_REVOKED;
1709 		} else if (resultadoValidacion.getEnumNivel() == EnumFormatoFirma.XAdES_T) {
1710 			//no hay información de revocación (respuestas OCSP)
1711 			logger.debug("[XAdESXLSignature.isValidSignatureOnly]::El XAdES es un XAdES-T");
1712 			return ValidationResult.RESULT_CERTIFICATE_CANNOT_BE_VALIDATED;
1713 		} else  {
1714 			//desconocido
1715 			logger.debug("[XAdESXLSignature.isValidSignatureOnly]::La firma no ha pasado la validación");
1716 			return ValidationResult.RESULT_CERTIFICATE_UNKNOWN;
1717 		}
1718 	}
1719 	
1720 	/**
1721 	 * Formato de firma: XAdES-X-L
1722 	 */
1723 	protected EnumFormatoFirma getXAdESSignatureFormat () {
1724 		return EnumFormatoFirma.XAdES_XL;
1725 	}
1726 	
1727 
1728 	//-- Métodos privados
1729 
1730 	/*
1731 	 * Añade el sello de archivo a una firma
1732 	 */
1733     private void addXadesA (Element firma, byte[] selloTiempo, ArrayList<String> inc) throws Exception {
1734     	
1735     	Document doc = firma.getOwnerDocument();
1736     	
1737     	ArrayList<Element> UnsignedSignaturePropertiesNodes = UtilidadTratarNodo.obtenerNodos(firma, 4, 
1738 				new NombreNodo(DEFAULT_XADES_SCHEMA_URI, ConstantesXADES.UNSIGNED_SIGNATURE_PROPERTIES));
1739     	Element UnsignedSignaturePropertiesNode = null;
1740     	if(UnsignedSignaturePropertiesNodes.size() == 1)
1741     		UnsignedSignaturePropertiesNode = (Element)UnsignedSignaturePropertiesNodes.get(0);
1742     	else
1743     		// No se encuentra el nodo UnsignedSignatureProperties
1744     		throw new AddXadesException(I18n.getResource(ConstantesXADES.LIBRERIAXADES_FIRMAXML_ERROR_19)) ;
1745 
1746     	Element archiveTimeStamp =
1747     		doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, xadesNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.ARCHIVE_TIME_STAMP);
1748     	
1749     	// Creamos los atributos de ArchiveTimeStamp (Id)
1750     	Attr archiveTimeStampId = doc.createAttributeNS(null, ConstantesXADES.ID);
1751     	archiveTimeStampId.setValue(UtilidadTratarNodo.newID(doc, 
1752     			ConstantesXADES.ARCHIVE_TIME_STAMP + ConstantesXADES.GUION));
1753     	NamedNodeMap archiveTimeStampAttributesElement =
1754     		archiveTimeStamp.getAttributes();
1755     	archiveTimeStampAttributesElement.setNamedItem(archiveTimeStampId);
1756     	
1757     	// Se agrega el nodo EncapsulatedTimeStamp, con Id y Encoding como atributos
1758     	Element encapsulatedTimeStamp =
1759     		doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, xadesNS + ConstantesXADES.DOS_PUNTOS + 
1760     				ConstantesXADES.ENCAPSULATED_TIME_STAMP);
1761     	
1762     	// Se escribe una Id única
1763     	Attr informacionElementoSigTimeStamp = doc.createAttributeNS(null, ConstantesXADES.ID);
1764     	String idSelloTiempo = UtilidadTratarNodo.newID(doc, ConstantesXADES.SELLO_TIEMPO_TOKEN);
1765     	informacionElementoSigTimeStamp.setValue(idSelloTiempo);
1766     	encapsulatedTimeStamp.getAttributes().setNamedItem(informacionElementoSigTimeStamp);
1767     	
1768     	// Se agrega el CanonicalizationMethod
1769     	Element canonicalizationElemento = doc.createElementNS(ConstantesXADES.SCHEMA_DSIG, xmldsigNS + ConstantesXADES.DOS_PUNTOS + ConstantesXADES.CANONICALIZATION_METHOD);		
1770 		Attr canonicalizationAttribute = doc.createAttributeNS(null, ConstantesXADES.ALGORITHM);
1771 		canonicalizationAttribute.setValue(Transforms.TRANSFORM_C14N_OMIT_COMMENTS);
1772 		canonicalizationElemento.getAttributes().setNamedItem(canonicalizationAttribute);
1773 
1774 		archiveTimeStamp.appendChild(canonicalizationElemento);
1775         
1776         encapsulatedTimeStamp.appendChild(doc.createTextNode(new String(Base64Coder.encode(selloTiempo))));       
1777         
1778         // Se agregan, si existen, los nodos include
1779         if (inc != null) {
1780         	Element includeNode = null;
1781         	for (int i = 0; i < inc.size(); ++i) {
1782         		includeNode = doc.createElementNS(DEFAULT_XADES_SCHEMA_URI, xadesNS + ConstantesXADES.DOS_PUNTOS + 
1783         				ConstantesXADES.INCLUDE);      	
1784         		includeNode.setAttributeNS(null, ConstantesXADES.URI_MAYUS, inc.get(i));
1785         		archiveTimeStamp.appendChild(includeNode);
1786         	}
1787         }
1788         
1789         archiveTimeStamp.appendChild(encapsulatedTimeStamp);
1790         
1791         // Se agrega el sello creado a las propiedades no firmadas
1792         UnsignedSignaturePropertiesNode.appendChild(archiveTimeStamp);
1793         
1794     }
1795 
1796     /*
1797      * Añade un elemento a una lista de nodos
1798      */
1799 	private void appendChild(NodeList nodeList, Element element) {
1800 		if (nodeList != null && element != null) {
1801 			for(int i=0; i<nodeList.getLength(); i++) {
1802 				nodeList.item(i).appendChild(element);
1803 			}
1804 		}
1805 	}
1806 
1807     @Override
1808     public String toString() {
1809     	StringBuffer sb = new StringBuffer();
1810     	sb.append(getString (xadesDocument));
1811     	return sb.toString();
1812     }
1813 
1814 	private String getString(Node node) {
1815     	StringBuffer sb = new StringBuffer();
1816     	sb.append(node.getNodeName() + ": " + node.getNodeValue() + "\n");
1817     	if (node.getAttributes() != null) {
1818 	        for (int i=0; i< node.getAttributes().getLength();i++) {
1819 	        	sb.append("@" + node.getAttributes().item(i).getNodeName() + ": " + node.getAttributes().item(i).getNodeValue() + "\n");
1820 	        }
1821     	}
1822         for (int i=0; i< node.getChildNodes().getLength();i++) {
1823     		sb.append(getString(node.getChildNodes().item(i)));
1824     	}
1825 		return sb.toString();
1826 	}
1827 }