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.FileOutputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.net.URL;
30 import java.security.InvalidKeyException;
31 import java.security.NoSuchAlgorithmException;
32 import java.security.NoSuchProviderException;
33 import java.security.PrivateKey;
34 import java.security.cert.X509Certificate;
35 import java.text.SimpleDateFormat;
36 import java.util.ArrayList;
37 import java.util.Arrays;
38 import java.util.Calendar;
39 import java.util.Date;
40 import java.util.HashMap;
41 import java.util.Iterator;
42 import java.util.List;
43
44 import org.apache.log4j.Logger;
45 import org.bouncycastle.asn1.ocsp.BasicOCSPResponse;
46 import org.bouncycastle.cert.ocsp.BasicOCSPResp;
47
48 import com.itextpdf.text.DocumentException;
49 import com.itextpdf.text.Image;
50 import com.itextpdf.text.Rectangle;
51 import com.itextpdf.text.pdf.AcroFields;
52 import com.itextpdf.text.pdf.PdfDate;
53 import com.itextpdf.text.pdf.PdfDictionary;
54 import com.itextpdf.text.pdf.PdfName;
55 import com.itextpdf.text.pdf.PdfPKCS7;
56 import com.itextpdf.text.pdf.PdfReader;
57 import com.itextpdf.text.pdf.PdfSignature;
58 import com.itextpdf.text.pdf.PdfSignatureAppearance;
59 import com.itextpdf.text.pdf.PdfStamper;
60 import com.itextpdf.text.pdf.PdfString;
61 import com.itextpdf.text.pdf.TSAClient;
62 import com.itextpdf.text.pdf.TSAClientBouncyCastle;
63
64 import es.accv.arangi.base.algorithm.DigitalSignatureAlgorithm;
65 import es.accv.arangi.base.certificate.Certificate;
66 import es.accv.arangi.base.certificate.validation.CAList;
67 import es.accv.arangi.base.certificate.validation.CertificateValidationService;
68 import es.accv.arangi.base.certificate.validation.ValidateCertificate;
69 import es.accv.arangi.base.device.DeviceManager;
70 import es.accv.arangi.base.document.IDocument;
71 import es.accv.arangi.base.document.InputStreamDocument;
72 import es.accv.arangi.base.exception.certificate.CertificateCANotFoundException;
73 import es.accv.arangi.base.exception.certificate.NormalizeCertificateException;
74 import es.accv.arangi.base.exception.device.AliasNotFoundException;
75 import es.accv.arangi.base.exception.device.LoadingObjectException;
76 import es.accv.arangi.base.exception.device.SearchingException;
77 import es.accv.arangi.base.exception.document.HashingException;
78 import es.accv.arangi.base.exception.signature.AlgorithmNotSuitableException;
79 import es.accv.arangi.base.exception.signature.InvalidCertificateException;
80 import es.accv.arangi.base.exception.signature.PDFDocumentException;
81 import es.accv.arangi.base.exception.signature.SignatureException;
82 import es.accv.arangi.base.exception.signature.SignatureNotFoundException;
83 import es.accv.arangi.base.exception.timestamp.MalformedTimeStampException;
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128 public class PDFSignature extends BasePDFSignature {
129
130
131
132
133
134 private static final String DEFAULT_SIGNATURE_REASON = "Firma realizada con Arangi (ACCV)";
135
136
137
138
139 static Logger logger = Logger.getLogger(PDFSignature.class);
140
141
142
143
144
145
146
147
148
149
150
151 public PDFSignature (File pdfFile) throws PDFDocumentException, SignatureNotFoundException {
152 initialize(pdfFile);
153 }
154
155
156
157
158
159
160
161
162
163
164 public PDFSignature (byte[] pdfContentBytes) throws PDFDocumentException, SignatureNotFoundException, IOException {
165
166 File fileTemp = null;
167 try {
168 fileTemp = getFileTemp ();
169 Util.saveFile(fileTemp, pdfContentBytes);
170 } catch (IOException e) {
171 logger.info("[PDFSignature(byte[])::No se puede crear el fichero temporal o no se puede escribir en él", e);
172 if (fileTemp != null) { fileTemp.delete(); }
173 throw e;
174 }
175
176 initialize(fileTemp);
177 }
178
179
180
181
182
183
184
185
186
187
188 public PDFSignature (InputStream streamPDF) throws PDFDocumentException, SignatureNotFoundException, IOException {
189
190 FileOutputStream fos = null;
191 File fileTemp = null;
192 try {
193 fileTemp = getFileTemp ();
194 fos = new FileOutputStream(fileTemp);
195 int c;
196 while ((c = streamPDF.read()) != -1) {
197 fos.write(c);
198 }
199 } catch (IOException e) {
200 logger.info("[PDFSignature(byte[])::No se puede crear el fichero temporal o no se puede escribir en él", e);
201 if (fileTemp != null) {
202 fos.close();
203 fos = null;
204 fileTemp.delete();
205 }
206 throw e;
207 } finally {
208 if (fos != null) {
209 fos.close();
210 }
211 }
212
213
214 initialize(fileTemp);
215 }
216
217
218
219
220
221
222
223
224
225
226 public PDFSignature (IDocument document) throws PDFDocumentException, SignatureNotFoundException, IOException {
227
228 FileOutputStream fos = null;
229 InputStream fis = null;
230 File fileTemp = null;
231 try {
232 fileTemp = getFileTemp ();
233 fis = document.getInputStream();
234 fos = new FileOutputStream(fileTemp);
235 int c;
236 while ((c = fis.read()) != -1) {
237 fos.write(c);
238 }
239 } catch (IOException e) {
240 logger.info("[PDFSignature(byte[])::No se puede crear el fichero temporal o no se puede escribir en él", e);
241 if (fileTemp != null) {
242 fos.close();
243 fos = null;
244 fileTemp.delete();
245 }
246 throw e;
247 } finally {
248 if (fos != null) {
249 fos.close();
250 }
251 if (fis != null) {
252 fis.close();
253 }
254 }
255
256
257 initialize(fileTemp);
258 }
259
260
261
262
263 protected PDFSignature (PDFSignature signature) {
264 this.pdfFile = signature.pdfFile;
265 }
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295 public static PDFSignature sign (DeviceManager managers[], String[] alias, IDocument pdfDocument, URL urlTimestamp,
296 CAList caList, String reason) throws AliasNotFoundException, LoadingObjectException, PDFDocumentException, SignatureException, HashingException, CertificateCANotFoundException, InvalidCertificateException {
297 try {
298 return sign (managers, alias, pdfDocument, null, urlTimestamp, null, null, caList, reason, false, null, -1, -1, -1, -1, 0);
299 } catch (AlgorithmNotSuitableException e) {
300 logger.info("El algoritmo por defecto no debería provocar este error", e);
301 throw new SignatureException("El algoritmo por defecto no debería provocar este error", e);
302 }
303 }
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334 public static PDFSignature sign (DeviceManager[] managers, String[] alias, IDocument pdfDocument, URL urlTimestamp,
335 String userTSA, String passwordTSA, CAList caList, String reason) throws AliasNotFoundException, LoadingObjectException, PDFDocumentException, SignatureException, HashingException, CertificateCANotFoundException, InvalidCertificateException {
336 try {
337 return sign (managers, alias, pdfDocument, null, urlTimestamp, userTSA, passwordTSA, caList, reason, false, null, -1, -1, -1, -1, 0);
338 } catch (AlgorithmNotSuitableException e) {
339 logger.info("El algoritmo por defecto no debería provocar este error", e);
340 throw new SignatureException("El algoritmo por defecto no debería provocar este error", e);
341 }
342 }
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368 public static PDFSignature sign (DeviceManager[] managers, String[] alias, IDocument pdfDocument,
369 CAList caList, String reason) throws AliasNotFoundException, LoadingObjectException, PDFDocumentException, SignatureException, HashingException, CertificateCANotFoundException, InvalidCertificateException {
370 try{
371 return sign (managers, alias, pdfDocument, null, null, null, null, caList, reason, false, null, -1, -1, -1, -1, 0);
372 } catch (AlgorithmNotSuitableException e) {
373 logger.info("El algoritmo por defecto no debería provocar este error", e);
374 throw new SignatureException("El algoritmo por defecto no debería provocar este error", e);
375 }
376 }
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414 public static PDFSignature sign (DeviceManager[] managers, String[] alias, IDocument pdfDocument,
415 CAList caList, String reason, boolean isVisible, byte[] image, float llX, float llY, float urX,
416 float urY, int page) throws AliasNotFoundException, LoadingObjectException, PDFDocumentException, SignatureException, HashingException, CertificateCANotFoundException, InvalidCertificateException {
417
418 try {
419 return sign(managers, alias, pdfDocument, null, null, null, null, caList, reason, isVisible, image, llX, llY, urX, urY, page);
420 } catch (AlgorithmNotSuitableException e) {
421 logger.info("El algoritmo por defecto no debería provocar este error", e);
422 throw new SignatureException("El algoritmo por defecto no debería provocar este error", e);
423 }
424 }
425
426
427
428
429
430
431
432
433
434
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 public static PDFSignature sign (DeviceManager[] managers, String[] alias, IDocument pdfDocument,
468 String digitalSignatureAlgorithm, URL urlTimestamp, String userTSA, String passwordTSA,
469 CAList caList, String reason, boolean isVisible, byte[] image,
470 float llX, float llY, float urX, float urY, int page) throws AliasNotFoundException, LoadingObjectException, PDFDocumentException, SignatureException, HashingException, CertificateCANotFoundException, InvalidCertificateException, AlgorithmNotSuitableException {
471
472 logger.debug("[PDFSignature.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) }));
473
474 FileOutputStream fos = null;
475 try {
476
477
478 if (reason == null) {
479 reason = DEFAULT_SIGNATURE_REASON;
480 }
481
482
483 TSAClient tsc = null;
484 if (urlTimestamp != null) {
485 tsc = new TSAClientBouncyCastle(urlTimestamp.toString(), userTSA, passwordTSA);
486 }
487
488
489 File fileResult1 = getFileTemp();
490 Util.saveFile(fileResult1, pdfDocument.getInputStream());
491
492 for (int i = 0; i < managers.length; i++) {
493
494
495 PrivateKey pk = managers[i].getPrivateKey(alias[i]);
496 if (pk == null) {
497 logger.info("[PDFSignature.sign]::No se ha podido encontrar el alias o bien éste no contiene una clave privada");
498 throw new AliasNotFoundException ("No se ha podido encontrar el alias o bien éste no contiene una clave privada");
499 }
500
501
502 X509Certificate x509Certificate = managers[i].getCertificate(alias[i]);
503 ValidateCertificate validateCertificate = null;
504 java.security.cert.Certificate[] chain;
505 if (caList != null) {
506 validateCertificate = new ValidateCertificate (x509Certificate, caList);
507 int validationResult;
508 if ((validationResult = validateCertificate.validate()) != ValidationResult.RESULT_VALID) {
509 logger.info("[PDFSignature.sign]::El certificado de firma no es válido: " + validationResult);
510 throw new InvalidCertificateException ("El certificado de firma no es válido: " + validationResult, validationResult);
511 }
512 chain = new java.security.cert.Certificate[] { x509Certificate, validateCertificate.getIssuerCertificate().toX509Certificate() };
513 } else {
514 chain = new java.security.cert.Certificate[] { x509Certificate };
515 }
516
517
518
519 FileInputStream fis = new FileInputStream(fileResult1);
520 PdfReader reader = new PdfReader(fis);
521 File fileResult2 = getFileTemp();
522 fos = new FileOutputStream (fileResult2);
523 AcroFields af = reader.getAcroFields();
524 ArrayList names = af.getSignatureNames();
525 PdfStamper stp;
526 if (names == null || names.isEmpty()) {
527 stp = PdfStamper.createSignature(reader, fos, '\0');
528 } else {
529 stp = PdfStamper.createSignature(reader, fos, '\0', null, true);
530 }
531
532
533 PdfSignatureAppearance sap = stp.getSignatureAppearance();
534 sap.setCrypto(null, chain, null, PdfSignatureAppearance.SELF_SIGNED);
535 sap.setReason(reason);
536 if (isVisible) {
537 sap.setVisibleSignature(new Rectangle(llX, llY, urX, urY), page, null);
538 StringBuffer detail = new StringBuffer();
539 if (validateCertificate != null) {
540 detail.append(DIGITALLY_SIGNED_TEXT + ": " + validateCertificate.getCommonName() + "\n");
541 }
542 SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm");
543 detail.append("Fecha: " + sdf.format(new Date()) + "\n");
544 if (reason != null && !reason.equals("")) {
545 detail.append("Motivo: " + reason + "\n");
546 }
547 sap.setLayer2Text(detail.toString());
548 if (image != null) {
549 sap.setImage(Image.getInstance(image));
550 }
551 }
552
553
554 PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached"));
555 dic.setReason(sap.getReason());
556 dic.setLocation(sap.getLocation());
557 dic.setContact(sap.getContact());
558 dic.setDate(new PdfDate(sap.getSignDate()));
559 sap.setCryptoDictionary(dic);
560 sap.setExternalDigest(new byte[128], null, "RSA");
561
562 int contentEstimated = 15000;
563 HashMap exc = new HashMap();
564 exc.put(PdfName.CONTENTS, new Integer(contentEstimated * 2 + 2));
565 sap.preClose(exc);
566
567
568 if (digitalSignatureAlgorithm == null) {
569 digitalSignatureAlgorithm = DigitalSignatureAlgorithm.getDefault();
570 }
571 String hashingAlgorithm = DigitalSignatureAlgorithm.getHashingAlgorithm(digitalSignatureAlgorithm);
572 if (hashingAlgorithm == null) {
573 logger.info("No se puede tratar el algoritmo de firma " + digitalSignatureAlgorithm);
574 throw new AlgorithmNotSuitableException("No se puede tratar el algoritmo de firma " + digitalSignatureAlgorithm);
575 }
576
577
578 Calendar cal = Calendar.getInstance();
579 PdfPKCS7 pkcs7 = new PdfPKCS7(null, chain, null, hashingAlgorithm, CRYPTOGRAPHIC_PROVIDER_NAME, false);
580 byte hash[] = new InputStreamDocument (sap.getRangeStream()).getHash(hashingAlgorithm);
581 byte sh[] = pkcs7.getAuthenticatedAttributeBytes(hash, cal, null);
582 byte[] signatureBytes = managers[i].signDocument(new ByteArrayInputStream (sh), alias[i], digitalSignatureAlgorithm);
583 pkcs7.setExternalDigest(signatureBytes, sh, "RSA");
584 byte[] encodedSig = pkcs7.getEncodedPKCS7(hash, cal, tsc, hashingAlgorithm, null);
585
586
587 if (contentEstimated + 2 < encodedSig.length) {
588 logger.info("[PDFSignature.sign]::No se puede añadir la firma al PDF por falta de espacio en el mismo");
589 throw new SignatureException ("No se puede añadir la firma al PDF por falta de espacio en el mismo");
590 }
591
592 byte[] paddedSig = new byte[contentEstimated];
593 System.arraycopy(encodedSig, 0, paddedSig, 0, encodedSig.length);
594
595 PdfDictionary dic2 = new PdfDictionary();
596 dic2.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true));
597 sap.close(dic2);
598
599 fis.close();
600 reader.close();
601 fos.close();
602 fos = null;
603
604 fileResult1.delete();
605 fileResult1 = fileResult2;
606 }
607
608 try {
609 return new PDFSignature (fileResult1);
610 } catch (SignatureNotFoundException e) {
611
612 return null;
613 } catch (PDFDocumentException e) {
614
615 return null;
616 }
617
618 } catch (LoadingObjectException e) {
619 logger.info("[PDFSignature.sign]::No se ha podido obtener la clave privada para firma", e);
620 throw new LoadingObjectException ("No se ha podido obtener la clave privada para firma", e);
621 } catch (SearchingException e) {
622 logger.info("[PDFSignature.sign]::No se ha podido encontrar la clave privada para firma", e);
623 throw new LoadingObjectException ("No se ha podido encontrar la clave privada para firma", e);
624 } catch (IOException e) {
625 logger.info("[PDFSignature.sign]::No se ha podido leer el fichero PDF o no se ha podido crear el fichero temporal con la firma", e);
626 throw new PDFDocumentException ("No se ha podido leer el fichero PDF o no se ha podido crear el fichero temporal con la firma", e);
627 } catch (DocumentException e) {
628 logger.info("[PDFSignature.sign]::No se ha podido manejar alguna de las partes del fichero PDF", e);
629 throw new PDFDocumentException ("No se ha podido manejar alguna de las partes del fichero PDF", e);
630 } catch (InvalidKeyException e) {
631 logger.info("[PDFSignature.sign]::La clave privada no es válida para realizar la firma", e);
632 throw new SignatureException ("La clave privada no es válida para realizar la firma", e);
633 } catch (NoSuchProviderException e) {
634 logger.info("[PDFSignature.sign]::No se ha podido obtener el proveedor criptográfico", e);
635 return null;
636 } catch (NoSuchAlgorithmException e) {
637 logger.info("[PDFSignature.sign]::No existen en el proveedor criptográfico los algoritmos de firma (SHA1WithRSA)", e);
638 throw new SignatureException ("No existen en el proveedor criptográfico los algoritmos de firma (SHA1WithRSA)", e);
639 } catch (CertificateCANotFoundException e) {
640 logger.info("[PDFSignature.sign]::La lista de certificado de CA no contiene el emisor del certificado de firma", e);
641 throw new CertificateCANotFoundException ("La lista de certificado de CA no contiene el emisor del certificado de firma", e);
642 } catch (NormalizeCertificateException e) {
643 logger.info("[PDFSignature.sign]::El certificado de la CA no es normalizable según el proveedor criptográfico de Arangi", e);
644 throw new CertificateCANotFoundException ("El certificado de la CA no es normalizable según el proveedor criptográfico de Arangi", e);
645 }
646
647 }
648
649
650
651
652
653
654 public ValidationResult[] isValid(CAList caList) throws HashingException, SignatureException, NormalizeCertificateException {
655
656 logger.debug("[PDFSignature.isValid]::Entrada::" + caList);
657
658 return isValidCommon(caList, null);
659 }
660
661
662
663
664
665
666 public ValidationResult[] isValid(IDocument document, CAList caList)
667 throws HashingException, SignatureException,
668 NormalizeCertificateException {
669 return isValid (caList);
670 }
671
672
673
674
675 public ValidationResult[] isValid(List<CertificateValidationService> validationServices)
676 throws HashingException, SignatureException, NormalizeCertificateException {
677
678 logger.debug("[PDFSignature.isValid]::Entrada::" + validationServices);
679
680 return isValidCommon(null, validationServices);
681
682 }
683
684
685
686
687
688
689 public ValidationResult[] isValid(IDocument document, List<CertificateValidationService> validationServices)
690 throws HashingException, SignatureException, NormalizeCertificateException {
691 return isValid(validationServices);
692 }
693
694
695
696
697
698
699 public String getSignatureType () {
700 return "PDF";
701 }
702
703
704
705
706
707
708
709
710 public Date[] getSigningTimes () {
711 logger.debug("[PDFSignature.getSigningTimes]::Entrada");
712
713 PdfReader reader;
714 try {
715 reader = new PdfReader(this.pdfFile.getAbsolutePath());
716 } catch (IOException e) {
717
718 logger.info("[PDFSignature.getSigningTimes]::No se puede leer el contenido de este objeto", e);
719 return null;
720 }
721
722 AcroFields af = reader.getAcroFields();
723 ArrayList names = getRealSignatureNames(af);
724 Date[] dates = new Date[names.size()];
725 for (int i = 0; i < names.size(); i++) {
726 String name = (String)names.get(i);
727
728
729 PdfPKCS7 pkcs7 = af.verifySignature(name, CRYPTOGRAPHIC_PROVIDER_NAME);
730
731
732 if (pkcs7.getTimeStampDate() != null) {
733
734 logger.debug("[PDFSignature.getSigningTimes]::" + i + ": Obteniendo fecha de sello de tiempos");
735 dates[i] = pkcs7.getTimeStampDate().getTime();
736 } else {
737
738 logger.debug("[PDFSignature.getSigningTimes]::" + i + ": Obteniendo fecha de la firma");
739 dates[i] = pkcs7.getSignDate().getTime();
740 }
741 }
742
743 logger.debug("[PDFSignature.getSigningTimes]:: Devolviendo " + dates.length + " fechas de la firma");
744 return dates;
745 }
746
747
748
749 private void initialize (File pdfFile) throws PDFDocumentException, SignatureNotFoundException {
750 logger.debug("[PDFSignature.initialize]::Entrada::" + pdfFile);
751
752
753 try {
754 PdfReader reader = new PdfReader(pdfFile.getAbsolutePath());
755 AcroFields af = reader.getAcroFields();
756 ArrayList names = getRealSignatureNames(af);
757 if (names == null || names.isEmpty()) {
758 logger.info("[PDFSignature.initialize]::El documento PDF no está firmado");
759 pdfFile.delete();
760 throw new SignatureNotFoundException ("El documento PDF no está firmado");
761 }
762 for (Iterator iterator = names.iterator(); iterator.hasNext();) {
763 String name = (String) iterator.next();
764 PdfPKCS7 pkcs7 = af.verifySignature(name, CRYPTOGRAPHIC_PROVIDER_NAME);
765 }
766 } catch (IOException e) {
767 logger.info("[PDFSignature.initialize]::No se ha podido leer el fichero PDF", e);
768 pdfFile.delete();
769 throw new PDFDocumentException ("No se ha podido leer el fichero PDF", e);
770 }
771
772
773 this.pdfFile = pdfFile;
774
775 }
776
777
778
779
780
781 private ValidationResult[] isValidCommon(CAList caList, List<CertificateValidationService> validationServices) throws HashingException, SignatureException, NormalizeCertificateException {
782
783 logger.debug("[PDFSignature.isValidCommon]::Entrada::" + caList);
784
785 PdfReader reader;
786 try {
787 reader = new PdfReader(this.pdfFile.getAbsolutePath());
788 } catch (IOException e) {
789
790 logger.info("[PDFSignature.isValidCommon]::No se puede leer el contenido de este objeto", e);
791 return null;
792 }
793 AcroFields af = reader.getAcroFields();
794 List<String> names = getRealSignatureNames(af);
795 List<ValidationResult> results = new ArrayList<ValidationResult>();
796 for (int i = 0; i < names.size(); i++) {
797 String name = (String)names.get(i);
798
799
800 PdfPKCS7 pkcs7 = af.verifySignature(name, CRYPTOGRAPHIC_PROVIDER_NAME);
801 Date fechaFirma = pkcs7.getSignDate().getTime();
802
803
804 logger.debug("[PDFSignature.isValidCommon]::" + i + ": Obteniendo fecha de sello de tiempos");
805 TimeStamp ts = null;
806 if (pkcs7.getTimeStampDate() != null) {
807 logger.debug("[PDFSignature.isValidCommon]::" + i + ": La firma no contiene sello de tiempos");
808
809 try {
810
811 ts = new TimeStamp (pkcs7.getTimeStampToken().getEncoded());
812 fechaFirma = ts.getTime();
813 } catch (MalformedTimeStampException e) {
814 logger.info("[PAdESLTVSignature.isValidCommon]::El sello de tiempos del documento no es correcto", e);
815 throw new SignatureException ("El sello de tiempos del documento no es correcto", e);
816 } catch (IOException e) {
817 logger.info("[PAdESLTVSignature.isValidCommon]::Error de entrada/salida obteniendo el sello de tiempos", e);
818 throw new SignatureException ("Error de entrada/salida obteniendo el sello de tiempos", e);
819 }
820 }
821
822
823 List<BasicOCSPResp> basicOcspResponses = null;
824 if (pkcs7.getOcspResponses() != null && !pkcs7.getOcspResponses().isEmpty()) {
825 try {
826 basicOcspResponses = new ArrayList<BasicOCSPResp>();
827 for(BasicOCSPResp bResp : pkcs7.getOcspResponses()) {
828 basicOcspResponses.add(new BasicOCSPResp(BasicOCSPResponse.getInstance(bResp.getEncoded())));
829 }
830 } catch (IOException e) {
831 logger.info("[PAdESLTVSignature.isValid]::No se ha podido parsear la respuesta OCSP en el CAdES de la firma " + i, e);
832 }
833 }
834
835
836 ValidationResult validationResult;
837 try {
838 if (pkcs7.verify()) {
839 validationResult = new ValidationResult (pkcs7.getSigningCertificate(), fechaFirma, ts, null);
840 } else {
841 validationResult = new ValidationResult (ValidationResult.RESULT_SIGNATURE_NOT_MATCH_DATA, pkcs7.getSigningCertificate(), fechaFirma, ts, null);
842 }
843 } catch (java.security.SignatureException e) {
844 logger.info("[PDFSignature.isValidCommon]::Error en una de las firmas del PDF", e);
845 throw new SignatureException ("Error en una de las firmas del PDF", e);
846 }
847
848 if (validationResult.isValid()) {
849
850 if (ts != null) {
851 try {
852 if (!ts.isValid()) {
853 validationResult.setResult(ValidationResult.RESULT_INVALID_TIMESTAMP);
854 logger.debug("[PDFSignature.isValidCommon]::" + i + ": Resultado validación: El sello de tiempos no es válido");
855 } else {
856
857
858 Certificate signingCertificate = getSigningCertificate(pkcs7.getCertificates());
859 if (signingCertificate == null) {
860 logger.info("Hay un hueco sin firma con el nombre '" + name + "'");
861 continue;
862 }
863
864
865 int resultadoValidacion = validateFromCAdES(basicOcspResponses, signingCertificate, signingCertificate, ts);
866 if (resultadoValidacion == ValidationResult.RESULT_VALID) {
867 validationResult.setResult(resultadoValidacion);
868 } else {
869
870
871 if (caList != null) {
872 logger.debug("[PDFSignature.isValidCommon]::Se valida mediante CAList");
873 ValidateCertificate certificate = new ValidateCertificate (signingCertificate.toDER(), caList);
874 if (certificate.isActive()) {
875 validationResult.setResult(certificate.validate(pkcs7.getTimeStampDate().getTime()));
876 } else {
877 validationResult.setResult(certificate.validate());
878 }
879 } else {
880 logger.debug("[PDFSignature.isValidCommon]::Se valida mediante servicios de validación");
881 if (signingCertificate.isActive()) {
882 validationResult.setResult(signingCertificate.validate(validationServices, pkcs7.getTimeStampDate().getTime()).getResult());
883 } else {
884 validationResult.setResult(signingCertificate.validate(validationServices).getResult());
885 }
886 }
887
888 }
889 results.add(validationResult);
890 logger.debug("[PDFSignature.isValidCommon]::" + i + ": Resultado validación: " + validationResult.getResult());
891 }
892
893 } catch (CertificateCANotFoundException e) {
894 logger.info("[PDFSignature.isValidCommon]::Certificado" + i + " no pertenece a ninguna de las CAs ");
895 results.add(new ValidationResult(ValidationResult.RESULT_CERTIFICATE_CHAIN_VALIDATION_INVALID, pkcs7.getSigningCertificate(), null, ts, null));
896 continue;
897 } catch (MalformedTimeStampException e) {
898 logger.info("[PAdESLTVSignature.isValidCommon]::El sello de tiempos del documento no es correcto", e);
899 throw new SignatureException ("El sello de tiempos del documento no es correcto", e);
900 }
901 } else {
902 results.add(validationResult);
903 logger.debug("[PDFSignature.isValidCommon]::" + i + ": Resultado validación si sello de tiempos: " + validationResult.getResult());
904 }
905 }
906
907 }
908
909 reader.close();
910
911 return results.toArray(new ValidationResult[0]);
912 }
913
914 }