1 package org.eparapher.core.crypto.cert;
2
3 import java.io.BufferedReader;
4 import java.io.ByteArrayInputStream;
5 import java.io.ByteArrayOutputStream;
6 import java.io.DataOutputStream;
7 import java.io.File;
8 import java.io.FileInputStream;
9 import java.io.FileWriter;
10 import java.io.IOException;
11 import java.io.InputStream;
12 import java.io.InputStreamReader;
13 import java.io.PrintStream;
14 import java.security.NoSuchProviderException;
15 import java.security.cert.CertPath;
16 import java.security.cert.Certificate;
17 import java.security.cert.CertificateEncodingException;
18 import java.security.cert.CertificateException;
19 import java.security.cert.CertificateFactory;
20 import java.security.cert.CertificateParsingException;
21 import java.security.cert.X509CRL;
22 import java.security.cert.X509Certificate;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Enumeration;
26 import java.util.HashSet;
27 import java.util.Hashtable;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Set;
31
32 import org.apache.log4j.Logger;
33 import org.bouncycastle.asn1.ASN1InputStream;
34 import org.bouncycastle.asn1.ASN1OctetString;
35 import org.bouncycastle.asn1.ASN1Sequence;
36 import org.bouncycastle.asn1.ASN1TaggedObject;
37 import org.bouncycastle.asn1.DEREncodable;
38 import org.bouncycastle.asn1.DERInteger;
39 import org.bouncycastle.asn1.DERNull;
40 import org.bouncycastle.asn1.DERObject;
41 import org.bouncycastle.asn1.DERObjectIdentifier;
42 import org.bouncycastle.asn1.DERTaggedObject;
43 import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
44 import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
45 import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
46 import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
47 import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
48 import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
49 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
50 import org.bouncycastle.asn1.x509.CRLDistPoint;
51 import org.bouncycastle.asn1.x509.DistributionPoint;
52 import org.bouncycastle.asn1.x509.X509Extensions;
53 import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
54 import org.bouncycastle.cms.CMSException;
55 import org.bouncycastle.cms.CMSSignedData;
56 import org.bouncycastle.jce.ECNamedCurveTable;
57 import org.bouncycastle.jce.PKCS10CertificationRequest;
58 import org.bouncycastle.jce.provider.X509CertificateObject;
59 import org.bouncycastle.util.Strings;
60 import org.bouncycastle.util.encoders.Base64;
61 import org.bouncycastle.x509.NoSuchStoreException;
62 import org.bouncycastle.x509.X509CertStoreSelector;
63 import org.bouncycastle.x509.X509Store;
64 import org.eparapher.core.EParapherManager;
65 import org.eparapher.core.tools.FileUtil;
66
67
68 public class X509Util {
69
70 private static Logger log = Logger.getLogger(X509Util.class);
71
72 private static Hashtable algorithms = new Hashtable();
73 private static Hashtable params = new Hashtable();
74 private static Set noParams = new HashSet();
75
76 private static final String X509_CERT_TYPE = "X.509";
77 private static final String PKCS7_ENCODING = "PKCS7";
78 public static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
79 public static final String END_CERT = "-----END CERTIFICATE-----";
80 public static final int CERT_LINE_LENGTH = 64;
81 public static final String BEGIN_CERT_REQ = "-----BEGIN CERTIFICATE REQUEST-----";
82 public static final String END_CERT_REQ = "-----END CERTIFICATE REQUEST-----";
83 public static final int CERT_REQ_LINE_LENGTH = 76;
84
85 static
86 {
87 algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption);
88 algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption);
89 algorithms.put("MD5WITHRSAENCRYPTION", PKCSObjectIdentifiers.md5WithRSAEncryption);
90 algorithms.put("MD5WITHRSA", PKCSObjectIdentifiers.md5WithRSAEncryption);
91 algorithms.put("SHA1WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha1WithRSAEncryption);
92 algorithms.put("SHA1WITHRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption);
93 algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption);
94 algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption);
95 algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption);
96 algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption);
97 algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption);
98 algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption);
99 algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption);
100 algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption);
101 algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
102 algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
103 algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
104 algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
105 algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS);
106 algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
107 algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160);
108 algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
109 algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128);
110 algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
111 algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256);
112 algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1);
113 algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1);
114 algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224);
115 algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256);
116 algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1);
117 algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1);
118 algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224);
119 algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256);
120 algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384);
121 algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512);
122 algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
123 algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
124 algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
125 algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
126 algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
127
128
129
130
131
132 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1);
133 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224);
134 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256);
135 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384);
136 noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512);
137 noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1);
138 noParams.add(NISTObjectIdentifiers.dsa_with_sha224);
139 noParams.add(NISTObjectIdentifiers.dsa_with_sha256);
140
141
142
143
144 noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94);
145 noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001);
146
147
148
149
150 AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, new DERNull());
151 params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20));
152
153 AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, new DERNull());
154 params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28));
155
156 AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, new DERNull());
157 params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32));
158
159 AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, new DERNull());
160 params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48));
161
162 AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, new DERNull());
163 params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64));
164 }
165
166 private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize)
167 {
168 return new RSASSAPSSparams(
169 hashAlgId,
170 new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId),
171 new DERInteger(saltSize),
172 new DERInteger(1));
173 }
174
175 static DERObjectIdentifier getAlgorithmOID(String algorithmName)
176 {
177 algorithmName = Strings.toUpperCase(algorithmName);
178
179 if (algorithms.containsKey(algorithmName))
180 {
181 return (DERObjectIdentifier)algorithms.get(algorithmName);
182 }
183
184 return new DERObjectIdentifier(algorithmName);
185 }
186
187 static AlgorithmIdentifier getSigAlgID( DERObjectIdentifier sigOid, String algorithmName)
188 {
189 if (noParams.contains(sigOid))
190 {
191 return new AlgorithmIdentifier(sigOid);
192 }
193
194 algorithmName = Strings.toUpperCase(algorithmName);
195
196 if (params.containsKey(algorithmName))
197 {
198 return new AlgorithmIdentifier(sigOid, (DEREncodable)params.get(algorithmName));
199 }
200 else
201 {
202 return new AlgorithmIdentifier(sigOid, new DERNull());
203 }
204 }
205
206 public static Iterator<String> getAlgNames()
207 {
208 Enumeration<String> e = algorithms.keys();
209 List<String> l = new ArrayList<String>();
210
211 while (e.hasMoreElements())
212 {
213 l.add(e.nextElement());
214 }
215
216 return l.iterator();
217 }
218 public static String[] getECSpecsNames()
219 {
220
221 Enumeration e = ECNamedCurveTable.getNames();
222 List<String> l = new ArrayList<String>();
223
224 while (e.hasMoreElements())
225 l.add((String) e.nextElement());
226
227 return l.toArray(new String[] {});
228 }
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
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
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333 public static DERObject getExtensionValue(X509Certificate cert, String oid)
334 throws IOException {
335 byte[] bytes = cert.getExtensionValue(oid);
336 if (bytes == null) {
337 return null;
338 }
339 ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(bytes));
340 ASN1OctetString octs = (ASN1OctetString) aIn.readObject();
341 aIn = new ASN1InputStream(new ByteArrayInputStream(octs.getOctets()));
342 return aIn.readObject();
343 }
344
345 private static String getStringFromGeneralNames(DERObject names) {
346 ASN1Sequence namesSequence = ASN1Sequence.getInstance((ASN1TaggedObject)names, false);
347 if (namesSequence.size() == 0) {
348 return null;
349 }
350 DERTaggedObject taggedObject = (DERTaggedObject)namesSequence.getObjectAt(0);
351 return new String(ASN1OctetString.getInstance(taggedObject, false).getOctets());
352 }
353
354
355
356
357 public static DistributionPoint[] getCrlDistributionPoint(X509Certificate certificate)
358 throws CertificateParsingException {
359 try {
360 DERObject obj = getExtensionValue(certificate, X509Extensions.CRLDistributionPoints.getId());
361 if (obj != null) {
362 CRLDistPoint crldp = new CRLDistPoint((ASN1Sequence) obj);
363 DistributionPoint[] alldp = crldp.getDistributionPoints();
364 return alldp;
365 }
366 }
367 catch (Exception e) {
368 log.error("Error parsing CrlDistributionPoint", e);
369 throw new CertificateParsingException(e.toString());
370 }
371 return null;
372 }
373
374
375
376 public static X509Certificate[] convertCertChaintoX509( Certificate[] certChain) {
377 if (certChain==null)
378 return null;
379 X509Certificate[] tempX509CertificateChain = new X509Certificate[certChain.length];
380 for (int i = 0; i < certChain.length; i++) {
381 if ( certChain[i] instanceof X509Certificate)
382 tempX509CertificateChain[i] = (X509Certificate) certChain[i];
383 }
384 return tempX509CertificateChain;
385 }
386
387
388
389
390
391
392 public static String getCertBase64Encoded(X509Certificate cert) {
393 try {
394 String sTmp = new String(Base64.encode(cert.getEncoded()));
395 String sEncoded = BEGIN_CERT + "\r\n";
396 for(int iCnt = 0; iCnt < sTmp.length(); iCnt += 64)
397 {
398 int iLineLength;
399 if(iCnt + 64 > sTmp.length())
400 iLineLength = sTmp.length() - iCnt;
401 else
402 iLineLength = 64;
403 sEncoded = sEncoded + sTmp.substring(iCnt, iCnt + iLineLength) + "\r\n";
404 }
405
406 sEncoded = sEncoded + END_CERT + "\r\n";
407 return sEncoded;
408 } catch(CertificateException e) {
409 log.debug(""+e.getLocalizedMessage(),e);
410 }
411 return null;
412 }
413
414
415
416
417
418
419
420
421 public static boolean saveX509toFile(String filename, X509Certificate cert) {
422 if (filename==null || filename.equals("")) {
423 log.warn("Bad filename to save certificate");
424 return false;
425 }
426 if ((new File(filename)).exists())
427 if ( !EParapherManager.getInstance().getUI().askUserYesNo( filename+ "already exists.\r\nOverwrite it?") ) {
428 log.warn("not overwriting " + filename);
429 return false;
430 }
431
432 FileWriter output;
433 try {
434 output = new FileWriter(filename, false);
435 output.write(getCertBase64Encoded(cert));
436 output.flush();
437 output.close();
438 return true;
439 } catch (IOException e) {
440 String msg = "Error writing certificate to " + filename + " : " + e.getMessage();
441 EParapherManager.getInstance().getUI().errorMessage(msg,e);
442 log.error(msg, e);
443 }
444 return false;
445 }
446
447
448
449
450
451
452
453
454
455
456
457 public static Collection<X509Certificate> getCertsFromPKCS7(String p7bfilename) throws IOException, CertificateException, CMSException, NoSuchProviderException, NoSuchStoreException {
458 log.info("Importing certificates from PKCS7 file " + p7bfilename);
459
460
461 byte[] p7bcontent = FileUtil.readFile(p7bfilename);
462 CMSSignedData data = new CMSSignedData(p7bcontent);
463 X509Store store = data.getCertificates("Collection", "BC");
464
465
466 X509CertStoreSelector selector = new X509CertStoreSelector();
467 selector.setBasicConstraints(-2);
468 Collection certificates = store.getMatches(selector);
469
470 Integer size = certificates.size();
471 Iterator it = certificates.iterator();
472 log.debug("Number of final certificates in the store: " + size);
473 while(it.hasNext()) {
474 X509Certificate certificate = (X509Certificate) it.next();
475 log.info("Found certificate: " + certificate.getSubjectDN().toString() +", serial:"+certificate.getSerialNumber());
476 }
477
478 return certificates;
479 }
480
481
482
483
484
485
486
487
488
489 public static Collection<X509Certificate> getCertsFromPEM(String certFile) throws IOException, CertificateException {
490 log.info("Importing certificates from PEM file " + certFile);
491 InputStream inStrm = null;
492 Collection certs = null;
493 try {
494 inStrm = new FileInputStream(certFile);
495 certs = getCertsFromPEM(inStrm);
496 } catch (IOException e ) {
497 log.debug("error while parsing " + certFile + " : "+e.getLocalizedMessage(),e);
498 } catch (CertificateException e) {
499 log.debug("error while parsing certificate in " + certFile + " : "+e.getLocalizedMessage(),e);
500 } finally {
501
502 if (inStrm != null) inStrm.close();
503 }
504 return certs;
505 }
506
507
508
509
510
511
512
513
514
515
516 public static Collection<X509Certificate> getCertsFromPEM(InputStream certstream) throws IOException, CertificateException {
517 ArrayList ret = new ArrayList();
518 BufferedReader bufRdr = null;
519 ByteArrayOutputStream ostr = null;
520 PrintStream opstr = null;
521 try {
522 bufRdr = new BufferedReader(new InputStreamReader(certstream));
523 while (bufRdr.ready()) {
524 ostr = new ByteArrayOutputStream();
525 opstr = new PrintStream(ostr);
526 String temp;
527 while ((temp = bufRdr.readLine()) != null
528 && !temp.equals(BEGIN_CERT))
529 continue;
530 if (temp == null)
531 throw new IOException("Error in " + certstream.toString()
532 + ", missing " + BEGIN_CERT + " boundary");
533 while ((temp = bufRdr.readLine()) != null
534 && !temp.equals(END_CERT))
535 opstr.print(temp);
536 if (temp == null)
537 throw new IOException("Error in " + certstream.toString()
538 + ", missing " + END_CERT + " boundary");
539 opstr.close();
540
541 byte[] certbuf = Base64.decode(ostr.toByteArray());
542 ostr.close();
543
544 CertificateFactory cf = getCertificateFactory();
545 X509Certificate x509cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(certbuf));
546 ret.add(x509cert);
547 }
548 } finally {
549 if (bufRdr != null) bufRdr.close();
550 if (opstr != null) opstr.close();
551 if (ostr != null) ostr.close();
552 }
553
554 return ret;
555 }
556
557
558
559
560
561
562
563
564
565 public static PKCS10CertificationRequest getCSRFromPEM(String csrFile) throws IOException, CertificateException {
566
567 log.info("Loading certificate signing request from PEM file " + csrFile);
568
569 BufferedReader bufRdr = null;
570 ByteArrayOutputStream ostr = null;
571 PrintStream opstr = null;
572 PKCS10CertificationRequest pkcs10 = null;
573
574 try {
575 InputStream inStrm = new FileInputStream(csrFile);
576 bufRdr = new BufferedReader(new InputStreamReader(inStrm));
577
578 while (bufRdr.ready()) {
579 ostr = new ByteArrayOutputStream();
580 opstr = new PrintStream(ostr);
581 String temp;
582
583
584 while ((temp = bufRdr.readLine()) != null
585 && !temp.equals(BEGIN_CERT_REQ))
586 continue;
587 if (!temp.equals(BEGIN_CERT_REQ))
588 throw new IOException("Error in " + csrFile + ", missing " + BEGIN_CERT_REQ + " boundary");
589
590
591 while ((temp = bufRdr.readLine()) != null
592 && !temp.equals(END_CERT_REQ))
593 opstr.print(temp);
594
595
596 if (!temp.equals(END_CERT_REQ))
597 throw new IOException("Error in "+csrFile+", missing " + END_CERT_REQ + " boundary");
598 opstr.close();
599
600 byte[] certbuf = Base64.decode(ostr.toByteArray());
601 ostr.close();
602
603
604 pkcs10 = new PKCS10CertificationRequest(certbuf);
605 }
606 } finally {
607 if (bufRdr != null) bufRdr.close();
608 if (opstr != null) opstr.close();
609 }
610 return pkcs10;
611 }
612
613 public static byte[] getCertEncodedPkcs7(X509Certificate cert) {
614 return getCertsEncodedPkcs7(new X509Certificate[] { cert } );
615 }
616
617 public static byte[] getCertsEncodedPkcs7(X509Certificate certs[]) {
618 try
619 {
620 ArrayList alCerts = new ArrayList();
621 for(int iCnt = 0; iCnt < certs.length; iCnt++)
622 alCerts.add(certs[iCnt]);
623 CertificateFactory cf = CertificateFactory.getInstance("X.509");
624 CertPath cp = cf.generateCertPath(alCerts);
625 return cp.getEncoded("PKCS7");
626 } catch(CertificateException e) {
627 log.error("getCertsEncodedPkcs7 error :",e);
628 }
629 return null;
630 }
631 public static CertificateFactory getCertificateFactory() {
632 try {
633 return CertificateFactory.getInstance("X.509", "BC");
634 } catch (NoSuchProviderException e) {
635 log.debug("error while getting BC Certificate Factory : " + e.getLocalizedMessage(),e);
636 } catch (CertificateException e) {
637 log.debug("error while getting BC Certificate Factory : " + e.getLocalizedMessage(),e);
638 }
639 return null;
640 }
641
642
643
644 public static String toHexString ( byte[] b ) {
645 StringBuffer sb = new StringBuffer( b.length * 2 );
646 for ( int i=0; i<b.length; i++ ) {
647
648 sb.append( hexChar [( b[i] & 0xf0 ) >>> 4] );
649
650 sb.append( hexChar [b[i] & 0x0f] );
651 }
652 return sb.toString();
653 }
654
655
656 static char[] hexChar = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f'};
657
658
659
660
661
662 public static byte[] fromHexString ( String s )
663 {
664 int stringLength = s.length();
665 if ( (stringLength & 0x1) != 0 )
666 {
667 throw new IllegalArgumentException ( "fromHexString requires an even number of hex characters" );
668 }byte[] b = new byte[stringLength / 2];
669
670 for ( int i=0,j=0; i<stringLength; i+=2,j++ )
671 {
672 int high = charToNibble( s.charAt ( i ) );
673 int low = charToNibble( s.charAt ( i+1 ) );
674 b[j] = (byte)( ( high << 4 ) | low );
675 }
676 return b;
677 }
678
679
680
681
682
683
684
685
686 public static X509Certificate getBCCertificate(X509Certificate cert) {
687 if ( cert!=null && !(cert instanceof X509CertificateObject) )
688 try {
689 ByteArrayInputStream bais = new ByteArrayInputStream(cert.getEncoded());
690 cert = (X509Certificate) getCertificateFactory().generateCertificate(bais);
691 } catch (CertificateEncodingException e) {
692 log.error("Certificate conversion to Bouncy Castle Object error",e);
693 } catch (CertificateException e) {
694 log.error("Certificate conversion to Bouncy Castle Object error",e);
695 } catch (Exception e) {
696 log.error("Certificate conversion to Bouncy Castle Object error",e);
697 }
698 return cert;
699 }
700
701
702
703
704
705
706
707
708 private static int charToNibble ( char c )
709 {
710 if ( '0' <= c && c <= '9' )
711 {
712 return c - '0';
713 }
714 else if ( 'a' <= c && c <= 'f' )
715 {
716 return c - 'a' + 0xa;
717 }
718 else if ( 'A' <= c && c <= 'F' )
719 {
720 return c - 'A' + 0xa;
721 }
722 else
723 {
724 throw new IllegalArgumentException ( "Invalid hex character: " + c );
725 }
726 }
727
728 public static X509CRL loadCRLFromDP(DistributionPoint dp) {
729
730 return null;
731 }
732 }