1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  package es.accv.arangi.base.signature;
22  
23  import java.io.ByteArrayInputStream;
24  import java.io.File;
25  import java.io.FileInputStream;
26  import java.io.FileNotFoundException;
27  import java.io.FileOutputStream;
28  import java.io.IOException;
29  import java.io.InputStream;
30  import java.net.URL;
31  import java.security.InvalidKeyException;
32  import java.security.NoSuchAlgorithmException;
33  import java.security.NoSuchProviderException;
34  import java.security.PrivateKey;
35  import java.security.cert.X509Certificate;
36  import java.text.SimpleDateFormat;
37  import java.util.ArrayList;
38  import java.util.Arrays;
39  import java.util.Calendar;
40  import java.util.Collections;
41  import java.util.Date;
42  import java.util.HashMap;
43  import java.util.HashSet;
44  import java.util.Iterator;
45  import java.util.List;
46  import java.util.Set;
47  
48  import org.apache.log4j.Logger;
49  import org.bouncycastle.asn1.ocsp.BasicOCSPResponse;
50  import org.bouncycastle.cert.ocsp.BasicOCSPResp;
51  import org.bouncycastle.cert.ocsp.OCSPResp;
52  
53  import com.itextpdf.text.DocumentException;
54  import com.itextpdf.text.Image;
55  import com.itextpdf.text.Rectangle;
56  import com.itextpdf.text.pdf.AcroFields;
57  import com.itextpdf.text.pdf.PdfDate;
58  import com.itextpdf.text.pdf.PdfDictionary;
59  import com.itextpdf.text.pdf.PdfDocumentSecurityStore;
60  import com.itextpdf.text.pdf.PdfName;
61  import com.itextpdf.text.pdf.PdfPKCS7;
62  import com.itextpdf.text.pdf.PdfReader;
63  import com.itextpdf.text.pdf.PdfSigGenericPKCS;
64  import com.itextpdf.text.pdf.PdfSignature;
65  import com.itextpdf.text.pdf.PdfSignatureAppearance;
66  import com.itextpdf.text.pdf.PdfStamper;
67  import com.itextpdf.text.pdf.PdfString;
68  import com.itextpdf.text.pdf.TSAClient;
69  import com.itextpdf.text.pdf.TSAClientBouncyCastle;
70  
71  import es.accv.arangi.base.algorithm.DigitalSignatureAlgorithm;
72  import es.accv.arangi.base.algorithm.HashingAlgorithm;
73  import es.accv.arangi.base.certificate.Certificate;
74  import es.accv.arangi.base.certificate.validation.CAList;
75  import es.accv.arangi.base.certificate.validation.CRL;
76  import es.accv.arangi.base.certificate.validation.CertificateOCSPResponse;
77  import es.accv.arangi.base.certificate.validation.CertificateValidationService;
78  import es.accv.arangi.base.certificate.validation.CertificateValidator;
79  import es.accv.arangi.base.certificate.validation.OCSPClient;
80  import es.accv.arangi.base.certificate.validation.OCSPResponse;
81  import es.accv.arangi.base.certificate.validation.ValidateCertificate;
82  import es.accv.arangi.base.device.DeviceManager;
83  import es.accv.arangi.base.document.IDocument;
84  import es.accv.arangi.base.document.InputStreamDocument;
85  import es.accv.arangi.base.exception.certificate.CRLParsingException;
86  import es.accv.arangi.base.exception.certificate.CertificateCANotFoundException;
87  import es.accv.arangi.base.exception.certificate.NormalizeCertificateException;
88  import es.accv.arangi.base.exception.certificate.validation.MalformedOCSPResponseException;
89  import es.accv.arangi.base.exception.device.AliasNotFoundException;
90  import es.accv.arangi.base.exception.device.LoadingObjectException;
91  import es.accv.arangi.base.exception.device.SearchingException;
92  import es.accv.arangi.base.exception.document.HashingException;
93  import es.accv.arangi.base.exception.signature.AlgorithmNotSuitableException;
94  import es.accv.arangi.base.exception.signature.InvalidCertificateException;
95  import es.accv.arangi.base.exception.signature.PDFDocumentException;
96  import es.accv.arangi.base.exception.signature.RetrieveOCSPException;
97  import es.accv.arangi.base.exception.signature.SignatureException;
98  import es.accv.arangi.base.exception.signature.SignatureNotFoundException;
99  import es.accv.arangi.base.exception.timestamp.MalformedTimeStampException;
100 import es.accv.arangi.base.exception.timestamp.ResponseTimeStampException;
101 import es.accv.arangi.base.exception.timestamp.TimeStampServerConnectionException;
102 import es.accv.arangi.base.timestamp.TimeStamp;
103 import es.accv.arangi.base.timestamp.TimeStampRequestParameters;
104 import es.accv.arangi.base.util.Util;
105 import es.accv.arangi.base.util.validation.ValidationResult;
106 
107 
108 
109 
110 
111 
112 
113 
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137 
138 
139 
140 
141 
142 
143 
144 
145 
146 
147 
148 
149 
150 
151 
152 
153 
154 
155 
156 
157 
158 
159 
160 
161 
162 
163 
164 
165 
166 
167 
168 
169 
170 
171 
172 
173 
174 
175 
176 
177 
178 
179 
180 
181 
182 
183 
184 
185 
186 
187 
188 
189 
190 
191 
192 
193 
194 
195 
196 
197 
198 
199 
200 
201 
202 
203 
204 
205 
206 
207 
208 
209 
210 
211 
212 
213 
214 
215 
216 public class PAdESLTVSignature extends BasePDFSignature {
217 
218 	
219 
220 
221 
222 	private static final String DEFAULT_SIGNATURE_REASON = "Firma realizada con Arangi (ACCV)";
223 
224     private final static boolean embedOcspInSignature = false;
225 
226     private static final String HASH_ALGORITHM = embedOcspInSignature ?"SHA256" : "SHA1";
227     
228     private static boolean onlyOCSPResponsesInDSS = true;
229     
230     
231 
232 
233 
234 
235     public static boolean olderVersionsAllowed = false; 
236 
237 	
238 
239 
240 	static Logger logger = Logger.getLogger(PAdESLTVSignature.class);
241 	
242 	
243 	
244 	
245 
246 
247 
248 
249 
250 
251 
252 	public PAdESLTVSignature (File pdfFile) throws PDFDocumentException, SignatureNotFoundException {
253 		
254 		File fileTemp = null;
255 		try {
256 			fileTemp = getFileTemp ();
257 			Util.saveFile(fileTemp, Util.loadFile(pdfFile));
258 		} catch (IOException e) {
259 			logger.info("[PAdESLTVSignature(byte[])::No se puede crear el fichero temporal o no se puede escribir en él", e);
260 			if (fileTemp != null) { fileTemp.delete(); }
261 			throw new PDFDocumentException ("No se puede crear el fichero temporal o no se puede escribir en él", e);
262 		}
263 
264 		initialize(fileTemp);
265 	}
266 	
267 	
268 
269 
270 
271 
272 
273 
274 
275 
276 	public PAdESLTVSignature (byte[] pdfContentBytes) throws PDFDocumentException, SignatureNotFoundException, IOException {
277 		
278 		File fileTemp = null;
279 		try {
280 			fileTemp = getFileTemp ();
281 			Util.saveFile(fileTemp, pdfContentBytes);
282 		} catch (IOException e) {
283 			logger.info("[PAdESLTVSignature(byte[])::No se puede crear el fichero temporal o no se puede escribir en él", e);
284 			if (fileTemp != null) { fileTemp.delete(); }
285 			throw e;
286 		}
287 		
288 		initialize(fileTemp);
289 	}
290 	
291 	
292 
293 
294 
295 
296 
297 
298 
299 
300 	public PAdESLTVSignature (InputStream streamPDF) throws PDFDocumentException, SignatureNotFoundException, IOException {
301 		
302 		File fileTemp = null;
303 		try {
304 			fileTemp = getFileTemp ();
305 			Util.saveFile(fileTemp, streamPDF);
306 		} catch (IOException e) {
307 			logger.info("[PAdESLTVSignature(byte[])::No se puede crear el fichero temporal o no se puede escribir en él", e);
308 			if (fileTemp != null) { fileTemp.delete(); }
309 			throw e;
310 		} 
311 		
312 		
313 		initialize(fileTemp);
314 	}
315 	
316 	
317 
318 
319 
320 
321 
322 
323 
324 
325 	public PAdESLTVSignature (IDocument document) throws PDFDocumentException, SignatureNotFoundException, IOException {
326 		
327 		InputStream fis = null;
328 		File fileTemp = null;
329 		try {
330 			fileTemp = getFileTemp ();
331 			fis = document.getInputStream();
332 			Util.saveFile(fileTemp, fis);
333 		} catch (IOException e) {
334 			logger.info("[PAdESLTVSignature(byte[])::No se puede crear el fichero temporal o no se puede escribir en él", e);
335 			if (fileTemp != null) { fileTemp.delete(); }
336 			throw e;
337 		} finally {
338 			if (fis != null) {
339 				fis.close();
340 			}
341 		}
342 		
343 		
344 		initialize(fileTemp);
345 	}
346 	
347 	
348 
349 
350 	protected PAdESLTVSignature (PAdESLTVSignature signature) {
351 		this.pdfFile = signature.pdfFile;
352 	}
353 	
354 	
355 	
356 	
357 
358 
359 
360 
361 
362 
363 
364 
365 
366 
367 
368 
369 
370 
371 
372 
373 
374 
375 
376 
377 
378 
379 
380 
381 
382 
383 
384 
385 	public static PAdESLTVSignature sign (DeviceManager[] managers, String[] alias, IDocument pdfDocument, URL urlTimestamp, 
386 			CAList caList, String reason) throws AliasNotFoundException, LoadingObjectException, PDFDocumentException, SignatureException, RetrieveOCSPException, HashingException, CertificateCANotFoundException, InvalidCertificateException, NormalizeCertificateException {
387 		try {
388 			return sign (managers, alias, pdfDocument, null, urlTimestamp, null, null, caList, reason, false, null, -1, -1, -1, -1, 0);
389 		} catch (AlgorithmNotSuitableException e) {
390 			logger.info("El algoritmo por defecto no debería provocar este error", e);
391 			throw new SignatureException("El algoritmo por defecto no debería provocar este error", e);
392 		}
393 	}
394 	
395 	
396 
397 
398 
399 
400 
401 
402 
403 
404 
405 
406 
407 
408 
409 
410 
411 
412 
413 
414 
415 
416 
417 
418 
419 
420 
421 
422 
423 
424 
425 
426 
427 
428 	public static PAdESLTVSignature sign (DeviceManager[] managers, String[] alias, IDocument pdfDocument, URL urlTimestamp, 
429 			String userTSA, String passwordTSA, CAList caList, String reason) throws AliasNotFoundException, LoadingObjectException, PDFDocumentException, SignatureException, RetrieveOCSPException, HashingException, CertificateCANotFoundException, InvalidCertificateException, NormalizeCertificateException {
430 		try {
431 			return sign (managers, alias, pdfDocument, null, urlTimestamp, userTSA, passwordTSA, caList, reason, false, null, -1, -1, -1, -1, 0);
432 		} catch (AlgorithmNotSuitableException e) {
433 			logger.info("El algoritmo por defecto no debería provocar este error", e);
434 			throw new SignatureException("El algoritmo por defecto no debería provocar este error", e);
435 		}
436 	}
437 	
438 	
439 
440 
441 
442 
443 
444 
445 
446 
447 
448 
449 
450 
451 
452 
453 
454 
455 
456 
457 
458 
459 
460 
461 
462 
463 
464 
465 
466 
467 
468 
469 
470 
471 
472 
473 
474 
475 
476 
477 
478 
479 
480 
481 
482 
483 	public static PAdESLTVSignature sign (DeviceManager[] managers, String[] alias, IDocument pdfDocument, 
484 			String digitalSignatureAlgorithm, URL urlTimestamp, String userTSA, String passwordTSA, 
485 			CAList caList, String reason, boolean isVisible, byte[] image, float llX, float llY, 
486 			float urX, float urY, int page) throws AliasNotFoundException, LoadingObjectException, PDFDocumentException, SignatureException, RetrieveOCSPException, HashingException, CertificateCANotFoundException, InvalidCertificateException, NormalizeCertificateException, AlgorithmNotSuitableException {
487 		
488 		logger.debug("[PAdESLTVSignature.sign]::Entrada::" + Arrays.asList (new Object [] { managers, alias, pdfDocument, digitalSignatureAlgorithm, urlTimestamp, userTSA, passwordTSA, caList, reason, new Boolean (isVisible), image, new Float (llX), new Float (llY), new Float (urX), new Float (urY), new Integer (page) }));
489 		
490 		FileOutputStream fos = null;
491 		try {
492 		
493 			
494 			if (reason == null) {
495 				reason = DEFAULT_SIGNATURE_REASON;
496 			}
497 			
498 			
499 			if (digitalSignatureAlgorithm == null) {
500 				digitalSignatureAlgorithm = DigitalSignatureAlgorithm.getDefault();
501 			}
502 			String hashingAlgorithm = DigitalSignatureAlgorithm.getHashingAlgorithm(digitalSignatureAlgorithm);
503 			if (hashingAlgorithm == null) {
504 				logger.info("No se puede tratar el algoritmo de firma " + digitalSignatureAlgorithm);
505 				throw new AlgorithmNotSuitableException("No se puede tratar el algoritmo de firma " + digitalSignatureAlgorithm);
506 			}
507 	
508 			
509 			TSAClient tsc = new TSAClientBouncyCastle(urlTimestamp.toString(), userTSA, passwordTSA);
510 			
511 			
512 			File fileResult1 = getFileTemp();
513 			Util.saveFile(fileResult1, pdfDocument.getInputStream());
514 			
515 			
516 			FileInputStream fis = new FileInputStream(fileResult1);
517 			PdfReader reader = new PdfReader(fis);
518 			addDocumentTimeStampDSS(reader, caList, fileResult1);
519 			reader.close();
520 			fis.close();
521 			
522 			List<String> diccionariosRecienFirmados = new ArrayList<String>();
523 			for (int i = 0; i < managers.length; i++) {
524 				
525 				
526 				PrivateKey pk = managers[i].getPrivateKey(alias[i]);
527 				if (pk == null) {
528 					logger.info("[PDFSignature.sign]::No se ha podido encontrar el alias o bien éste no contiene una clave privada");
529 					throw new AliasNotFoundException ("No se ha podido encontrar el alias o bien éste no contiene una clave privada");
530 				}
531 				
532 				
533 				X509Certificate x509Certificate = managers[i].getCertificate(alias[i]);
534 				ValidateCertificate validateCertificate = new ValidateCertificate (x509Certificate, caList);
535 				int validationResult;
536 				if ((validationResult = validateCertificate.validate()) != ValidationResult.RESULT_VALID) {
537 					logger.info("[PDFSignature.sign]::El certificado de firma no es válido: " + validationResult);
538 					throw new InvalidCertificateException ("El certificado de firma no es válido: " + validationResult, validationResult);
539 				}
540 				
541 				
542 				java.security.cert.Certificate[] chain = new java.security.cert.Certificate[] { x509Certificate, validateCertificate.getIssuerCertificate().toX509Certificate() };
543 		
544 				
545 				
546 				fis = new FileInputStream(fileResult1);
547 				reader = new PdfReader(fis);
548 				File fileResult2 = getFileTemp();
549 				fos = new FileOutputStream (fileResult2);
550 				AcroFields af = reader.getAcroFields();
551 				ArrayList names = af.getSignatureNames();
552 				PdfStamper stp;
553 				if (names == null || names.isEmpty()) {
554 					stp = PdfStamper.createSignature(reader, fos, '\0');
555 				} else {
556 					stp = PdfStamper.createSignature(reader, fos, '\0', null, true);
557 				}
558 				
559 				
560 				PdfSignatureAppearance sap = stp.getSignatureAppearance();
561 				sap.setCrypto(null, chain, null, PdfSignatureAppearance.SELF_SIGNED);
562 				sap.setReason(reason);
563 				if (isVisible) {
564 					sap.setVisibleSignature(new Rectangle(llX, llY, urX, urY), page, null);
565 					StringBuffer detail = new StringBuffer();
566 					detail.append(DIGITALLY_SIGNED_TEXT + ": " + validateCertificate.getCommonName() + "\n");
567 					SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm");
568 					detail.append("Fecha: " + sdf.format(new Date()) + "\n");
569 					if (reason != null && !reason.equals("")) {
570 						detail.append("Motivo: " + reason + "\n");
571 					}
572 					sap.setLayer2Text(detail.toString());
573 					if (image != null) {
574 						sap.setImage(Image.getInstance(image));
575 					}
576 				}
577 		
578 				
579 				PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached"));
580 				dic.setReason(sap.getReason());
581 				dic.setLocation(sap.getLocation());
582 				dic.setContact(sap.getContact());
583 				dic.setDate(new PdfDate(sap.getSignDate()));
584 				sap.setCryptoDictionary(dic);
585 				sap.setExternalDigest(new byte[128], null, "RSA"); 
586 		
587 				int contentEstimated = 15000;
588 				HashMap exc = new HashMap();
589 				exc.put(PdfName.CONTENTS, new Integer(contentEstimated * 2 + 2));
590 				sap.preClose(exc);
591 		
592 				
593 				Calendar cal = Calendar.getInstance();
594 				PdfPKCS7 pkcs7 = new PdfPKCS7(null, chain, null, hashingAlgorithm, CRYPTOGRAPHIC_PROVIDER_NAME, false);
595 				byte hash[] = new InputStreamDocument (sap.getRangeStream()).getHash(hashingAlgorithm);
596 				byte sh[] = pkcs7.getAuthenticatedAttributeBytes(hash, cal, null);
597 				byte[] signatureBytes = managers[i].signDocument(new ByteArrayInputStream (sh), alias[i], digitalSignatureAlgorithm);
598 				pkcs7.setExternalDigest(signatureBytes, sh, "RSA"); 
599 				byte[] encodedSig = pkcs7.getEncodedPKCS7(hash, cal, tsc, hashingAlgorithm, null);
600 				
601 				
602 				if (contentEstimated + 2 < encodedSig.length) {
603 					logger.info("[PDFSignature.sign]::No se puede añadir la firma al PDF por falta de espacio en el mismo");
604 					throw new SignatureException ("No se puede añadir la firma al PDF por falta de espacio en el mismo");
605 				}
606 		
607 				byte[] paddedSig = new byte[contentEstimated];
608 				System.arraycopy(encodedSig, 0, paddedSig, 0, encodedSig.length);
609 		
610 				PdfDictionary dic2 = new PdfDictionary();
611 				dic2.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true));
612 				sap.close(dic2);
613 				
614 				fis.close();
615 	            reader.close();
616 	            fos.close();
617 	            fos = null;
618 	            
619 	            fileResult1.delete();
620 	            fileResult1 = fileResult2;
621 	            
622 	            diccionariosRecienFirmados.add(sap.getFieldName());
623 	            
624 			}
625 
626 			
627 			reader = null;
628 			fis = null;
629 			try {
630 				fis = new FileInputStream(fileResult1);
631 				reader = new PdfReader(fis);
632 				return PAdESLTVSignature.completeToPAdESLTV(reader, urlTimestamp, userTSA, passwordTSA, hashingAlgorithm, caList, diccionariosRecienFirmados);
633 			} catch (PDFDocumentException e) {
634 				
635 				return null;
636 			} finally {
637 				if (fis != null) { fis.close(); }
638 				if (reader != null) { reader.close(); }
639 				fileResult1.delete();
640 			}
641 			
642 		} catch (LoadingObjectException e) {
643 			logger.info("[PAdESLTVSignature.sign]::No se ha podido obtener la clave privada para firma", e);
644 			throw new LoadingObjectException ("No se ha podido obtener la clave privada para firma", e);
645 		} catch (SearchingException e) {
646 			logger.info("[PAdESLTVSignature.sign]::No se ha podido encontrar la clave privada para firma", e);
647 			throw new LoadingObjectException ("No se ha podido encontrar la clave privada para firma", e);
648 		} catch (IOException e) {
649 			logger.info("[PAdESLTVSignature.sign]::No se ha podido leer el fichero PDF o no se ha podido crear el fichero temporal con la firma", e);
650 			throw new PDFDocumentException ("No se ha podido leer el fichero PDF o no se ha podido crear el fichero temporal con la firma", e);
651 		} catch (DocumentException e) {
652 			logger.info("[PAdESLTVSignature.sign]::No se ha podido manejar alguna de las partes del fichero PDF", e);
653 			throw new PDFDocumentException ("No se ha podido manejar alguna de las partes del fichero PDF", e);
654 		} catch (InvalidKeyException e) {
655 			logger.info("[PAdESLTVSignature.sign]::La clave privada no es válida para realizar la firma", e);
656 			throw new SignatureException ("La clave privada no es válida para realizar la firma", e);
657 		} catch (NoSuchProviderException e) {
658 			logger.info("[PAdESLTVSignature.sign]::No se ha podido obtener el proveedor criptográfico", e);
659 			return null;
660 		} catch (NoSuchAlgorithmException e) {
661 			logger.info("[PAdESLTVSignature.sign]::No existen en el proveedor criptográfico los algoritmos de firma (SHA1WithRSA)", e);
662 			throw new SignatureException ("No existen en el proveedor criptográfico los algoritmos de firma (SHA1WithRSA)", e);
663 		} catch (CertificateCANotFoundException e) {
664 			logger.info("[PAdESLTVSignature.sign]::La lista de certificado de CA no contiene el emisor del certificado de firma", e);
665 			throw new CertificateCANotFoundException ("La lista de certificado de CA no contiene el emisor del certificado de firma", e);
666 		} 
667 
668 	}
669 	
670 	
671 
672 
673 
674 
675 
676 
677 
678 
679 
680 
681 
682 
683 
684 
685 
686 
687 
688 
689 
690 
691 	public static PAdESLTVSignature completeToPAdESLTV (PDFSignature signature, URL urlTimestamp, CAList caList) throws SignatureException, 
692 		RetrieveOCSPException, InvalidCertificateException, NormalizeCertificateException, PDFDocumentException, CertificateCANotFoundException, 
693 		HashingException {
694 		
695 		return PAdESLTVSignature.completeToPAdESLTV(signature, urlTimestamp, null, caList);
696 		
697 	}
698 
699 	
700 
701 
702 
703 
704 
705 
706 
707 
708 
709 
710 
711 
712 
713 
714 
715 
716 
717 
718 
719 
720 
721 	public static PAdESLTVSignature completeToPAdESLTV (PDFSignature signature, URL urlTimestamp, String tsaHashingAlgorithm, CAList caList) throws SignatureException, 
722 		RetrieveOCSPException, InvalidCertificateException, NormalizeCertificateException, PDFDocumentException, CertificateCANotFoundException, 
723 		HashingException {
724 		
725 		return PAdESLTVSignature.completeToPAdESLTV(signature, urlTimestamp, null, null, caList);
726 		
727 	}
728 
729 	
730 
731 
732 
733 
734 
735 
736 
737 
738 
739 
740 
741 
742 
743 
744 
745 
746 
747 
748 
749 
750 
751 
752 
753 
754 
755 	public static PAdESLTVSignature completeToPAdESLTV (PDFSignature signature, URL urlTimestamp, 
756 			String userTSA, String passwordTSA, CAList caList) throws SignatureException, RetrieveOCSPException, InvalidCertificateException, 
757 			PDFDocumentException, CertificateCANotFoundException, HashingException, NormalizeCertificateException {
758 		return completeToPAdESLTV(signature, urlTimestamp, userTSA, passwordTSA, null, caList);
759 	}
760 	
761 	
762 
763 
764 
765 
766 
767 
768 
769 
770 
771 
772 
773 
774 
775 
776 
777 
778 
779 
780 
781 
782 
783 
784 
785 
786 
787 
788 	public static PAdESLTVSignature completeToPAdESLTV (PDFSignature signature, URL urlTimestamp, 
789 			String userTSA, String passwordTSA, String tsaHashingAlgorithm, CAList caList) throws SignatureException, RetrieveOCSPException, InvalidCertificateException, 
790 			PDFDocumentException, CertificateCANotFoundException, HashingException, NormalizeCertificateException {
791 		logger.debug ("[PAdESLTVSignature.completeToPAdESLTV]::Entrada::" + signature);
792 		
793 		FileInputStream fis = null;
794 		PdfReader reader = null;
795 		File fileResult = null;
796 		try {
797 			
798 			fileResult = getFileTemp();
799 			signature.save(fileResult);
800 			fis = new FileInputStream(fileResult);
801 			reader = new PdfReader(fis);
802 			
803 			return completeToPAdESLTV(reader, urlTimestamp, userTSA, passwordTSA, tsaHashingAlgorithm, caList, null);
804 			
805 		} catch (IOException e) {
806 			logger.info("[PAdESLTVSignature.completeToPAdESLTV]::No se ha podido leer el fichero PDF o no se ha podido crear el fichero temporal con la firma", e);
807 			throw new PDFDocumentException ("No se ha podido leer el fichero PDF o no se ha podido crear el fichero temporal con la firma", e);
808 		} finally {
809 			if (fis != null) { try { fis.close(); } catch (IOException e) { } }
810 			if (reader != null) { reader.close(); }
811 			if (fileResult != null) { fileResult.delete(); }
812 		}
813 		
814 	}
815 	
816 	
817 	
818 	
819 
820 
821 	public ValidationResult[] isValid(CAList caList) throws HashingException, SignatureException, NormalizeCertificateException {
822 		
823 		logger.debug("[PAdESLTVSignature.isValid]::Entrada::" + caList);
824 		
825 		return isValidCommon(caList, null);
826 		
827 	}
828 	
829 	
830 
831 
832 
833 
834 	public ValidationResult[] isValid(IDocument document, CAList caList)
835 			throws HashingException, SignatureException,
836 			NormalizeCertificateException {
837 		return isValid (caList);
838 	}
839 	
840 	
841 
842 
843 	public ValidationResult[] isValid(List<CertificateValidationService> validationServices)
844 			throws HashingException, SignatureException, NormalizeCertificateException {
845 		
846 		logger.debug("[PAdESLTVSignature.isValid]::Entrada::" + validationServices);
847 		
848 		return isValidCommon(null, validationServices);
849 		
850 	}
851 
852 	
853 
854 
855 
856 
857 	public ValidationResult[] isValid(IDocument document, List<CertificateValidationService> validationServices)
858 			throws HashingException, SignatureException, NormalizeCertificateException {
859 		return isValid(validationServices);
860 	}
861 
862 	
863 
864 
865 
866 
867 	public String getSignatureType () {
868 		return "PAdES-LTV";
869 	}
870 	
871 	
872 
873 
874 
875 
876 
877 
878 
879 	public Date getTimeStampCertificateExpiration() throws SignatureException {
880 		logger.debug("[PAdESLTVSignature.getTimeStampCertificateExpiration]::Entrada");
881 		
882 		PdfReader reader;
883 		try {
884 			reader = new PdfReader(this.pdfFile.getAbsolutePath());
885 		} catch (IOException e) {
886 			
887 			logger.info("[PAdESLTVSignature.getTimeStampCertificateExpiration]::No se puede leer el contenido de este objeto", e);
888 			return null;
889 		}
890 		AcroFields af = reader.getAcroFields();
891 		ArrayList<String> tempNames = af.getSignatureNames();
892 		ArrayList<String> names = new ArrayList<String>();
893 		
894 		
895 		for (Iterator iterator = tempNames.iterator(); iterator.hasNext();) {
896 			String name = (String) iterator.next();
897 			if (af.getSignatureDictionary(name).get(PdfName.SUBFILTER) != null &&
898 					af.getSignatureDictionary(name).get(PdfName.SUBFILTER).equals(new PdfName("ETSI.RFC3161"))) {
899 				
900 				TimeStamp ts;
901 				try {
902 					ts = new TimeStamp (af.getSignatureDictionary(name).getAsString(PdfName.CONTENTS).getOriginalBytes());
903 					logger.debug("[PAdESLTVSignature.getTimeStampCertificateExpiration]::Devolviendo: " + ts.getSignatureCertificate().getValidityPeriodEnd());
904 					return ts.getSignatureCertificate().getValidityPeriodEnd();
905 				} catch (MalformedTimeStampException e) {
906 					logger.info("[PAdESLTVSignature.getTimeStampCertificateExpiration]::El sello de tiempos del documento no es correcto", e);
907 					throw new SignatureException ("El sello de tiempos del documento no es correcto", e);
908 				}
909 
910 			} else {
911 				names.add(name);
912 			}
913 		}
914 		
915 		
916 		logger.info("[PAdESLTVSignature.getTimeStampCertificateExpiration]::No hay sello de tiempos del documento");
917 		throw new SignatureException ("No hay sello de tiempos del documento");
918 		
919 	}
920 
921 	
922 
923 
924 
925 
926 
927 
928 
929 
930 
931 
932 
933 
934 
935 
936 	public void addDocumentTimeStamp (URL urlTSA, CAList caList, String hashingAlgorithm) throws SignatureException, RetrieveOCSPException, ResponseTimeStampException, CertificateCANotFoundException {
937 		addDocumentTimeStamp(urlTSA, null, null, caList, hashingAlgorithm);
938 	}
939 	
940 	
941 
942 
943 
944 
945 
946 
947 
948 
949 
950 
951 
952 
953 
954 	public void addDocumentTimeStamp (URL urlTSA, CAList caList) throws SignatureException, RetrieveOCSPException, ResponseTimeStampException, CertificateCANotFoundException {
955 		addDocumentTimeStamp(urlTSA, null, null, caList);
956 	}
957 	
958 	
959 
960 
961 
962 
963 
964 
965 
966 
967 
968 
969 
970 
971 
972 
973 
974 
975 
976 
977 	public void addDocumentTimeStamp (URL urlTSA, String userTSA, String passwordTSA, CAList caList) throws SignatureException, RetrieveOCSPException, ResponseTimeStampException, CertificateCANotFoundException {
978 		addDocumentTimeStamp(urlTSA, userTSA, passwordTSA, caList, HashingAlgorithm.getDefault());
979 	}
980 	
981 	
982 
983 
984 
985 
986 
987 
988 
989 
990 
991 
992 
993 
994 
995 
996 
997 
998 
999 
1000 
1001 	public void addDocumentTimeStamp (URL urlTSA, String userTSA, String passwordTSA, CAList caList, String hashingAlgorithm) throws SignatureException, RetrieveOCSPException, ResponseTimeStampException, CertificateCANotFoundException {
1002 		logger.debug("[PAdESLTVSignature.addDocumentTimeStamp]::Entrada::"+ Arrays.asList(new Object[] { urlTSA, userTSA, passwordTSA, caList, hashingAlgorithm } ));
1003 		
1004 		FileOutputStream fos = null;
1005 		try {
1006 		
1007 			
1008 			File fileResult = getFileTemp();
1009 			
1010     		PdfReader reader;
1011     		try {
1012     			reader = new PdfReader(this.pdfFile.getAbsolutePath());
1013     		} catch (IOException e) {
1014     			
1015     			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::No se puede leer el contenido de este objeto", e);
1016     			return;
1017     		}
1018     		
1019     		
1020     		addDocumentTimeStampDSS(reader, caList, fileResult);
1021     
1022 			
1023 			File fileResult2 = getFileTemp();
1024 			addDocumentTimeStamp(fileResult, fileResult2, urlTSA, hashingAlgorithm, userTSA, passwordTSA);
1025 			fileResult.delete();
1026 			this.pdfFile.delete();
1027 			initialize(fileResult2);
1028 			
1029 		} catch (DocumentException e) {
1030 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::No se ha podido manejar alguna de las partes del fichero PDF", e);
1031 			throw new SignatureException ("No se ha podido manejar alguna de las partes del fichero PDF", e);
1032 		} catch (ResponseTimeStampException e) {
1033 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::El servidos de sello de tiempos devuelve un error en la respuesta", e);
1034 			throw e;
1035 		} catch (TimeStampServerConnectionException e) {
1036 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::No ha sido posible conectarse al servidor de sello de tiempos", e);
1037 			throw new ResponseTimeStampException ("No ha sido posible conectarse al servidor de sello de tiempos", e);
1038 		} catch (MalformedTimeStampException e) {
1039 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::El sello de tiempos obtenido no está bien formado", e);
1040 			throw new ResponseTimeStampException ("El sello de tiempos obtenido no está bien formado", e);
1041 		} catch (CertificateCANotFoundException e) {
1042 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::El certificado del último sello de tiempos de documento no pertenece a ninguna de las CAs de confianza", e);
1043 			throw e;
1044 		} catch (NormalizeCertificateException e) {
1045 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::El certificado del último sello de tiempos de documento no puede ser normalizado", e);
1046 			throw new SignatureException ("El certificado del último sello de tiempos de documento no puede ser normalizado", e);
1047 		} catch (RetrieveOCSPException e) {
1048 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::No se puede obtener la respuesta OCSP", e);
1049 			throw e;
1050 		} catch (InvalidCertificateException e) {
1051 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::El certificado del último sello de tiempos de documento no es válido", e);
1052 			throw new SignatureException ("El certificado del último sello de tiempos de documento no es válido", e);
1053 		} catch (IOException e) {
1054 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::Error de entrada/salida tratando el PDF", e);
1055 			throw new SignatureException ("Error de entrada/salida tratando el PDF", e);
1056 		} catch (HashingException e) {
1057 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::Error obteniendo el hash para sellar", e);
1058 			throw new SignatureException ("Error obteniendo el hash para sellar", e);
1059 		} catch (PDFDocumentException e) {
1060 			
1061 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::El PDF tras el resellado no puede ser abierto", e);
1062 			throw new SignatureException ("El PDF tras el resellado no puede ser abierto", e);
1063 		} catch (SignatureNotFoundException e) {
1064 			
1065 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::El PDF tras el resellado no presenta firma", e);
1066 			throw new SignatureException ("El PDF tras el resellado no presenta firma", e);
1067 		} catch (NoSuchAlgorithmException e) {
1068 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::No existe el algoritmo de hash con el que se quiere realizar el sellado de tiempos", e);
1069 			throw new SignatureException ("No existe el algoritmo de hash con el que se quiere realizar el sellado de tiempos", e);
1070 		} 
1071 		
1072 	}
1073 	
1074 	
1075 
1076 
1077 
1078 
1079 
1080 
1081 
1082 	public TimeStampDictionary[] getOrderedDocumentTimestamp () throws SignatureException {
1083 		PdfReader reader;
1084 		try {
1085 			reader = new PdfReader(this.pdfFile.getAbsolutePath());
1086 		} catch (IOException e) {
1087 			
1088 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::No se puede leer el contenido de este objeto", e);
1089 			throw new SignatureException ("No se puede leer el contenido de este objeto");
1090 		}
1091 		
1092 		return PAdESLTVSignature.getOrderedDocumentTimestamp(reader);
1093 	}
1094 	
1095 	public static boolean isOnlyOCSPResponsesInDSS() {
1096 		return onlyOCSPResponsesInDSS;
1097 	}
1098 
1099 	public static void setOnlyOCSPResponsesInDSS(boolean onlyOCSPResponsesInDSS) {
1100 		PAdESLTVSignature.onlyOCSPResponsesInDSS = onlyOCSPResponsesInDSS;
1101 	}
1102 
1103 	
1104 	
1105 	private void initialize (File pdfFile) throws PDFDocumentException, SignatureNotFoundException {
1106 		logger.debug("[PAdESLTVSignature.initialize]::Entrada::" + pdfFile);
1107 		
1108 		
1109 		try {
1110 			PdfReader reader = new PdfReader(pdfFile.getAbsolutePath());
1111 			AcroFields af = reader.getAcroFields();
1112 			ArrayList names = af.getSignatureNames();
1113 			if (names == null || names.isEmpty()) {
1114 				logger.info("[PAdESLTVSignature.initialize]::El documento PDF no está firmado");
1115 				pdfFile.delete(); 
1116 				throw new SignatureNotFoundException ("El documento PDF no está firmado");
1117 			}
1118 			if (names.size() == 1) {
1119 				logger.info("[PAdESLTVSignature.initialize]::El documento PDF no es PAdES-LTV: sólo hay una firma y debería haber firma y sello de tiempos");
1120 				pdfFile.delete(); 
1121 				throw new SignatureNotFoundException ("El documento PDF no es PAdES-LTV: sólo hay una firma y debería haber firma y sello de tiempos");
1122 			}
1123 			
1124 			
1125 			if (reader.getCatalog().get(new PdfName("DSS")) == null) {
1126 				logger.info("[PAdESLTVSignature.initialize]::El documento PDF no es PAdES-LTV: no contiene un diccionario Document Security Store (DSS)");
1127 				pdfFile.delete(); 
1128 				throw new SignatureNotFoundException ("El documento PDF no es PAdES-LTV: no contiene un diccionario Document Security Store (DSS)");
1129 			}
1130 			
1131 			
1132 			boolean encontrado = false;
1133 			for (Iterator iterator = names.iterator(); iterator.hasNext();) {
1134 				String name = (String) iterator.next();
1135 				if (af.getSignatureDictionary(name) != null && af.getSignatureDictionary(name).get(PdfName.SUBFILTER) != null &&
1136 						af.getSignatureDictionary(name).get(PdfName.SUBFILTER).equals(new PdfName("ETSI.RFC3161"))) {
1137 					encontrado = true;
1138 					break;
1139 				}
1140 			}
1141 			if (!encontrado) {
1142 				logger.info("[PAdESLTVSignature.initialize]::El documento PDF no es PAdES-LTV: no contiene un sello de tiempos para todo el documento)");
1143 				pdfFile.delete(); 
1144 				throw new SignatureNotFoundException ("El documento PDF no es PAdES-LTV: no contiene un sello de tiempos para todo el documento)");
1145 			}
1146 			
1147 		} catch (IOException e) {
1148 			logger.info("[PAdESLTVSignature.initialize]::No se ha podido leer el fichero PDF", e);
1149 			pdfFile.delete(); 
1150 			throw new PDFDocumentException ("No se ha podido leer el fichero PDF", e);
1151 		} 
1152 		
1153 		
1154 		this.pdfFile = pdfFile;
1155 
1156 	}
1157 
1158 	
1159 
1160 
1161 	private static void addDocumentTimeStamp (File sourcePdf, File destPdf, URL urlTimestamp, String hashingAlgorithm,
1162 			String userTSA, String passwordTSA) throws FileNotFoundException, IOException, DocumentException, MalformedTimeStampException, HashingException, ResponseTimeStampException, TimeStampServerConnectionException, NoSuchAlgorithmException {
1163 		
1164 		if (hashingAlgorithm == null) {
1165 			hashingAlgorithm = HashingAlgorithm.getDefault();
1166 		}
1167 		
1168 		FileInputStream fis = null;
1169 		PdfReader reader = null;
1170         FileOutputStream fos = null;
1171         try {
1172         	fis = new FileInputStream(sourcePdf);
1173         	reader = new PdfReader(fis);
1174     		AcroFields af = reader.getAcroFields();
1175     		ArrayList names = af.getSignatureNames();
1176 	        fos = new FileOutputStream (destPdf);
1177 	        PdfStamper stp;
1178 			if (names == null || names.isEmpty()) {
1179 				stp = PdfStamper.createSignature(reader, fos, '\0');
1180 			} else {
1181 				stp = PdfStamper.createSignature(reader, fos, '\0', null, true);
1182 			}
1183 	        PdfSignatureAppearance sap = stp.getSignatureAppearance();
1184 	
1185 	        PdfSignature timeStampSignature = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("ETSI.RFC3161"));
1186 	        timeStampSignature.put(PdfName.TYPE, new PdfName("DocTimeStamp"));
1187 	        sap.setCryptoDictionary(timeStampSignature);
1188 	
1189 	        int csize = 15000;
1190 	        HashMap<PdfName,Integer> exc = new HashMap<PdfName,Integer>();
1191 	        exc.put(PdfName.CONTENTS, new Integer(csize * 2 + 2));
1192 	        sap.preClose(exc);
1193 	
1194 	        TimeStampRequestParameters tsParameters = new TimeStampRequestParameters();
1195 	        tsParameters.setUser(userTSA);
1196 	        tsParameters.setPassword(passwordTSA);
1197 	        TimeStamp ts = TimeStamp.stampDocument(Util.readStream(sap.getRangeStream()), urlTimestamp, hashingAlgorithm, tsParameters);
1198 	        byte[] timestampToken = ts.toDER();
1199 	
1200 	        byte[] outc = new byte[csize];
1201 	        PdfDictionary dic = new PdfDictionary();
1202 	        System.arraycopy(timestampToken, 0, outc, 0, timestampToken.length);
1203 	        dic.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true));
1204 	        sap.close(dic);
1205         } finally {
1206         	if (fis != null) { fis.close(); }
1207         	if (reader != null) { reader.close(); }
1208         	if (fos != null) { fos.close(); }
1209         }
1210 
1211 	}
1212 	
1213 	
1214 
1215 
1216 	private static OCSPResponse getOcspBasicResponse(ValidateCertificate validateCertificate) throws RetrieveOCSPException, InvalidCertificateException, IOException {
1217 		OCSPClient[] ocspClient = validateCertificate.getOCSPClients();
1218 		OCSPResponse ocspResponse = null;
1219 		for (int i = 0; i < ocspClient.length; i++) {
1220 			try {
1221 				ocspResponse = ocspClient[i].getOCSPResponse(validateCertificate);
1222 				logger.debug ("[PAdESLTVSignature.sign]::Encontrada respuesta OCSP en " + ocspClient[i].getURL());
1223 			} catch (Exception e) {
1224 				
1225 				logger.debug ("[PAdESLTVSignature.sign]::Excepción buscando respuesta OCSP en " + ocspClient[i].getURL(), e);
1226 			}
1227 		}
1228 		if (ocspResponse == null) {
1229 			logger.info("[PAdESLTVSignature.sign]::No se puede obtener una respuesta de un servidor OCSP para validar el certificado de firma");
1230 			throw new RetrieveOCSPException ("No se puede obtener una respuesta de un servidor OCSP para validar el certificado de firma");
1231 		}
1232 		if (ocspResponse.getStatus() != ValidationResult.RESULT_VALID) {
1233 			logger.info("[PAdESLTVSignature.sign]::Según la respuesta OCSP el certificado de firma no es válido::" + CertificateValidator.getString(ocspResponse.getStatus()));
1234 			throw new InvalidCertificateException ("Según la respuesta OCSP el certificado de firma no es válido: " + CertificateValidator.getString(ocspResponse.getStatus()), ocspResponse.getStatus());
1235 		}
1236 
1237 		return ocspResponse;
1238 	}
1239 
1240 	
1241 
1242 
1243 
1244 
1245 
1246 
1247 
1248 
1249 
1250 
1251 
1252 
1253 
1254 
1255 
1256 
1257 
1258 
1259 
1260 
1261 
1262 
1263 
1264 
1265 
1266 	private static PAdESLTVSignature completeToPAdESLTV (PdfReader reader, URL urlTimestamp, 
1267 			String userTSA, String passwordTSA, String hashingAlgorithm, CAList caList, List<String> diccionariosRecienFirmados) throws SignatureException, RetrieveOCSPException, InvalidCertificateException, 
1268 			PDFDocumentException, CertificateCANotFoundException, HashingException, NormalizeCertificateException {
1269 		logger.debug ("[PAdESLTVSignature.completeToPAdESLTV]::Entrada");
1270 		
1271 		try {
1272 		
1273 			
1274     		PdfDocumentSecurityStore dss = new PdfDocumentSecurityStore();
1275     		
1276     		
1277     		
1278     		if (hashingAlgorithm == null) {
1279     			hashingAlgorithm = HashingAlgorithm.getDefault();
1280     		}
1281 			
1282 			
1283 			
1284 			AcroFields af = reader.getAcroFields();
1285 			ArrayList<String> names = getRealSignatureNames(af);
1286 			for (Iterator<String> iterator = names.iterator(); iterator.hasNext();) {
1287 				String name = iterator.next();
1288 				
1289 				if (diccionariosRecienFirmados != null && !diccionariosRecienFirmados.contains(name)) {
1290 					continue;
1291 				}
1292             
1293 				
1294 				PdfPKCS7 pkcs7 = af.verifySignature(name, CRYPTOGRAPHIC_PROVIDER_NAME);
1295 				boolean valido;
1296 				try {
1297 					valido = pkcs7.verify();
1298 				} catch (java.security.SignatureException e) {
1299 					logger.info("[PAdESLTVSignature.completeToPAdESLTV]::Error en una de las firmas del PDF", e);
1300 					throw new SignatureException ("Error en una de las firmas del PDF", e);
1301 				}
1302 				if (!valido) {
1303 					logger.info("[PAdESLTVSignature.completeToPAdESLTV]::Una de las firmas del PDF no es correcta");
1304 					throw new SignatureException ("Una de las firmas del PDF no es correcta");
1305 				}
1306 				
1307 				if (HashingAlgorithm.isGreater(pkcs7.getHashAlgorithm(), hashingAlgorithm)) {
1308 					try {
1309 						hashingAlgorithm = HashingAlgorithm.getAlgorithmFromExternalName(pkcs7.getHashAlgorithm());
1310 					} catch (NoSuchAlgorithmException e) {
1311 						logger.info("No se puede hacer el sello para el algoritmo de hash: " + pkcs7.getHashAlgorithm()) ;
1312 					}
1313 				}
1314 				
1315 				
1316 				
1317 				Certificate signingCertificate = getSigningCertificate(pkcs7.getCertificates());
1318 				if (signingCertificate != null) {
1319 					
1320 					ValidateCertificate certificate = new ValidateCertificate (signingCertificate.toDER(), caList);
1321 					
1322 					
1323 					ValidateCertificate certificateTimestamp = null;
1324 					List<List<ValidateCertificate>> cadenaTimestamp = null;
1325 					if (pkcs7.getTimeStampToken() != null) {
1326 						TimeStamp ts = new TimeStamp (pkcs7.getTimeStampToken().getEncoded());
1327 						certificateTimestamp = new ValidateCertificate (ts.getSignatureCertificate().toX509Certificate(), caList);
1328 						cadenaTimestamp = certificateTimestamp.getCertificationChainSeveralIssuers();
1329 					}
1330 					
1331 					
1332 			        TimeStampRequestParameters tsParameters = new TimeStampRequestParameters();
1333 			        tsParameters.setUser(userTSA);
1334 			        tsParameters.setPassword(passwordTSA);
1335 			        TimeStamp ts = TimeStamp.stampDocument("a sellar".getBytes(), urlTimestamp, hashingAlgorithm, tsParameters);
1336 					ValidateCertificate certificateArchiveTimestamp = new ValidateCertificate (ts.getSignatureCertificate().toX509Certificate(), caList);
1337 					List<List<ValidateCertificate>> cadenaArchiveTimestamp = certificateArchiveTimestamp.getCertificationChainSeveralIssuers();
1338 					
1339 		            
1340 					List<List<ValidateCertificate>> cadenaCertificate = certificate.getCertificationChainSeveralIssuers();
1341 					List<List<ValidateCertificate>> certificadosDSS = juntarListasDSS (certificate, certificateTimestamp, 
1342 							certificateArchiveTimestamp, cadenaCertificate, cadenaTimestamp, cadenaArchiveTimestamp);
1343 					
1344 					cargarDSS(certificadosDSS, dss, caList);
1345 				}
1346 				
1347 			}
1348 			
1349 			
1350 			FileOutputStream fos = null;
1351 			File fileResult = getFileTemp();
1352 			try {
1353 	            fos = new FileOutputStream (fileResult);
1354 	            PdfStamper stamper = new PdfStamper(reader, fos, '\0', true);
1355 				stamper.addDocumentSecurityStore(dss);
1356 				stamper.close();
1357 			} finally {
1358 				if (fos != null) {
1359 					fos.close();
1360 				}
1361 			}
1362 			
1363 			
1364 			File fileResult2 = getFileTemp();
1365 			addDocumentTimeStamp(fileResult, fileResult2, urlTimestamp, hashingAlgorithm, userTSA, passwordTSA);
1366 			fileResult.delete();
1367 			try {
1368 				return new PAdESLTVSignature (fileResult2);
1369 			} catch (SignatureNotFoundException e) {
1370 				
1371 				return null;
1372 			} catch (PDFDocumentException e) {
1373 				
1374 				return null;
1375 			}
1376 			
1377 		} catch (IOException e) {
1378 			logger.info("[PAdESLTVSignature.completeToPAdESLTV]::No se ha podido leer el fichero PDF o no se ha podido crear el fichero temporal con la firma", e);
1379 			throw new PDFDocumentException ("No se ha podido leer el fichero PDF o no se ha podido crear el fichero temporal con la firma", e);
1380 		} catch (CertificateCANotFoundException e) {
1381 			logger.info("[PAdESLTVSignature.completeToPAdESLTV]::La lista de certificado de CA no contiene el emisor del certificado de firma", e);
1382 			throw new CertificateCANotFoundException ("La lista de certificado de CA no contiene el emisor del certificado de firma", e);
1383 		} catch (MalformedTimeStampException e) {
1384 			logger.info("[PAdESLTVSignature.sign]::El sello de tiempos obtenido no está bien formado", e);
1385 			throw new SignatureException ("El sello de tiempos obtenido no está bien formado", e);
1386 		} catch (ResponseTimeStampException e) {
1387 			logger.info("[PAdESLTVSignature.sign]::El servidos de sello de tiempos devuelve un error en la respuesta", e);
1388 			throw new SignatureException ("El servidos de sello de tiempos devuelve un error en la respuesta", e);
1389 		} catch (DocumentException e) {
1390 			logger.info("[PAdESLTVSignature.completeToPAdESLTV]::No se ha podido manejar alguna de las partes del fichero PDF", e);
1391 			throw new PDFDocumentException ("No se ha podido manejar alguna de las partes del fichero PDF", e);
1392 		} catch (TimeStampServerConnectionException e) {
1393 			logger.info("[PAdESLTVSignature.sign]::No ha sido posible conectarse al servidor de sello de tiempos", e);
1394 			throw new SignatureException ("No ha sido posible conectarse al servidor de sello de tiempos", e);
1395 		} catch (NoSuchAlgorithmException e) {
1396 			logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::No existe el algoritmo de hash con el que se quiere realizar el sellado de tiempos", e);
1397 			throw new SignatureException ("No existe el algoritmo de hash con el que se quiere realizar el sellado de tiempos", e);
1398 		} 
1399 		
1400 	}
1401 	
1402 	
1403 
1404 
1405     private static List<List<ValidateCertificate>> juntarListasDSS(ValidateCertificate certificate,
1406 			ValidateCertificate certificateTimestamp, ValidateCertificate certificateArchiveTimestamp, 
1407 			List<List<ValidateCertificate>> cadenaCertificate, List<List<ValidateCertificate>> cadenaTimestamp,
1408 			List<List<ValidateCertificate>> cadenaArchiveTimestamp) {
1409 		
1410     	HashSet<String> setHuellas = new HashSet<String>();
1411     	List<List<ValidateCertificate>> certificates = new ArrayList<List<ValidateCertificate>>();
1412     	
1413     	if (certificate != null) {
1414     		List<ValidateCertificate> lista = new ArrayList<ValidateCertificate>();
1415     		lista.add(certificate);
1416 	    	certificates.add(lista);
1417 	    	setHuellas.add(certificate.getFingerPrint());
1418     	}
1419     	
1420     	if (certificateTimestamp != null && !setHuellas.contains(certificateTimestamp.getFingerPrint())) {
1421     		List<ValidateCertificate> lista = new ArrayList<ValidateCertificate>();
1422     		lista.add(certificateTimestamp);
1423 	    	certificates.add(lista);
1424         	setHuellas.add(certificateTimestamp.getFingerPrint());
1425     	}
1426     	
1427     	if (certificateArchiveTimestamp != null && !setHuellas.contains(certificateArchiveTimestamp.getFingerPrint())) {
1428     		List<ValidateCertificate> lista = new ArrayList<ValidateCertificate>();
1429     		lista.add(certificateArchiveTimestamp);
1430 	    	certificates.add(lista);
1431         	setHuellas.add(certificateArchiveTimestamp.getFingerPrint());
1432     	}
1433     	
1434     	if (cadenaCertificate != null) {
1435 	    	for (List<ValidateCertificate> lista : cadenaCertificate) {
1436 	    		boolean encontrados = true;
1437 	    		for(ValidateCertificate cert : lista) {
1438 		        	if (!setHuellas.contains(cert.getFingerPrint())) {
1439 		            	encontrados = false;
1440 		            	setHuellas.add(cert.getFingerPrint());
1441 		        	}
1442 	    		}
1443 	    		if (!encontrados) {
1444 	    			certificates.add(lista);
1445 	    		}
1446 			}
1447     	}
1448     	if (cadenaTimestamp != null) {
1449 	    	for (List<ValidateCertificate> lista : cadenaTimestamp) {
1450 	    		boolean encontrados = true;
1451 	    		for(ValidateCertificate cert : lista) {
1452 		        	if (!setHuellas.contains(cert.getFingerPrint())) {
1453 		            	encontrados = false;
1454 		            	setHuellas.add(cert.getFingerPrint());
1455 		        	}
1456 	    		}
1457 	    		if (!encontrados) {
1458 	    			certificates.add(lista);
1459 	    		}
1460 			}
1461     	}
1462     	if (cadenaArchiveTimestamp != null) {
1463 	    	for (List<ValidateCertificate> lista : cadenaArchiveTimestamp) {
1464 	    		boolean encontrados = true;
1465 	    		for(ValidateCertificate cert : lista) {
1466 		        	if (!setHuellas.contains(cert.getFingerPrint())) {
1467 		            	encontrados = false;
1468 		            	setHuellas.add(cert.getFingerPrint());
1469 		        	}
1470 	    		}
1471 	    		if (!encontrados) {
1472 	    			certificates.add(lista);
1473 	    		}
1474 			}
1475     	}
1476     	
1477 		return certificates;
1478 	}
1479 
1480     
1481 
1482 
1483 	private static int[] toArray(ArrayList<Integer> certIds) {
1484 		int[] result = new int [certIds.size()];
1485 		int i = 0;
1486 		for (Iterator<Integer> iterator = certIds.iterator(); iterator.hasNext();) {
1487 			result[i] = iterator.next();
1488 			i++;			
1489 		}
1490 		return result;
1491 	}
1492 
1493 	
1494 
1495 
1496 	private List<Certificate> getCertificadosDeDSS(PdfDocumentSecurityStore dss) throws NormalizeCertificateException {
1497 		ArrayList<Certificate> lCertificates = new ArrayList<Certificate>();
1498 		Set<Integer> setKeys = dss.getCertificates().keySet();
1499 		for (Integer key : setKeys) {
1500 			lCertificates.add(new Certificate(dss.getCertificates().get(key)));
1501 		}
1502 		return lCertificates;
1503 	}
1504 	
1505 	
1506 
1507 
1508 
1509 
1510 
1511 
1512 
1513 	private static TimeStampDictionary[] getOrderedDocumentTimestamp (PdfReader reader) throws SignatureException {
1514 		logger.debug("[PAdESLTVSignature.getOrderedDocumentTimestamp]::Entrada");
1515 
1516 		AcroFields af = reader.getAcroFields();
1517 		ArrayList<String> tempNames = af.getSignatureNames();
1518 		ArrayList<TimeStampDictionary> lTimeStamps = new ArrayList<TimeStampDictionary>();
1519 		for (Iterator iterator = tempNames.iterator(); iterator.hasNext();) {
1520 			String name = (String) iterator.next();
1521 			if (af.getSignatureDictionary(name).get(PdfName.SUBFILTER) != null &&
1522 					af.getSignatureDictionary(name).get(PdfName.SUBFILTER).equals(new PdfName("ETSI.RFC3161"))) {
1523 				
1524 				try {
1525 					lTimeStamps.add(new PAdESLTVSignature.TimeStampDictionary (
1526 							name,
1527 							new TimeStamp (af.getSignatureDictionary(name).getAsString(PdfName.CONTENTS).getOriginalBytes()),
1528 							af.getSignatureDictionary(name)));
1529 				} catch (MalformedTimeStampException e) {
1530 					logger.info("[PAdESLTVSignature.isValid]::El sello de tiempos del documento no es correcto", e);
1531 					throw new SignatureException ("El sello de tiempos del documento no es correcto", e);
1532 				}
1533 
1534 			} 
1535 		}
1536 		
1537 		logger.debug("[PAdESLTVSignature.getOrderedDocumentTimestamp]::Ordenando " + lTimeStamps.size() + " sellos de tiempo de documento");
1538 		Collections.sort(lTimeStamps);
1539 		
1540 		logger.debug("[PAdESLTVSignature.getOrderedDocumentTimestamp]::Devolviendo " + lTimeStamps.size() + " sellos de tiempo de documento");
1541 		return lTimeStamps.toArray(new TimeStampDictionary[0]);
1542 		
1543 	}
1544 
1545 	
1546 
1547 
1548 	private static void cargarDSS (List<List<ValidateCertificate>> certificadosDSS, PdfDocumentSecurityStore dss, CAList caList) throws NormalizeCertificateException, RetrieveOCSPException, InvalidCertificateException, IOException {
1549 		ArrayList<ValidateCertificate> selfSignedCertificates = new ArrayList<ValidateCertificate>(); 
1550 		ArrayList<ValidateCertificate> ocspCertificatesWithoutNoRevocationCheck = new ArrayList<ValidateCertificate>(); 
1551 		for (List<ValidateCertificate> lista : certificadosDSS) {
1552 			ValidateCertificate certificadoDSS = lista.get(0);
1553 			
1554 			if (certificadoDSS.isExpired()) {
1555 				throw new InvalidCertificateException ("El certificado está caducado", ValidationResult.RESULT_CERTIFICATE_NOT_ACTIVE);
1556 			}
1557 
1558 			if (!certificadoDSS.isSelfSigned()) {
1559 				dss.registerCertificate(certificadoDSS.toDER());
1560 				try {
1561 					logger.debug("Intentando cargar respuesta OCSP en DSS para el certificado " + certificadoDSS.getCommonName());
1562 					OCSPResponse ocspResponse = getOcspBasicResponse (certificadoDSS);
1563 					dss.registerOcspBasicResp(ocspResponse.getBasicOCSPResponse().getEncoded());
1564 					if (!ocspResponse.getSignatureCertificate().hasNoRevocationCheck()) {
1565 						ocspCertificatesWithoutNoRevocationCheck.add(new ValidateCertificate (ocspResponse.getSignatureCertificate().toX509Certificate(), caList));
1566 					}
1567 				} catch (Exception eOcsp) {
1568 					logger.debug("No es posible obtener una respuesta OCSP para el certificado " + certificadoDSS.getCommonName(), eOcsp);
1569 					if (PAdESLTVSignature.isOnlyOCSPResponsesInDSS() || (eOcsp instanceof InvalidCertificateException)) {
1570 						if (eOcsp instanceof RetrieveOCSPException) { throw (RetrieveOCSPException) eOcsp; }
1571 						if (eOcsp instanceof InvalidCertificateException) { throw (InvalidCertificateException) eOcsp; }
1572 						if (eOcsp instanceof IOException) { throw (IOException) eOcsp; }
1573 					}
1574 					logger.debug("Intentando cargar CRL en DSS para el certificado " + certificadoDSS.getCommonName());
1575 					try {
1576 						CRL crl = certificadoDSS.getCRL();
1577 						if (crl.isRevoked(certificadoDSS)) {
1578 							throw new InvalidCertificateException(ValidationResult.RESULT_CERTIFICATE_REVOKED);
1579 						}
1580 						dss.registerCrl(crl.toDER());
1581 					} catch (Exception e1) {
1582 						logger.debug("No es posible obtener una CRL para el certificado " + certificadoDSS.getCommonName(), e1);
1583 						if (eOcsp instanceof RetrieveOCSPException) { throw (RetrieveOCSPException) eOcsp; }
1584 						if (eOcsp instanceof InvalidCertificateException) { throw (InvalidCertificateException) eOcsp; }
1585 						if (eOcsp instanceof IOException) { throw (IOException) eOcsp; }
1586 					} 
1587 				} 
1588 				
1589 			} else {
1590 				selfSignedCertificates.add(certificadoDSS);
1591 			}
1592 		}
1593 		for (Iterator<ValidateCertificate> iterator2 = selfSignedCertificates.iterator(); iterator2.hasNext();) {
1594 			dss.registerCertificate(iterator2.next().toDER());
1595 		}
1596 		for (Iterator<ValidateCertificate> iteratorOcsp = ocspCertificatesWithoutNoRevocationCheck.iterator(); iteratorOcsp.hasNext();) {
1597 			ValidateCertificate ocspCertificate = iteratorOcsp.next();
1598 			dss.registerCertificate(ocspCertificate.toDER());
1599 			try {
1600 				logger.debug("Intentando cargar respuesta OCSP en DSS para el certificado " + ocspCertificate.getCommonName());
1601 				OCSPResponse ocspResponse = getOcspBasicResponse (ocspCertificate);
1602 				dss.registerOcspBasicResp(ocspResponse.getBasicOCSPResponse().getEncoded());
1603 			} catch (Exception eOcsp) {
1604 				logger.debug("No es posible obtener una respuesta OCSP para el certificado " + ocspCertificate.getCommonName(), eOcsp);
1605 				logger.debug("Intentando cargar CRL en DSS para el certificado " + ocspCertificate.getCommonName());
1606 				try {
1607 					dss.registerCrl(ocspCertificate.getCRL().toDER());
1608 				} catch (Exception e1) {
1609 					logger.debug("No es posible obtener una CRL para el certificado " + ocspCertificate.getCommonName(), e1);
1610 					if (eOcsp instanceof RetrieveOCSPException) { throw (RetrieveOCSPException) eOcsp; }
1611 					if (eOcsp instanceof InvalidCertificateException) { throw (InvalidCertificateException) eOcsp; }
1612 					if (eOcsp instanceof IOException) { throw (IOException) eOcsp; }
1613 				} 
1614 			} 
1615 		}
1616 
1617 	}
1618 	
1619 	
1620 
1621 
1622 
1623 	private ValidationResult[] isValidCommon(CAList caList, List<CertificateValidationService> validationServices) throws HashingException, SignatureException, NormalizeCertificateException {
1624 		
1625 		logger.debug("[PAdESLTVSignature.isValidCommon]::Entrada::" + Arrays.asList(new Object[] { caList, validationServices }));
1626 		
1627 		PdfReader reader;
1628 		try {
1629 			reader = new PdfReader(this.pdfFile.getAbsolutePath());
1630 		} catch (IOException e) {
1631 			
1632 			logger.info("[PAdESLTVSignature.isValidCommon]::No se puede leer el contenido de este objeto", e);
1633 			throw new SignatureException ("No se puede leer el contenido de este objeto");
1634 		}
1635 		AcroFields af = reader.getAcroFields();
1636 		
1637 		TimeStampDictionary[] sellosTiempoDocumento = PAdESLTVSignature.getOrderedDocumentTimestamp(reader);
1638 		logger.debug("[PAdESLTVSignature.isValidCommon]::Se han obtenido " + sellosTiempoDocumento.length + " sellos de tiempo de documento");
1639 		if (sellosTiempoDocumento.length == 0) {
1640 			logger.info("[PAdESLTVSignature.isValidCommon]::No hay ningún sello de tiempos de documento");
1641 			throw new SignatureException ("No hay ningún sello de tiempos de documento");
1642 		}
1643 		
1644 		
1645 		TimeStamp ts = sellosTiempoDocumento[sellosTiempoDocumento.length - 1].getTs();
1646 		try {
1647 			if (!ts.isValid()) {
1648 				logger.info("[PAdESLTVSignature.isValidCommon]::El último sello de tiempos del documento de fecha " + ts.getTime() + " no es correcto");
1649 				throw new SignatureException ("El último sello de tiempos del documento de fecha " + ts.getTime() + " no es correcto");
1650 			}
1651 		} catch (MalformedTimeStampException e) {
1652 			logger.info("[PAdESLTVSignature.isValidCommon]::El último sello de tiempos del documento está mal formado", e);
1653 			throw new SignatureException ("El último sello de tiempos del documento está mal formado", e);
1654 		}
1655 		logger.debug("[PAdESLTVSignature.isValidCommon]::El sello de tiempos de fecha " + ts.getTime() + " es correcto");
1656 		
1657 		
1658 		int validationResult;
1659 		if (caList != null) {
1660 			
1661 			logger.debug("[PAdESLTVSignature.isValidCommon]::Validar el certificado de la tsa con CAList");
1662 			ValidateCertificate tsCertificate;
1663 			try {
1664 				tsCertificate = new ValidateCertificate(ts.getSignatureCertificate().toX509Certificate(), caList);
1665 			} catch (CertificateCANotFoundException e) {
1666 				logger.info("[PAdESLTVSignature.isValidCommon]::El certificado del último sello de tiempos del documento no pertenece a una de las CA de confianza", e);
1667 				throw new SignatureException ("El certificado del último sello de tiempos del documento no pertenece a una de las CA de confianza", e);
1668 			} catch (MalformedTimeStampException e) {
1669 				logger.info("[PAdESLTVSignature.isValidCommon]::El último sello de tiempos del documento está mal formado", e);
1670 				throw new SignatureException ("El último sello de tiempos del documento está mal formado", e);
1671 			}
1672 			
1673 			validationResult = tsCertificate.validate();
1674 		} else {
1675 			
1676 			logger.debug("[PAdESLTVSignature.isValidCommon]::Validar el certificado de la tsa con servicio de validación");
1677 			try {
1678 				validationResult = ts.getSignatureCertificate().validate(validationServices).getResult();
1679 			} catch (MalformedTimeStampException e) {
1680 				logger.info("[PAdESLTVSignature.isValidCommon]::El último sello de tiempos del documento está mal formado", e);
1681 				throw new SignatureException ("El último sello de tiempos del documento está mal formado", e);
1682 			}
1683 		}
1684 		
1685 		
1686 		if (validationResult != ValidationResult.RESULT_VALID) {
1687 			
1688 			logger.info("[PAdESLTVSignature.isValidCommon]::El último certificado del sello de tiempos no es válido:" + CertificateValidator.getString(validationResult));
1689 			ArrayList<String> allSignatureNames = af.getSignatureNames();
1690 			ArrayList<ValidationResult> result = new ArrayList<ValidationResult>();
1691 			for (Iterator<String> iterator = allSignatureNames.iterator(); iterator.hasNext();) {
1692 				String name = iterator.next();
1693 				if (af.getSignatureDictionary(name).get(PdfName.SUBFILTER) == null ||
1694 						!af.getSignatureDictionary(name).get(PdfName.SUBFILTER).equals(new PdfName("ETSI.RFC3161"))) {
1695 					PdfPKCS7 pkcs7 = af.verifySignature(name, CRYPTOGRAPHIC_PROVIDER_NAME);
1696 					result.add(new ValidationResult(ValidationResult.RESULT_INVALID_TIMESTAMP, pkcs7.getSigningCertificate(), ts.getTime(), ts, null));
1697 				}
1698 			}
1699 			return result.toArray(new ValidationResult[0]);
1700 		}
1701 		
1702 		
1703 		PdfDocumentSecurityStore dss;
1704 		try {
1705 			dss = new PdfDocumentSecurityStore ((PdfDictionary)reader.getCatalog().getAsDict(new PdfName("DSS")));
1706 		} catch (IOException e) {
1707 			logger.info("[PAdESLTVSignature.isValidCommon]::No ha sido posible leer alguno de los objetos contenidos en el DSS", e);
1708 			throw new SignatureException ("No ha sido posible leer alguno de los objetos contenidos en el DSS", e);
1709 		}
1710 		
1711 		
1712 		try {
1713 			return isValid(ts, dss, caList, af.extractRevision(sellosTiempoDocumento[sellosTiempoDocumento.length - 1].getName()));
1714 		} catch (IOException e) {
1715 			logger.info("[PAdESLTVSignature.isValidCommon]::No es posible obtener la parte del PDF que sella el último sello de tiempos del documento", e);
1716 			throw new SignatureException ("No es posible obtener la parte del PDF que sella el último sello de tiempos del documento", e);
1717 		}
1718 	}
1719 	
1720 	
1721 
1722 
1723 
1724 
1725 	private ValidationResult[] isValid (TimeStamp ts, PdfDocumentSecurityStore dssAdobe, CAList caList, InputStream is) throws HashingException, SignatureException, NormalizeCertificateException {
1726 		
1727 		PdfReader reader = null;
1728 		try {
1729 			try {
1730 				reader = new PdfReader(is);
1731 			} catch (IOException e) {
1732 				
1733 				logger.info("[PAdESLTVSignature.isValid*]::No se puede leer el contenido de este objeto", e);
1734 				return null;
1735 			}
1736 			AcroFields af = reader.getAcroFields();
1737 	
1738 			
1739 			Date fechaComprobacion = ts.getTime();
1740 			
1741 			
1742 			PdfDocumentSecurityStore dss;
1743 			try {
1744 				PdfDictionary dssDictionary = (PdfDictionary)reader.getCatalog().getAsDict(new PdfName("DSS"));
1745 				if (dssDictionary != null) {
1746 					dss = new PdfDocumentSecurityStore (dssDictionary);
1747 				} else {
1748 					dss = dssAdobe; 
1749 				}
1750 			} catch (IOException e) {
1751 				logger.info("[PAdESLTVSignature.isValid*]::No ha sido posible leer alguno de los objetos contenidos en el DSS", e);
1752 				throw new SignatureException ("No ha sido posible leer alguno de los objetos contenidos en el DSS", e);
1753 			}
1754 			
1755 			
1756 			
1757 			List<Certificate> certificadosDSS;
1758 			try {
1759 				certificadosDSS = getCertificadosDeDSS (dss);
1760 				if (caList == null) {
1761 					caList = new CAList(certificadosDSS);
1762 				}
1763 			} catch (NormalizeCertificateException e) {
1764 				logger.info("[PAdESLTVSignature.isValid]::Alguno de los certificados del DSS no puede ser normalizado", e);
1765 				throw new SignatureException ("Alguno de los certificados del DSS no puede ser normalizado");
1766 			}
1767 			
1768 			
1769 			logger.debug("[PAdESLTVSignature.isValid*]::Se han acabado los sellos de tiempo de documento, validar las firmas");
1770 			ArrayList<String> allSignatureNames = af.getSignatureNames();
1771 			Collections.sort(allSignatureNames);
1772 			ArrayList<String> noTimestampNames = new ArrayList<String>();
1773 			for (Iterator iterator = allSignatureNames.iterator(); iterator.hasNext();) {
1774 				String name = (String) iterator.next();
1775 				if (af.getSignatureDictionary(name).get(PdfName.SUBFILTER) == null ||
1776 						!af.getSignatureDictionary(name).get(PdfName.SUBFILTER).equals(new PdfName("ETSI.RFC3161"))) {
1777 	
1778 					noTimestampNames.add(name);
1779 					
1780 				}
1781 			}
1782 	
1783 			logger.debug("[PAdESLTVSignature.isValid*]::Se van a validar " + noTimestampNames.size() + " firmas");
1784 			List<ValidationResult> results = new ArrayList<ValidationResult>(); 
1785 			for (int i = 0; i < noTimestampNames.size(); i++) {
1786 				String name = noTimestampNames.get(i);
1787 				
1788 				
1789 				PdfPKCS7 pkcs7 = af.verifySignature(name, CRYPTOGRAPHIC_PROVIDER_NAME);
1790 				
1791 				
1792 				try {
1793 					if (!pkcs7.verify()) {
1794 						logger.info("[PAdESLTVSignature.isValid]::La firma no se corresponde con el documento");
1795 						results.add(new ValidationResult(ValidationResult.RESULT_SIGNATURE_NOT_MATCH_DATA, pkcs7.getSigningCertificate(), ts.getTime(), ts, null));
1796 						continue;
1797 					}
1798 				} catch (java.security.SignatureException e) {
1799 					logger.info("[PAdESLTVSignature.isValid]::Error en una de las firmas del PDF", e);
1800 					throw new SignatureException ("Error en una de las firmas del PDF", e);
1801 				}
1802 				
1803 				
1804 				
1805 				Certificate signingCertificate = getSigningCertificate(pkcs7.getCertificates());
1806 				if (signingCertificate != null) {
1807 					
1808 					ValidateCertificate signatureCertificate;
1809 					try {
1810 						signatureCertificate = new ValidateCertificate (signingCertificate.toDER(), caList);
1811 					} catch (CertificateCANotFoundException e) {
1812 						logger.info("[PAdESLTVSignature.isValid]::Certificado" + i + " no pertenece a ninguna de las CAs de confianza");
1813 						results.add(new ValidationResult(ValidationResult.RESULT_CERTIFICATE_NOT_BELONGS_TRUSTED_CAS, pkcs7.getSigningCertificate(), ts.getTime(), ts, null));
1814 						continue;
1815 					}
1816 					List<List<ValidateCertificate>> chainCertificate = signatureCertificate.getCertificationChainSeveralIssuers();
1817 					
1818 					
1819 					
1820 					TimeStamp timestamp = null;
1821 					List<List<ValidateCertificate>> chainTimestamp = null;
1822 					ValidateCertificate timestampCertificate = null;
1823 					try {
1824 						if (pkcs7.getTimeStampToken() != null) {
1825 							timestamp = new TimeStamp(pkcs7.getTimeStampToken().getEncoded());
1826 						}
1827 					} catch (Exception e) {
1828 						logger.info("[PAdESLTVSignature.isValid]::No es posible leer el sello de tiempos interno de la firma", e);
1829 					}
1830 					
1831 					
1832 					if (timestamp != null) {
1833 						ts = timestamp;
1834 					}
1835 					
1836 					if (timestamp != null && !olderVersionsAllowed) {
1837 						
1838 						
1839 						try {
1840 							timestampCertificate = new ValidateCertificate (timestamp.getSignatureCertificate().toX509Certificate(), caList);
1841 						} catch (CertificateCANotFoundException e) {
1842 							logger.info("[PAdESLTVSignature.isValid]::Certificado de sello de tiempos " + i + " no pertenece a ninguna de las CAs de confianza");
1843 							results.add(new ValidationResult(ValidationResult.RESULT_CERTIFICATE_NOT_BELONGS_TRUSTED_CAS, pkcs7.getSigningCertificate(), ts.getTime(), ts, null));
1844 							continue;
1845 						} catch (MalformedTimeStampException e) {
1846 							logger.info("[PAdESLTVSignature.isValid]::No se ha podido obtener el certificado del sello de tiempos " + i, e);
1847 							results.add(new ValidationResult(ValidationResult.RESULT_CERTIFICATE_CHAIN_VALIDATION_INVALID, pkcs7.getSigningCertificate(), ts.getTime(), ts, null));
1848 							continue;
1849 						}
1850 						chainTimestamp = timestampCertificate.getCertificationChainSeveralIssuers();
1851 					}
1852 					
1853 					
1854 					List<BasicOCSPResp> basicOcspResponses = null;
1855 					if (pkcs7.getOcspResponses() != null && !pkcs7.getOcspResponses().isEmpty()) {
1856 						try {
1857 							basicOcspResponses = new ArrayList<BasicOCSPResp>();
1858 							for(BasicOCSPResp bResp : pkcs7.getOcspResponses()) {
1859 								basicOcspResponses.add(new BasicOCSPResp(BasicOCSPResponse.getInstance(bResp.getEncoded())));
1860 							}
1861 						} catch (IOException e) {
1862 							logger.info("[PAdESLTVSignature.isValid]::No se ha podido parsear la respuesta OCSP en el CAdES de la firma " + i, e);
1863 						}
1864 					}
1865 					
1866 					
1867 					List<List<ValidateCertificate>> certificadosFirma = juntarListasDSS (signatureCertificate, timestampCertificate, null, chainCertificate, chainTimestamp, null);
1868 					
1869 					
1870 					results.add(validarCertificadosContraDSS(certificadosFirma, signatureCertificate, timestampCertificate, dss, 
1871 							certificadosDSS, fechaComprobacion, ts, basicOcspResponses, caList));
1872 				}
1873 			}
1874 			
1875 			
1876 			TimeStampDictionary[] sellosTiempoDocumento = PAdESLTVSignature.getOrderedDocumentTimestamp(reader);
1877 			logger.debug("[PAdESLTVSignature.isValid*]::Se han obtenido " + sellosTiempoDocumento.length + " sellos de tiempo de documento");
1878 			
1879 			
1880 			
1881 			if (sellosTiempoDocumento.length > 1) {
1882 				logger.debug("[PAdESLTVSignature.isValid*]::Validando otro sello de tiempos de documento");
1883 				
1884 				TimeStamp siguienteTS = sellosTiempoDocumento[sellosTiempoDocumento.length - 2].getTs();
1885 				try {
1886 					if (!siguienteTS.isValid()) {
1887 						logger.info("[PAdESLTVSignature.isValid*]::El sello de tiempos del documento de fecha " + siguienteTS.getTime() + " no es válido");
1888 						throw new SignatureException ("El sello de tiempos del documento de fecha " + siguienteTS.getTime() + " no es válido");
1889 					}
1890 				} catch (MalformedTimeStampException e) {
1891 					logger.info("[PAdESLTVSignature.isValid*]::El sello de tiempos del documento no es correcto", e);
1892 					throw new SignatureException ("El sello de tiempos del documento no es correcto", e);
1893 				}
1894 				logger.debug("[PAdESLTVSignature.isValid*]::El sello de tiempos de documento de fecha " + siguienteTS.getTime() + " es válido");
1895 				
1896 				
1897 				ValidateCertificate tsCertificate;
1898 				try {
1899 					tsCertificate = new ValidateCertificate(siguienteTS.getSignatureCertificate().toX509Certificate(), caList);
1900 				} catch (CertificateCANotFoundException e) {
1901 					logger.info("[PAdESLTVSignature.isValid]::El sello de tiempos del documento de fecha " + siguienteTS.getTime() + " no pertenece a una de las CA de confianza", e);
1902 					throw new SignatureException ("El sello de tiempos del documento de fecha " + siguienteTS.getTime() + " no pertenece a una de las CA de confianza", e);
1903 				} catch (MalformedTimeStampException e) {
1904 					logger.info("[PAdESLTVSignature.isValid]::El sello de tiempos del documento de fecha " + siguienteTS.getTime() + " está mal formado", e);
1905 					throw new SignatureException ("El sello de tiempos del documento de fecha " + siguienteTS.getTime() + " está mal formado", e);
1906 				}
1907 				List<List<ValidateCertificate>> chainCertificate = tsCertificate.getCertificationChainSeveralIssuers();
1908 				ValidationResult tsCertValidationResult = validarCertificadosContraDSS(chainCertificate, tsCertificate, null, dss, certificadosDSS, fechaComprobacion, siguienteTS, null, caList);
1909 				if (!tsCertValidationResult.isValid()) {
1910 					
1911 					logger.info("[PAdESLTVSignature.isValid]::El certificado del sello de tiempos del documento de fecha " + siguienteTS.getTime() + "  no es válido:" + CertificateValidator.getString(tsCertValidationResult.getResult()));
1912 					ArrayList<ValidationResult> result = new ArrayList<ValidationResult>();
1913 					for (Iterator<String> iterator = allSignatureNames.iterator(); iterator.hasNext();) {
1914 						String name = iterator.next();
1915 						if (af.getSignatureDictionary(name).get(PdfName.SUBFILTER) == null ||
1916 								!af.getSignatureDictionary(name).get(PdfName.SUBFILTER).equals(new PdfName("ETSI.RFC3161"))) {
1917 							PdfPKCS7 pkcs7 = af.verifySignature(name, CRYPTOGRAPHIC_PROVIDER_NAME);
1918 							result.add(new ValidationResult(ValidationResult.RESULT_INVALID_TIMESTAMP, pkcs7.getSigningCertificate(), siguienteTS.getTime(), siguienteTS, null));
1919 						}
1920 					}
1921 					return result.toArray(new ValidationResult[0]);
1922 				}
1923 				
1924 				
1925 				try {
1926 					return isValid(siguienteTS, dss, caList, af.extractRevision(sellosTiempoDocumento[sellosTiempoDocumento.length - 2].getName()));
1927 				} catch (IOException e) {
1928 					logger.info("[PAdESLTVSignature.isValid*]::No es posible obtener la parte del PDF que sella el sello de tiempos del documento de fecha " + siguienteTS.getTime(), e);
1929 					throw new SignatureException ("No es posible obtener la parte del PDF que sella el sello de tiempos del documento de fecha " + siguienteTS.getTime(), e);
1930 				}
1931 			}
1932 			
1933 			
1934 			return results.toArray(new ValidationResult[0]);
1935 
1936 		} finally {
1937 			if (reader != null) {
1938 				reader.close();
1939 			}
1940 		}
1941 	}
1942 	
1943 	
1944 
1945 
1946 	private ValidationResult validarCertificadosContraDSS (List<List<ValidateCertificate>> certificadosAValidar, ValidateCertificate certificadoFirma,
1947 			ValidateCertificate certificadoTS, PdfDocumentSecurityStore dss, List<Certificate> certificadosDSS, 
1948 			Date fechaComprobacion, TimeStamp ts, List<BasicOCSPResp> basicOcspResponses, CAList caList) throws SignatureException {
1949 		
1950 		int resultadoValidacion = ValidationResult.RESULT_VALID;
1951 		
1952 		
1953 		List<OCSPResponse> lOcspResponses = new ArrayList<OCSPResponse>();
1954 		int nivel = -1;
1955 		boolean todosValidados = true;
1956 		for (List<ValidateCertificate> lista : certificadosAValidar) {
1957 			nivel++;
1958 			boolean encontradaValidacionCertificado = false;
1959 			for (ValidateCertificate certificadoAValidar : lista) {
1960 			
1961 				
1962 				if (!certificadosDSS.contains(certificadoAValidar)) {
1963 					logger.info("[PAdESLTVSignature.isValid]::El certificado no se encuentra en el DSS::" + certificadoAValidar);
1964 	
1965 	
1966 	
1967 	
1968 	
1969 	
1970 				}
1971 				
1972 				
1973 				try {
1974 					if(certificadoAValidar.isSelfSigned()) {
1975 						encontradaValidacionCertificado = true;
1976 						break;
1977 					}
1978 				} catch (NormalizeCertificateException e) {
1979 					logger.info("[PAdESLTVSignature.isValid]::Uno de los certificados no puede ser normalizado:: " + certificadoAValidar.getCommonName(), e);
1980 					throw new SignatureException ("Uno de los certificados no puede ser normalizado", e);
1981 				}
1982 				
1983 				
1984 				boolean encontradaRespuestaOCSP = false;
1985 				Set<Integer> setKeys = dss.getOcsps().keySet();
1986 				for (Integer key : setKeys) {
1987 					OCSPResponse ocspResponse;
1988 					try {
1989 						ocspResponse = new OCSPResponse (dss.getOcsps().get(key));
1990 					} catch (MalformedOCSPResponseException e) {
1991 						logger.info("[PAdESLTVSignature.isValid]::Una de las respuestas OCSP del DSS está mal formada", e);
1992 						break;
1993 					}
1994 					
1995 					if (ocspResponse.getSingleResponses()[0].match(certificadoAValidar)) {
1996 						logger.debug("[PAdESLTVSignature.isValid]::Encontrada respuesta OCSP para el certificado. Estado: " + ocspResponse.getSingleResponses()[0].getStatus());
1997 						encontradaRespuestaOCSP = true;
1998 						
1999 						
2000 						if (!ocspResponse.isSignatureValid()) {
2001 							if(certificadoAValidar.equals(certificadoFirma) || (certificadoTS != null && certificadoAValidar.equals(certificadoTS))) {
2002 								resultadoValidacion = ValidationResult.RESULT_INVALID_VALIDITY_ITEM;
2003 							} else {
2004 								resultadoValidacion = ValidationResult.RESULT_CERTIFICATE_CHAIN_VALIDATION_INVALID;
2005 							}
2006 							continue;
2007 						}
2008 						
2009 						
2010 						if (ocspResponse.getSingleResponses()[0].getStatus() != ValidationResult.RESULT_VALID) {
2011 							if(certificadoAValidar.equals(certificadoFirma) || (certificadoTS != null && certificadoAValidar.equals(certificadoTS))) {
2012 								resultadoValidacion = ocspResponse.getSingleResponses()[0].getStatus();
2013 							} else {
2014 								resultadoValidacion = ValidationResult.RESULT_CERTIFICATE_CHAIN_VALIDATION_INVALID;
2015 							}
2016 							continue;
2017 						}
2018 						
2019 						
2020 						
2021 						
2022 						if ((ocspResponse.getSingleResponses()[0].getValidityPeriodEnd() != null && 
2023 								ocspResponse.getSingleResponses()[0].getValidityPeriodEnd().before(fechaComprobacion)) ||
2024 								ocspResponse.getSingleResponses()[0].getValidityPeriodBeginning().after(certificadoAValidar.getValidityPeriodEnd())) {
2025 							logger.debug("[PAdESLTVSignature.isValid]::La fecha de la respuesta OCSP (" + ocspResponse.getSingleResponses()[0].getValidityPeriodEnd() + 
2026 									") es anterior a la fecha de comprobación (" + fechaComprobacion + ")");
2027 							if(certificadoAValidar.equals(certificadoFirma) || (certificadoTS != null && certificadoAValidar.equals(certificadoTS))) {
2028 								resultadoValidacion = ValidationResult.RESULT_TIMESTAMP_AFTER_VALIDITY_ITEM;
2029 							} else {
2030 								resultadoValidacion = ValidationResult.RESULT_CERTIFICATE_CHAIN_VALIDATION_INVALID;
2031 							}
2032 							continue;
2033 						}
2034 						
2035 						
2036 						logger.debug("[PAdESLTVSignature.isValid]::La respuesta OCSP es correcta para el certificado de CN=" + certificadoFirma.getCommonName());
2037 						resultadoValidacion = ValidationResult.RESULT_VALID;
2038 						break;
2039 					}
2040 				}
2041 				
2042 				
2043 				if (encontradaRespuestaOCSP && resultadoValidacion == ValidationResult.RESULT_VALID) {
2044 					encontradaValidacionCertificado = true;
2045 					break;
2046 				}
2047 				
2048 				
2049 				try {
2050 					resultadoValidacion = validateFromCAdES(basicOcspResponses, certificadoAValidar, certificadoFirma, ts);
2051 				} catch (MalformedTimeStampException e) {
2052 					logger.info("[PAdESLTVSignature.isValid]::El sello de tiempo CAdES no se puede parsear", e);
2053 					resultadoValidacion = ValidationResult.RESULT_CERTIFICATE_CANNOT_BE_VALIDATED;
2054 				}
2055 				if (resultadoValidacion == ValidationResult.RESULT_VALID) {
2056 					encontradaValidacionCertificado = true;
2057 					break;
2058 				}
2059 				
2060 				
2061 				logger.debug("[PAdESLTVSignature.isValid]::No se ha encontrado una respuesta OCSP para el certificado. Probar con CRLs");
2062 				
2063 				boolean encontradaCRL = false;
2064 				setKeys = dss.getCrls().keySet();
2065 				for (Integer key : setKeys) {
2066 					try {
2067 						CRL crl = new CRL (dss.getCrls().get(key));
2068 						
2069 						logger.debug("[PAdESLTVSignature.isValid]::Obtenida CRL, comprobar si sirve para validar el certificado");
2070 						if (crl.match(certificadoAValidar)) {
2071 							encontradaCRL = true;
2072 						
2073 							
2074 							try {
2075 								crl.validate(caList);
2076 							} catch (Exception e) {
2077 								if(certificadoAValidar.equals(certificadoFirma) || (certificadoTS != null && certificadoAValidar.equals(certificadoTS))) {
2078 									resultadoValidacion = ValidationResult.RESULT_INVALID_VALIDITY_ITEM;
2079 								} else {
2080 									resultadoValidacion = ValidationResult.RESULT_CERTIFICATE_CHAIN_VALIDATION_INVALID;
2081 								}
2082 								break;
2083 							} 
2084 							
2085 							
2086 							logger.debug("[PAdESLTVSignature.isValid]::Obtenida CRL, comprobar si el certificado está entre los revocados");
2087 							if (crl.isRevoked(certificadoAValidar.getSerialNumberBigInteger())) {
2088 								if(certificadoAValidar.equals(certificadoFirma) || (certificadoTS != null && certificadoAValidar.equals(certificadoTS))) {
2089 									resultadoValidacion = ValidationResult.RESULT_CERTIFICATE_REVOKED;
2090 								} else {
2091 									resultadoValidacion = ValidationResult.RESULT_CERTIFICATE_CHAIN_VALIDATION_INVALID;
2092 								}
2093 								break;
2094 							}
2095 							
2096 							
2097 							
2098 							if (crl.getValidityPeriodEnd().before(fechaComprobacion)) {
2099 								logger.debug("[PAdESLTVSignature.isValid]::La fecha de la CRL (" + crl.getValidityPeriodEnd() + 
2100 										") es anterior a la fecha de comprobación (" + fechaComprobacion + ")");
2101 								if(certificadoAValidar.equals(certificadoFirma) || (certificadoTS != null && certificadoAValidar.equals(certificadoTS))) {
2102 									resultadoValidacion = ValidationResult.RESULT_TIMESTAMP_AFTER_VALIDITY_ITEM;
2103 								} else {
2104 									resultadoValidacion = ValidationResult.RESULT_CERTIFICATE_CHAIN_VALIDATION_INVALID;
2105 								}
2106 								break;
2107 							}
2108 	
2109 							
2110 							logger.debug("[PAdESLTVSignature.isValid]::La CRL es correcta para el certificado de CN=" + certificadoFirma.getCommonName());
2111 							resultadoValidacion = ValidationResult.RESULT_VALID;
2112 							break;
2113 						}
2114 						
2115 					} catch (CRLParsingException e) {
2116 						logger.info("[PAdESLTVSignature.isValid]::No se ha podido cargar una de las CRLs contenidas en el DSS", e);
2117 					}
2118 				}
2119 	
2120 				
2121 				if (encontradaCRL && resultadoValidacion == ValidationResult.RESULT_VALID) {
2122 					encontradaValidacionCertificado = true;
2123 					break;
2124 				}
2125 				
2126 				
2127 				resultadoValidacion = certificadoAValidar.validate();
2128 				if (resultadoValidacion == ValidationResult.RESULT_VALID) {
2129 					encontradaValidacionCertificado = true;
2130 					break;
2131 				}
2132 				
2133 			}
2134 			
2135 			
2136 			if (!encontradaValidacionCertificado) {
2137 				logger.debug("[PAdESLTVSignature.isValid]::No se ha encontrado una CRL para validar el certificado");
2138 				if(nivel == 0) {
2139 					resultadoValidacion = ValidationResult.RESULT_CERTIFICATE_CANNOT_BE_VALIDATED;
2140 				} else {
2141 					resultadoValidacion = ValidationResult.RESULT_CERTIFICATE_CHAIN_VALIDATION_INVALID;
2142 				}
2143 				todosValidados = false;
2144 				break;
2145 			}
2146 		}
2147 		
2148 		if (todosValidados) {
2149 			resultadoValidacion = ValidationResult.RESULT_VALID;
2150 		}
2151 		
2152 		return new ValidationResult(resultadoValidacion, certificadoFirma.toX509Certificate(), ts.getTime(), ts, lOcspResponses.toArray(new OCSPResponse[0]));
2153 		
2154 	}
2155 	
2156 	private static void addDocumentTimeStampDSS(PdfReader reader, CAList caList, File fileResult) throws SignatureException, NoSuchAlgorithmException, CertificateCANotFoundException, NormalizeCertificateException, RetrieveOCSPException, InvalidCertificateException, IOException, DocumentException {
2157 		TimeStampDictionary[] diccionariosSellosTiempoDocumento = getOrderedDocumentTimestamp(reader);
2158 		if (diccionariosSellosTiempoDocumento.length > 0) {
2159     		TimeStampDictionary diccionarioSellosTiempoDocumento = diccionariosSellosTiempoDocumento[diccionariosSellosTiempoDocumento.length - 1];
2160     		
2161 			
2162 			TimeStamp ts = diccionarioSellosTiempoDocumento.getTs();
2163 			
2164 			
2165 			ValidateCertificate certificateTimestamp;
2166 			try {
2167 				certificateTimestamp = new ValidateCertificate (ts.getSignatureCertificate().toX509Certificate(), caList);
2168 			} catch (MalformedTimeStampException e) {
2169 				logger.info("[PAdESLTVSignature.addDocumentTimeStamp]::El último sello de tiempos del documento no está bien formado", e);
2170 				throw new SignatureException ("El último sello de tiempos del documento no está bien formado", e);
2171 			} 
2172 			List<List<ValidateCertificate>> cadenaTimestamp = certificateTimestamp.getCertificationChainSeveralIssuers();
2173 			
2174 			
2175 			List<List<ValidateCertificate>> certificadosDSS = juntarListasDSS (null, certificateTimestamp, null, null, cadenaTimestamp, null);
2176 			PdfDocumentSecurityStore dss = new PdfDocumentSecurityStore();
2177 			cargarDSS(certificadosDSS, dss, caList);
2178 
2179 			
2180 			FileOutputStream fos = null;
2181 			try {
2182 	            fos = new FileOutputStream (fileResult);
2183 	            PdfStamper stamper = new PdfStamper(reader, fos, '\0', true);
2184 				stamper.addDocumentSecurityStore(dss);
2185 				stamper.close();
2186 			} finally {
2187 				if (fos != null) {
2188 					fos.close();
2189 				}
2190 			}
2191 		}
2192 	}
2193 	
2194 	
2195 	
2196 	static class MyPdfPKCS extends PdfSigGenericPKCS {
2197         
2198 
2199 
2200         public MyPdfPKCS() {
2201                 super(PdfName.ADOBE_PPKMS, (embedOcspInSignature) ? PdfName.ADBE_PKCS7_DETACHED : PdfName.ADBE_PKCS7_SHA1);
2202                 hashAlgorithm = HASH_ALGORITHM;
2203         }
2204 
2205         
2206 
2207 
2208 
2209 
2210         public MyPdfPKCS(String provider) {
2211                 this();
2212                 this.provider = provider;
2213         }
2214     }
2215 	
2216 	public static class TimeStampDictionary implements Comparable<TimeStampDictionary>{
2217 		String name;
2218 		TimeStamp ts;
2219 		PdfDictionary dictionary;
2220 		public TimeStampDictionary(String name, TimeStamp ts, PdfDictionary dictionary) {
2221 			super();
2222 			this.name = name;
2223 			this.ts = ts;
2224 			this.dictionary = dictionary;
2225 		}
2226 		public String getName() {
2227 			return name;
2228 		}
2229 		public void setName(String name) {
2230 			this.name = name;
2231 		}
2232 		public TimeStamp getTs() {
2233 			return ts;
2234 		}
2235 		public void setTs(TimeStamp ts) {
2236 			this.ts = ts;
2237 		}
2238 		public PdfDictionary getDictionary() {
2239 			return dictionary;
2240 		}
2241 		public void setDictionary(PdfDictionary dictionary) {
2242 			this.dictionary = dictionary;
2243 		}
2244 		public int compareTo(TimeStampDictionary o) {
2245 			return this.ts.getTime().compareTo(o.getTs().getTime());
2246 		}
2247 		
2248 	}
2249 
2250 }