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.signature;
22
23 import java.io.ByteArrayInputStream;
24 import java.io.ByteArrayOutputStream;
25 import java.io.File;
26 import java.io.FileNotFoundException;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.OutputStream;
30 import java.net.MalformedURLException;
31 import java.net.URL;
32 import java.text.SimpleDateFormat;
33 import java.util.Arrays;
34 import java.util.Date;
35 import java.util.List;
36 import java.util.Properties;
37 import java.util.TimeZone;
38
39 import javax.activation.DataSource;
40 import javax.mail.MessagingException;
41 import javax.mail.Multipart;
42 import javax.mail.Session;
43 import javax.mail.internet.MimeBodyPart;
44 import javax.mail.internet.MimeMessage;
45 import javax.mail.internet.MimeMultipart;
46 import javax.mail.util.SharedByteArrayInputStream;
47
48 import org.apache.log4j.Logger;
49 import org.bouncycastle.cms.CMSException;
50 import org.bouncycastle.util.encoders.Hex;
51
52 import es.accv.arangi.base.certificate.Certificate;
53 import es.accv.arangi.base.certificate.validation.CAList;
54 import es.accv.arangi.base.certificate.validation.CertificateOCSPResponse;
55 import es.accv.arangi.base.certificate.validation.CertificateValidationService;
56 import es.accv.arangi.base.certificate.validation.OCSPResponse;
57 import es.accv.arangi.base.document.ByteArrayDocument;
58 import es.accv.arangi.base.document.IDocument;
59 import es.accv.arangi.base.exception.certificate.NormalizeCertificateException;
60 import es.accv.arangi.base.exception.certificate.validation.MalformedOCSPResponseException;
61 import es.accv.arangi.base.exception.certificate.validation.ServiceException;
62 import es.accv.arangi.base.exception.certificate.validation.ServiceNotFoundException;
63 import es.accv.arangi.base.exception.document.HashingException;
64 import es.accv.arangi.base.exception.signature.NoDocumentToSignException;
65 import es.accv.arangi.base.exception.signature.SignatureException;
66 import es.accv.arangi.base.exception.timestamp.MalformedTimeStampException;
67 import es.accv.arangi.base.signature.ISignature;
68 import es.accv.arangi.base.signature.Signature;
69 import es.accv.arangi.base.util.Util;
70 import es.accv.arangi.base.util.validation.ValidationResult;
71 import es.accv.arangi.exception.signature.ACCVWebServicesConnectionException;
72 import es.accv.arangi.exception.signature.MalformedTokenException;
73 import es.accv.arangi.timestamp.TimeStamp;
74 import es.accv.arangi.util.smime.SMIMESigned;
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93 public class ACCVValidationToken extends Signature {
94
95
96
97
98 Logger logger = Logger.getLogger(ACCVValidationToken.class);
99
100
101
102
103 public static final String URL_ACCV_WEBSERVICES = "http://webserv.pki.gva.es:8080/axis/services/serviciospki";
104
105
106
107
108 public static final String URL_ACCV_WEBSERVICES_TEST = "http://sleipnir2.pki.gva.es:8084/axis/services/serviciospki";
109
110
111
112
113 public static SimpleDateFormat VALIDATION_XML_DATE_FORMAT = new SimpleDateFormat ("yyyyMMddHHmmssz");
114
115
116
117
118 private MimeMessage token;
119
120
121
122
123 private byte[] tokenB64;
124
125
126
127
128 private PKCS7Signature pkcs7Signature;
129
130
131
132
133 private PKCS7Signature tokenSignature;
134
135
136
137
138 private TimeStamp timeStamp;
139
140
141
142
143 private OCSPResponse ocspResponse;
144
145
146
147
148 private TimeStamp archiveTimeStamp;
149
150
151
152
153 private OCSPResponse tsCertificateOcspResponse;
154
155 static {
156
157
158 VALIDATION_XML_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("Etc/GMT+0"));
159
160
161 addClassToSignatureValidation();
162 }
163
164
165
166
167
168
169
170
171
172
173 public ACCVValidationToken(byte[] bytesToken) throws MalformedTokenException {
174 initialize(bytesToken);
175 }
176
177
178
179
180
181
182
183
184
185 public ACCVValidationToken(File fileToken) throws MalformedTokenException, FileNotFoundException {
186 try {
187 initialize (Util.loadFile(fileToken));
188 } catch (IOException e) {
189 logger.info ("[ACCVValidationToken]::El fichero no existe o no se puede leer", e);
190 throw new FileNotFoundException ("El fichero no existe o no se puede leer");
191 }
192 }
193
194
195
196
197
198
199
200
201 public ACCVValidationToken(InputStream isToken) throws MalformedTokenException {
202 try {
203 initialize(Util.readStream(isToken));
204 } catch (IOException e) {
205 logger.info ("[ACCVValidationToken]::Ha ocurrido un error leyendo el stream de lectura", e);
206 throw new MalformedTokenException ("Ha ocurrido un error leyendo el stream de lectura", e);
207 }
208 }
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224 public ACCVValidationToken (IDocument document, es.accv.arangi.base.signature.PKCS7Signature pkcs7Signature) throws HashingException, SignatureException, MalformedTokenException, ACCVWebServicesConnectionException {
225 try {
226 initialize(document, pkcs7Signature, new URL(ACCVValidationToken.URL_ACCV_WEBSERVICES));
227 } catch (MalformedURLException e) {
228
229 }
230 }
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249 public ACCVValidationToken (IDocument document, es.accv.arangi.base.signature.PKCS7Signature pkcs7Signature, URL urlWebServices) throws HashingException, SignatureException, MalformedTokenException, ACCVWebServicesConnectionException {
250 initialize(document, pkcs7Signature, urlWebServices);
251 }
252
253
254
255
256
257 public Certificate[] getCertificates() {
258 return pkcs7Signature.getCertificates();
259 }
260
261
262
263
264 public IDocument getDocument() {
265 return null;
266 }
267
268
269
270
271
272 public ValidationResult[] isValid(CAList arg0) throws HashingException, SignatureException, NormalizeCertificateException,
273 NoDocumentToSignException {
274 throw new NoDocumentToSignException ("El token de validación de la ACCV nunca contiene el documento firmado, " +
275 "por lo que es imposible realizar esta validación");
276 }
277
278
279
280
281
282
283
284
285
286
287
288
289 public ValidationResult[] isValid(IDocument document, CAList caList) throws HashingException, SignatureException, NormalizeCertificateException {
290 return isValid(document);
291 }
292
293
294
295
296
297 public ValidationResult[] isValid(List<CertificateValidationService> validationServices)
298 throws HashingException, SignatureException, NormalizeCertificateException, NoDocumentToSignException {
299 throw new NoDocumentToSignException ("El token de validación de la ACCV nunca contiene el documento firmado, " +
300 "por lo que es imposible realizar esta validación");
301 }
302
303
304
305
306
307
308
309
310
311
312
313
314 public ValidationResult[] isValid(IDocument document, List<CertificateValidationService> validationServices)
315 throws HashingException, SignatureException, NormalizeCertificateException {
316 return isValid(document);
317 }
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340 public ValidationResult[] isValid (IDocument document) throws HashingException, SignatureException, NormalizeCertificateException {
341 return isValidWithHash(document.getHash());
342 }
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362 public ValidationResult[] isValidWithHash (byte[] hash) throws SignatureException {
363 logger.debug("[ACCVValidationToken.isValidWithHash]::Entrada::" + Arrays.asList(new Object[] { hash }));
364
365
366 Certificate certificate = null;
367 if (getCertificates() != null && getCertificates().length > 0) {
368 certificate = getCertificates()[0];
369 }
370
371
372 try {
373 SMIMESigned smimeSigned = new SMIMESigned((MimeMultipart) token.getContent());
374 ByteArrayOutputStream baos = new ByteArrayOutputStream();
375 smimeSigned.getContent().writeTo(baos);
376 ByteArrayDocument tokenDocument = new ByteArrayDocument(baos.toByteArray());
377 ValidationResult[] validationResults = this.tokenSignature.isValidSignatureOnly(tokenDocument);
378 for (int i = 0; i < validationResults.length; i++) {
379 if (!validationResults[i].isValid()) {
380 logger.debug("[ACCVValidationToken.isValidWithHash]::La firma del token no se corresponde con el contenido del mismo: " + validationResults[i].getResultText());
381 return new ValidationResult[] {new ValidationResult(ValidationResult.RESULT_INVALID, certificate.toX509Certificate(), null, getTimeStamp(), new OCSPResponse[] { getOcspResponse() }) };
382 }
383 }
384 } catch (Exception e1) {
385 logger.debug("[ACCVValidationToken.isValidWithHash]::No es posible validar la firma del token");
386 return new ValidationResult[] {new ValidationResult(ValidationResult.RESULT_INVALID, certificate.toX509Certificate(), null, getTimeStamp(), new OCSPResponse[] { getOcspResponse() }) };
387 }
388
389
390 ValidationResult[] validationResults = this.pkcs7Signature.isValidSignatureOnlyWithHash(hash);
391 for (int i = 0; i < validationResults.length; i++) {
392 if (!validationResults[i].isValid()) {
393 logger.debug("[ACCVValidationToken.isValidWithHash]::El PKCS#7 no se corresponde con el documento: " + validationResults[i].getResultText());
394 return new ValidationResult[] {new ValidationResult(ValidationResult.RESULT_SIGNATURE_NOT_MATCH_DATA, certificate.toX509Certificate(), null, getTimeStamp(), new OCSPResponse[] { getOcspResponse() }) };
395 }
396 }
397
398
399 boolean timeStampValid;
400 try {
401 timeStampValid = this.timeStamp.isValid();
402 } catch (MalformedTimeStampException e) {
403 logger.debug("[ACCVValidationToken.isValidWithHash]::El sello de tiempos se halla mal formado", e);
404 return new ValidationResult[] {new ValidationResult(ValidationResult.RESULT_INVALID_TIMESTAMP, certificate.toX509Certificate(), null, getTimeStamp(), new OCSPResponse[] { getOcspResponse() }) };
405 }
406 if (!timeStampValid) {
407
408 logger.debug("[ACCVValidationToken.isValidWithHash]::El sello de tiempos no es válido");
409 }
410
411
412 Date tsDate = this.timeStamp.getTime();
413
414
415
416 CertificateOCSPResponse[] ocspResponses = this.ocspResponse.getSingleResponses();
417 for(int i=0;i<ocspResponses.length;i++) {
418 if (ocspResponses[i].getValidityPeriodBeginning().after(tsDate) ||
419 ocspResponses[i].getValidityPeriodEnd().before(tsDate)) {
420 logger.debug("[ACCVValidationToken.isValidWithHash]::La fecha del sello de tiempos no se encuentra en el periodo de validez de la respuesta OCSP");
421 return new ValidationResult[] {new ValidationResult(ValidationResult.RESULT_TIMESTAMP_AFTER_VALIDITY_ITEM, certificate.toX509Certificate(), null, getTimeStamp(), new OCSPResponse[] { getOcspResponse() }) };
422 }
423 }
424
425
426 for(int i=0;i<ocspResponses.length;i++) {
427 if (!ocspResponses[i].match(certificate)) {
428 logger.debug("[ACCVValidationToken.isValidWithHash]::La respuesta OCSP del token no se corresponde con el certificado");
429 return new ValidationResult[] {new ValidationResult(ValidationResult.RESULT_INVALID_VALIDITY_ITEM, certificate.toX509Certificate(), null, getTimeStamp(), new OCSPResponse[] { getOcspResponse() }) };
430 }
431 }
432
433
434 for(int i=0;i<ocspResponses.length;i++) {
435 if (ocspResponses[i].getStatus() != ValidationResult.RESULT_VALID) {
436 logger.debug("[ACCVValidationToken.isValidWithHash]::La respuesta OCSP del token no es una respuesta válida: " + ocspResponses[i].getStatus());
437 return new ValidationResult[] {new ValidationResult(ValidationResult.RESULT_INVALID_VALIDITY_ITEM, certificate.toX509Certificate(), null, getTimeStamp(), new OCSPResponse[] { getOcspResponse() }) };
438 }
439 }
440
441
442 logger.debug("[ACCVValidationToken.isValidWithHash]::TOKEN VÁLIDO");
443 return new ValidationResult[] {new ValidationResult(ValidationResult.RESULT_VALID, certificate.toX509Certificate(), null, getTimeStamp(), new OCSPResponse[] { getOcspResponse() }) };
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 public String getValidationXML (byte[] hash) {
477 logger.debug("[ACCVValidationToken.getValidationXML]::Entrada::" + Arrays.asList(new Object[] { hash }));
478
479
480 Certificate certificate = null;
481 if (getCertificates() != null && getCertificates().length > 0) {
482 certificate = getCertificates()[0];
483 }
484
485
486 try {
487 SMIMESigned smimeSigned = new SMIMESigned((MimeMultipart) token.getContent());
488 ByteArrayOutputStream baos = new ByteArrayOutputStream();
489 smimeSigned.getContent().writeTo(baos);
490 ByteArrayDocument tokenDocument = new ByteArrayDocument(baos.toByteArray());
491 ValidationResult[] validationResults = this.tokenSignature.isValidSignatureOnly(tokenDocument);
492 for (int i = 0; i < validationResults.length; i++) {
493 if (!validationResults[i].isValid()) {
494 logger.debug("[ACCVValidationToken.getValidationXML]::La firma del token no se corresponde con el contenido del mismo: " + validationResults[i].getResultText());
495 return getXMLValidacionError();
496 }
497 }
498 } catch (Exception e) {
499 logger.debug("[ACCVValidationToken.getValidationXML]::No es posible validar la firma del token", e);
500 return getXMLValidacionError();
501 }
502
503
504 ValidationResult[] validationResults;
505 try {
506 validationResults = this.pkcs7Signature.isValidSignatureOnlyWithHash(hash);
507 } catch (SignatureException e1) {
508 logger.debug("[ACCVValidationToken.getValidationXML]::Error validando el PKCS#7");
509 return getXMLFirmaDocumentoNoMatch();
510 }
511 for (int i = 0; i < validationResults.length; i++) {
512 if (!validationResults[i].isValid()) {
513 logger.debug("[ACCVValidationToken.getValidationXML]::El PKCS#7 no se corresponde con el documento: " + validationResults[i].getResultText());
514 return getXMLFirmaDocumentoNoMatch();
515 }
516 }
517
518
519 String textoTS = null;
520 try {
521 if (!this.timeStamp.isValid()) {
522
523 logger.debug("[ACCVValidationToken.getValidationXML]::El sello de tiempos no es válido");
524 }
525 } catch (MalformedTimeStampException e) {
526 logger.debug("[ACCVValidationToken.getValidationXML]::El sello de tiempos se halla mal formado", e);
527 textoTS = "Fallo al verificar el sello de tiempos";
528 }
529
530
531 Date tsDate = this.timeStamp.getTime();
532
533
534
535 String textoOCSP = null;
536 CertificateOCSPResponse[] ocspResponses = this.ocspResponse.getSingleResponses();
537 for(int i=0;i<ocspResponses.length;i++) {
538 if (ocspResponses[i].getValidityPeriodBeginning().after(tsDate) ||
539 ocspResponses[i].getValidityPeriodEnd().before(tsDate)) {
540 logger.debug("[ACCVValidationToken.getValidationXML]::La fecha del sello de tiempos no se encuentra en el periodo de validez de la respuesta OCSP");
541 textoOCSP = "No es valida en la fecha del sello";
542 }
543 }
544
545
546 for(int i=0;i<ocspResponses.length;i++) {
547 if (!ocspResponses[i].match(certificate)) {
548 logger.debug("[ACCVValidationToken.getValidationXML]::La respuesta OCSP del token no se corresponde con el certificado");
549 textoOCSP = "No valida";
550 }
551 }
552
553
554 for(int i=0;i<ocspResponses.length;i++) {
555 if (ocspResponses[i].getStatus() != ValidationResult.RESULT_VALID) {
556 logger.debug("[ACCVValidationToken.getValidationXML]::La respuesta OCSP del token no es una respuesta válida: " + ocspResponses[i].getStatus());
557 textoOCSP = "No valida";
558 }
559 }
560
561
562 logger.debug("[ACCVValidationToken.getValidationXML]::TOKEN VÁLIDO");
563 return getXMLFirmaOk (textoTS, textoOCSP, certificate, tsDate);
564 }
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579 public boolean isValid (IDocument document, URL urlWebServices) throws HashingException, ACCVWebServicesConnectionException {
580 logger.debug("[ACCVValidationToken.isValid]::Entrada::" + document);
581
582
583 String message = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
584 "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
585 "<soapenv:Body><ns1:getEstadoToken_hash soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"urn:serviciospki\">" +
586 "<in0 xsi:type=\"xsd:string\">" + new String (Hex.encode(document.getHash())) + "</in0>" +
587 "<in1 xsi:type=\"xsd:string\">" + new String (this.tokenB64) + "</in1>" +
588 "</ns1:getEstadoToken_hash></soapenv:Body></soapenv:Envelope>";
589
590 try {
591
592 StringBuffer sb = Util.sendPost(message, urlWebServices);
593
594
595 if (sb.indexOf("-1") > -1) {
596 return false;
597 } else {
598 return true;
599 }
600
601 } catch (ServiceNotFoundException e) {
602 logger.info("[ACCVValidationToken.isValid]::Error de conexión en la URL '" + urlWebServices + "'", e);
603 throw new ACCVWebServicesConnectionException ("Error de conexión en la URL '" + urlWebServices + "'", e);
604 } catch (ServiceException e) {
605 logger.info("[ACCVValidationToken.isValid]::No se puede obtener una respuesta correcta de la URL '" + urlWebServices + "'", e);
606 throw new ACCVWebServicesConnectionException ("No se puede obtener una respuesta correcta de la URL '" + urlWebServices + "'", e);
607 }
608
609 }
610
611
612
613
614
615 public ValidationResult[] isValidSignatureOnly() throws HashingException, SignatureException, NoDocumentToSignException {
616 throw new NoDocumentToSignException ("El token de validación de la ACCV nunca contiene el documento firmado, " +
617 "por lo que es imposible realizar esta validación");
618 }
619
620
621
622
623 public ValidationResult[] isValidSignatureOnly(IDocument document) throws HashingException, SignatureException {
624 return pkcs7Signature.isValidSignatureOnly(document);
625 }
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
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
692
693
694
695
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
722
723
724
725
726
727
728
729 public TimeStamp getTimeStamp() {
730 return timeStamp;
731 }
732
733
734
735
736
737
738 public OCSPResponse getOcspResponse() {
739 return ocspResponse;
740 }
741
742
743
744
745
746
747 public PKCS7Signature getPkcs7Signature() {
748 return pkcs7Signature;
749 }
750
751
752
753
754
755
756
757 public void save (File file) throws IOException {
758 logger.debug ("[CMSPKCS7Signature.save]::Entrada::" + file);
759
760 Util.saveFile(file, this.tokenB64);
761 }
762
763
764
765
766
767
768
769 public void save (OutputStream out) throws IOException {
770 logger.debug ("[CMSPKCS7Signature.save]::Entrada::" + out);
771
772 Util.save(out, this.tokenB64);
773 }
774
775
776
777
778 public static String getXMLValidacionError() {
779 return "<?xml version=\"1.0\"?><ERROR><FIRMA>No se ha podido verificar la firma de la aplicacion.</FIRMA></ERROR>";
780 }
781
782
783
784
785
786
787
788
789
790
791
792 public static ISignature getSignatureInstance (byte[] bSignature) throws Exception {
793 return new ACCVValidationToken(bSignature);
794 }
795
796
797
798
799
800
801 public static void addClassToSignatureValidation () {
802 Signature.addRecognizerClass(ACCVValidationToken.class);
803 }
804
805
806
807
808
809
810 public byte[] toByteArray() {
811 return this.tokenB64;
812 }
813
814 public String getSignatureType() {
815 return "Token Validación ACCV";
816 }
817
818
819
820
821
822
823 private void initialize(byte[] bytesToken) throws MalformedTokenException {
824
825 logger.debug("[ACCVValidationToken.initialize]::Entrada::" + bytesToken);
826
827
828 ByteArrayInputStream bais = new ByteArrayInputStream (Util.decodeBase64(new String (bytesToken)));
829
830 try {
831
832
833 Properties properties = new Properties();
834 Session session = Session.getDefaultInstance(properties, null);
835
836
837 token = new MimeMessage(session, bais);
838 SMIMESigned smimeSigned = new SMIMESigned((MimeMultipart) token.getContent());
839 Multipart multiPart = (Multipart) smimeSigned.getContent().getContent();
840 if (multiPart.getCount() != 3) {
841 throw new SignatureException("El token contiene " + multiPart.getCount() + " multiparts en lugar de 3");
842 }
843
844
845 MimeBodyPart partFirma = (MimeBodyPart) multiPart.getBodyPart(0);
846 SharedByteArrayInputStream sbais = (SharedByteArrayInputStream)partFirma.getContent();
847 String pkcs7SignatureB64 = new String(Util.readStream(sbais));
848 pkcs7Signature = new PKCS7Signature (Util.decodeBase64(pkcs7SignatureB64));
849
850
851 MimeBodyPart partOCSP = (MimeBodyPart) multiPart.getBodyPart(1);
852 com.sun.mail.util.BASE64DecoderStream decoderStream = (com.sun.mail.util.BASE64DecoderStream)partOCSP.getContent();
853 byte[] abRet = new byte[decoderStream.available()];
854 decoderStream.read(abRet);
855 ocspResponse = new OCSPResponse(abRet);
856
857
858 MimeBodyPart partTSS = (MimeBodyPart) multiPart.getBodyPart(2);
859 decoderStream = (com.sun.mail.util.BASE64DecoderStream)partTSS.getContent();
860 abRet = new byte[decoderStream.available()];
861 decoderStream.read(abRet);
862 timeStamp = new TimeStamp (abRet);
863
864
865 tokenSignature = new PKCS7Signature (smimeSigned.getEncoded());
866
867
868 tokenB64 = bytesToken;
869
870 } catch (MessagingException e) {
871 logger.info("[ACCVValidationToken.initialize]::El token no es un SMIME correcto", e);
872 throw new MalformedTokenException ("El token no es un SMIME correcto", e);
873 } catch (IOException e) {
874 logger.info("[ACCVValidationToken.initialize]::No se puede leer alguna de las partes del token", e);
875 throw new MalformedTokenException ("No se puede leer alguna de las partes del token", e);
876 } catch (CMSException e) {
877 logger.info("[ACCVValidationToken.initialize]::No se ha encontrado la firma del SMIME o ésta no es correcta", e);
878 throw new MalformedTokenException ("No se ha encontrado la firma del SMIME o ésta no es correcta", e);
879 } catch (NormalizeCertificateException e) {
880 logger.info("[ACCVValidationToken.initialize]::El certificado de la firma PKCS#7 no puede ser tratado por el proveedor criptográfico de Arangi", e);
881 throw new MalformedTokenException ("El certificado de la firma PKCS#7 no puede ser tratado por el proveedor criptográfico de Arangi", e);
882 } catch (MalformedOCSPResponseException e) {
883 logger.info("[ACCVValidationToken.initialize]::La respuesta OCSP del token no está bien construída", e);
884 throw new MalformedTokenException ("La respuesta OCSP del token no está bien construída", e);
885 } catch (MalformedTimeStampException e) {
886 logger.info("[ACCVValidationToken.initialize]::El sello de tiempos del token no está bien construído", e);
887 throw new MalformedTokenException ("El sello de tiempos del token no está bien construído", e);
888 } catch (SignatureException e) {
889 logger.info("[ACCVValidationToken.initialize]::Error obteniendo los certificados del PKCS#7", e);
890 throw new MalformedTokenException ("Error obteniendo los certificados del PKCS#7", e);
891 } catch (Exception e) {
892 logger.info("[ACCVValidationToken.initialize]::La firma no parece un token de validación de la ACCV en base64", e);
893 throw new MalformedTokenException ("La firma no parece un token de validación de la ACCV en base64", e);
894 }
895
896 }
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915 private void initialize (IDocument document, es.accv.arangi.base.signature.PKCS7Signature pkcs7Signature, URL urlWebServices) throws HashingException, SignatureException, MalformedTokenException, ACCVWebServicesConnectionException {
916 logger.debug("[ACCVValidationToken.initialize]::Entrada::" + document);
917
918
919 String message = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
920 "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
921 "<soapenv:Body><ns1:getToken_hash soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:ns1=\"urn:serviciospki\">" +
922 "<in0 xsi:type=\"xsd:string\">" + new String (Hex.encode(document.getHash())) + "</in0>" +
923 "<in1 xsi:type=\"xsd:string\">" + Util.encodeBase64(pkcs7Signature.toByteArray()) + "</in1>" +
924 "</ns1:getToken_hash></soapenv:Body></soapenv:Envelope>";
925
926 StringBuffer sb;
927 try {
928 sb = Util.sendPost(message, urlWebServices);
929 logger.debug("[ACCVValidationToken.initialize]::Response::" + sb.toString());
930
931 } catch (ServiceNotFoundException e) {
932 logger.info("[ACCVValidationToken.isValid]::Error de conexión en la URL '" + urlWebServices + "'", e);
933 throw new ACCVWebServicesConnectionException ("Error de conexión en la URL '" + urlWebServices + "'", e);
934 } catch (ServiceException e) {
935 logger.info("[ACCVValidationToken.isValid]::No se puede obtener una respuesta correcta de la URL '" + urlWebServices + "'", e);
936 throw new ACCVWebServicesConnectionException ("No se puede obtener una respuesta correcta de la URL '" + urlWebServices + "'", e);
937 }
938
939
940 if (sb.indexOf("getToken_hashReturn") > -1) {
941
942 String finalMessage = sb.substring(sb.indexOf("getToken_hashReturn"));
943 finalMessage = finalMessage.substring(finalMessage.indexOf(">") + 1);
944 finalMessage = finalMessage.substring(0, finalMessage.indexOf("<"));
945 if (finalMessage.equals("Fallo al verificar la firma.")) {
946 logger.info("[ACCVValidationToken.initialize]::Fallo al verificar la firma");
947 throw new SignatureException ("El servicio web de la ACCV devuelve un fallo al verificar la firma");
948 }
949 if (finalMessage.equals("Imposible comprobar el Certificado")) {
950 logger.info("[ACCVValidationToken.initialize]::Imposible comprobar el Certificado");
951 throw new SignatureException ("El servicio web de la ACCV devuelve que es imposible comprobar el certificado");
952 }
953
954 initialize(finalMessage.getBytes());
955 }
956 }
957
958
959
960
961
962 private static String getXMLFirmaDocumentoNoMatch() {
963 return "<?xml version=\"1.0\"?><APLICACION>Se ha verificado la firma de la aplicacion</APLICACION><FIRMA>Fallo al verificar la firma</FIRMA>";
964 }
965
966
967
968
969 private static String getXMLFirmaOk(String textoTS,
970 String textoOCSP, Certificate certificate, Date tsDate) {
971 return "<?xml version=\"1.0\"?><APLICACION>Se ha verificado la firma de la aplicacion</APLICACION>" +
972 "<FIRMA>Resultado de la firma original<FIRMANTE>" + certificate.getSubjectDN().replaceAll("SERIALNUMBER=", "SN=") + "</FIRMANTE>" +
973 "<CERTIFICADO>" + (textoOCSP != null ? "Certificado no Valido" : "Certificado Valido") +
974 "</CERTIFICADO></FIRMA><OCSP>" + (textoOCSP != null ? textoOCSP : "Valido") +
975 "</OCSP><TSS>" + (textoTS != null ? textoTS : VALIDATION_XML_DATE_FORMAT.format(tsDate)) + "</TSS>";
976 }
977
978
979
980
981
982
983 public class TokenDataSource implements DataSource {
984
985 byte[] contenido;
986 String contentType;
987 String name;
988
989 public TokenDataSource (byte[] contenido, String contentType, String name) {
990 this.contenido = contenido;
991 this.contentType = contentType;
992 this.name = name;
993 }
994
995 public String getContentType() {
996 return this.contentType;
997 }
998
999 public InputStream getInputStream() throws IOException {
1000 return new ByteArrayInputStream(this.contenido);
1001 }
1002
1003 public String getName() {
1004 return this.name;
1005 }
1006
1007 public OutputStream getOutputStream() throws IOException {
1008 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1009 return baos;
1010 }
1011
1012 }
1013
1014 }