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.certificate.validation;
22
23 import java.io.BufferedOutputStream;
24 import java.io.DataInputStream;
25 import java.io.DataOutputStream;
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.FileNotFoundException;
29 import java.io.IOException;
30 import java.net.HttpURLConnection;
31 import java.net.URL;
32 import java.security.KeyStore;
33 import java.security.KeyStoreException;
34 import java.security.NoSuchAlgorithmException;
35 import java.security.PrivateKey;
36 import java.security.cert.CertificateException;
37 import java.security.cert.X509Certificate;
38 import java.util.Arrays;
39 import java.util.Date;
40
41 import org.apache.log4j.Logger;
42 import org.bouncycastle.asn1.ASN1Integer;
43 import org.bouncycastle.asn1.ASN1OctetString;
44 import org.bouncycastle.asn1.DEROctetString;
45 import org.bouncycastle.asn1.ocsp.CertID;
46 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
47 import org.bouncycastle.asn1.x509.GeneralName;
48 import org.bouncycastle.cert.X509CertificateHolder;
49 import org.bouncycastle.cert.ocsp.CertificateID;
50 import org.bouncycastle.cert.ocsp.OCSPException;
51 import org.bouncycastle.cert.ocsp.OCSPReq;
52 import org.bouncycastle.cert.ocsp.OCSPReqBuilder;
53 import org.bouncycastle.cert.ocsp.OCSPResp;
54 import org.bouncycastle.cert.ocsp.OCSPRespBuilder;
55 import org.bouncycastle.operator.ContentSigner;
56 import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
57 import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
58
59 import es.accv.arangi.base.ArangiObject;
60 import es.accv.arangi.base.algorithm.HashingAlgorithm;
61 import es.accv.arangi.base.certificate.Certificate;
62 import es.accv.arangi.base.document.ByteArrayDocument;
63 import es.accv.arangi.base.exception.certificate.NormalizeCertificateException;
64 import es.accv.arangi.base.exception.certificate.validation.MalformedOCSPResponseException;
65 import es.accv.arangi.base.exception.certificate.validation.OCSPRequestGenerationException;
66 import es.accv.arangi.base.exception.certificate.validation.OCSPServerConnectionException;
67 import es.accv.arangi.base.exception.certificate.validation.OCSPValidateException;
68 import es.accv.arangi.base.exception.device.OpeningDeviceException;
69 import es.accv.arangi.base.exception.document.HashingException;
70 import es.accv.arangi.base.util.Util;
71 import es.accv.arangi.base.util.validation.ValidationResult;
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 public class OCSPClient extends ArangiObject {
92
93
94
95
96 static Logger logger = Logger.getLogger(OCSPClient.class);
97
98
99
100
101 URL urlOCSP;
102
103
104
105
106 String requestorName;
107
108
109
110
111 KeyStore keyStore;
112
113
114
115
116
117 String alias;
118
119
120
121
122 String aliasPassword;
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139 public OCSPClient(URL urlOCSP, String requestorName, File keystoreFile,
140 String keystoreType, String keystorePassword, String alias, String aliasPassword) throws OpeningDeviceException {
141
142
143 try {
144 keyStore = KeyStore.getInstance(keystoreType, CRYPTOGRAPHIC_PROVIDER);
145 } catch (KeyStoreException e) {
146 logger.info("[OCSPClient]::Cannot instantiate a keystore with type '" + keystoreType + "'", e);
147 throw new OpeningDeviceException ("Cannot instantiate a keystore with type '" + keystoreType + "'", e);
148 }
149 FileInputStream fis = null;
150 try {
151 fis = new FileInputStream (keystoreFile);
152 keyStore.load(fis, keystorePassword.toCharArray());
153 } catch (FileNotFoundException e) {
154 logger.error("[OCSPClient]::File not found (" + keystoreFile + ")", e);
155 throw new OpeningDeviceException ("File not found (" + keystoreFile + ")", e);
156 } catch (NoSuchAlgorithmException e) {
157 logger.info("[OCSPClient]::The algorithm used to check the integrity of the keystore cannot be found", e);
158 throw new OpeningDeviceException ("The algorithm used to check the integrity of the keystore cannot be found", e);
159 } catch (CertificateException e) {
160 logger.info("[OCSPClient]::Any of the certificates in the keystore could not be loaded", e);
161 throw new OpeningDeviceException ("Any of the certificates in the keystore could not be loaded", e);
162 } catch (IOException e) {
163 logger.info("[OCSPClient]::there is an I/O or format problem with the keystore data", e);
164 throw new OpeningDeviceException ("there is an I/O or format problem with the keystore data", e);
165 } finally {
166 if (fis != null) {
167 try {
168 fis.close();
169 } catch (IOException e) {
170 }
171 }
172 }
173
174
175 try {
176 if (!keyStore.containsAlias(alias)) {
177 logger.info("[OCSPClient]::The alias '" + alias + "' is not present in the keystore");
178 throw new OpeningDeviceException ("The alias '" + alias + "' is not present in the keystore");
179 }
180 } catch (KeyStoreException e) {
181 logger.info("[OCSPClient]::The keystore has not been initialized (loaded)", e);
182 throw new OpeningDeviceException ("The keystore has not been initialized (loaded)", e);
183 }
184
185
186 this.urlOCSP = urlOCSP;
187 this.requestorName = requestorName;
188 this.alias = alias;
189 this.aliasPassword = aliasPassword;
190
191 }
192
193
194
195
196
197
198
199 public OCSPClient(URL urlOCSP, String requestorName) {
200
201 this.urlOCSP = urlOCSP;
202 this.requestorName = requestorName;
203
204 }
205
206
207
208
209
210
211 public OCSPClient(URL urlOCSP) {
212 this (urlOCSP, null);
213 }
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228 public int validate (Certificate certificate, Certificate issuerCertificate) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, OCSPValidateException {
229 return validate(certificate, issuerCertificate, new Date());
230 }
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249 public int validate (Certificate certificate) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, OCSPValidateException {
250 return validate(certificate, new Date());
251 }
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273 public int validate (Certificate certificate, Certificate issuerCertificate, Date validationDate) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, OCSPValidateException {
274 return validate (new Certificate[] { certificate }, new Certificate [] { issuerCertificate }, validationDate) [0];
275 }
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301 public int validate (Certificate certificate, Date validationDate) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, OCSPValidateException {
302 return validate (new Certificate[] { certificate }, validationDate) [0];
303 }
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320 public int[] validate (X509Certificate[] certificates, X509Certificate[] issuerCertificates) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, OCSPValidateException, NormalizeCertificateException {
321 return validate (certificates, issuerCertificates, new Date());
322 }
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343 public int[] validate (X509Certificate[] certificates) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, OCSPValidateException, NormalizeCertificateException {
344 return validate (certificates, new Date());
345 }
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369 public int[] validate (X509Certificate[] certificates, X509Certificate[] issuerCertificates, Date validationDate) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, OCSPValidateException, NormalizeCertificateException {
370 Certificate[] arangiCertificates = new Certificate [certificates.length];
371 Certificate[] arangiIssuers = new Certificate [certificates.length];
372 for (int i = 0; i < certificates.length; i++) {
373 arangiCertificates[i] = new Certificate (certificates[i]);
374 arangiIssuers[i] = new Certificate (issuerCertificates[i]);
375 }
376 return validate (arangiCertificates, arangiIssuers, validationDate);
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 public int[] validate (X509Certificate[] certificates, Date validationDate) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, OCSPValidateException, NormalizeCertificateException {
406 Certificate[] arangiCertificates = new Certificate [certificates.length];
407 for (int i = 0; i < certificates.length; i++) {
408 arangiCertificates[i] = new Certificate (certificates[i]);
409 }
410 return validate (arangiCertificates, validationDate);
411 }
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426 public int[] validate (Certificate[] certificates, Certificate[] issuerCertificates) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, OCSPValidateException {
427 return validate (certificates, issuerCertificates, new Date());
428 }
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447 public int[] validate (Certificate[] certificates) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, OCSPValidateException {
448 return validate (certificates, new Date());
449 }
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471 public int[] validate (Certificate[] certificates, Certificate[] issuerCertificates, Date validationDate) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, OCSPValidateException {
472 logger.debug("[OCSPClient.validate] :: Start :: " + Arrays.asList(new Object[] { certificates, validationDate }));
473
474
475 OCSPResponse oscpResponse = getOCSPResponse(certificates, issuerCertificates);
476
477 if (!oscpResponse.isSignatureValid ()) {
478 logger.info ("[OCSPClient.validate] :: La firma de la respuesta OCSP no es correcta");
479 throw new OCSPValidateException ("La firma de la respuesta OCSP no es correcta");
480 }
481
482
483 int [] result = new int [certificates.length];
484
485
486 CertificateOCSPResponse[] singleResponses = oscpResponse.getSingleResponses();
487 for (int i = 0; i < singleResponses.length; i++) {
488 if(singleResponses[i] != null) {
489
490
491 if (singleResponses[i].getValidityPeriodEnd() != null && singleResponses[i].getValidityPeriodEnd().before(new Date())) {
492 logger.error ("[OCSPClient.validate] :: La respuesta OCSP ha superado su periodo de validez, que acababa el " + Util.dateFormatAccurate.format(singleResponses[i].getValidityPeriodEnd()));
493 throw new OCSPValidateException ("La respuesta OCSP ha superado su periodo de validez, que acababa el " + Util.dateFormatAccurate.format(singleResponses[i].getValidityPeriodEnd()));
494 }
495
496
497 if(singleResponses[i].getStatus() != ValidationResult.RESULT_CERTIFICATE_REVOKED){
498
499 result [i] = singleResponses[i].getStatus();
500
501 }else{
502
503 if (singleResponses[i].getRevocationTime().before(validationDate) || singleResponses[i].getRevocationTime().equals(validationDate)) {
504
505 result [i] = ValidationResult.RESULT_CERTIFICATE_REVOKED;
506 } else {
507
508 result [i] = ValidationResult.RESULT_VALID;
509 }
510 }
511 }
512
513 }
514
515
516 return result;
517 }
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543 public int[] validate (Certificate[] certificates, Date validationDate) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, OCSPValidateException {
544
545 logger.debug("[OCSPClient.validate] :: Start :: " + Arrays.asList(new Object[] { certificates, validationDate }));
546
547
548 OCSPResponse oscpResponse = getOCSPResponse(certificates);
549
550 if (!oscpResponse.isSignatureValid ()) {
551 logger.info ("[OCSPClient.validate] :: La firma de la respuesta OCSP no es correcta");
552 throw new OCSPValidateException ("La firma de la respuesta OCSP no es correcta");
553 }
554
555
556 int [] result = new int [certificates.length];
557
558
559 CertificateOCSPResponse[] singleResponses = oscpResponse.getSingleResponses();
560 for (int i = 0; i < singleResponses.length; i++) {
561 if(singleResponses[i] != null) {
562
563
564 if (singleResponses[i].getValidityPeriodEnd() != null && singleResponses[i].getValidityPeriodEnd().before(new Date())) {
565 logger.error ("[OCSPClient.validate] :: La respuesta OCSP ha superado su periodo de validez, que acababa el " + Util.dateFormatAccurate.format(singleResponses[i].getValidityPeriodEnd()));
566 throw new OCSPValidateException ("La respuesta OCSP ha superado su periodo de validez, que acababa el " + Util.dateFormatAccurate.format(singleResponses[i].getValidityPeriodEnd()));
567 }
568
569
570 if(singleResponses[i].getStatus() != ValidationResult.RESULT_CERTIFICATE_REVOKED){
571
572 result [i] = singleResponses[i].getStatus();
573
574 }else{
575
576 if (singleResponses[i].getRevocationTime().before(validationDate) || singleResponses[i].getRevocationTime().equals(validationDate)) {
577
578 result [i] = ValidationResult.RESULT_CERTIFICATE_REVOKED;
579 } else {
580
581 result [i] = ValidationResult.RESULT_VALID;
582 }
583 }
584 }
585
586 }
587
588
589 return result;
590 }
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609 public OCSPResponse getOCSPResponse (X509Certificate certificate, X509Certificate issuerCertificate) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, NormalizeCertificateException {
610 return getOCSPResponse(new Certificate (certificate), new Certificate (issuerCertificate));
611 }
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634 public OCSPResponse getOCSPResponse (X509Certificate certificate) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException, NormalizeCertificateException {
635 return getOCSPResponse(new Certificate (certificate));
636 }
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653 public OCSPResponse getOCSPResponse (Certificate certificate, Certificate issuerCertificate) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException {
654 return getOCSPResponse(new Certificate[] {certificate}, new Certificate [] {issuerCertificate});
655 }
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671 public OCSPResponse getOCSPResponse (ValidateCertificate certificate) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException {
672 return getOCSPResponse(new Certificate[] {certificate}, new Certificate[] {certificate.getIssuerCertificate()});
673 }
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694 public OCSPResponse getOCSPResponse (Certificate certificate) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException {
695 return getOCSPResponse(new Certificate[] {certificate});
696 }
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714 public OCSPResponse getOCSPResponse (Certificate[] certificates, Certificate[] issuerCertificates) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException {
715
716 logger.debug("[OCSPClient.getOCSPResponse] :: Entrada");
717
718
719 if (certificates == null || certificates.length == 0) {
720 logger.info ("[OCSPClient.getOCSPResponse] :: No hay certificados a validar");
721 throw new OCSPRequestGenerationException ("No hay certificados a validar");
722 }
723
724
725 if (issuerCertificates == null || issuerCertificates.length == 0) {
726 logger.info ("[OCSPClient.getOCSPResponse] :: No hay certificados emisores para realizar la validación");
727 throw new OCSPRequestGenerationException ("No hay certificados emisores para realizar la validación");
728 }
729
730
731 if (certificates.length != issuerCertificates.length) {
732 logger.info ("[OCSPClient.getOCSPResponse] :: El tamaño de los arrays de certificados y emisores es diferente");
733 throw new OCSPRequestGenerationException ("El tamaño de los arrays de certificados y emisores es diferente");
734 }
735
736
737 byte[] ocspRequest = generateOCSPRequest(certificates, issuerCertificates, requestorName, keyStore, alias, aliasPassword);
738
739
740 return getOCSPResponse(ocspRequest);
741 }
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762 public OCSPResponse getOCSPResponse (Certificate[] certificates) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException {
763
764 logger.debug("[OCSPClient.getOCSPResponse] :: Entrada");
765
766
767 if (certificates == null || certificates.length == 0) {
768 logger.info ("[OCSPClient.getOCSPResponse] :: No hay certificados a validar");
769 throw new OCSPRequestGenerationException ("No hay certificados a validar");
770 }
771
772
773 byte[] ocspRequest = generateOCSPRequest(certificates, requestorName, keyStore, alias, aliasPassword);
774
775
776 return getOCSPResponse(ocspRequest);
777 }
778
779
780
781
782
783
784
785
786
787 public static byte[] generateOCSPRequest(Certificate certificate, Certificate issuerCertificate) throws Exception{
788
789 return generateOCSPRequest(new Certificate [] { certificate }, new Certificate [] { issuerCertificate });
790
791 }
792
793
794
795
796
797
798
799
800
801
802
803
804
805 public static byte[] generateOCSPRequest(Certificate certificate) throws Exception{
806
807 return generateOCSPRequest(new Certificate [] { certificate });
808
809 }
810
811
812
813
814
815
816
817
818
819 public static byte[] generateOCSPRequest(Certificate [] certificates, Certificate [] issuerCertificates) throws Exception{
820
821 return OCSPClient.generateOCSPRequest(certificates, issuerCertificates, null, null, null, null);
822
823 }
824
825
826
827
828
829
830
831
832
833
834
835
836
837 public static byte[] generateOCSPRequest(Certificate [] certificates) throws Exception{
838
839 return OCSPClient.generateOCSPRequest(certificates, null, null, null, null);
840
841 }
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856 public static byte[] generateOCSPRequest(Certificate [] certificates, Certificate [] issuerCertificates,
857 String requestorName, KeyStore keystore, String alias, String aliasPassword) throws OCSPRequestGenerationException{
858
859
860 if (certificates == null || certificates.length == 0) {
861 throw new OCSPRequestGenerationException ("List of certificates to validate is empty");
862 }
863 if (issuerCertificates == null || issuerCertificates.length == 0) {
864 throw new OCSPRequestGenerationException ("List of CA certificates to validate is empty");
865 }
866 if (certificates.length != issuerCertificates.length) {
867 throw new OCSPRequestGenerationException ("List of certificates and CA certificates must have the same number of elements");
868 }
869
870
871 OCSPReqBuilder constructorPeticion = new OCSPReqBuilder();
872 for (int i=0;i<certificates.length;i++) {
873
874 CertificateID identificadorCert;
875 try {
876 identificadorCert = new CertificateID(new JcaDigestCalculatorProviderBuilder().
877 setProvider(CRYPTOGRAPHIC_PROVIDER_NAME).build().get(CertificateID.HASH_SHA1),
878 new X509CertificateHolder(issuerCertificates [i].toDER()), certificates[i].getSerialNumberBigInteger());
879 } catch (Exception e) {
880 logger.info ("[OCSPClient.generateOCSPRequest] :: Cannot create a new certificate ID for the OCSP request", e);
881 throw new OCSPRequestGenerationException ("Cannot create a new certificate ID for the OCSP request", e);
882 }
883
884
885 constructorPeticion.addRequest(identificadorCert);
886 }
887
888
889 if (requestorName != null) {
890 constructorPeticion.setRequestorName(new GeneralName (GeneralName.rfc822Name, requestorName));
891 }
892
893
894 OCSPReq peticionOCSP;
895 try {
896 if (keystore == null) {
897 peticionOCSP = constructorPeticion.build();
898 } else {
899 PrivateKey pk = (PrivateKey) keystore.getKey(alias, aliasPassword.toCharArray());
900 ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(CRYPTOGRAPHIC_PROVIDER_NAME).build(pk);
901 peticionOCSP = constructorPeticion.build(sha1Signer, new X509CertificateHolder[] { new X509CertificateHolder(keystore.getCertificate(alias).getEncoded()) });
902 }
903 } catch (Exception e) {
904 logger.info ("[OCSPClient.generateOCSPRequest] :: Cannot create a new OCSP request", e);
905 throw new OCSPRequestGenerationException ("Cannot create a new OCSP request", e);
906 }
907
908
909 try {
910 return peticionOCSP.getEncoded();
911 } catch (IOException e) {
912 logger.info ("[OCSPClient.generateOCSPRequest] :: Cannot encode the OCSP request", e);
913 throw new OCSPRequestGenerationException ("Cannot encode the OCSP request", e);
914 }
915
916 }
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935 public static byte[] generateOCSPRequest(Certificate [] certificates,
936 String requestorName, KeyStore keystore, String alias, String aliasPassword) throws OCSPRequestGenerationException{
937
938
939 if (certificates == null || certificates.length == 0) {
940 throw new OCSPRequestGenerationException ("List of certificates to validate is empty");
941 }
942
943
944 OCSPReqBuilder constructorPeticion = new OCSPReqBuilder();
945 for (int i=0;i<certificates.length;i++) {
946
947 CertificateID identificadorCert;
948 try {
949 identificadorCert = getCertificateID(certificates[i]);
950 } catch (HashingException e) {
951 logger.info ("[OCSPClient.generateOCSPRequest] :: Cannot create a new certificate ID for the OCSP request", e);
952 throw new OCSPRequestGenerationException ("Cannot create a new certificate ID for the OCSP request", e);
953 }
954
955
956 constructorPeticion.addRequest(identificadorCert);
957 }
958
959
960 if (requestorName != null) {
961 constructorPeticion.setRequestorName(new GeneralName (GeneralName.rfc822Name, requestorName));
962 }
963
964
965 OCSPReq peticionOCSP;
966 try {
967 if (keystore == null) {
968 peticionOCSP = constructorPeticion.build();
969 } else {
970 PrivateKey pk = (PrivateKey) keystore.getKey(alias, aliasPassword.toCharArray());
971 ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(CRYPTOGRAPHIC_PROVIDER_NAME).build(pk);
972 peticionOCSP = constructorPeticion.build(sha1Signer, new X509CertificateHolder[] { new X509CertificateHolder(keystore.getCertificate(alias).getEncoded()) });
973 }
974 } catch (Exception e) {
975 logger.info ("[OCSPClient.generateOCSPRequest] :: Cannot create a new OCSP request", e);
976 throw new OCSPRequestGenerationException ("Cannot create a new OCSP request", e);
977 }
978
979
980 try {
981 return peticionOCSP.getEncoded();
982 } catch (IOException e) {
983 logger.info ("[OCSPClient.generateOCSPRequest] :: Cannot encode the OCSP request", e);
984 throw new OCSPRequestGenerationException ("Cannot encode the OCSP request", e);
985 }
986
987
988 }
989
990
991
992
993
994
995 public URL getURL() {
996 return this.urlOCSP;
997 }
998
999
1000
1001
1002
1003
1004
1005
1006
1007 public static CertificateID getCertificateID (Certificate certificate) throws HashingException {
1008
1009
1010 AlgorithmIdentifier hashAlg = CertificateID.HASH_SHA1;
1011
1012
1013 ByteArrayDocument document = new ByteArrayDocument(certificate.toX509Certificate().getIssuerX500Principal().getEncoded());
1014 ASN1OctetString issuerNameHash = new DEROctetString(document.getHash(HashingAlgorithm.SHA1));
1015
1016
1017 ASN1OctetString issuerKeyHash = null;
1018 if (certificate.getIssuerKeyIdentifier() != null) {
1019 issuerKeyHash = new DEROctetString(Util.decodeBase64(certificate.getIssuerKeyIdentifier()));
1020 }
1021
1022
1023 CertID certId = new CertID(hashAlg, issuerNameHash, issuerKeyHash, new ASN1Integer(certificate.getSerialNumberBigInteger()));
1024
1025 return new CertificateID(certId);
1026 }
1027
1028
1029
1030
1031
1032
1033 private OCSPResponse getOCSPResponse (byte[] ocspRequest) throws OCSPServerConnectionException, MalformedOCSPResponseException, OCSPRequestGenerationException {
1034
1035 logger.debug("[OCSPClient.getOCSPResponse] :: Entrada");
1036
1037
1038 DataOutputStream dataOut = null;
1039 HttpURLConnection httpConnection;
1040 try {
1041 httpConnection = (HttpURLConnection) urlOCSP.openConnection();
1042 } catch (IOException e) {
1043 logger.info ("[OCSPClient.getOCSPResponse] :: Unable to connect to " + urlOCSP, e);
1044 throw new OCSPServerConnectionException ("Unable to connect to " + urlOCSP, e);
1045 }
1046
1047
1048 httpConnection.setRequestProperty("Content-Type", "application/ocsp-request");
1049 httpConnection.setRequestProperty("Accept", "application/ocsp-response");
1050
1051 httpConnection.setDoOutput(true);
1052
1053
1054 try {
1055 dataOut = new DataOutputStream(new BufferedOutputStream (httpConnection.getOutputStream()));
1056 dataOut.write(ocspRequest, 0, ocspRequest.length);
1057 dataOut.flush();
1058 } catch (IOException e) {
1059 logger.info ("[OCSPClient.getOCSPResponse] :: Error sending the OCSP request to: " + urlOCSP, e);
1060 throw new OCSPServerConnectionException ("Error sending the OCSP request to: " + urlOCSP, e);
1061 } finally {
1062 if (dataOut != null) {
1063 try { dataOut.close(); } catch (IOException e) { logger.info ("[OCSPClient.getOCSPResponse] :: No se puede cerrar el stream de escritura a " + urlOCSP, e); }
1064 }
1065 }
1066
1067
1068 int lIntResponseCode;
1069 try {
1070 lIntResponseCode = httpConnection.getResponseCode();
1071 } catch (IOException e) {
1072 logger.info ("[OCSPClient.getOCSPResponse] :: Error getting the OCSP response code", e);
1073 throw new OCSPServerConnectionException ("Error getting the OCSP response code", e);
1074 }
1075 String lStrContentType = httpConnection.getContentType();
1076 if (lIntResponseCode==200 && lStrContentType != null && lStrContentType.equalsIgnoreCase("application/ocsp-response")) {
1077
1078 int lLngLongitud = httpConnection.getContentLength();
1079
1080 DataInputStream dataIn = null;
1081 byte[] lBytRespuesta;
1082 try {
1083 dataIn = new DataInputStream(httpConnection.getInputStream());
1084 lBytRespuesta = new byte[lLngLongitud];
1085 dataIn.readFully(lBytRespuesta, 0, lBytRespuesta.length);
1086
1087
1088 OCSPResp ocspResponse = new OCSPResp(lBytRespuesta);
1089
1090
1091 if (ocspResponse.getStatus() == OCSPRespBuilder.TRY_LATER) {
1092 throw new OCSPException ("The OCSP response indicates that it will be try later");
1093 }
1094 if (ocspResponse.getStatus() == OCSPRespBuilder.INTERNAL_ERROR) {
1095 throw new OCSPException ("The OCSP response indicates that there is an internal error in OCSP server");
1096 }
1097 if (ocspResponse.getStatus() == OCSPRespBuilder.MALFORMED_REQUEST) {
1098 throw new OCSPException ("The OCSP response indicates that the request is malformed");
1099 }
1100 if (ocspResponse.getStatus() == OCSPRespBuilder.SIG_REQUIRED) {
1101 throw new OCSPException ("The OCSP response indicates that the request must be signed");
1102 }
1103 if (ocspResponse.getStatus() == OCSPRespBuilder.UNAUTHORIZED) {
1104 throw new OCSPException ("The OCSP response indicates that the request must contain authorization information");
1105 }
1106
1107
1108 return new OCSPResponse (ocspResponse);
1109
1110 } catch (IOException e) {
1111 logger.info ("[OCSPClient.getOCSPResponse] :: Cannot get the OCSP response", e);
1112 throw new OCSPServerConnectionException ("Cannot get the the OCSP response", e);
1113 } catch (OCSPException e) {
1114 logger.info ("[OCSPClient.getOCSPResponse] :: Cannot get the OCSP basic response", e);
1115 throw new OCSPServerConnectionException ("Cannot get the the OCSP basic response", e);
1116 } finally {
1117 if (dataIn != null) {
1118 try { dataIn.close(); } catch (IOException e) { logger.info ("[OCSPClient.getOCSPResponse] :: No se puede cerrar el stream de lectura de " + urlOCSP, e); }
1119 }
1120 }
1121
1122 } else {
1123 logger.info ("[OCSPClient.getOCSPResponse] :: HTTP response code is " + lIntResponseCode + ". Content type is " + lStrContentType);
1124 throw new OCSPServerConnectionException ("HTTP response code is " + lIntResponseCode + ". Content type is " + lStrContentType);
1125 }
1126
1127 }
1128
1129 }