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;
22
23 import java.io.ByteArrayInputStream;
24 import java.io.File;
25 import java.io.FileNotFoundException;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.math.BigInteger;
29 import java.net.MalformedURLException;
30 import java.net.URL;
31 import java.security.InvalidKeyException;
32 import java.security.MessageDigest;
33 import java.security.NoSuchAlgorithmException;
34 import java.security.NoSuchProviderException;
35 import java.security.PrivateKey;
36 import java.security.PublicKey;
37 import java.security.SecureRandom;
38 import java.security.SignatureException;
39 import java.security.cert.CertificateEncodingException;
40 import java.security.cert.CertificateException;
41 import java.security.cert.CertificateExpiredException;
42 import java.security.cert.CertificateFactory;
43 import java.security.cert.CertificateNotYetValidException;
44 import java.security.cert.CertificateParsingException;
45 import java.security.cert.X509Certificate;
46 import java.text.SimpleDateFormat;
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.Date;
50 import java.util.Enumeration;
51 import java.util.HashMap;
52 import java.util.Iterator;
53 import java.util.List;
54 import java.util.Map;
55 import java.util.StringTokenizer;
56 import java.util.TreeMap;
57 import java.util.Vector;
58
59 import org.apache.log4j.Logger;
60 import org.bouncycastle.asn1.ASN1Encoding;
61 import org.bouncycastle.asn1.ASN1InputStream;
62 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
63 import org.bouncycastle.asn1.ASN1OctetString;
64 import org.bouncycastle.asn1.ASN1Primitive;
65 import org.bouncycastle.asn1.ASN1Sequence;
66 import org.bouncycastle.asn1.ASN1String;
67 import org.bouncycastle.asn1.DERIA5String;
68 import org.bouncycastle.asn1.DEROctetString;
69 import org.bouncycastle.asn1.DERSequence;
70 import org.bouncycastle.asn1.DERTaggedObject;
71 import org.bouncycastle.asn1.DERUTF8String;
72 import org.bouncycastle.asn1.cms.ContentInfo;
73 import org.bouncycastle.asn1.cms.IssuerAndSerialNumber;
74 import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers;
75 import org.bouncycastle.asn1.x500.RDN;
76 import org.bouncycastle.asn1.x500.X500Name;
77 import org.bouncycastle.asn1.x500.style.BCStyle;
78 import org.bouncycastle.asn1.x509.AccessDescription;
79 import org.bouncycastle.asn1.x509.AuthorityInformationAccess;
80 import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
81 import org.bouncycastle.asn1.x509.BasicConstraints;
82 import org.bouncycastle.asn1.x509.CRLDistPoint;
83 import org.bouncycastle.asn1.x509.DistributionPoint;
84 import org.bouncycastle.asn1.x509.DistributionPointName;
85 import org.bouncycastle.asn1.x509.Extension;
86 import org.bouncycastle.asn1.x509.GeneralName;
87 import org.bouncycastle.asn1.x509.GeneralNames;
88 import org.bouncycastle.asn1.x509.KeyUsage;
89 import org.bouncycastle.asn1.x509.PolicyInformation;
90 import org.bouncycastle.asn1.x509.SubjectKeyIdentifier;
91 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
92 import org.bouncycastle.cert.CertIOException;
93 import org.bouncycastle.cert.X509CertificateHolder;
94 import org.bouncycastle.cert.X509v3CertificateBuilder;
95 import org.bouncycastle.cert.jcajce.JcaCertStore;
96 import org.bouncycastle.cms.CMSException;
97 import org.bouncycastle.cms.CMSProcessableByteArray;
98 import org.bouncycastle.cms.CMSSignedData;
99 import org.bouncycastle.cms.CMSSignedDataGenerator;
100 import org.bouncycastle.operator.ContentSigner;
101 import org.bouncycastle.operator.OperatorCreationException;
102 import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
103 import org.bouncycastle.util.encoders.Hex;
104 import org.ietf.ldap.LDAPDN;
105
106 import es.accv.arangi.base.ArangiObject;
107 import es.accv.arangi.base.algorithm.DigitalSignatureAlgorithm;
108 import es.accv.arangi.base.algorithm.HashingAlgorithm;
109 import es.accv.arangi.base.certificate.data.CertificateDataService;
110 import es.accv.arangi.base.certificate.validation.CertificateValidationService;
111 import es.accv.arangi.base.certificate.validation.CertificateValidationServiceResult;
112 import es.accv.arangi.base.certificate.validation.OCSPClient;
113 import es.accv.arangi.base.certificate.validation.OCSPResponse;
114 import es.accv.arangi.base.exception.certificate.CertificateFieldException;
115 import es.accv.arangi.base.exception.certificate.NormalizeCertificateException;
116 import es.accv.arangi.base.util.AlternativeNameElement;
117 import es.accv.arangi.base.util.Util;
118 import es.accv.arangi.base.util.validation.ValidationResult;
119
120
121
122
123
124
125
126
127
128
129 public class Certificate extends ArangiObject{
130
131
132
133
134 static Logger logger = Logger.getLogger(Certificate.class);
135
136
137
138
139 public static final String OID_OCSP_AIA_EXTENSION = "1.3.6.1.5.5.7.48.1";
140
141
142
143
144 public static final String OID_ID_AT_COMMONNAME = "2.5.4.3";
145
146
147
148
149 public static final String OID_USERID = "0.9.2342.19200300.100.1.1";
150
151 private static final String[] DN_OBJECTS = {
152 "unstructuredaddress", "unstructuredname", "emailaddress", "e", "email", "uid", "cn", "sn", "serialnumber", "gn", "givenname",
153 "initials", "surname", "t", "ou", "o", "l", "st", "dc", "c"
154 };
155
156
157
158
159 protected static SimpleDateFormat dateFormat = new SimpleDateFormat ("yyyy-MM-dd HH:mm");
160
161
162
163
164 protected X509Certificate certificate;
165
166
167
168
169 org.bouncycastle.asn1.x509.Certificate asn1Certificate;
170
171
172
173
174 private Boolean selfSigned;
175
176
177 private static final HashMap<String,ASN1ObjectIdentifier> oids = new HashMap<String,ASN1ObjectIdentifier>();
178
179 static {
180 oids.put("c", BCStyle.C);
181 oids.put("dc", BCStyle.DC);
182 oids.put("st", BCStyle.ST);
183 oids.put("l", BCStyle.L);
184 oids.put("o", BCStyle.O);
185 oids.put("ou", BCStyle.OU);
186 oids.put("t", BCStyle.T);
187 oids.put("surname", BCStyle.SURNAME);
188 oids.put("initials", BCStyle.INITIALS);
189 oids.put("givenname", BCStyle.GIVENNAME);
190 oids.put("gn", BCStyle.GIVENNAME);
191 oids.put("sn", BCStyle.SN);
192 oids.put("serialnumber", BCStyle.SN);
193 oids.put("cn", BCStyle.CN);
194 oids.put("uid", BCStyle.UID);
195 oids.put("emailaddress", BCStyle.EmailAddress);
196 oids.put("e", BCStyle.EmailAddress);
197 oids.put("email", BCStyle.EmailAddress);
198 oids.put("unstructuredname", BCStyle.UnstructuredName);
199 oids.put("unstructuredaddress", BCStyle.UnstructuredAddress);
200 }
201
202 private static final String[] dNObjects = {
203 "unstructuredaddress", "unstructuredname", "emailaddress", "e", "email", "uid", "cn", "sn", "serialnumber", "gn", "givenname",
204 "initials", "surname", "t", "ou", "o", "l", "st", "dc", "c"
205 };
206
207
208
209
210
211
212
213
214
215 public Certificate(X509CertificateHolder certificate) throws NormalizeCertificateException {
216 super();
217
218 try {
219 initialize (Util.getCertificate(certificate));
220 } catch (CertificateException e) {
221 logger.info("[Certificate]::No se puede pasar de la estructura al certificado X.509");
222 throw new NormalizeCertificateException("No se puede pasar de la estructura al certificado X.509");
223 }
224 }
225
226
227
228
229
230
231
232
233
234 public Certificate(X509Certificate certificate) throws NormalizeCertificateException {
235 super();
236
237 initialize (certificate);
238 }
239
240
241
242
243
244
245
246
247
248
249 public Certificate(File fileCertificate) throws NormalizeCertificateException, FileNotFoundException {
250 super();
251
252
253 X509Certificate certificate = Util.getCertificate(fileCertificate);
254 if (certificate == null) {
255 logger.info("[Certificate]::El fichero no es un certificado digital");
256 throw new NormalizeCertificateException("El fichero no es un certificado digital");
257 }
258
259
260 this.certificate = normalize (certificate);
261
262
263 initialize(certificate);
264 }
265
266
267
268
269
270
271
272
273
274 public Certificate(InputStream isCertificate) throws NormalizeCertificateException {
275 super();
276
277
278 X509Certificate certificate = Util.getCertificate(isCertificate);
279 if (certificate == null) {
280 logger.info("[Certificate]::El fichero no es un certificado digital");
281 throw new NormalizeCertificateException("El fichero no es un certificado digital");
282 }
283
284
285 this.certificate = normalize (certificate);
286
287
288 initialize(certificate);
289 }
290
291
292
293
294
295
296
297
298
299 public Certificate(byte[] contenidoCertificado) throws NormalizeCertificateException {
300 super();
301
302
303 ByteArrayInputStream bais = new ByteArrayInputStream (contenidoCertificado);
304 X509Certificate certificate = Util.getCertificate(bais);
305 if (certificate == null) {
306 logger.info("[Certificate]::El fichero no es un certificado digital");
307 throw new NormalizeCertificateException("El fichero no es un certificado digital");
308 }
309
310
311 this.certificate = normalize (certificate);
312
313
314 initialize(certificate);
315 }
316
317
318
319
320
321
322
323
324
325
326 public boolean isSelfSigned() throws NormalizeCertificateException {
327 logger.debug("[Certificate.isSelfSigned]:: Inicio ");
328
329 if (this.selfSigned == null) {
330 PublicKey pubKey = certificate.getPublicKey();
331 try {
332 certificate.verify(pubKey, CRYPTOGRAPHIC_PROVIDER_NAME);
333 logger.debug("[Certificate.isSelfSigned]::Es autofirmado ");
334
335 this.selfSigned = new Boolean (true);
336
337 } catch (InvalidKeyException e) {
338
339 logger.debug("[Certificate.isSelfSigned]::No es autofirmado");
340 this.selfSigned = new Boolean (false);
341 } catch (CertificateException e) {
342 logger.info ("[Certificate.isSelfSigned]::La firma del certificado no está correctamente codificada", e);
343 throw new NormalizeCertificateException ("La firma del certificado no está correctamente codificada", e);
344 } catch (NoSuchAlgorithmException e) {
345 logger.info ("[Certificate.isSelfSigned]::El algoritmo de la firma del certificado no está soportado", e);
346 throw new NormalizeCertificateException ("El algoritmo de la firma del certificado no está soportado", e);
347 } catch (NoSuchProviderException e) {
348
349 logger.info ("[Certificate.isSelfSigned]::No existe el proveedor criptográfico de Arangi", e);
350 throw new NormalizeCertificateException ("No existe el proveedor criptográfico de Arangi", e);
351 } catch (SignatureException e) {
352
353 logger.debug("[Certificate.isSelfSigned]::No es autofirmado");
354 this.selfSigned = new Boolean (false);
355 }
356 }
357
358 return this.selfSigned.booleanValue();
359 }
360
361
362
363
364
365
366
367 public String getPolicyOID() {
368
369 logger.debug("[Certificate.getPolicyOID]::Entrada");
370
371 List<String> policyOIDs = getPolicyOIDs();
372 if (policyOIDs.isEmpty()) {
373 return null;
374 }
375
376 return policyOIDs.get(0);
377 }
378
379
380
381
382
383
384 public List<String> getPolicyOIDs() {
385
386 logger.debug("[Certificate.getPolicyOIDs]::Entrada");
387
388 List<String> policyOIDs = new ArrayList<String>();
389
390
391 byte[] extension = certificate.getExtensionValue(Extension.certificatePolicies.getId());
392
393 if (extension == null) {
394 return policyOIDs;
395 }
396
397 try {
398 ByteArrayInputStream bais = new ByteArrayInputStream(extension);
399 ASN1InputStream asn1IS = new ASN1InputStream(bais);
400
401 bais = new ByteArrayInputStream(((ASN1OctetString) asn1IS.readObject()).getOctets());
402 asn1IS = new ASN1InputStream(bais);
403
404 Enumeration enumeration = ((ASN1Sequence) asn1IS.readObject()).getObjects();
405 while (enumeration.hasMoreElements()) {
406 Enumeration enumeration2 = ((ASN1Sequence) enumeration.nextElement()).getObjects();
407
408 String policy = ((ASN1ObjectIdentifier) enumeration2.nextElement()).getId();
409 logger.debug("[Certificate.getPolicyOIDs]::Una política del certificado es" + policy);
410 policyOIDs.add(policy);
411 }
412
413 return policyOIDs;
414
415 } catch (Exception e) {
416 logger.info("[Certificate.getPolicyOIDs]::No es posible obtener la extensión del certificado", e);
417 return new ArrayList<String>();
418 }
419 }
420
421
422
423
424
425
426 public String getIssuerKeyIdentifier() {
427 return Certificate.getIssuerKeyIdentifier(this.certificate);
428 }
429
430
431
432
433
434
435 public String getSubjectKeyIdentifier() {
436 return Certificate.getSubjectKeyIdentifier(this.certificate);
437 }
438
439
440
441
442
443
444
445
446
447 public String [] getCrlUrls() throws CertificateFieldException{
448
449 logger.debug("[Certificate.getCrlUrls]::Entrada");
450
451 DERIA5String lDERObjCRL_URL;
452 byte[] extBytes = certificate.getExtensionValue(Extension.cRLDistributionPoints.getId());
453
454
455 if (extBytes == null) {
456 logger.debug("[Certificate.getCrlUrls]::No existe la extensión CDP en el certificado");
457 return new String[0];
458 }
459
460
461 ASN1InputStream ais = new ASN1InputStream(new ByteArrayInputStream(extBytes));
462
463 try {
464 DEROctetString oct = (DEROctetString) ais.readObject();
465 ais = new ASN1InputStream(new ByteArrayInputStream(oct.getOctets()));
466 CRLDistPoint cdp = CRLDistPoint.getInstance((ASN1Sequence) ais.readObject());
467
468 DistributionPoint[] points = cdp.getDistributionPoints();
469
470 ArrayList alURLs = new ArrayList();
471 for (int i = 0; i < points.length; i++) {
472 DistributionPoint point = points[i];
473
474 DistributionPointName name = point.getDistributionPoint();
475
476 GeneralName[] gns = ((GeneralNames) name.getName()).getNames();
477 for (int j = 0; j < gns.length; j++) {
478 GeneralName gn = gns[j];
479
480
481 if (gn.getTagNo() == GeneralName.uniformResourceIdentifier) {
482 lDERObjCRL_URL = (DERIA5String) ((DERTaggedObject)gn.toASN1Primitive().toASN1Primitive()).getObject();
483 alURLs.add (lDERObjCRL_URL.getString());
484 } else if (gn.getTagNo() == GeneralName.directoryName) {
485 }
486 }
487 }
488
489
490 return (String []) alURLs.toArray(new String [0]);
491
492 } catch (IOException e) {
493 logger.info("[Certificate.getCrlUrls]::La extensión CDP en el certificado existe pero no se puede leer", e);
494 throw new CertificateFieldException ("La extensión CDP en el certificado existe pero no se puede leer", e);
495 }
496 }
497
498
499
500
501
502
503
504
505
506 public String [] getOcspUrls() throws CertificateFieldException{
507
508 byte[] extBytes = certificate.getExtensionValue(Extension.authorityInfoAccess.getId());
509
510
511 if (extBytes == null) {
512 logger.debug("[Certificate.getCrlUrls]::No existe la extensión AIA en el certificado");
513 return new String[0];
514 }
515
516
517 ASN1InputStream ais = new ASN1InputStream(new ByteArrayInputStream(extBytes));
518
519 try {
520 DEROctetString oct = (DEROctetString) ais.readObject();
521 ais = new ASN1InputStream(new ByteArrayInputStream(oct.getOctets()));
522 AuthorityInformationAccess aia = AuthorityInformationAccess.getInstance((ASN1Sequence) ais.readObject());
523 List<String> urls = new ArrayList<String>();
524 for (int i=0; i<aia.getAccessDescriptions().length; i++) {
525 AccessDescription accessDescription = aia.getAccessDescriptions() [i];
526 if (accessDescription.getAccessLocation().getTagNo() == GeneralName.uniformResourceIdentifier &&
527 accessDescription.getAccessMethod().getId().equals(OID_OCSP_AIA_EXTENSION)) {
528 DERIA5String lDERObjCRL_URL = (DERIA5String) ((DERTaggedObject)accessDescription.getAccessLocation().toASN1Primitive()).getObject();
529 urls.add(lDERObjCRL_URL.getString());
530 }
531 }
532
533 return (String[]) urls.toArray(new String[0]);
534
535 } catch (IOException e) {
536 logger.info("[Certificate.getCrlUrls]::La extensión AIA en el certificado existe pero no se puede leer", e);
537 throw new CertificateFieldException ("La extensión AIA en el certificado existe pero no se puede leer", e);
538 }
539 }
540
541
542
543
544
545
546
547 public boolean isActive() {
548
549 logger.debug ("[Certificate.isCertificateInValidityInterval]::Entrada");
550
551 try {
552 certificate.checkValidity();
553 } catch (CertificateNotYetValidException e) {
554 logger.debug ("[Certificate.isCertificateInValidityInterval]::El certificado aun no es válido");
555 return false;
556 } catch (CertificateExpiredException e) {
557 logger.debug ("[Certificate.isCertificateInValidityInterval]::El certificado ya no es válido");
558 return false;
559 }
560
561 return true;
562 }
563
564
565
566
567
568
569
570 public boolean isNotYetActive() {
571
572 logger.debug ("[Certificate.isNotYetActive]::Entrada");
573
574 try {
575 certificate.checkValidity();
576 } catch (CertificateNotYetValidException e) {
577 logger.debug ("[Certificate.isNotYetActive]::El certificado aun no es válido");
578 return true;
579 } catch (CertificateExpiredException e) {
580 logger.debug ("[Certificate.isNotYetActive]::El certificado ya no es válido");
581 return false;
582 }
583
584 return false;
585 }
586
587
588
589
590
591
592
593 public boolean isExpired() {
594
595 logger.debug ("[Certificate.isExpired]::Entrada");
596
597 try {
598 certificate.checkValidity();
599 } catch (CertificateNotYetValidException e) {
600 logger.debug ("[Certificate.isExpired]::El certificado aun no es válido");
601 return false;
602 } catch (CertificateExpiredException e) {
603 logger.debug ("[Certificate.isExpired]::El certificado ya no es válido");
604 return true;
605 }
606
607 return false;
608 }
609
610
611
612
613
614
615 public Date getValidityPeriodBeginning () {
616
617 logger.debug ("[Certificate.getValidityPeriodBeginning]::Entrada");
618
619 return certificate.getNotBefore();
620 }
621
622
623
624
625
626
627 public Date getValidityPeriodEnd () {
628
629 logger.debug ("[Certificate.getValidityPeriodEnd]::Entrada");
630
631 return certificate.getNotAfter();
632 }
633
634
635
636
637
638
639 public boolean isKeyUsageDigitalSignature () {
640
641 logger.debug ("[Certificate.isKeyUsageDigitalSignature]::Entrada");
642
643 if (certificate.getKeyUsage() == null) {
644 return true;
645 }
646
647 return certificate.getKeyUsage()[0];
648 }
649
650
651
652
653
654
655 public boolean isKeyUsageNonRepudiation () {
656
657 logger.debug ("[Certificate.isKeyUsageNonRepudiation]::Entrada");
658
659 if (certificate.getKeyUsage() == null) {
660 return true;
661 }
662
663 return certificate.getKeyUsage()[1];
664 }
665
666
667
668
669
670
671 public boolean isKeyUsageKeyEncipherment () {
672
673 logger.debug ("[Certificate.isKeyUsageKeyEncipherment]::Entrada");
674
675 if (certificate.getKeyUsage() == null) {
676 return true;
677 }
678
679 return certificate.getKeyUsage()[2];
680 }
681
682
683
684
685
686
687 public boolean isKeyUsageDataEncipherment () {
688
689 logger.debug ("[Certificate.isKeyUsageDataEncipherment]::Entrada");
690
691 if (certificate.getKeyUsage() == null) {
692 return true;
693 }
694
695 return certificate.getKeyUsage()[3];
696 }
697
698
699
700
701
702
703 public boolean isKeyUsageKeyAgreement () {
704
705 logger.debug ("[Certificate.isKeyUsageKeyAgreement]::Entrada");
706
707 if (certificate.getKeyUsage() == null) {
708 return true;
709 }
710
711 return certificate.getKeyUsage()[4];
712 }
713
714
715
716
717
718
719 public boolean isKeyUsageKeyCertSign () {
720
721 logger.debug ("[Certificate.isKeyUsageKeyCertSign]::Entrada");
722
723 if (certificate.getKeyUsage() == null) {
724 return true;
725 }
726
727 return certificate.getKeyUsage()[5];
728 }
729
730
731
732
733
734
735 public boolean isKeyUsageCRLSign () {
736
737 logger.debug ("[Certificate.isKeyUsageCRLSign]::Entrada");
738
739 if (certificate.getKeyUsage() == null) {
740 return true;
741 }
742
743 return certificate.getKeyUsage()[6];
744 }
745
746
747
748
749
750
751 public boolean isKeyUsageEncipherOnly () {
752
753 logger.debug ("[Certificate.isKeyUsageEncipherOnly]::Entrada");
754
755 if (certificate.getKeyUsage() == null) {
756 return true;
757 }
758
759 return certificate.getKeyUsage()[7];
760 }
761
762
763
764
765
766
767 public boolean isKeyUsageDecipherOnly () {
768
769 logger.debug ("[Certificate.isKeyUsageDecipherOnly]::Entrada");
770
771 if (certificate.getKeyUsage() == null) {
772 return true;
773 }
774
775 return certificate.getKeyUsage()[8];
776 }
777
778
779
780
781
782
783
784
785
786
787
788
789
790 public List<String> getExtendedKeyUsage () throws es.accv.arangi.base.exception.CertificateException {
791
792 logger.debug ("[Certificate.getExtendedKeyUsage]::Entrada");
793
794 try {
795 List<String> result = certificate.getExtendedKeyUsage();
796 if (result == null) {
797 return new ArrayList<String>();
798 }
799 return result;
800 } catch (CertificateParsingException e) {
801 logger.info("[Certificate.getExtendedKeyUsage]::La extensión no puede ser descodificada", e);
802 throw new es.accv.arangi.base.exception.CertificateException("La extensión no puede ser descodificada", e);
803 }
804 }
805
806
807
808
809
810
811
812
813
814
815 public String getFingerPrint() {
816 return getFingerPrint(DEFAULT_HASHING_ALGORITHM);
817 }
818
819
820
821
822
823
824
825
826
827 public String getFingerPrint(String hashingAlgorithm) {
828
829 logger.debug ("[Certificate.getFingerPrint]::Entrada");
830
831 try {
832
833 byte[] lBytesHash = getDigest(hashingAlgorithm);
834
835
836 byte[] lBytesHash_HEX = Hex.encode(lBytesHash);
837
838
839 String lStrHash = new String(lBytesHash_HEX);
840
841 return lStrHash.toUpperCase();
842 } catch (CertificateEncodingException e0) {
843 logger.info ("[Certificate.getFingerPrint]::Error de codificación del certificado");
844 return "";
845 } catch (NoSuchAlgorithmException e2) {
846 logger.info ("[Certificate.getFingerPrint]::No se encuentra el algoritmo " + DEFAULT_HASHING_ALGORITHM);
847 return "";
848 }
849 }
850
851
852
853
854
855
856
857
858
859
860
861
862 public byte[] getDigest() throws CertificateEncodingException, NoSuchAlgorithmException {
863 return getDigest(DEFAULT_HASHING_ALGORITHM);
864 }
865
866
867
868
869
870
871
872
873
874
875
876 public byte[] getDigest(String hashingAlgorithm) throws NoSuchAlgorithmException, CertificateEncodingException {
877
878 logger.debug ("[Certificate.getDigest]::Entrada::" + hashingAlgorithm);
879
880
881 MessageDigest lObjHashMaker = MessageDigest.getInstance(hashingAlgorithm);
882
883
884 return lObjHashMaker.digest(certificate.getEncoded());
885
886 }
887
888
889
890
891
892
893
894 public String getDigestAlgorithm () throws NoSuchAlgorithmException {
895 String sigAlgorithm = certificate.getSigAlgName();
896 logger.debug("Algoritmo de firma del certificado: " + sigAlgorithm);
897 return DigitalSignatureAlgorithm.getHashingAlgorithm(sigAlgorithm);
898 }
899
900
901
902
903
904
905
906
907
908
909
910
911 public String getElementSubject (ASN1ObjectIdentifier oid) {
912
913 logger.debug ("[Certificate.getElementSubject]::Buscando OID '" + oid.getId() + "' en el subject");
914
915 X500Name subjectName = this.asn1Certificate.getSubject();
916 RDN[] rdns = subjectName.getRDNs(oid);
917 if (rdns == null || rdns.length == 0) {
918 logger.debug ("[Certificate.getElementSubject]::Para el OID '" + oid.getId() + "' no hay ningún elemento en el subject");
919 return null;
920 }
921 return rdns[0].getFirst().getValue().toString();
922 }
923
924
925
926
927
928
929
930
931
932
933
934
935 public String[] getElementsSubject (ASN1ObjectIdentifier oid) {
936
937 logger.debug ("[Certificate.getElementSubject]::Buscando OID '" + oid.getId() + "' en el subject");
938
939 X500Name subjectName = this.asn1Certificate.getSubject();
940 RDN[] rdns = subjectName.getRDNs(oid);
941 if (rdns == null || rdns.length == 0) {
942 logger.debug ("[Certificate.getElementSubject]::Para el OID '" + oid.getId() + "' no hay ningún elemento en el subject");
943 return null;
944 }
945 String[] result = new String[rdns.length];
946 for(int i=0;i<rdns.length;i++) {
947 result[i] = rdns[i].getFirst().getValue().toString();
948 }
949 return result;
950 }
951
952
953
954
955
956
957 public String getCommonName () {
958
959 logger.debug ("[Certificate.getCommonName]::Entrada");
960
961 return getElementSubject(BCStyle.CN);
962 }
963
964
965
966
967
968
969 public String getCountry () {
970
971 logger.debug ("[Certificate.getCountry]::Entrada");
972
973 return getElementSubject(BCStyle.C);
974 }
975
976
977
978
979
980
981 public String getSubjectDN () {
982 return this.certificate.getSubjectDN().getName();
983 }
984
985
986
987
988
989
990 public String getIssuerDN () {
991 return this.certificate.getIssuerDN().getName();
992 }
993
994
995
996
997
998
999 public String getIssuerCommonName () {
1000
1001 logger.debug ("[Certificate.getIssuerCommonName]::Entrada");
1002
1003 String dn = this.certificate.getIssuerDN().getName();
1004 StringTokenizer st = new StringTokenizer(dn, ",");
1005 while(st.hasMoreTokens()) {
1006 String token = st.nextToken();
1007 if (token.startsWith("CN=")) {
1008 return token.substring(3);
1009 }
1010 }
1011
1012 return null;
1013 }
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023 public List getSubjectAlternativeName() throws CertificateFieldException {
1024
1025 logger.debug ("[Certificate.getSubjectAlternativeName]::Entrada");
1026
1027 byte[] extVal = certificate.getExtensionValue(Extension.subjectAlternativeName.getId());
1028
1029 try {
1030 return getAlternativeNames(extVal);
1031 } catch (CertificateParsingException e) {
1032 logger.info("[Certificate.getSubjectAlternativeNames]::Error leyendo la extensión SubjectAlternativeName", e);
1033 throw new CertificateFieldException ("Error leyendo la extensión SubjectAlternativeName", e);
1034 }
1035 }
1036
1037
1038
1039
1040
1041
1042
1043 public String getSubjectAlternativeNameString() throws CertificateFieldException {
1044
1045 logger.debug ("[Certificate.getSubjectAlternativeNameString]::Entrada");
1046
1047 List<AlternativeNameElement> elementos = getSubjectAlternativeName();
1048 StringBuffer sb = new StringBuffer("");
1049 int i=0;
1050 for (AlternativeNameElement elemento : elementos) {
1051 switch (elemento.getType()) {
1052 case GeneralName.ediPartyName:
1053 break;
1054 case GeneralName.x400Address:
1055 break;
1056 case GeneralName.otherName:
1057 break;
1058 case GeneralName.directoryName:
1059 if (i>0) { sb.append(","); }
1060 sb.append("directoryName=");
1061 TreeMap<String,String> dn = (TreeMap<String,String>) elemento.getValue();
1062 int campos = 0;
1063 StringBuffer directoryName = new StringBuffer("");
1064 for(String key : dn.keySet()) {
1065 if (campos > 0) {directoryName.append(",");}
1066 directoryName.append("OID." + key + "=" + dn.get(key));
1067 campos++;
1068 }
1069 sb.append(LDAPDN.escapeRDN(directoryName.toString()));
1070 i++;
1071 break;
1072 case GeneralName.dNSName:
1073 if (i>0) { sb.append(","); }
1074 sb.append("dNSName=" + elemento.getValue());
1075 i++;
1076 break;
1077 case GeneralName.rfc822Name:
1078 if (i>0) { sb.append(","); }
1079 sb.append("rfc822Name=" + elemento.getValue());
1080 i++;
1081 break;
1082 case GeneralName.uniformResourceIdentifier:
1083 break;
1084 case GeneralName.registeredID:
1085 break;
1086 case GeneralName.iPAddress:
1087 break;
1088 }
1089
1090 }
1091
1092 return sb.toString();
1093
1094 }
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108 public String getSubjectAlternativeNameElement (String oid) throws CertificateFieldException {
1109
1110 logger.debug ("[Certificate.getSubjectAlternativeNameElement]::Entrada::" + oid);
1111
1112 String[] resultado = getSubjectAlternativeNameElements (oid);
1113 if (resultado.length == 0) {
1114 return null;
1115 }
1116
1117 return resultado[0];
1118 }
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131 public String[] getSubjectAlternativeNameElements (String oid) throws CertificateFieldException {
1132
1133 logger.debug ("[Certificate.getSubjectAlternativeNameElements]::Entrada::" + oid);
1134
1135
1136 List lNames = getSubjectAlternativeName();
1137
1138
1139 List<String> resultado = new ArrayList<String>();
1140 for (Iterator iterator = lNames.iterator(); iterator.hasNext();) {
1141 AlternativeNameElement element = (AlternativeNameElement) iterator.next();
1142 if (element.getValue() instanceof Map) {
1143 Map<String,String> mapElement = (Map<String,String>) element.getValue();
1144 if (mapElement.containsKey(oid)) {
1145 logger.debug ("[Certificate.getSubjectAlternativeNameElement]::Encontrado el elemento::" + mapElement.get(oid));
1146 resultado.add(mapElement.get(oid));
1147 }
1148 }
1149 }
1150
1151 return resultado.toArray(new String[0]);
1152 }
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165 public List<AlternativeNameElement> getSubjectAlternativeNameElements (int type) throws CertificateFieldException {
1166
1167 logger.debug ("[Certificate.getSubjectAlternativeNameElements]::Entrada::" + type);
1168
1169
1170 List lNames = getSubjectAlternativeName();
1171
1172
1173 List<AlternativeNameElement> resultado = new ArrayList<AlternativeNameElement>();
1174 for (Iterator iterator = lNames.iterator(); iterator.hasNext();) {
1175 AlternativeNameElement element = (AlternativeNameElement) iterator.next();
1176 if (element.getType() == type) {
1177 logger.debug ("[Certificate.getSubjectAlternativeNameElement]::Encontrado el elemento para el tipo " + type);
1178 resultado.add(element);
1179 }
1180 }
1181
1182 return resultado;
1183 }
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193 public List getIssuerAlternativeName() throws CertificateFieldException {
1194
1195 logger.debug ("[Certificate.getIssuerAlternativeNames]::Entrada");
1196
1197 byte[] extVal = certificate.getExtensionValue(Extension.issuerAlternativeName.getId());
1198
1199 try {
1200 return getAlternativeNames(extVal);
1201 } catch (CertificateParsingException e) {
1202 logger.info("[Certificate.getIssuerAlternativeNames]::Error leyendo la extensión IssuerAlternativeName", e);
1203 throw new CertificateFieldException ("Error leyendo la extensión IssuerAlternativeName", e);
1204 }
1205 }
1206
1207
1208
1209
1210
1211
1212
1213
1214 public Vector getIssuerAlternativeNameElement (String oid) throws CertificateFieldException {
1215
1216 logger.debug ("[Certificate.getIssuerAlternativeNameElement]::Entrada::" + oid);
1217
1218
1219 List lNames = getIssuerAlternativeName();
1220
1221
1222 for (Iterator iterator = lNames.iterator(); iterator.hasNext();) {
1223 AlternativeNameElement element = (AlternativeNameElement) iterator.next();
1224 if (element.getValue() instanceof Map) {
1225 Map mapElement = (Map) element.getValue();
1226 if (mapElement.containsKey(oid)) {
1227 logger.debug ("[Certificate.getIssuerAlternativeNameElement]::Encontrado el elemento::" + (Vector) mapElement.get(oid));
1228 return (Vector) mapElement.get(oid);
1229 }
1230 }
1231 }
1232
1233 logger.debug ("[Certificate.getIssuerAlternativeNameElement]::No se ha encontrado el elemento para el oid " + oid);
1234 return null;
1235 }
1236
1237
1238
1239
1240
1241
1242
1243 public String getSerialNumber() {
1244
1245 logger.debug ("[Certificate.getSerialNumber]::Entrada");
1246
1247 return certificate.getSerialNumber().toString(16).toUpperCase();
1248 }
1249
1250
1251
1252
1253
1254
1255
1256 public BigInteger getSerialNumberBigInteger() {
1257
1258 logger.debug ("[Certificate.getSerialNumberBigInteger]::Entrada");
1259
1260 return certificate.getSerialNumber();
1261 }
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272 public IssuerAndSerialNumber getIssuerAndSerialNumber() throws CertificateFieldException {
1273
1274 logger.debug ("[Certificate.getIssuerAndSerialNumber]::Entrada");
1275
1276 try {
1277 ASN1InputStream inputStreamTbsCertificate = new ASN1InputStream(new ByteArrayInputStream(toX509Certificate().getTBSCertificate()));
1278 ASN1Sequence seqAux = (ASN1Sequence)inputStreamTbsCertificate.readObject();
1279 ASN1Primitive tbsCertificateDER = (ASN1Primitive)seqAux.getObjectAt(seqAux.getObjectAt(0) instanceof DERTaggedObject ? 3 : 2);
1280 return new IssuerAndSerialNumber(X500Name.getInstance((ASN1Sequence)tbsCertificateDER),
1281 toX509Certificate().getSerialNumber());
1282 } catch (CertificateEncodingException e) {
1283 logger.info("[Certificate.toDER]::Error obteniendo la información del certificado en formato DER", e);
1284 throw new CertificateFieldException ("Error obteniendo la información del certificado en formato DER", e);
1285 } catch (IOException e) {
1286 logger.info("[Certificate.toDER]::Error leyendo la información del certificado en formato DER", e);
1287 throw new CertificateFieldException ("Error leyendo la información del certificado en formato DER", e);
1288 }
1289 }
1290
1291
1292
1293
1294
1295
1296 public PublicKey getPublicKey () {
1297
1298 logger.debug ("[Certificate.getPublicKey]::Entrada");
1299
1300 return certificate.getPublicKey();
1301 }
1302
1303
1304
1305
1306
1307
1308 public X509Certificate toX509Certificate () {
1309 return certificate;
1310 }
1311
1312
1313
1314
1315
1316
1317
1318
1319 public byte[] toDER () throws NormalizeCertificateException {
1320 try {
1321 return certificate.getEncoded();
1322 } catch (CertificateEncodingException e) {
1323 logger.info("[Certificate.toDER]::Error codificando el certificado en formato DER", e);
1324 throw new NormalizeCertificateException ("Error codificando el certificado en formato DER", e);
1325 }
1326 }
1327
1328
1329
1330
1331
1332
1333
1334 public X509CertificateHolder toX509CertificateHolder () {
1335 return new X509CertificateHolder(asn1Certificate);
1336 }
1337
1338
1339
1340
1341
1342
1343
1344
1345 public String toPEM () throws NormalizeCertificateException {
1346
1347 return "-----BEGIN CERTIFICATE-----\n" + Util.encodeBase64(toDER()) +
1348 "\n-----END CERTIFICATE-----";
1349 }
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359 public byte[] toPKCS7(Certificate[] chain) throws SignatureException {
1360
1361 logger.debug("[Certificate.toPKCS7]::Entrada::" + (chain==null?"null":chain.length));
1362
1363
1364 CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
1365
1366
1367 X509Certificate certificate = toX509Certificate();
1368 List<X509Certificate> certList = new ArrayList<X509Certificate>();
1369 certList.add(certificate);
1370 if (chain != null) {
1371 for (int i = 0; i < chain.length; i++) {
1372 certList.add(chain[i].toX509Certificate());
1373 }
1374 }
1375
1376
1377 try {
1378 gen.addCertificates(new JcaCertStore(certList));
1379 CMSProcessableByteArray process = new CMSProcessableByteArray(null);
1380 CMSSignedData data = gen.generate(process);
1381 ContentInfo contentInfo = data.toASN1Structure();
1382 return contentInfo.getEncoded(ASN1Encoding.DER);
1383 } catch (CMSException e) {
1384 logger.info ("[Certificate.toPKCS7]::El certificado no puede ser almacenado en formato PKCS#7", e);
1385 throw new SignatureException ("El certificado no puede ser almacenado en formato PKCS#7", e);
1386 } catch (IOException e) {
1387 logger.info ("[Certificate.toPKCS7]::Excepción de entrada/salida", e);
1388 throw new SignatureException ("Excepción de entrada/salida", e);
1389 } catch (CertificateEncodingException e) {
1390 logger.info ("[Certificate.toPKCS7]::El certificado no puede ser almacenado", e);
1391 throw new SignatureException ("El certificado no puede ser almacenado", e);
1392 }
1393
1394 }
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404 public void save (File file) throws NormalizeCertificateException, Exception {
1405 Util.saveFile(file, toDER());
1406 }
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416 public void saveToPEM (File file) throws NormalizeCertificateException, Exception {
1417 Util.saveFile(file, toPEM().getBytes());
1418 }
1419
1420
1421
1422
1423
1424
1425 public String toString () {
1426 return certificate.toString();
1427 }
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440 public static X509Certificate normalize (X509Certificate originalCert) throws NormalizeCertificateException {
1441
1442 byte[] bytes;
1443 try {
1444 bytes = originalCert.getEncoded();
1445 } catch (CertificateEncodingException e) {
1446 logger.info ("[Certificate.normalize]::Error de codificación del certificado", e);
1447 throw new NormalizeCertificateException ("Error de codificación del certificado", e);
1448 }
1449
1450 ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
1451 CertificateFactory cf;
1452 try {
1453 cf = CertificateFactory.getInstance("X.509", CRYPTOGRAPHIC_PROVIDER);
1454 } catch (CertificateException e) {
1455 logger.info ("[Certificate.normalize]::El tipo del certificado no está disponible para el proveedor criptográfico de Arangi: " + CRYPTOGRAPHIC_PROVIDER, e);
1456 throw new NormalizeCertificateException ("El tipo del certificado no está disponible para el proveedor criptográfico de Arangi: " + CRYPTOGRAPHIC_PROVIDER, e);
1457 }
1458
1459 X509Certificate normalizedCertificate;
1460 try {
1461 normalizedCertificate = (X509Certificate) cf.generateCertificate(bais);
1462 } catch (CertificateException e) {
1463 logger.info ("[Certificate.normalize]::Error generando el certificado", e);
1464 throw new NormalizeCertificateException ("Error generando el certificado", e);
1465 }
1466 try {
1467 bais.close();
1468 } catch (IOException e) {}
1469
1470 return normalizedCertificate;
1471
1472 }
1473
1474
1475
1476
1477
1478
1479
1480
1481 public static String getIssuerKeyIdentifier(X509Certificate certificate) {
1482
1483 byte[] extension = certificate.getExtensionValue(Extension.authorityKeyIdentifier.getId());
1484 if (extension == null) {
1485 return null;
1486 }
1487
1488 ASN1InputStream is1 = null, is2 = null;
1489 try {
1490 is1 = new ASN1InputStream(extension);
1491 byte[] authBytes = ((ASN1OctetString)is1.readObject()).getOctets();
1492 is2 = new ASN1InputStream(authBytes);
1493 AuthorityKeyIdentifier aki = AuthorityKeyIdentifier.getInstance(is2.readObject());
1494 return Util.encodeBase64(aki.getKeyIdentifier());
1495 } catch (Exception e) {
1496 logger.debug("[Certificate.getIssuerKeyIdentifier]::No es posible obtener el IKI del certificado: " + certificate.getSubjectDN(), e);
1497 return null;
1498 } finally {
1499 if (is1 != null) { try { is1.close(); } catch (IOException e) { } }
1500 if (is2 != null) { try { is2.close(); } catch (IOException e) { } }
1501 }
1502 }
1503
1504
1505
1506
1507
1508
1509
1510
1511 public static String getSubjectKeyIdentifier(X509Certificate certificate) {
1512
1513 byte[] extension = certificate.getExtensionValue(Extension.subjectKeyIdentifier.getId());
1514 if (extension == null) {
1515 return null;
1516 }
1517
1518 ASN1InputStream is1 = null, is2 = null;
1519 try {
1520 is1 = new ASN1InputStream(extension);
1521 byte[] authBytes = ((ASN1OctetString)is1.readObject()).getOctets();
1522 is2 = new ASN1InputStream(authBytes);
1523 SubjectKeyIdentifier ski = SubjectKeyIdentifier.getInstance(is2.readObject());
1524 return Util.encodeBase64(ski.getKeyIdentifier());
1525 } catch (Exception e) {
1526 logger.debug("[Certificate.getSubjectKeyIdentifier]::No es posible obtener el SKI del certificado: " + certificate.getSubjectDN(), e);
1527 return null;
1528 } finally {
1529 if (is1 != null) { try { is1.close(); } catch (IOException e) { } }
1530 if (is2 != null) { try { is2.close(); } catch (IOException e) { } }
1531 }
1532 }
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546 public static X500Name stringToBcX500Name(String dn) {
1547
1548
1549 if (dn == null)
1550 return null;
1551
1552 List<RDN> lRDNs = new ArrayList<RDN>();
1553 StringTokenizer st = new StringTokenizer(dn, ",");
1554
1555 while (st.hasMoreTokens()) {
1556
1557 String pair = st.nextToken();
1558 int ix = pair.indexOf("=");
1559
1560 if (ix != -1) {
1561 String key = pair.substring(0, ix).toLowerCase();
1562 String val = pair.substring(ix + 1);
1563
1564
1565 ASN1ObjectIdentifier oid = oids.get(key.toLowerCase());
1566
1567
1568 if (oid == null) {
1569 oid = new ASN1ObjectIdentifier(key);
1570 }
1571
1572 RDN rdn = new RDN(oid, new DERUTF8String(val));
1573 lRDNs.add(rdn);
1574
1575 } else {
1576 logger.info("[Certificate.stringToBcX509Name]:: Algún par OID=valor no es correcto: " + dn);
1577 }
1578 }
1579
1580 return getOrderedX500Name(new X500Name(lRDNs.toArray(new RDN[0])), getDefaultX500FieldOrder());
1581 }
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602 public static X509Certificate generateSelfCertificate(String dn, long validity, String policyId,
1603 PrivateKey privKey, PublicKey pubKey, boolean isCA) throws NoSuchAlgorithmException, CertificateEncodingException, InvalidKeyException, IllegalStateException, SignatureException
1604 {
1605 return generateSelfCertificate(dn, validity, policyId, privKey, pubKey, isCA, ArangiObject.DEFAULT_SIGNING_ALGORITHM);
1606 }
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625 public static X509Certificate generateSelfCertificate(String dn, long validity, String policyId,
1626 PrivateKey privKey, PublicKey pubKey, boolean isCA, String signatureAlgorithm) throws NoSuchAlgorithmException, CertificateEncodingException {
1627
1628
1629 Date firstDate = new Date();
1630
1631
1632 firstDate.setTime(firstDate.getTime() - (10 * 60 * 1000));
1633
1634 Date lastDate = new Date();
1635
1636
1637
1638 byte[] serno = new byte[8];
1639 SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
1640 random.setSeed((new Date().getTime()));
1641 random.nextBytes(serno);
1642
1643
1644 lastDate.setTime(lastDate.getTime() + (validity * (24 * 60 * 60 * 1000)));
1645
1646 SubjectPublicKeyInfo spki = SubjectPublicKeyInfo.getInstance(pubKey.getEncoded());
1647
1648 X509v3CertificateBuilder certgen = new X509v3CertificateBuilder(
1649 stringToBcX500Name(dn),
1650 new java.math.BigInteger(serno),
1651 firstDate,
1652 lastDate,
1653 stringToBcX500Name(dn),
1654 spki);
1655
1656
1657 BasicConstraints bc = new BasicConstraints(isCA);
1658 try {
1659 certgen.addExtension(Extension.basicConstraints, true, bc);
1660 } catch (CertIOException e) {
1661 logger.info("[Certificate.generateSelfCertificate]:: No se puede añadir la extensión basicConstraints", e);
1662 throw new CertificateEncodingException ("No se puede añadir la extensión basicConstraints", e);
1663 }
1664
1665
1666 if (isCA) {
1667 int keyusage = KeyUsage.keyCertSign + KeyUsage.cRLSign;
1668 KeyUsage ku = new KeyUsage(keyusage);
1669 try {
1670 certgen.addExtension(Extension.keyUsage, true, ku);
1671 } catch (CertIOException e) {
1672 logger.info("[Certificate.generateSelfCertificate]:: No se puede añadir la extensión keyusage", e);
1673 throw new CertificateEncodingException ("No se puede añadir la extensión keyusage", e);
1674 }
1675 }
1676
1677
1678 try {
1679 if (isCA) {
1680 SubjectKeyIdentifier ski = new SubjectKeyIdentifier(spki.getEncoded(ASN1Encoding.DER));
1681 AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(spki.getEncoded(ASN1Encoding.DER));
1682
1683 certgen.addExtension(Extension.subjectKeyIdentifier, false, ski);
1684 certgen.addExtension(Extension.authorityKeyIdentifier, false, aki);
1685 }
1686 } catch (IOException e) {
1687 }
1688
1689
1690 if (policyId != null) {
1691 PolicyInformation pi = new PolicyInformation(new ASN1ObjectIdentifier(policyId));
1692 DERSequence seq = new DERSequence(pi);
1693 try {
1694 certgen.addExtension(Extension.certificatePolicies, false, seq);
1695 } catch (CertIOException e) {
1696 logger.debug("[Certificate.generateSelfCertificate]:: No se puede añadir la extensión certificatePolicies", e);
1697 }
1698 }
1699
1700 try {
1701 ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(CRYPTOGRAPHIC_PROVIDER_NAME).build(privKey);
1702 return Util.getCertificate(certgen.build(sha1Signer));
1703 } catch (OperatorCreationException e) {
1704 logger.info("[Certificate.generateSelfCertificate]:: No se puede construir el nuevo certificado", e);
1705 throw new CertificateEncodingException ("No se puede construir el nuevo certificado", e);
1706 } catch (CertificateException e) {
1707 logger.info("[Certificate.generateSelfCertificate]:: No se puede parsear la estructura del nuevo certificado", e);
1708 throw new CertificateEncodingException ("No se puede parsear la estructura del nuevo certificado", e);
1709 }
1710 }
1711
1712
1713
1714
1715
1716
1717
1718
1719 public boolean hasNoRevocationCheck () {
1720 logger.debug("[Certificate.hasNoRevocationCheck]::Entrada");
1721 boolean result = certificate.getExtensionValue(OCSPObjectIdentifiers.id_pkix_ocsp_nocheck.getId()) != null;
1722 logger.debug("[Certificate.hasNoRevocationCheck]::Resultado: " + result);
1723
1724 return result;
1725 }
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735 public CertificateValidationServiceResult validate (List<CertificateValidationService> validationServices) {
1736 return validate (validationServices, new Date());
1737 }
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747 public CertificateValidationServiceResult validate (List<CertificateValidationService> validationServices, Date validationDate) {
1748 logger.debug("[Certificate.validate]::Entrada::" + Arrays.asList(new Object[] { validationServices, validationDate } ));
1749
1750 CertificateValidationServiceResult result = null;
1751
1752
1753 if (getValidityPeriodBeginning().after(validationDate)) {
1754 logger.debug ("[Certificate.validate] :: El certificado con subject DN=" + getSubjectDN().toString() +
1755 " no estará activo hasta " + dateFormat.format(getValidityPeriodBeginning()) + ".");
1756 return new CertificateValidationServiceResult (ValidationResult.RESULT_CERTIFICATE_NOT_ACTIVE, null);
1757 }
1758 if (getValidityPeriodEnd().before(validationDate)) {
1759 logger.debug ("[Certificate.validate] :: El certificado con subject DN=" + getSubjectDN().toString() +
1760 " ha caducado en " + dateFormat.format(getValidityPeriodEnd()) + ".");
1761 return new CertificateValidationServiceResult (ValidationResult.RESULT_CERTIFICATE_NOT_ACTIVE, null);
1762 }
1763
1764
1765 try {
1766 if (isSelfSigned()) {
1767 logger.debug ("[Certificate.validate] :: Certificado con subject DN=" + getSubjectDN().toString() +
1768 " es válido y autofirmado.");
1769 return new CertificateValidationServiceResult (ValidationResult.RESULT_VALID, null);
1770 }
1771 } catch (NormalizeCertificateException e1) {
1772
1773 }
1774
1775 logger.debug("[Certificate.validate] :: El certificado no ha caducado ni es autofirmado, ir a los servicios de validación a validar.");
1776 for (CertificateValidationService service : validationServices) {
1777 if (service != null) {
1778 try {
1779 result = service.validate(this, null);
1780 } catch (Exception e) {
1781 logger.info("[Certificate.validate]::No se ha podido validar en " + service, e);
1782 continue;
1783 }
1784 if (result.getResult() == ValidationResult.RESULT_VALID) {
1785 break;
1786 }
1787 }
1788 }
1789
1790
1791 if (result != null && result.getResult() == ValidationResult.RESULT_CERTIFICATE_REVOKED) {
1792 if (result.getRevocationDate() != null && result.getRevocationDate().after(validationDate)) {
1793 logger.debug("[Certificate.validate] :: Aunque el certificado está revocado no lo estaba en la fecha de la validación. Fecha de revocación: " + result.getRevocationDate());
1794 result.setResult(ValidationResult.RESULT_VALID);
1795 }
1796 }
1797
1798
1799 if (result == null) {
1800 logger.debug("[Certificate.validate] :: No se ha podido validar el certificado");
1801 result = new CertificateValidationServiceResult(ValidationResult.RESULT_CERTIFICATE_CANNOT_BE_VALIDATED, null);
1802 }
1803
1804 logger.debug("[Certificate.validate]::resultado: " + result.getResult());
1805 return result;
1806 }
1807
1808
1809
1810
1811
1812
1813
1814 public Map<String,String> getData (List<CertificateDataService> dataServices) {
1815 logger.debug("[Certificate.getData]::Entrada::" + Arrays.asList(new Object[] { dataServices } ));
1816
1817 for(CertificateDataService service : dataServices) {
1818 try {
1819 Map<String,String> data = service.getData(this, null);
1820 if (data != null) {
1821 logger.debug("[Certificate.getData]::Obtenidos los campos: " + data);
1822 return data;
1823 }
1824 } catch (Exception e) {
1825 logger.info("[Certificate.getData]::No se han podido obtener los campos en " + service);
1826 }
1827 }
1828
1829 logger.debug("[Certificate.getData]::No se han podido obtener los campos");
1830 return null;
1831 }
1832
1833
1834
1835
1836
1837
1838 public String getCertificateEmail () {
1839
1840 logger.debug ("[Certificate.getCertificateEmail]::Entrada");
1841
1842 List altNames;
1843 try {
1844 altNames = getSubjectAlternativeName();
1845 } catch (CertificateFieldException e) {
1846 logger.info ("[Certificate.getCertificateEmail]::No ha sido posible obtener el e-mail", e);
1847 return null;
1848 }
1849
1850
1851 if (altNames == null || altNames.isEmpty()) {
1852 return null;
1853 }
1854
1855
1856 return (String) ((AlternativeNameElement) altNames.get(0)).getValue();
1857 }
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868 public OCSPClient[] getOCSPClients () {
1869
1870 logger.debug ("[Certificate.getOCSPClients]::Entrada");
1871
1872 List lOCSPClients = new ArrayList ();
1873
1874
1875 String urlsOCSP [] = null;
1876 try {
1877 urlsOCSP = getOcspUrls();
1878 for (int i = 0; i < urlsOCSP.length; i++) {
1879 try {
1880 lOCSPClients.add (new OCSPClient (new URL (urlsOCSP[i])));
1881 } catch (MalformedURLException e1) {
1882
1883 logger.debug("[Certificate.getOCSPClients]::La URL no es válida::" + urlsOCSP[i]);
1884 }
1885 }
1886
1887 return (OCSPClient[]) lOCSPClients.toArray(new OCSPClient[0]);
1888 } catch (Exception e) {
1889
1890 logger.debug("[Certificate.getOCSPClients]::No se han encontrado URLs para OCSP ni en " +
1891 "un fichero validation.xml ni en el campo AIA");
1892 return new OCSPClient [0];
1893 }
1894 }
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912 public OCSPResponse getOCSPResponse () {
1913
1914 logger.debug ("[Certificate.getOCSPResponse]::Entrada");
1915
1916 OCSPClient[] ocspClients = getOCSPClients();
1917 OCSPResponse response = null;
1918 for (int i = 0; i < ocspClients.length; i++) {
1919 try {
1920 response = ocspClients[i].getOCSPResponse(this);
1921 break;
1922 } catch (Exception e) {
1923 logger.info("[Certificate.getOCSPResponse]::No se puede obtener respuesta OCSP de " + ocspClients[i].getURL(), e);
1924 }
1925 }
1926
1927 return response;
1928 }
1929
1930 @Override
1931 public boolean equals(Object obj) {
1932
1933
1934 if (!(obj instanceof Certificate)) {
1935 return false;
1936 }
1937
1938
1939 Certificate certificateToCompare = (Certificate) obj;
1940 IssuerAndSerialNumber issuerSN1;
1941 IssuerAndSerialNumber issuerSN2;
1942 try {
1943 issuerSN1 = certificateToCompare.getIssuerAndSerialNumber();
1944 issuerSN2 = getIssuerAndSerialNumber();
1945 } catch (CertificateFieldException e) {
1946 return false;
1947 }
1948
1949 if (issuerSN1.getName().equals(issuerSN2.getName()) &&
1950 issuerSN1.getSerialNumber().getValue().equals(issuerSN2.getSerialNumber().getValue())) {
1951 return true;
1952 }
1953
1954 return false;
1955 }
1956
1957
1958
1959
1960
1961
1962
1963
1964 private void initialize (X509Certificate certificate) throws NormalizeCertificateException {
1965
1966
1967 this.certificate = normalize (certificate);
1968
1969
1970 try {
1971 ASN1InputStream ais = new ASN1InputStream(certificate.getEncoded());
1972 ASN1Primitive obj = ais.readObject();
1973 ASN1Sequence seq = (ASN1Sequence)obj;
1974 ais.close();
1975 this.asn1Certificate = org.bouncycastle.asn1.x509.Certificate.getInstance(seq);
1976 } catch (Exception e) {
1977 logger.info("[Certificate.initialize]::No ha sido posible obtener una representación ASN.1 del certificado", e);
1978 throw new NormalizeCertificateException ("No ha sido posible obtener una representación ASN.1 del certificado", e);
1979 }
1980
1981 }
1982
1983
1984
1985
1986 private List getAlternativeNames(byte[] extVal) throws CertificateParsingException {
1987 List result = new ArrayList ();
1988 if (extVal == null) {
1989 return result;
1990 }
1991 try {
1992 byte[] extnValue = DEROctetString.getInstance(ASN1Primitive.fromByteArray(extVal)).getOctets();
1993 Enumeration it = DERSequence.getInstance(ASN1Primitive.fromByteArray(extnValue)).getObjects();
1994 while (it.hasMoreElements()) {
1995 GeneralName genName = GeneralName.getInstance(it.nextElement());
1996 AlternativeNameElement element = new AlternativeNameElement ();
1997 element.setType(genName.getTagNo());
1998 switch (genName.getTagNo()) {
1999 case GeneralName.ediPartyName:
2000 case GeneralName.x400Address:
2001 case GeneralName.otherName:
2002 element.setValue(genName.getName().toASN1Primitive());
2003 break;
2004 case GeneralName.directoryName:
2005 element.setValue(X500Name.getInstance(genName.getName()));
2006 break;
2007 case GeneralName.dNSName:
2008 case GeneralName.rfc822Name:
2009 case GeneralName.uniformResourceIdentifier:
2010 element.setValue(((ASN1String)genName.getName()).getString());
2011 break;
2012 case GeneralName.registeredID:
2013 element.setValue(ASN1ObjectIdentifier.getInstance(genName.getName()).getId());
2014 break;
2015 case GeneralName.iPAddress:
2016 element.setValue(new String (DEROctetString.getInstance(genName.getName()).getOctets()));
2017 break;
2018 default:
2019 throw new IOException("Bad tag number: " + genName.getTagNo());
2020 }
2021
2022 result.add(element);
2023 }
2024 } catch (Exception e) {
2025 throw new CertificateParsingException(e.getMessage());
2026 }
2027 return result;
2028 }
2029
2030
2031
2032
2033
2034
2035 private static List<ASN1ObjectIdentifier> getDefaultX500FieldOrder(){
2036
2037 List<ASN1ObjectIdentifier> fieldOrder = new ArrayList<ASN1ObjectIdentifier>();
2038
2039 for (int i = 0; i < dNObjects.length; i++) {
2040 fieldOrder.add(oids.get(dNObjects[i].toLowerCase()));
2041 }
2042
2043 return fieldOrder;
2044
2045 }
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055 private static X500Name getOrderedX500Name( X500Name x500Name, List<ASN1ObjectIdentifier> ordering ){
2056
2057
2058 if ( ordering == null ){ ordering = new ArrayList<ASN1ObjectIdentifier>(); }
2059
2060
2061 List<RDN> newRDNs = new ArrayList<RDN>();
2062
2063 HashMap<ASN1ObjectIdentifier,Object> ht = new HashMap<ASN1ObjectIdentifier,Object>();
2064 Iterator<ASN1ObjectIdentifier> it = ordering.iterator();
2065
2066 logger.debug("Add ordered fields: ");
2067
2068 while( it.hasNext() ) {
2069 ASN1ObjectIdentifier oid = it.next();
2070
2071 if ( !ht.containsKey(oid) ){
2072 List<RDN> valueList = getX500NameFields(x500Name, oid);
2073
2074
2075 if ( valueList != null ){
2076 Iterator<RDN> itVals = valueList.iterator();
2077
2078 while( itVals.hasNext() ){
2079 RDN value = itVals.next();
2080 ht.put(oid, value);
2081 newRDNs.add(value);
2082 }
2083
2084 }
2085 }
2086 }
2087
2088 RDN[] rDNs = x500Name.getRDNs();
2089
2090 logger.debug("Add unespected fields to the end: ");
2091
2092 for ( int i=0; i<rDNs.length; i++ ) {
2093
2094 ASN1ObjectIdentifier oid = rDNs[i].getFirst().getType();
2095
2096 if ( !ht.containsKey(oid) ){
2097 List<RDN> valueList = getX500NameFields(x500Name, oid);
2098
2099
2100 if ( valueList != null ){
2101 Iterator<RDN> itVals = valueList.iterator();
2102
2103 while( itVals.hasNext() ){
2104 RDN value = itVals.next();
2105 ht.put(oid, value);
2106 newRDNs.add(value);
2107 logger.debug("added --> " + oid + " val: " + value);
2108 }
2109
2110 }
2111 }
2112
2113 }
2114
2115
2116 X500Name orderedName = new X500Name(newRDNs.toArray(new RDN[0]));
2117 logger.debug("[getOrderedX509Name.retorna]:: " + orderedName);
2118
2119 return orderedName;
2120
2121 }
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131 private static List<RDN> getX500NameFields( X500Name name, ASN1ObjectIdentifier id ){
2132
2133 RDN[] rDNs = name.getRDNs();
2134 List<RDN> vRet = null;
2135
2136 for (int j = 0; j < rDNs.length; j++) {
2137 if ( rDNs[j].getFirst().getType().equals(id)) {
2138 if ( vRet == null ){ vRet = new ArrayList<RDN>(); }
2139 vRet.add(rDNs[j]);
2140 }
2141
2142 }
2143
2144 return vRet;
2145
2146 }
2147
2148
2149 }