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.util;
22
23 import java.io.BufferedReader;
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.DataOutputStream;
27 import java.io.File;
28 import java.io.FileInputStream;
29 import java.io.FileNotFoundException;
30 import java.io.FileOutputStream;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.InputStreamReader;
34 import java.io.OutputStream;
35 import java.io.OutputStreamWriter;
36 import java.io.PrintStream;
37 import java.io.RandomAccessFile;
38 import java.math.BigInteger;
39 import java.net.HttpURLConnection;
40 import java.net.URL;
41 import java.security.Provider;
42 import java.security.Security;
43 import java.security.cert.CertificateException;
44 import java.security.cert.CertificateFactory;
45 import java.security.cert.X509Certificate;
46 import java.text.SimpleDateFormat;
47 import java.util.Arrays;
48 import java.util.Map;
49 import java.util.Properties;
50
51 import org.apache.log4j.Logger;
52 import org.bouncycastle.asn1.ASN1InputStream;
53 import org.bouncycastle.asn1.ASN1Primitive;
54 import org.bouncycastle.cert.X509CertificateHolder;
55 import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
56
57 import es.accv.arangi.base.ArangiObject;
58 import es.accv.arangi.base.device.KeyStoreManager;
59 import es.accv.arangi.base.exception.certificate.NormalizeCertificateException;
60 import es.accv.arangi.base.exception.certificate.validation.ServiceException;
61 import es.accv.arangi.base.exception.certificate.validation.ServiceNotFoundException;
62 import es.accv.arangi.base.util.base64.BASE64Decoder;
63 import es.accv.arangi.base.util.base64.BASE64Encoder;
64
65
66
67
68
69
70 public class Util {
71
72
73
74
75 private static Logger logger = Logger.getLogger(Util.class);
76
77
78
79
80 public static final SimpleDateFormat dateFormat = new SimpleDateFormat ("dd/MM/yyyy HH:mm");
81
82
83
84
85 public static final SimpleDateFormat dateFormatAccurate = new SimpleDateFormat ("dd/MM/yyyy HH:mm:ss");
86
87
88
89
90 public static final int DEFAULT_KEY_LENGTH = 1024;
91
92
93
94
95 private static final String PRUEBA_PKCS12_FILE = "es/accv/arangi/base/resource/prueba.p12";
96
97
98
99
100 private static final String PRUEBA_PKCS12_PIN = "Mu4lWyke";
101
102
103
104
105 public static void setProvider(String providerName, Provider provider) {
106
107
108 if (!existsCryptographicProvider(providerName)) {
109
110 logger.debug ("[Util.setProvider] :: Installed " + provider + "provider");
111 Security.addProvider(provider);
112 }
113 }
114
115
116
117
118
119
120
121 public static boolean existsCryptographicProvider(String providerID) {
122
123 Provider[] arrayProviders = Security.getProviders();
124 for (int i = 0; i < arrayProviders.length; i++) {
125 if (arrayProviders[i].getName().equalsIgnoreCase(providerID)) {
126 return true;
127 }
128 }
129
130 return false;
131 }
132
133
134
135
136
137
138
139
140 public static X509Certificate getCertificate(byte [] bCertificate) throws NormalizeCertificateException{
141
142 ByteArrayInputStream bais = new ByteArrayInputStream (bCertificate);
143
144
145 return getCertificate(bais);
146 }
147
148
149
150
151
152
153
154
155 public static X509Certificate getCertificate(InputStream isCertificate) throws NormalizeCertificateException{
156 try {
157
158 setProvider (ArangiObject.CRYPTOGRAPHIC_PROVIDER_NAME, ArangiObject.CRYPTOGRAPHIC_PROVIDER);
159
160
161 CertificateFactory certFactory = CertificateFactory.getInstance("X.509", ArangiObject.CRYPTOGRAPHIC_PROVIDER);
162 return (X509Certificate) certFactory.generateCertificate(isCertificate);
163
164 } catch (CertificateException e) {
165 logger.info ("Error generando el certificado");
166 throw new NormalizeCertificateException ("Error generando el certificado", e);
167 }
168 }
169
170
171
172
173
174
175
176
177
178 public static X509Certificate getCertificate(File file) throws FileNotFoundException, NormalizeCertificateException{
179 try {
180 return getCertificate (new FileInputStream (file));
181 } catch (NormalizeCertificateException e) {
182 logger.info ("Error generando el certificado desde " + file.getAbsolutePath());
183 throw new NormalizeCertificateException ("Error generando el certificado desde " + file.getAbsolutePath(), e);
184 }
185 }
186
187
188
189
190
191
192
193
194
195 public static X509Certificate getCertificate(X509CertificateHolder certificateHolder) throws CertificateException {
196 return new JcaX509CertificateConverter().getCertificate(certificateHolder);
197 }
198
199
200
201
202
203
204
205
206 public static void saveFile(File file, byte[] contenido) throws IOException {
207
208 try {
209
210 RandomAccessFile lObjSalida = new RandomAccessFile(file, "rw");
211 lObjSalida.write(contenido,0,contenido.length);
212 lObjSalida.close();
213 } catch (IOException e){
214 logger.info ("Error saving file at " + file, e);
215 throw e;
216 }
217 }
218
219
220
221
222
223
224
225
226 public static void saveFile(File file, InputStream iStream) throws IOException {
227
228 FileOutputStream fos = null;
229 try {
230 fos = new FileOutputStream (file);
231 byte[] buffer = new byte [1024];
232 int len;
233 while ((len = iStream.read(buffer)) > -1) {
234 fos.write(buffer, 0, len);
235 }
236 } catch (IOException e){
237 logger.info ("Error saving file at " + file, e);
238 throw e;
239 } finally {
240 if (fos != null) {
241 fos.close();
242 }
243 }
244 }
245
246
247
248
249
250
251
252
253 public static void save(OutputStream out, InputStream iStream) throws IOException {
254
255 try {
256 byte[] buffer = new byte [1024];
257 int len;
258 while ((len = iStream.read(buffer)) > -1) {
259 out.write(buffer, 0, len);
260 }
261 } catch (IOException e){
262 logger.info ("Error guardando en stream de escritura", e);
263 throw e;
264 }
265 }
266
267
268
269
270
271
272
273
274 public static void save(OutputStream out, byte[] contenido) throws IOException {
275
276 try {
277 out.write(contenido, 0, contenido.length);
278 } catch (IOException e){
279 logger.info ("Error guardando en stream de escritura", e);
280 throw e;
281 }
282 }
283
284
285
286
287
288
289
290
291
292
293
294 public static void saveFileFromClasspath(File file, String classPathFile) throws FileNotFoundException, IOException {
295
296 InputStream iStream = new Util().getClass().getClassLoader().getResourceAsStream(classPathFile);
297 if (iStream == null) {
298 throw new FileNotFoundException("No es posible leer el fichero '" + classPathFile + "'dentro del classpath");
299 }
300 saveFile(file, iStream);
301 }
302
303
304
305
306
307
308
309
310 public static byte[] loadFile(File file) throws IOException {
311
312 try {
313
314 RandomAccessFile lObjFile = new RandomAccessFile(file, "r");
315 byte lBytDatos[] = new byte[(int)lObjFile.length()];
316 lObjFile.read(lBytDatos);
317 lObjFile.close();
318
319 return lBytDatos;
320
321 } catch (IOException e) {
322 logger.info ("Error cargando el fichero de " + file, e);
323 throw e;
324 }
325 }
326
327
328
329
330
331
332
333
334 public static byte[] readStream(InputStream is) throws IOException {
335
336 try {
337
338 byte[] buffer = new byte [1024];
339 ByteArrayOutputStream baos = new ByteArrayOutputStream();
340 int len;
341 while ((len = is.read(buffer)) > -1) {
342 baos.write(buffer, 0, len);
343 }
344
345 return baos.toByteArray();
346
347 } catch (IOException e) {
348 logger.info ("Error cargando el stream de lectura ", e);
349 throw e;
350 }
351 }
352
353
354
355
356
357
358
359
360
361 public static void copyFile (File srcFile, File dstFile) throws FileNotFoundException, IOException {
362
363 InputStream in = null;
364 OutputStream out = null;
365 try {
366 in = new FileInputStream(srcFile);
367 out = new FileOutputStream(dstFile);
368
369 byte[] buf = new byte[1024];
370 int len;
371 while ((len = in.read(buf)) > 0) {
372 out.write(buf, 0, len);
373 }
374 } finally {
375 if (in != null) { in.close(); }
376 if (out != null) { out.close(); }
377 }
378 }
379
380
381
382
383
384
385
386 public static String encodeBase64 (byte [] toCode) {
387
388 BASE64Encoder encoder = new BASE64Encoder();
389 return encoder.encode(toCode);
390 }
391
392
393
394
395
396
397
398 public static String encodeBase64 (InputStream isToEncode) {
399
400 BASE64Encoder encoder = new BASE64Encoder();
401 ByteArrayOutputStream baos = new ByteArrayOutputStream();
402 try {
403 encoder.encode(isToEncode, baos);
404 } catch (IOException e) {
405 return null;
406 }
407
408 return baos.toString();
409 }
410
411
412
413
414
415
416
417 public static byte[] decodeBase64 (String toDecode) {
418
419 BASE64Decoder decoder = new BASE64Decoder();
420 try {
421 return decoder.decodeBuffer(toDecode);
422 } catch (IOException e) {
423 return null;
424 }
425 }
426
427
428
429
430
431
432
433 public static byte[] decodeBase64 (InputStream isToDecode) {
434
435 BASE64Decoder decoder = new BASE64Decoder();
436 try {
437 return decoder.decodeBuffer(isToDecode);
438 } catch (IOException e) {
439 return null;
440 }
441 }
442
443
444
445
446
447
448
449 public static ASN1Primitive toDER(InputStream isDER) throws IOException {
450
451 ASN1Primitive lObjRes = null;
452
453 ASN1InputStream lObjDerOut = new ASN1InputStream(isDER);
454 lObjRes = lObjDerOut.readObject();
455
456 return lObjRes;
457 }
458
459
460
461
462
463
464
465 public static ASN1Primitive getDER(byte[] bytesDER) throws IOException {
466
467 ByteArrayInputStream bais = new ByteArrayInputStream(bytesDER);
468
469 return toDER (bais);
470 }
471
472
473
474
475
476
477
478
479 public static byte[] fromUnicode(byte[] bytesUnicode){
480 byte[] bytes = new byte[bytesUnicode.length/2];
481 for (int i = 0; i< bytes.length; i++) {
482 bytes[i] = bytesUnicode[2*i];
483 }
484 return bytes;
485 }
486
487
488
489
490
491
492
493
494
495
496
497
498 public static InputStream fromUnicode(InputStream isUnicode){
499
500 logger.debug ("[Util.fromUnicode]::Entrada");
501
502
503
504 FileOutputStream fos = null;
505 try {
506 File fileTemp = File.createTempFile("fromUnicode", null);
507 fos = new FileOutputStream (fileTemp);
508 byte[] buffer = new byte[2];
509 while (isUnicode.read(buffer) >= 0) {
510 fos.write(buffer[0]);
511 }
512
513 return new FileInputStream (fileTemp);
514
515 } catch (IOException e) {
516 logger.info("[Util.fromUnicode]::Un error de entrada/salida impide el paso desde Unicode", e);
517 return null;
518 } finally {
519 if (fos != null) {
520 try {
521 fos.close();
522 } catch (IOException e) {
523 logger.info("[Util.fromUnicode]::No se puede cerrar el stream de escritura al fichero temporal", e);
524 return null;
525 }
526 }
527 }
528 }
529
530
531
532
533
534
535
536
537 public static byte[] toUnicode(byte[] bytes){
538 byte[] bytesUnicode = new byte[2*bytes.length];
539 for (int j = 0; j< bytes.length; j++) {
540 bytesUnicode[2*j] = bytes[j];
541 bytesUnicode[2*j+1] = 0x00;
542 }
543 return bytesUnicode;
544 }
545
546
547
548
549
550
551
552
553
554
555
556
557 public static File toUnicode(InputStream isNormal){
558
559 logger.debug ("[Util.toUnicode]::Entrada");
560
561
562
563 FileOutputStream fos = null;
564 try {
565 File fileTemp = File.createTempFile("toUnicode", null);
566 fos = new FileOutputStream (fileTemp);
567 byte[] buffer = new byte[1];
568 while (isNormal.read(buffer) >= 0) {
569 fos.write(buffer[0]);
570 fos.write(0x00);
571 }
572
573 return fileTemp;
574
575 } catch (IOException e) {
576 logger.info("[Util.toUnicode]::Un error de entrada/salida impide el paso a Unicode", e);
577 return null;
578 } finally {
579 if (fos != null) {
580 try {
581 fos.close();
582 } catch (IOException e) {
583 logger.info("[Util.toUnicode]::No se puede cerrar el stream de escritura al fichero temporal", e);
584 return null;
585 }
586 }
587 }
588 }
589
590
591
592
593
594
595 public static boolean isJCEInstalled () {
596 logger.debug ("[Util.isJCEInstalled]::Entrada");
597
598 KeyStoreManager manager;
599 try {
600
601 manager = new KeyStoreManager(ClassLoader.getSystemResourceAsStream(PRUEBA_PKCS12_FILE), PRUEBA_PKCS12_PIN);
602
603 } catch (Exception e) {
604 logger.debug ("[Util.isJCEInstalled]::Error abriendo el PKCS12: " + e.getMessage());
605 return false;
606 }
607
608 logger.debug ("[Util.isJCEInstalled]::No ha habido error abriendo el PKCS12");
609 return true;
610
611 }
612
613
614
615
616
617
618
619
620
621 public static String convertCharSet (String text, String newCharset) throws IOException {
622 logger.debug ("[Util.convertCharSet]::Entrada");
623
624 ByteArrayOutputStream baos = new ByteArrayOutputStream();
625 OutputStreamWriter out = new OutputStreamWriter(baos, newCharset);
626 out.write(text);
627 out.flush();
628 out.close();
629
630 return new String (baos.toByteArray(), newCharset);
631 }
632
633
634
635
636
637
638
639
640 public static String toHexadecimal (byte[] bytes) {
641 logger.debug ("[Util.toHexadecimal]::Entrada::" + bytes);
642
643 BigInteger bi = new BigInteger(1, bytes);
644 String result = bi.toString(16).toUpperCase();
645 if (result.length() % 2 != 0) {
646 result = "0" + result;
647 }
648
649 return result;
650 }
651
652
653
654
655
656
657
658
659
660
661
662
663 public static byte[] getBytesFromPEM(String pemContent) throws IOException {
664 logger.debug("[Util.getBytesFromPEM]::Entrada::" + pemContent);
665
666
667 String[] PKCS10_INIT = new String[] {"-----BEGIN CERTIFICATE REQUEST-----", "-----BEGIN NEW CERTIFICATE REQUEST-----"};
668 String[] PKCS10_END = new String[] {"-----END CERTIFICATE REQUEST-----", "-----END NEW CERTIFICATE REQUEST-----"};
669
670
671 byte[] csrBin = null;
672 int headerType = -1;
673
674 for (int i = 0; i < PKCS10_INIT.length; i++) {
675 if (pemContent.startsWith(PKCS10_INIT[i])) {
676 logger.debug("[Util.getBytesFromPEM]:: Tipo de cabecera encontrado [" + i + "]");
677 headerType = i;
678 break;
679 } else {
680 logger.debug("[[Util.getBytesFromPEM]:: El pem no comienza por... '" + PKCS10_INIT[i] + "'");
681 }
682 }
683
684
685 if (headerType == -1) {
686 logger.debug("[Util.getBytesFromPEM]::No se han encontrado cabeceras, se decodifica de base64");
687 return decodeBase64(pemContent);
688 }
689
690
691 ByteArrayInputStream instream = new ByteArrayInputStream(pemContent.getBytes());
692 BufferedReader bufRdr = new BufferedReader(new InputStreamReader(instream));
693 ByteArrayOutputStream ostr = new ByteArrayOutputStream();
694 PrintStream opstr = new PrintStream(ostr);
695 String temp;
696
697 while (((temp = bufRdr.readLine()) != null) && !temp.equals(PKCS10_INIT[headerType])) {
698 continue;
699 }
700
701 if (temp == null) {
702 throw new IOException("[Util.getBytesFromPEM]::Error in input buffer, missing " + PKCS10_INIT[headerType] + " boundary");
703 }
704
705 while (((temp = bufRdr.readLine()) != null) && !temp.equals(PKCS10_END[headerType])) {
706 opstr.print(temp);
707 }
708
709 if (temp == null) {
710 throw new IOException("[Util.getBytesFromPEM]::Error in input buffer, missing " + PKCS10_END[headerType] + " boundary");
711 }
712
713 opstr.close();
714 byte[] internalBytes = decodeBase64(new String (ostr.toByteArray()));
715 logger.info("[Util.getBytesFromPEM]::Devuelve" + internalBytes.length);
716 return internalBytes;
717 }
718
719
720
721
722
723
724
725
726
727 public static StringBuffer sendPost (String message, URL url) throws ServiceNotFoundException, ServiceException {
728 logger.debug("[Util.getPostConnectionResponse]::Entrada::" + url);
729
730 HttpURLConnection uc = null;
731
732 try {
733 uc = (HttpURLConnection) url.openConnection();
734
735 uc.setDoInput(true);
736 uc.setDoOutput(true);
737 uc.setUseCaches(false);
738 uc.setRequestProperty("Content-Length", "" + message.length());
739 uc.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");
740 uc.setRequestProperty("SOAPAction", "");
741 uc.setRequestMethod("POST");
742
743 uc.connect();
744 } catch (IOException e) {
745 throw new ServiceNotFoundException(e);
746 }
747
748
749 StringBuffer sb = new StringBuffer ("");
750 try {
751 byte[] data = message.getBytes("UTF-8");
752 DataOutputStream dos = new DataOutputStream(uc.getOutputStream());
753 dos.write(data, 0, data.length);
754 dos.flush();
755 dos.close();
756
757
758 BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream()));
759 String res = null;
760 while ((res = br.readLine()) != null) {
761 sb.append(res);
762 }
763 br.close();
764 logger.debug("[Util.getPostConnectionResponse]::Response::" + sb.toString());
765 } catch (IOException e) {
766 throw new ServiceException(e);
767 }
768
769 return sb;
770 }
771
772
773
774
775
776
777
778
779
780 public static String fillTemplate (InputStream template, Map<String,String> parameters) throws IOException {
781 logger.debug("[Util.fillTemplate]::Entrada::" + Arrays.asList(new Object[] { template, parameters }));
782
783 StringBuffer sb = new StringBuffer();
784 StringBuffer palabra = new StringBuffer();
785 int letra;
786 boolean leyendoPalabra = false;
787 while ((letra = template.read()) > -1) {
788 if ((char)letra == '$' && (char) template.read() == '{') {
789 leyendoPalabra = true;
790 } else {
791 if (leyendoPalabra) {
792 if ((char)letra != '}') {
793 palabra.append((char) letra);
794 } else {
795 if (parameters.containsKey(palabra.toString())) {
796 sb.append (parameters.get(palabra.toString()));
797 }
798 palabra = new StringBuffer();
799 leyendoPalabra = false;
800 }
801 } else {
802 sb.append((char) letra);
803 }
804 }
805 }
806
807 logger.debug("[Util.fillTemplate]::Entrada::" + Arrays.asList(new Object[] { template, parameters }));
808 return sb.toString();
809
810 }
811
812 }