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.timestamp;
22
23 import java.io.ByteArrayInputStream;
24 import java.io.ByteArrayOutputStream;
25 import java.io.DataInputStream;
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.FileNotFoundException;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.OutputStream;
32 import java.math.BigInteger;
33 import java.net.HttpURLConnection;
34 import java.net.URL;
35 import java.security.NoSuchAlgorithmException;
36 import java.util.ArrayList;
37 import java.util.Arrays;
38 import java.util.Date;
39 import java.util.Hashtable;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.Map;
43
44 import org.apache.log4j.Logger;
45 import org.bouncycastle.asn1.ASN1Encoding;
46 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
47 import org.bouncycastle.asn1.ASN1Sequence;
48 import org.bouncycastle.asn1.cmp.PKIFailureInfo;
49 import org.bouncycastle.asn1.cmp.PKIFreeText;
50 import org.bouncycastle.asn1.cmp.PKIStatus;
51 import org.bouncycastle.asn1.cmp.PKIStatusInfo;
52 import org.bouncycastle.asn1.tsp.TimeStampResp;
53 import org.bouncycastle.cert.X509CertificateHolder;
54 import org.bouncycastle.cms.CMSException;
55 import org.bouncycastle.cms.CMSSignatureAlgorithmNameGenerator;
56 import org.bouncycastle.cms.CMSSignedData;
57 import org.bouncycastle.cms.DefaultCMSSignatureAlgorithmNameGenerator;
58 import org.bouncycastle.cms.SignerInformationVerifier;
59 import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
60 import org.bouncycastle.operator.DigestCalculatorProvider;
61 import org.bouncycastle.operator.OperatorCreationException;
62 import org.bouncycastle.operator.SignatureAlgorithmIdentifierFinder;
63 import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
64 import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
65 import org.bouncycastle.tsp.TSPException;
66 import org.bouncycastle.tsp.TSPValidationException;
67 import org.bouncycastle.tsp.TimeStampRequest;
68 import org.bouncycastle.tsp.TimeStampRequestGenerator;
69 import org.bouncycastle.tsp.TimeStampResponse;
70 import org.bouncycastle.tsp.TimeStampToken;
71 import org.bouncycastle.util.Store;
72
73 import es.accv.arangi.base.ArangiObject;
74 import es.accv.arangi.base.algorithm.HashingAlgorithm;
75 import es.accv.arangi.base.certificate.Certificate;
76 import es.accv.arangi.base.document.ByteArrayDocument;
77 import es.accv.arangi.base.document.Document;
78 import es.accv.arangi.base.document.FileDocument;
79 import es.accv.arangi.base.document.InputStreamDocument;
80 import es.accv.arangi.base.document.URLDocument;
81 import es.accv.arangi.base.exception.certificate.NormalizeCertificateException;
82 import es.accv.arangi.base.exception.document.HashingException;
83 import es.accv.arangi.base.exception.document.InitDocumentException;
84 import es.accv.arangi.base.exception.timestamp.MalformedTimeStampException;
85 import es.accv.arangi.base.exception.timestamp.ResponseTimeStampException;
86 import es.accv.arangi.base.exception.timestamp.TimeStampServerConnectionException;
87 import es.accv.arangi.base.util.Util;
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 public class TimeStamp extends ArangiObject implements Comparable<TimeStamp>{
115
116
117
118
119 static Logger logger = Logger.getLogger(TimeStamp.class);
120
121
122
123
124 private TimeStampToken timeStamp;
125
126
127
128
129
130
131
132
133 public TimeStamp (TimeStampToken timeStamp) {
134 logger.debug("[TimeStamp(File)]::Entrada::" + timeStamp);
135
136 this.timeStamp = timeStamp;
137 }
138
139
140
141
142
143
144
145
146
147 public TimeStamp (File fileTimeStamp) throws MalformedTimeStampException, FileNotFoundException {
148 logger.debug("[TimeStamp(File)]::Entrada::" + fileTimeStamp);
149
150 FileInputStream fis = null;
151 try {
152
153 fis = new FileInputStream (fileTimeStamp);
154
155
156 initialize (fis);
157 } catch (FileNotFoundException e) {
158 logger.info("[TimeStamp(File)]::No se ha podido encontrar el fichero " + fileTimeStamp.getAbsolutePath(), e);
159 throw e;
160 } finally {
161 if (fis != null) {
162 try {
163 fis.close();
164 } catch (IOException e) {
165 logger.info("[TimeStamp(File)]::No se ha podido cerrar el stream de lectura al fichero " + fileTimeStamp.getAbsolutePath());
166 }
167 }
168 }
169 }
170
171
172
173
174
175
176
177
178 public TimeStamp (InputStream isTimeStamp) throws MalformedTimeStampException {
179 logger.debug("[TimeStamp(InputStream)]::Entrada::" + isTimeStamp);
180
181
182 initialize (isTimeStamp);
183 }
184
185
186
187
188
189
190
191
192 public TimeStamp (byte[] bytesTimeStamp) throws MalformedTimeStampException {
193 logger.debug("[TimeStamp(byte[])]::Entrada::" + bytesTimeStamp);
194
195 ByteArrayInputStream bais = null;
196 try {
197
198 bais = new ByteArrayInputStream (bytesTimeStamp);
199
200
201 initialize (bais);
202 } finally {
203 if (bais != null) {
204 try {
205 bais.close();
206 } catch (IOException e) {
207 logger.info("[TimeStamp(byte[])]::No se ha podido cerrar el stream de lectura");
208 }
209 }
210 }
211 }
212
213
214
215
216
217
218
219 public Date getTime () {
220 logger.debug("[TimeStamp.getTime]::Entrada");
221
222 return timeStamp.getTimeStampInfo().getGenTime();
223 }
224
225
226
227
228 public BigInteger getNonce () {
229 logger.debug("[TimeStamp.getNonce]::Entrada");
230
231 return timeStamp.getTimeStampInfo().getNonce();
232 }
233
234
235
236
237
238
239 public byte[] toDER () {
240 logger.debug("[TimeStamp.toDER]::Entrada");
241
242 try {
243 return timeStamp.getEncoded();
244 } catch (IOException e) {
245
246 return null;
247 }
248 }
249
250
251
252
253
254
255 public byte[] getHash () {
256 logger.debug("[TimeStamp.getDataStamped]::Entrada");
257
258 return timeStamp.getTimeStampInfo().getMessageImprintDigest();
259 }
260
261
262
263
264
265
266
267 public String getHashAlgorithm () {
268 logger.debug("[TimeStamp.getHashAlgorithm]::Entrada");
269
270 return timeStamp.getTimeStampInfo().getMessageImprintAlgOID().getId();
271 }
272
273
274
275
276
277
278
279
280 public String getHashAlgorithmName () throws NoSuchAlgorithmException {
281 logger.debug("[TimeStamp.getHashAlgorithmName]::Entrada");
282
283 return HashingAlgorithm.getAlgorithmName(timeStamp.getTimeStampInfo().getMessageImprintAlgOID().getId());
284 }
285
286
287
288
289
290
291 public String getPolicyOID () {
292 logger.debug("[TimeStamp.getPolicyOID]::Entrada");
293
294 return timeStamp.getTimeStampInfo().getPolicy().getId();
295 }
296
297
298
299
300
301
302 public String getTSA () {
303 logger.debug("[TimeStamp.getTSA]::Entrada");
304 if (timeStamp.getTimeStampInfo() == null || timeStamp.getTimeStampInfo().getTsa() == null) {
305 return null;
306 }
307
308 return timeStamp.getTimeStampInfo().getTsa().toString();
309 }
310
311
312
313
314
315
316
317
318
319 public Certificate getSignatureCertificate () throws MalformedTimeStampException {
320 logger.debug("[TimeStamp.getSignatureCertificate]::Entrada");
321
322 Store certs = timeStamp.getCertificates();
323
324 Iterator<X509CertificateHolder> iterator1 = certs.getMatches(timeStamp.getSID()).iterator();
325 Iterator<X509CertificateHolder> iterator2 = certs.getMatches(timeStamp.getSID()).iterator();
326
327 List<String> lIssuers = new ArrayList<String>();
328
329 while (iterator1.hasNext()) {
330 try {
331 Certificate certificate = new Certificate (iterator1.next());
332 lIssuers.add(certificate.getIssuerDN());
333 } catch (NormalizeCertificateException e) {
334 logger.info("[TimeStamp.getSignatureCertificate]::El certificado contenido en el sello de tiempos no puede " +
335 "ser normalizado de acuerdo al proveedor criptográfico de Arangi", e);
336 }
337 }
338
339 while (iterator2.hasNext()) {
340 try {
341 Certificate certificate = new Certificate (iterator2.next());
342 if (!lIssuers.contains(certificate.getSubjectDN())) {
343 logger.debug("[TimeStamp.getSignatureCertificate]::Encontrado certificado de sello: " + certificate.getCommonName());
344 return certificate;
345 }
346 } catch (NormalizeCertificateException e) {
347 logger.info("[TimeStamp.getSignatureCertificate]::El certificado contenido en el sello de tiempos no puede " +
348 "ser normalizado de acuerdo al proveedor criptográfico de Arangi", e);
349 }
350 }
351
352 throw new MalformedTimeStampException ("No se ha encontrado un certificado normalizable de sello de" +
353 " tiempos en el sello de tiempos");
354
355 }
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375 public boolean isValid () throws MalformedTimeStampException {
376 logger.debug("[TimeStamp.isValid]::Entrada::" + timeStamp);
377
378
379 Certificate certificate = getSignatureCertificate();
380 logger.debug("Certificado timestamp: " + certificate);
381
382
383 try {
384 JcaContentVerifierProviderBuilder qaz = new JcaContentVerifierProviderBuilder();
385 CMSSignatureAlgorithmNameGenerator sang = new DefaultCMSSignatureAlgorithmNameGenerator();
386 SignatureAlgorithmIdentifierFinder saif = new DefaultSignatureAlgorithmIdentifierFinder();
387 DigestCalculatorProvider dcp = new JcaDigestCalculatorProviderBuilder().build();
388 SignerInformationVerifier siv = new SignerInformationVerifier(sang, saif, qaz.build(certificate.toX509Certificate()), dcp);
389 timeStamp.validate(siv);
390 } catch (TSPValidationException e) {
391 logger.debug("[TimeStamp.isValid]::La firma no es válida", e);
392 return false;
393 } catch (TSPException e) {
394 logger.debug("[TimeStamp.isValid]::El CMS de la firma no es correcto", e);
395 return false;
396 } catch (OperatorCreationException e) {
397 logger.debug("[TimeStamp.isValid]::No es posible obtener el validador del certificado de firma de la TSA", e);
398 return false;
399 }
400
401
402 return true;
403 }
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423 public static boolean validate (TimeStamp timeStamp) throws MalformedTimeStampException {
424 return timeStamp.isValid ();
425 }
426
427
428
429 public int compareTo(TimeStamp ts) {
430 return getTime().compareTo(ts.getTime());
431 }
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450 public static TimeStamp stampDocument (File file, URL serverTimeStampURL, TimeStampRequestParameters parameters) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException, InitDocumentException {
451 FileDocument document = new FileDocument(file);
452 try {
453 return stampHash (document.getHash(), serverTimeStampURL, HashingAlgorithm.getDefault(), parameters);
454 } catch (NoSuchAlgorithmException e) {
455
456 return null;
457 }
458 }
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474 public static TimeStamp stampDocument (File file, URL serverTimeStampURL) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException, InitDocumentException {
475 FileDocument document = new FileDocument(file);
476 return TimeStamp.stampHash(document.getHash(), serverTimeStampURL);
477 }
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493 public static TimeStamp stampDocument (byte[] bDocument, URL serverTimeStampURL, TimeStampRequestParameters parameters) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException {
494 ByteArrayDocument document = new ByteArrayDocument(bDocument);
495 try {
496 return stampHash (document.getHash(), serverTimeStampURL, HashingAlgorithm.getDefault(), parameters);
497 } catch (NoSuchAlgorithmException e) {
498
499 return null;
500 }
501 }
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516 public static TimeStamp stampDocument (byte[] bDocument, URL serverTimeStampURL) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException {
517 ByteArrayDocument document = new ByteArrayDocument(bDocument);
518 return TimeStamp.stampHash(document.getHash(), serverTimeStampURL);
519 }
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535 public static TimeStamp stampDocument (InputStream stream, URL serverTimeStampURL, TimeStampRequestParameters parameters) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException {
536 InputStreamDocument document = new InputStreamDocument(stream);
537 try {
538 return stampHash (document.getHash(), serverTimeStampURL, HashingAlgorithm.getDefault(), parameters);
539 } catch (NoSuchAlgorithmException e) {
540
541 return null;
542 }
543 }
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558 public static TimeStamp stampDocument (InputStream stream, URL serverTimeStampURL) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException {
559 InputStreamDocument document = new InputStreamDocument(stream);
560 return TimeStamp.stampHash(document.getHash(), serverTimeStampURL);
561 }
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578 public static TimeStamp stampDocument (URL urlDocument, URL serverTimeStampURL, TimeStampRequestParameters parameters) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException, InitDocumentException {
579 URLDocument document = new URLDocument(urlDocument);
580 try {
581 return stampHash (document.getHash(), serverTimeStampURL, HashingAlgorithm.getDefault(), parameters);
582 } catch (NoSuchAlgorithmException e) {
583
584 return null;
585 }
586 }
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602 public static TimeStamp stampDocument (URL urlDocument, URL serverTimeStampURL) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException, InitDocumentException {
603 URLDocument document = new URLDocument(urlDocument);
604 return TimeStamp.stampHash(document.getHash(), serverTimeStampURL);
605 }
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621 public static TimeStamp stampDocument (Document document, URL serverTimeStampURL, TimeStampRequestParameters parameters) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException {
622 try {
623 return stampHash (document.getHash(), serverTimeStampURL, HashingAlgorithm.getDefault(), parameters);
624 } catch (NoSuchAlgorithmException e) {
625
626 return null;
627 }
628 }
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643 public static TimeStamp stampDocument (Document document, URL serverTimeStampURL) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException {
644 return TimeStamp.stampHash(document.getHash(), serverTimeStampURL);
645 }
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664 public static TimeStamp stampDocument (File file, URL serverTimeStampURL, String hashingAlgorithm, TimeStampRequestParameters parameters) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException, InitDocumentException, NoSuchAlgorithmException {
665 FileDocument document = new FileDocument(file);
666 return TimeStamp.stampHash(document.getHash(hashingAlgorithm), serverTimeStampURL, hashingAlgorithm, parameters);
667 }
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684 public static TimeStamp stampDocument (File file, URL serverTimeStampURL, String hashingAlgorithm) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException, InitDocumentException {
685 FileDocument document = new FileDocument(file);
686 return TimeStamp.stampHash(document.getHash(hashingAlgorithm), serverTimeStampURL);
687 }
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705 public static TimeStamp stampDocument (byte[] bDocument, URL serverTimeStampURL, String hashingAlgorithm, TimeStampRequestParameters parameters) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException, NoSuchAlgorithmException {
706 ByteArrayDocument document = new ByteArrayDocument(bDocument);
707 return TimeStamp.stampHash(document.getHash(hashingAlgorithm), serverTimeStampURL, hashingAlgorithm, parameters);
708 }
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724 public static TimeStamp stampDocument (byte[] bDocument, URL serverTimeStampURL, String hashingAlgorithm) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException {
725 ByteArrayDocument document = new ByteArrayDocument(bDocument);
726 return TimeStamp.stampHash(document.getHash(hashingAlgorithm), serverTimeStampURL);
727 }
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745 public static TimeStamp stampDocument (InputStream stream, URL serverTimeStampURL, String hashingAlgorithm, TimeStampRequestParameters parameters) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException, NoSuchAlgorithmException {
746 InputStreamDocument document = new InputStreamDocument(stream);
747 return TimeStamp.stampHash(document.getHash(hashingAlgorithm), serverTimeStampURL, hashingAlgorithm, parameters);
748 }
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764 public static TimeStamp stampDocument (InputStream stream, URL serverTimeStampURL, String hashingAlgorithm) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException {
765 InputStreamDocument document = new InputStreamDocument(stream);
766 return TimeStamp.stampHash(document.getHash(hashingAlgorithm), serverTimeStampURL);
767 }
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786 public static TimeStamp stampDocument (URL urlDocument, URL serverTimeStampURL, String hashingAlgorithm, TimeStampRequestParameters parameters) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException, InitDocumentException, NoSuchAlgorithmException {
787 URLDocument document = new URLDocument(urlDocument);
788 return TimeStamp.stampHash(document.getHash(hashingAlgorithm), serverTimeStampURL, hashingAlgorithm, parameters);
789 }
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806 public static TimeStamp stampDocument (URL urlDocument, URL serverTimeStampURL, String hashingAlgorithm) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException, InitDocumentException {
807 URLDocument document = new URLDocument(urlDocument);
808 return TimeStamp.stampHash(document.getHash(hashingAlgorithm), serverTimeStampURL);
809 }
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827 public static TimeStamp stampDocument (Document document, URL serverTimeStampURL, String hashingAlgorithm, TimeStampRequestParameters parameters) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException, NoSuchAlgorithmException {
828 return TimeStamp.stampHash(document.getHash(hashingAlgorithm), serverTimeStampURL, hashingAlgorithm, parameters);
829 }
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845 public static TimeStamp stampDocument (Document document, URL serverTimeStampURL, String hashingAlgorithm) throws HashingException, TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException {
846 return TimeStamp.stampHash(document.getHash(hashingAlgorithm), serverTimeStampURL);
847 }
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864 public static TimeStamp stampHash (byte[] hash, URL serverTimeStampURL, String hashingAlgorithm, TimeStampRequestParameters parameters) throws TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException, NoSuchAlgorithmException {
865 return new TimeStamp (getTimeStamp(hash, serverTimeStampURL, hashingAlgorithm, parameters));
866 }
867
868
869
870
871
872
873
874
875
876
877
878
879
880 public static TimeStamp stampHash (byte[] hash, URL serverTimeStampURL) throws TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException {
881 try {
882 return stampHash (hash, serverTimeStampURL, HashingAlgorithm.getDefault(), null);
883 } catch (NoSuchAlgorithmException e) {
884
885 return null;
886 }
887 }
888
889
890
891
892
893
894
895
896
897
898 public static TimeStampResponse getErrorTimestamp (PKIStatus status, String statusString, PKIFailureInfo failInfo) {
899 logger.debug("[TimeStamp.getErrorTimestamp]::Entrada::" + Arrays.asList(new Object[] {status, statusString, failInfo}));
900
901 PKIFreeText textoEstado = null;
902 if (statusString != null) {
903 textoEstado = new PKIFreeText(statusString);
904 }
905
906 PKIStatusInfo statusInfo = new PKIStatusInfo(status, textoEstado, failInfo);
907 TimeStampResp response = new TimeStampResp(statusInfo, null);
908 try {
909 return new TimeStampResponse(response);
910 } catch (Exception e) {
911 logger.info("[TimeStamp.getErrorTimestamp]::Error inesperado", e);
912 return null;
913 }
914 }
915
916
917
918
919
920
921
922
923
924
925 public static TimeStampRequest getTimeStampRequest(byte[] hash, String hashingAlgorithm, TimeStampRequestParameters parameters) throws NoSuchAlgorithmException {
926 logger.debug("[TimeStamp.getTimeStampRequest]::Entrada::" + Arrays.asList(new Object[] { hash, parameters }));
927
928
929 TimeStampRequestGenerator tsrGenerator = new TimeStampRequestGenerator();
930 tsrGenerator.setCertReq(true);
931
932
933 if (parameters != null) {
934 if (parameters.getOid() != null) {
935 tsrGenerator.setReqPolicy(new ASN1ObjectIdentifier(parameters.getOid()));
936 }
937
938
939 if (parameters.getExtensions() != null && !parameters.getExtensions().isEmpty()) {
940 for(TimeStampRequestParameters.TimeStampRequestExtension extension : parameters.getExtensions()) {
941 tsrGenerator.addExtension(new ASN1ObjectIdentifier(extension.getOid()), false, extension.getValue());
942 }
943 }
944 }
945
946
947 String hashingAlgorithmOID = HashingAlgorithm.getOID(hashingAlgorithm);
948 try {
949 switch (hash.length) {
950 case 20:
951 hashingAlgorithmOID = HashingAlgorithm.getOID(HashingAlgorithm.SHA1);
952 break;
953 case 32:
954 hashingAlgorithmOID = HashingAlgorithm.getOID(HashingAlgorithm.SHA256);
955 break;
956 case 48:
957 hashingAlgorithmOID = HashingAlgorithm.getOID(HashingAlgorithm.SHA384);
958 break;
959 case 64:
960 hashingAlgorithmOID = HashingAlgorithm.getOID(HashingAlgorithm.SHA512);
961 }
962 } catch (NoSuchAlgorithmException e) {
963 logger.debug("[TimeStamp.getTimeStamp]::No existe el algoritmo para el tamaño: " + hash.length);
964 }
965
966
967 BigInteger nonce = BigInteger.valueOf(System.currentTimeMillis());
968 if (parameters != null && parameters.getNonce() != null) {
969 nonce = parameters.getNonce();
970 }
971
972 return tsrGenerator.generate(new ASN1ObjectIdentifier(hashingAlgorithmOID), hash, nonce);
973 }
974
975
976
977
978
979
980 protected static TimeStampToken getTimeStamp (byte[] hash, URL serverTimeStampURL, String hashingAlgorithm, TimeStampRequestParameters parameters) throws TimeStampServerConnectionException, MalformedTimeStampException, ResponseTimeStampException, NoSuchAlgorithmException {
981 logger.debug("[TimeStamp.getTimeStamp]::Entrada::" + Arrays.asList(new Object[] { hash, serverTimeStampURL, hashingAlgorithm, parameters }));
982
983 TimeStampRequest request = TimeStamp.getTimeStampRequest(hash, hashingAlgorithm, parameters);
984 byte[] requestBytes = null;
985 try {
986 requestBytes = request.getEncoded();
987 } catch (IOException e) {
988 logger.info("[TimeStamp.getTimeStamp]:: Error obteniendo la petición de sello de tiempo", e);
989 }
990
991
992 Hashtable reqProperties = new Hashtable();
993
994 if (parameters != null && parameters.getUser() != null && parameters.getPassword() != null) {
995 String userPassword = parameters.getUser() + ":" + parameters.getPassword();
996 String reqString = "Basic " + new String(Util.encodeBase64(userPassword.getBytes()));
997 reqProperties.put("Authorization", reqString);
998 reqProperties.put("Content-Length", String.valueOf(reqString.length()));
999 }
1000
1001 reqProperties.put("Content-Type", "application/timestamp-query");
1002 reqProperties.put("Content-Transfer-Encoding", "binary");
1003
1004 TimeStampResponse response;
1005 try {
1006 response = connect(serverTimeStampURL, reqProperties, requestBytes);
1007 } catch (IOException e) {
1008 logger.info("[TimeStamp.getTimeStamp]::Error conectando con la TSA", e);
1009 throw new TimeStampServerConnectionException ("Error conectando con la TSA", e);
1010 }
1011
1012
1013 if (response.getTimeStampToken()== null) {
1014
1015 if (response.getFailInfo() == null) {
1016 logger.info("[TimeStamp.getTimeStamp]::Por algún motivo desconocido la TSA no ha podido devolver un sello de tiempos");
1017 throw new ResponseTimeStampException ("Por algún motivo desconocido la TSA no ha podido devolver un sello de tiempos");
1018 } else {
1019
1020 switch (response.getFailInfo().intValue()) {
1021 case PKIFailureInfo.badAlg:
1022 logger.info("[TimeStamp.getTimeStamp]::El algoritmo del hashing no está reconocido por la TSA");
1023 throw new ResponseTimeStampException ("El algoritmo del hashing no está reconocido por la TSA");
1024 case PKIFailureInfo.badRequest:
1025 logger.info("[TimeStamp.getTimeStamp]::La TSA considera que la petición no es correcta");
1026 throw new ResponseTimeStampException ("La TSA considera que la petición no es correcta");
1027 case PKIFailureInfo.badDataFormat:
1028 logger.info("[TimeStamp.getTimeStamp]::La información a sellar tiene un formato incorrecto");
1029 throw new ResponseTimeStampException ("La información a sellar tiene un formato incorrecto");
1030 case PKIFailureInfo.timeNotAvailable:
1031 logger.info("[TimeStamp.getTimeStamp]::En estos momentos la fuente de tiempos de la TSA no se encuentra disponible");
1032 throw new ResponseTimeStampException ("En estos momentos la fuente de tiempos de la TSA no se encuentra disponible");
1033 case PKIFailureInfo.unacceptedPolicy:
1034 logger.info("[TimeStamp.getTimeStamp)]::La política pedida a la TSA no es aceptada por ésta");
1035 throw new ResponseTimeStampException ("La política pedida a la TSA no es aceptada por ésta");
1036 case PKIFailureInfo.unacceptedExtension:
1037 logger.info("[TimeStamp.getTimeStamp]::La extensión pedida no es aceptada por la TSA");
1038 throw new ResponseTimeStampException ("La extensión pedida no es aceptada por la TSA");
1039 case PKIFailureInfo.addInfoNotAvailable:
1040 logger.info("[TimeStamp.getTimeStamp]::La información adicional pedida no es entendida o no está disponible en la TSA");
1041 throw new ResponseTimeStampException ("La información adicional pedida no es entendida o no está disponible en la TSA");
1042 case PKIFailureInfo.systemFailure:
1043 logger.info("[TimeStamp.getTimeStamp]::La respuesta no puede ser atendida debido a un error interno del servidor");
1044 throw new ResponseTimeStampException ("La respuesta no puede ser atendida debido a un error interno del servidor");
1045 default:
1046 logger.info("[TimeStamp.getTimeStamp]::Por algún motivo desconocido la TSA no ha podido devolver un sello de tiempos");
1047 throw new ResponseTimeStampException ("Por algún motivo desconocido la TSA no ha podido devolver un sello de tiempos");
1048 }
1049 }
1050 }
1051
1052 return response.getTimeStampToken();
1053
1054 }
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064 private void initialize (InputStream isTimeStamp) throws MalformedTimeStampException {
1065 logger.debug("[TimeStamp.initialize]::Entrada::" + isTimeStamp);
1066
1067
1068 ASN1Sequence derTS;
1069 try {
1070 derTS = (ASN1Sequence)Util.toDER(isTimeStamp);
1071 } catch (IOException e) {
1072 logger.info("[TimeStamp.initialize]::El stream no parece contener un objeto en formato DER", e);
1073 throw new MalformedTimeStampException ("El stream no parece contener un objeto en formato DER", e);
1074 }
1075
1076 try {
1077 this.timeStamp = new TimeStampToken (new CMSSignedData(derTS.getEncoded(ASN1Encoding.DER)));
1078 } catch (TSPException e) {
1079 logger.info("[TimeStamp.initialize]::El stream no parece contener un sello de tiempos", e);
1080 throw new MalformedTimeStampException ("El stream no parece contener un sello de tiempos", e);
1081 } catch (IOException e) {
1082 logger.info("[TimeStamp.initialize]::El stream no parece contener un objeto en formato DER", e);
1083 throw new MalformedTimeStampException ("El stream no parece contener un objeto en formato DER", e);
1084 } catch (CMSException e) {
1085 logger.info("[TimeStamp.initialize]::El stream no parece contener un sello de tiempos", e);
1086 throw new MalformedTimeStampException ("El stream no parece contener un sello de tiempos", e);
1087 }
1088
1089 }
1090
1091
1092
1093
1094
1095 private static TimeStampResponse connect(URL serverTimeStampURL, Hashtable reqProperties, byte[] requestBytes) throws IOException, MalformedTimeStampException {
1096 logger.debug("[TimeStamp.connect]:: " + Arrays.asList(new Object[] { serverTimeStampURL, reqProperties, requestBytes }));
1097
1098 HttpURLConnection urlConn;
1099 OutputStream printout = null;
1100 DataInputStream input = null;
1101
1102
1103 urlConn = (HttpURLConnection) serverTimeStampURL.openConnection();
1104
1105
1106 urlConn.setDoInput(true);
1107 urlConn.setDoOutput(true);
1108 urlConn.setRequestMethod("POST");
1109
1110
1111 urlConn.setUseCaches(false);
1112
1113
1114 Iterator iter = reqProperties.entrySet().iterator();
1115 while (iter.hasNext()) {
1116 Map.Entry entry = (Map.Entry) iter.next();
1117 urlConn.setRequestProperty((String) entry.getKey(), (String) entry.getValue());
1118 }
1119
1120
1121 try {
1122 printout = urlConn.getOutputStream();
1123 printout.write(requestBytes);
1124 printout.flush();
1125 } finally {
1126 if (printout != null) {
1127 try { printout.close(); } catch (IOException e) { }
1128 }
1129 }
1130
1131
1132 ByteArrayOutputStream baos = new ByteArrayOutputStream();
1133 try {
1134 input = new DataInputStream(urlConn.getInputStream());
1135
1136 byte[] buffer = new byte[1024];
1137 int bytesRead = 0;
1138 while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
1139 baos.write(buffer, 0, bytesRead);
1140 }
1141 } finally {
1142 if (input != null) {
1143 try { input.close(); } catch (IOException e) { }
1144 }
1145 }
1146
1147 try {
1148 return new TimeStampResponse (baos.toByteArray());
1149 } catch (TSPException e) {
1150 logger.info("[TimeStamp.connect]::La respuesta del servidor no parece una respuesta de sello de tiempos", e);
1151 throw new MalformedTimeStampException ("La respuesta del servidor no parece una respuesta de sello de tiempos", e);
1152 }
1153
1154
1155 }
1156
1157
1158 }